מדיה ויקי:Gadget-PageNumbers.js

מתוך ויקיטקסט, מאגר הטקסטים החופשי

הערה: לאחר הפרסום, ייתכן שיהיה צורך לנקות את זיכרון המטמון (cache) של הדפדפן כדי להבחין בשינויים.

  • פיירפוקס / ספארי: להחזיק את המקש Shift בעת לחיצה על טעינה מחדש (Reload) או ללחוץ על צירוף המקשים Ctrl-F5 או Ctrl-R (במחשב מק: ⌘-R).
  • גוגל כרום: ללחוץ על צירוף המקשים Ctrl-Shift-R (במחשב מק: ⌘-Shift-R).
  • אינטרנט אקספלורר / אדג': להחזיק את המקש Ctrl בעת לחיצה על רענן (Refresh) או ללחוץ על צירוף המקשים Ctrl-F5.
  • אופרה: ללחוץ על Ctrl-F5.
/* eslint-disable camelcase */

/* Based on [[en:MediaWiki:Gadget-PageNumbers-core.js]].
Import by [[User:Shalomori123]].

To make it work here, for future versions, replace the next:

1) Replace:
```
				// wait for the layouts code to signal that the containers are ready
				mw.hook( 'ws.layouts.ready' ).add( function () {
					doInit();
				} );
```

TO:
```
				doInit();
```

2) Delete completly the definitions of `layout` and `display`,
	and write instead:
	`var layout, display,`

3) Delete the lines of:
```
			layout.init();
			display.init();
```

*/

