All files / ext.wikilambda.app/composables usePageTitle.js

100% Statements 123/123
100% Branches 17/17
100% Functions 6/6
100% Lines 123/123

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 12423x 23x 23x 23x 23x 23x 23x 23x 23x 23x 23x 23x 23x 23x 23x 23x 23x 23x 23x 23x 23x 69x 69x 69x 69x 69x 69x 69x 69x 69x 69x 69x 69x 69x 69x 69x 69x 69x 69x 69x 69x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 69x 69x 69x 69x 69x 69x 69x 69x 69x 69x 23x 23x 12x 12x 11x 11x 16x 2x 2x 1x 1x 2x 10x 23x 69x 69x 69x 69x 69x 23x 23x 23x 23x 23x 23x 23x 23x 23x 23x 23x 23x 23x 69x 69x 69x 69x 69x 69x 69x 69x 69x 69x 69x 10x 10x 10x 10x 10x 10x 10x 10x 9x 9x 9x 9x 9x 10x 10x 69x 69x 23x  
/*!
 * Page Title composable for Vue 3 Composition API.
 * Provides functions to change page titles outside Vue scope
 *
 * @module ext.wikilambda.app.composables.usePageTitle
 * @copyright 2020– Abstract Wikipedia team; see AUTHORS.txt
 * @license MIT
 */
'use strict';
 
const { inject } = require( 'vue' );
const { storeToRefs } = require( 'pinia' );
const useMainStore = require( '../store/index.js' );
const { getZMonolingualLangValue } = require( '../utils/zobjectUtils.js' );
 
/**
 * Page Title composable
 *
 * @return {Object} Page Title composable API
 */
module.exports = function usePageTitle() {
	const i18n = inject( 'i18n' );
 
	const mainStore = useMainStore();
	const {
		getFallbackLanguageZids,
		getLabelData,
		getLanguageIsoCodeOfZLang,
		getUserLangZid,
		getZObjectByKeyPath,
		getZPersistentName
	} = storeToRefs( mainStore );
 
	/**
	 * Build a title data object from a resolved name terminal value.
	 *
	 * @param {Object} name - terminal value containing keyPath and value
	 * @param {boolean} hasChip
	 * @return {{title: string, hasChip: boolean, chip: string, chipName: string}}
	 */
	function buildTitleData( name, hasChip ) {
		const parentKeyPath = name.keyPath.split( '.' ).slice( 0, -2 );
		const monolingual = getZObjectByKeyPath.value( parentKeyPath );
		const langZid = getZMonolingualLangValue( monolingual );
		const langCode = getLanguageIsoCodeOfZLang.value( langZid );
		return {
			title: name.value,
			hasChip,
			chip: langCode,
			chipName: getLabelData.value( langZid ).label
		};
	}
 
	/**
	 * Resolve the best available title data for the current ZObject:
	 * - user language label if available
	 * - first fallback language label (with chip) if available
	 * - null title with no chip when untitled
	 *
	 * @return {{title: string|null, hasChip: boolean, chip: string|null, chipName: string|null}}
	 */
	function resolveTitleData() {
		const name = getZPersistentName.value( getUserLangZid.value );
		if ( name ) {
			return buildTitleData( name, false );
		}
		const fallbackLanguages = getFallbackLanguageZids.value
			.slice( getFallbackLanguageZids.value.indexOf( getUserLangZid.value ) + 1 );
		for ( const lang of fallbackLanguages ) {
			const fallbackName = getZPersistentName.value( lang );
			if ( fallbackName ) {
				return buildTitleData( fallbackName, true );
			}
		}
		return { title: null, hasChip: false, chip: null, chipName: null };
	}
 
	/**
	 * Update the ZObject edit-page heading and language chip in the DOM.
	 */
	function updateZObjectPageTitle() {
		const titleData = resolveTitleData();
		// eslint-disable-next-line no-jquery/no-global-selector
		const $firstHeading = $( '#firstHeading' );
		const $pageTitle = $firstHeading.find( '.ext-wikilambda-editpage-header__title--function-name' ).first();
		const $langChip = $firstHeading.find( '.ext-wikilambda-editpage-header__bcp47-code-name' );
		$pageTitle
			.toggleClass( 'ext-wikilambda-editpage-header__title--untitled', !titleData.title )
			.text( titleData.title || i18n( 'wikilambda-editor-default-name' ).text() );
		$langChip
			.toggleClass( 'ext-wikilambda-editpage-header__bcp47-code--hidden', !titleData.hasChip )
			.text( titleData.chip )
			.attr( 'data-title', titleData.chipName );
	}
 
	/**
	 * Update the Special:CreateAbstract page heading once a Wikidata entity is selected.
	 * PHP has already rendered the editpage-header wrapper with a title span; this function
	 * updates that span's text (using the label when available) and finds or creates the
	 * copyable QID chip span, mirroring the structure PHP builds for the pre-selected case.
	 *
	 * @param {string} qid
	 * @param {string} [label]
	 */
	function updateAbstractPageTitle( qid, label ) {
		// eslint-disable-next-line no-jquery/no-global-selector
		const $firstHeading = $( '#firstHeading' );
		const titleText = i18n( 'wikilambda-abstract-special-create-qid' ).params( [ label || qid ] ).text();
 
		$firstHeading.find( '.ext-wikilambda-editpage-header__title' ).text( titleText );
 
		let $qidSpan = $firstHeading.find( '.ext-wikilambda-editpage-header__qid' );
		if ( !$qidSpan.length ) {
			$qidSpan = $( '<span>' )
				.addClass( 'ext-wikilambda-editpage-header__qid' )
				.attr( { role: 'button', tabindex: '0', 'aria-live': 'polite' } );
			$firstHeading.find( '.ext-wikilambda-editpage-header' ).append( ' ', $qidSpan );
		}
		$qidSpan.text( qid );
	}
 
	return { updateZObjectPageTitle, updateAbstractPageTitle };
};