( function ( mw, $ ) {

	function initSetting( cookie_name, init ) {
	/* Sets JS variable to (in order of preference):
		2. current cookie value
		3. provided init parameter
		4. false
	*/
		// get current value of appropriate cookie
		var cookie_val = mw.cookie.get( cookie_name );

		// If JS variable still has no value, use provided init value. If no init
		// value provided, use false.
		if ( typeof cookie_val === 'undefined' || cookie_val === null ) {
			cookie_val = init || false;
		}

		// If JS variable is now the string "false", convert to boolean false
		// (to fix JS confusion where "false" string evaluates to true).
		if ( cookie_val === 'false' ) {
			cookie_val = false;
		}

		return cookie_val;
	}

	function saveSetting( name, value ) {
		mw.cookie.set( name, value );
	}

	/**
	 * Messages are configurable here
	 */
	mw.messages.set( {
		do: 'Display Options',
		displayOptions: 'Display Options',
		optlist: 'Display Options',
		'p-do': 'Display Options',
		page_numbers_hidden: 'Page links hidden',
		page_numbers_displayed: 'Page links displayed',
		page_numbers_inline: 'Page links within text',
		page_numbers_beside: 'Page links beside text',
		layout_name: 'layout_1',
		layout: 'Layout',
		use_serif: 'Use serif fonts',
		use_sans_serif: 'Use sans-serif fonts',
		serif_text_title: 'Change between serif and sans-serif fonts',
		default_layout_on: 'Default layouts on',
		default_layout_off: 'Default layouts off',
		default_layout_title: 'Default layouts allow pages to choose a specific layout for you.'
		+ ' Turn it off if you always want the layout you set.',
		default_layout_suffix: 'default',
		what_is_this_title: 'What is this?',
		what_is_this_symbol: '?'
	} );

	var standard_layouts = [
		{
			id: 'layout_1',
			name: 'Layout 1'
		},
		{
			id: 'layout_2',
			name: 'Layout 2'
		},
		{
			id: 'layout_3',
			name: 'Layout 3'
		},
		{
			id: 'layout_4',
			name: 'Layout 4'
		}
	];

	// eslint-disable-next-line no-jquery/no-global-selector
	var $classedContainer = $( '#mw-content-text' );

	var containers = {};

	function removeClassesWithPrefix( el, prefix ) {
		var classes = el.className.split( ' ' ).filter( function ( c ) {
			return c.lastIndexOf( prefix, 0 ) !== 0;
		} );
		// eslint-disable-next-line mediawiki/class-doc
		el.className = classes.join( ' ' ).trim();
	}

	/*
	 * The display control options:
	 *  * serif/sans serif fonts
	 */
	var display,
		layout,

		pagenumbers = ( function () {

			// some shared variables to avoid selecting these elements repeatedly
			var $div_pagenumbers,
				dp_y,
				y_prev,
				$pagenumbers_collection,
				$div_ss,
				$div_highlight,

				show_params = {
					link_text: mw.msg( 'page_numbers_displayed' ),
					visible: true
				},
				hide_params = {
					link_text: mw.msg( 'page_numbers_hidden' ),
					visible: false
				};

			function pagenum_in() {
				if ( self.proofreadpage_disable_highlighting ) {
					return false;
				}
				if ( !$div_highlight ) {
					return false; // could not find it
				}
				var id = this.id.substring( 11 ),

					$page_span = $( document.getElementById( id ) ),
					$next = self.$pagenum_ml.eq( self.$pagenum_ml.index( $page_span ) + 1 );
				if ( $next.length === 0 ) {
					$next = $div_ss;
				}

				var $container = containers.$column;

				// we need to use document offsets in case a page break occurs within
				// a positioned element
				var c_os = $container.offset(),
					ps_os = $page_span.offset(),
					n_os = $next.offset();

				ps_os = {
					top: ps_os.top - c_os.top,
					left: ps_os.left - c_os.left
				};
				n_os = {
					top: n_os.top - c_os.top,
					left: n_os.left - c_os.left
				};

				$div_highlight.css( {
					display: 'block',
					top: ps_os.top + 'px'
				} );
				$div_highlight.children().eq( 0 ).css( {
					height: $page_span.height() + 'px',
					width: ( ps_os.left < 1 ) ? '100%' : ( ( $container.width() - ps_os.left ) + 'px' )
				} );
				// div_ss.height() ~= height of 1 line of text
				$div_highlight.children().eq( 1 ).css( 'height', ( n_os.top - ps_os.top - $page_span.height() ) + 'px' );
				$div_highlight.children().eq( 2 ).css( {
					height: $next.height() + 'px',
					width: n_os.left + 'px'
				} );
				return true;
			}

			function pagenum_out() {
				if ( self.proofreadpage_disable_highlighting ) {
					return false;
				}
				if ( !$div_highlight ) {
					return false; // could not find it
				}
				$div_highlight.css( 'display', 'none' );
				$div_highlight.children().eq( 0 ).css( 'width', '0px' );
				$div_highlight.children().eq( 1 ).css( 'height', '0px' );
				$div_highlight.children().eq( 2 ).css( 'width', '0px' );
				return true;
			}

			function refresh_elem_offset( page_span, $pagenumber ) {
				var y = $( page_span ).offset().top;
				$pagenumber.css( 'top', y - dp_y );
				if ( self.proofreadpage_numbers_visible && y - y_prev.val > 5 ) {
					y_prev.val = y;
					$pagenumber.removeClass( 'pagenumber-invisible' );
				} else {
					$pagenumber.addClass( 'pagenumber-invisible' );
				}
			}

			function refresh_offsets() {
				// do nothing if container is not set up
				if ( self.proofreadpage_numbers_inline || !$div_pagenumbers ) {
					return false;
				}

				dp_y = $div_pagenumbers.offset().top;
				y_prev = {
					val: -10
				};

				var $pagenumber = $pagenumbers_collection.first();

				self.$pagenum_ml.each( function ( i, page_span ) {
					refresh_elem_offset( page_span, $pagenumber );
					$pagenumber = $pagenumber.next();
				} );

				return true;
			}

			var inline_params = {
					elem: 'span',
					link_pre: '&#x0020;[',
					link_post: ']'
				},
				beside_params = {
					elem: 'div',
					link_pre: '[',
					link_post: ']'
				};

			function setup_elem( i, page_span ) {
				var params = self.proofreadpage_numbers_inline ? inline_params : beside_params,

					// styled also by classes: div.pagenumber or span.pagenumber
					$pagenumber = $( '<' + params.elem + '>' )
						.attr( 'id', $.data( page_span, 'pagenumber_id' ) )
						.addClass( 'pagenumber noprint' )
						.append( params.link_pre + $.data( page_span, 'link_str' ) + params.link_post )
						.toggleClass( 'pagenumber-invisible', !self.proofreadpage_numbers_visible );

				if ( !self.proofreadpage_numbers_inline ) {
					refresh_elem_offset( page_span, $pagenumber );
				}

				// clear the span provided by [[MediaWiki:Proofreadpage pagenum template]]
				$( page_span ).find( '.pagenum-inner' ).empty();

				$pagenumber.appendTo(
					self.proofreadpage_numbers_inline ? page_span : $div_pagenumbers );

				$pagenumbers_collection = $pagenumbers_collection.add( $pagenumber );
			}

			function init_elem( i, page_span ) {
				var name = page_span.getAttribute( 'data-page-number' ) || page_span.id,

					// what if two pages have the same number? increment the id
					pagenumber_id = 'pagenumber_' + page_span.id,
					count;

				if ( $pagenumbers_collection.is( '#' + $.escapeSelector( pagenumber_id ) ) ) {
					count = ( $pagenumbers_collection.filter( "[id ^= '" + pagenumber_id + "']" ).length + 1 );
					page_span.id += ( '_' + count );
					pagenumber_id += ( '_' + count );
				}

				if ( !page_span.title ) {
					// there's no page to link to - just set plain text
					$.data( page_span, 'link_str', mw.html.escape( name ) );
				} else {
					$.data( page_span, 'pagenumber_id', pagenumber_id );
					var page_title = decodeURI( page_span.title ).replace( /%26/g, '&' ).replace( /%3F/g, '?' ),
						page_url =
				mw.config.get( 'wgArticlePath' )
					.replace( '$1', encodeURIComponent( page_title.replace( / /g, '_' ) ) )
				// encodeURIComponent encodes '/', which breaks subpages
					.replace( /%2F/g, '/' ),

						// if transcluded Page: (ll) is a redlink then make page class
						// (class_str) a redlink also
						ll = page_span.parentNode.nextSibling,
						class_str = '',
						action_str = '';

					if ( ll && ll.tagName === 'A' && ll.className === 'new' ) {
						class_str = ' class="new" ';
						action_str = '?action=edit&redlink=1';
					}

					$.data(
						page_span,
						'link_str',
						'<a href= "' + page_url + action_str + '"' +
				class_str +
				' title= "' + mw.html.escape( page_title ) + '">' +
				mw.html.escape( name ) +
				'</a>'
					);
				}

				setup_elem( i, page_span );
			}

			function refresh_display() {
				// determine if we need to set things up
				var inited = !$pagenumbers_collection;

				// JQuery collection of all pagenumber elements
				if ( !inited ) {
					$pagenumbers_collection.remove();
				}
				$pagenumbers_collection = $();

				if ( $div_pagenumbers ) {
					$div_pagenumbers.remove();
				}

				if ( !self.proofreadpage_numbers_inline ) {
					// html div container for page numbers stored in shared variable div_pagenumbers

					//  put pagenumbers container div in the outermost layout container
					$div_pagenumbers = $( '<div>' )
						.attr( 'id', 'ct-pagenumbers' )
						.appendTo( containers.$page );
					dp_y = $div_pagenumbers.offset().top;
					y_prev = {
						val: -10
					};
				}
				self.$pagenum_ml.each( inited ? init_elem : setup_elem );

				if ( self.proofreadpage_numbers_inline ) {
					$pagenumbers_collection.off( 'mouseenter mouseleave' );
				} else {
					$pagenumbers_collection.on( {
						mouseenter: pagenum_in,
						mouseleave: pagenum_out
					} );
				}
			}

			function toggle_visible() {
				var params = self.proofreadpage_numbers_visible ? hide_params : show_params;

				$pagenumbers_collection.toggleClass( 'pagenumber-invisible', !params.visible );
				$( '#d-pageNumbers_visible' ).children( 'a' ).html( params.link_text );
				self.proofreadpage_numbers_visible = params.visible;
				mw.cookie.set( 'pagenums_visible', params.visible );
			}

			function toggle_inline() {
				// toggle inline view unless layouts are not set up
				self.proofreadpage_numbers_inline = !layout || !self.proofreadpage_numbers_inline;
				$( '#d-pageNumbers_inline' ).children( 'a' )
					.html( mw.msg( self.proofreadpage_numbers_inline ? 'page_numbers_inline' : 'page_numbers_beside' ) );
				mw.cookie.set( 'pagenums_inline', self.proofreadpage_numbers_inline );
				refresh_display();
			}

			function doInit() {
				// Mark the container as having pagenumbers.
				// Some layouts can use that information.
				$( containers.$page )
					.addClass( 'dynlayout-haspagenums' );

				// get_optlist();
				self.proofreadpage_numbers_visible = initSetting( 'pagenums_visible', true );
				var portletLink = mw.util.addPortletLink(
					'p-do',
					'#',
					self.proofreadpage_numbers_visible ? mw.msg( 'page_numbers_displayed' ) : mw.msg( 'page_numbers_hidden' ),
					'd-pageNumbers_visible',
					'The current state of embedded link visibility',
					'n',
					'#d-serif'
				);
				$( portletLink ).on( 'click', function ( e ) {
					e.preventDefault();
					toggle_visible();
				} );

				self.proofreadpage_numbers_inline = initSetting( 'pagenums_inline', false );

				// if layouts are not initialized show pagenumbers inline since
				// "beside" view won't work
				if ( !layout ) {
					self.proofreadpage_numbers_inline = true;
				}

				portletLink = mw.util.addPortletLink(
					'p-do',
					'#',
					self.proofreadpage_numbers_inline ? mw.msg( 'page_numbers_inline' ) : mw.msg( 'page_numbers_beside' ),
					'd-pageNumbers_inline',
					'The current positioning used for embedded link presentation',
					'i',
					'#d-pageNumbers_visible'
				);

				$( portletLink ).on( 'click', function ( e ) {
					e.preventDefault();
					toggle_inline();
				} );

				// store container for the highlight to shared variable "div_highlight"
				$div_highlight = $( '<div id= "highlight-area">' +
					'<div style="float:right; width:0px;"><div class="wsg-pagenumbers-clearfix"></div></div>' +
					'<div style="width:100%; height:0px; clear:both;"></div>' +
					'<div style="width:0px;"><div class="wsg-pagenumbers-clearfix" style= "float:left; clear:both;"></div></div>' +
					'</div>'
				);

				// assign new div element to shared variable "div_ss"
				$div_ss = $( '<div id= "my-ss"><div class="wsg-pagenumbers-clearfix"></div></div>' ); // empty span following some text

				// put divs in the innermost dynamic layout container
				if ( layout ) {
					containers.$column
						.append( $div_highlight );
					$classedContainer.append( $div_ss );
				} else {
					$classedContainer.append( $div_highlight, $div_ss );
				}

				self.$pagenum_ml = $classedContainer.find( '.pagenum' );
				refresh_display();
			}

			function init() {
				// skip if pagenumbers are already set up
				if ( $pagenumbers_collection ) {
					return false;
				}

				doInit();

			}

			return {
				init: init,
				refresh_offsets: refresh_offsets
			};
		}() );

	if ( [ 'view', 'submit', 'purge' ].indexOf( mw.config.get( 'wgAction' ) ) !== -1 ) {
		if ( !self.debug_page_layout &&
			// don't do anything on DoubleWiki or difference comparison views
			document.URL.indexOf( 'match=' ) === -1 ) {

			$( function () {
				if ( $classedContainer.find( '.pagenum' ).length ) {
					pagenumbers.init();

					if ( document.readyState === 'complete' ) {
						$( pagenumbers.refresh_offsets );
					} else {
						$( window ).on( 'load', pagenumbers.refresh_offsets );
					}
				}
			} );

			// Add a "what's this" helper to display options
			// eslint-disable-next-line no-jquery/no-global-selector
			$( '#p-do-label' ).append( $( '<span>' )
				.css( { float: 'right' } )
				.append( $( '<a>' )
					.attr( {
						href: '/wiki/Help:Layout',
						title: mw.msg( 'what_is_this_title' )
					} )
					.append( mw.msg( 'what_is_this_symbol' ) )
				)
			);
		}
		var position = window.location.hash.substring( 1 );
		if ( position && document.getElementById( position ) ) {
			document.getElementById( position ).scrollIntoView();
		}

		/**
		 * Install the DOM-ready hook to force header and footer content out of
		 * Dynamic Layouts
		 */
		$( function () {

			var $c = $classedContainer;

			$c.find( '.acContainer' ).insertAfter( $c.find( 'div.printfooter' ) );

			$( '<div>' )
				.addClass( 'mw-parser-output dynlayout-exempt dynlayout-exempt-footer' )
				.insertBefore( 'div#catlinks' )
				.append( $c.find( '.acContainer' ) )
				.append( $c.find( 'div.licenseContainer' ).not( 'div.licenseContainer div.licenseContainer' ) )
				.append( $c.find( '#editform' ) )
				.append( $c.find( '.ws-footer' ) );

			$( '<div>' )
				.addClass( 'mw-parser-output dynlayout-exempt dynlayout-exempt-header' )
				.insertBefore( containers.$page )
				.prepend( $c.find( '.ws-header' ).not( '#headerContainer' ) )
				.prepend( $c.find( '#headerContainer' ) )
				.prepend( $c.find( '.similar' ) )
				.prepend( $c.find( '.ambox' ) )
				.prepend( $c.find( '#mw-previewheader' ) );
		} );
	}

/* eslint-disable-next-line no-undef */
}( mediaWiki, jQuery ) );