ผลต่างระหว่างรุ่นของ "มีเดียวิกิ:Gadget-PageNumbers-core.js"

จาก วิกิซอร์ซ
เนื้อหาที่ลบ เนื้อหาที่เพิ่ม
Geonuch (คุย | ส่วนร่วม)
Reverted to revision 101583 by Geonuch. (TW)
ป้ายระบุ: ทำกลับ
ลองซ่อม ​ (random new line displayed)
ป้ายระบุ: ถูกย้อนกลับแล้ว
(ไม่แสดง 1 รุ่นระหว่างกลางโดยผู้ใช้คนเดียวกัน)
บรรทัดที่ 1: บรรทัดที่ 1:
/* eslint-disable camelcase */
function init_setting ( variable_name, cookie_name, init ) {
/* Sets JS variable to (in order of preference):
1. previously initialized JS variable value
2. current cookie value
3. provided init parameter
4. false


( function ( mw, $ ) {
Then, if cookie was not previously set, set it to current value of JS variable (this bit currently disabled)
*/
// get current value of appropriate cookie
var cookie_val = $.cookie( cookie_name );
// some code so that people's cookies will change from digits to boolean values. remove after a week or so.
// in case you are wondering, this is to avoid the mixed use of digits as numbers and as booleans. --Eliyak
// if ( cookie_val === "0" ) { cookie_val = false; $.cookie( cookie_name, false ); }
// else if ( cookie_val === "1" ) { cookie_val = true; $.cookie( cookie_name, true ); }


function initSetting( cookie_name, init ) {
// If JS variable was not previously initialized in this page load, set it now to the cookie value.
/* Sets JS variable to (in order of preference):
self[ variable_name ] = self[ variable_name ] || cookie_val;
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 JS variable still has no value, use provided init value. If no init
// value provided, use false.
if ( typeof self[ variable_name ] === "undefined" || self[ variable_name ] === null ) self[ variable_name ] = init || false;
if ( typeof cookie_val === 'undefined' || cookie_val === null ) {
cookie_val = init || false;
}


// If cookie was not set, set it now to the current value of the JS variable.
// If JS variable is now the string "false", convert to boolean false
// (to fix JS confusion where "false" string evaluates to true).
// disabling for now - cookie should not need to be set if value was initialized but not changed afterwards.
// if ( typeof cookie_val === "undefined" ) $.cookie( cookie_name, self[ variable_name ] );
if ( cookie_val === 'false' ) {
cookie_val = false;
}


return cookie_val;
// If JS variable is now the string "false", convert to boolean false (to fix JS confusion where "false" string evaluates to true).
}
if ( self[ variable_name ] === "false" ) self[ variable_name ] = false;
}


function saveSetting( name, value ) {
if(!self.ws_messages) self.ws_messages = { };
mw.cookie.set( name, value );
}


/**
window.ws_msg = function (name) {
* Messages are configurable here
var m = self.ws_messages[name];
*/
if(m) return m; else return name;
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 = [
/**
* Messages are configurable here
*/
self.ws_messages = {
'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',
'layout':'Layout',
'layout_1':'Layout 1',
'layout_2':'Layout 2',
'layout_3':'Layout 3',
'proposed_layout':'Proposed Layout',
};
/**
* Dynamic Layouts
*/
if ( !self.ws_layouts ) {
self.ws_layouts = { };
}
self.ws_layouts['Layout 1'] = {
'#pageContainer':"",
'#regionContainer':"",
'#columnContainer':"",
'.sidenote-right':"float:right; margin:0.5em; padding:3px; border:solid 1px gray; max-width:9em; text-indent:0em; text-align:left;",
'.sidenote-left':"float:left; margin:0.5em; padding:3px; border:solid 1px gray; max-width:9em; text-indent:0em; text-align:left;",
'.mw-editsection':"",
'#headerContainer':""
};
self.ws_layouts['Layout 2'] = {
'#pageContainer':"",
'#regionContainer':"width:36em; margin:0 auto 0 auto; font-family:Georgia,serif;",
'#columnContainer':"text-align:justify;",
'.sidenote-right':"position:absolute; left:37em; width:16em; text-indent:0em; text-align:left;",
'.sidenote-left':"position:absolute; left:37em; width:16em; text-indent:0em; text-align:left;",
'.mw-editsection':"",
'#headerContainer':"font-family:sans-serif;"
};
self.ws_layouts['Layout 3'] = {
'#pageContainer':"",
'#regionContainer':"min-width:60em; float:left; width:100%; margin-right:-23em;",
'#columnContainer':"position:relative; text-align:justify; margin-right:23em; text-indent:0em; padding-left:0px; padding-right:0px; width:auto;",
'.sidenote-right':"position:absolute; right:-10em; width:9em; background-color:#eeeeee; text-indent:0em; text-align:left;",
'.sidenote-left':"position:absolute; right:-10em; width:9em; background-color:#eeeeee; text-indent:0em; text-align:left;",
'.mw-editsection':"",
'#headerContainer':"position:absolute; top:0em; right:-23em; width:21em; float:right; text-align:left;"
};
self.ws_layouts['Proposed Layout'] = {
'#pageContainer':"",
'#regionContainer':"",
'#columnContainer':"margin-right:calc(1rem * 9); text-align:justify;",
'.sidenote-right':"position:absolute; right:-10em; width:9.00em; background-color:#eeeeee; text-indent:0.00em; text-align:left;",
'.sidenote-left':"position:absolute; right:-10em; width:9.00em; background-color:#eeeeee; text-indent:0.00em; text-align:left;",
'.mw-editsection':"",
'#headerContainer':"font-family:sans-serif;"
};
/*
window.get_optlist = function () {
var optlist = document.getElementById( "p-displayOptions" ), cl;
if( !optlist ) {
var displayOptions = document.createElement( "div" );
if (mw.user.options.get( 'skin' ) === 'vector' ) {
displayOptions.className="portal";
displayOptions.setAttribute( "id", "p-displayOptions" );
displayOptions.setAttribute( "role", "navigation" );
displayOptions.setAttribute( "aria-labelledby", "p-displayOptions-label" );
cl="body";
displayOptions.innerHTML = '<h3 id="p-displayOptions-label">' + ws_msg('optlist') + '<\/h3><div class="body"><ul><\/ul><\/div>';
} else
{
{
id: 'layout_1',
displayOptions.className="portlet";
name: 'Layout 1'
displayOptions.setAttribute( "id", "p-displayOptions" );
},
displayOptions.setAttribute( "role", "navigation" );
{
cl="pBody";
id: 'layout_2',
displayOptions.innerHTML = '<h3>' + ws_msg('optlist') + '<\/h3><div class="pBody"><ul id="optlist"><\/ul><\/div>';
name: 'Layout 2'
},
{
id: 'layout_3',
name: 'Layout 3'
},
{
id: 'layout_4',
name: 'Layout 4'
}
}
];
var ptb = document.getElementById( "p-tb" );
ptb.parentNode.insertBefore( displayOptions, ptb );
displayOptions.id="p-displayOptions";
optlist = document.getElementById( "p-displayOptions" );
}
return optlist;
};
*/
var layout = function () {
if ( !self.ws_layouts ) self.ws_layouts = {};
else self.ws_layouts.names = [];
var n = 0;
for( var key in self.ws_layouts ) {
self.ws_layouts[ key ].number = n; // get number easily in the future
self.ws_layouts.names[ n ] = key; // get name from number easily as well
n++;
}
n -= 1;
function toggle () {
set_by_number( ( self.ws_layouts[ self.layout_name ].number + 1 ) % n, true );
}
function set_by_number ( number, persist ) {
set_by_name( self.ws_layouts.names[ number ], persist );
}
function set_by_name ( name, persist ) {
var selected_layout = self.ws_layouts[ name ];
if ( !selected_layout ) return; //does not exist


// eslint-disable-next-line no-jquery/no-global-selector
$.each( selected_layout, function ( selector, style ) {
var $classedContainer = $( '#mw-content-text' );
$( selector ).attr( "style", style );

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();
}


/*
$( "#d-textLayout" ).children( "a" ).html( name );
* The display control options:
* * serif/sans serif fonts
*/
var display = ( function () {


// My kingdom for Vuex
self.layout_name = name;
var State = {
if ( persist ) $.cookie( "layout", name );
serif: false,


cache: {}
pagenumbers.refresh_offsets();
}
};
function init () {
var name;
// do return if we are already set up
if ( document.getElementById( "pageContainer" ) ) return;


function updateSerifs() {
// get_optlist();
// tthe relevant class on the content
var portletLink = mw.util.addPortletLink(
containers.$page.toggleClass( 'ws-display-serif', State.serif );
"p-do",
"#",
ws_msg( "layout" ),
"d-textLayout",
"The designation of the dynamic layout being applied [alt-l]",
"l"
);
$( portletLink ).click( function ( e ) {
e.preventDefault();
toggle();
} );


var msg = mw.msg( State.serif ? 'use_sans_serif' : 'use_serif' );
// Check for presence of Proofreading extension by looking for pr_quality color status bar
State.cache.$serifSwitch.children( 'a' ).html( msg );
if ( $( 'table.pr_quality' ).length ) {
// remove all these classes to maintain backwards-compatibility
$( '.text, .lefttext, .centertext, .indented-page, .prose' ).removeClass();
// DynamicFlaw - a independent Div should have been the parent to this 3-into-1 step
$( 'body div.mw-content-ltr' ).wrapInner( '<div id="pageContainer"><div id="regionContainer"><div id="columnContainer"></div></div></div><div style="clear:both;"></div>' );
}
}


function init() {
// If cookie is not set, default layout is first available option. Use index "0" in case layout name is ever changed.
init_setting( "layout_name", "layout", "0" );


State.cache.$serifSwitch = $( mw.util.addPortletLink(
if ( self.layout_overrides_have_precedence || ! $.cookie( "layout") ) {
'p-do', '#', '', 'd-serif', mw.msg( 'serif_text_title' ) )
name = $( "#dynamic_layout_overrider" ).text();
)
.on( 'click', function () {
State.serif = !State.serif;
updateSerifs();
saveSetting( 'ws-display-serif', State.serif );
} );

State.serif = initSetting( 'ws-display-serif', false );
updateSerifs();
}
}
name = name || self.layout_name;
if ( $.isNumeric( name ) )
set_by_number( name, false );
else if ( name )
set_by_name( name, false );
else
set_by_number( 0, false );
}
return {
init: init
};
}();


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


var pagenumbers = function () {
var layout = ( function () {
var State = {
allow_default: true,
// some shared variables to avoid selecting these elements repeatedly
default_applied: false,
var container;
layout_name: 'Layout 1',
var div_pagenumbers;
layouts: [],
var dp_y;
cache: {}
var y_prev;
};
var pagenumbers_collection;
var div_ss;
var div_highlight;


function set_by_name( name ) {
var show_params = { display: "", link_text: ws_msg( "page_numbers_displayed" ), visible: true };
var hide_params = { display: "none", link_text: ws_msg( "page_numbers_hidden" ), visible: false };


var selected_layout;
function toggle_visible () {
for ( var i = 0; i < State.layouts.length; ++i ) {
var params = self.proofreadpage_numbers_visible ? hide_params : show_params;
if ( State.layouts[ i ].name.toLowerCase() === name.toLowerCase() ) {
pagenumbers_collection.css( "display", params.display );
selected_layout = State.layouts[ i ];
$( "#d-pageNumbers_visible" ).children( "a" ).html( params.link_text );
}
self.proofreadpage_numbers_visible = params.visible;
}
$.cookie( "pagenums_visible", params.visible );
}


if ( !selected_layout ) {
function toggle_inline () {
return false; // does not exist
// toggle inline view unless layouts are not set up
}
self.proofreadpage_numbers_inline = !layout || !self.proofreadpage_numbers_inline;
$( "#d-pageNumbers_inline" ).children( "a" ).html( ws_msg( self.proofreadpage_numbers_inline ? "page_numbers_inline" : "page_numbers_beside" ) );
$.cookie( "pagenums_inline", self.proofreadpage_numbers_inline );
refresh_display();
}


State.layout_name = selected_layout.name;
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 );


var layoutText = selected_layout.name;
var page_span = $( document.getElementById( id ) );
if ( State.allow_default && State.default_applied ) {
var next = self.pagenum_ml.eq( self.pagenum_ml.index( page_span ) + 1 );
layoutText += ' (' + mw.msg( 'default_layout_suffix' ) + ')';
if ( next.length === 0 ) next = div_ss;
}
// we need to use document offsets in case a page break occurs within a positioned element
var c_os = container.offset();
var ps_os = page_span.offset();
var n_os = next.offset();


State.cache.$layoutSwitch.children( 'a' ).html( layoutText );
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 };


removeClassesWithPrefix( $classedContainer[ 0 ], 'dynlayout-' );
div_highlight.css( { "display": "block", "top": ps_os.top + "px" } );
// eslint-disable-next-line mediawiki/class-doc
div_highlight.children().eq( 0 ).css( {
$classedContainer.addClass( 'dynlayout-' + selected_layout.id );
"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;
}


pagenumbers.refresh_offsets();
function pagenum_out () {
return true;
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 init () {
function updateLayout() {
var name;
// skip if pagenumbers are already set up
State.default_applied = false;
if ( pagenumbers_collection ) return false;
if ( State.allow_default || !mw.cookie.get( 'layout' ) ) {
var overrider = State.cache.$overrider || $classedContainer.find( '#dynamic_layout_overrider' );
name = overrider.text();
if ( name ) {
State.default_applied = true;
}
} else {
name = State.layout_name || mw.cookie.get( 'layout' );
}
if ( !set_by_name( name || State.layout_name ) ) {
// failed to set the default: maybe it's not a valid layout
State.default_applied = false;
set_by_name( State.layout_name );
}
}


function set_by_number( number ) {
// get_optlist();
State.layout_name = State.layouts[ number ].name;
init_setting( "proofreadpage_numbers_visible", "pagenums_visible", true );
updateLayout();
var portletLink = mw.util.addPortletLink(
"p-do",
}
"#",
self.proofreadpage_numbers_visible ? ws_msg( "page_numbers_displayed" ) : ws_msg( "page_numbers_hidden" ),
"d-pageNumbers_visible",
"The current state of embedded link visibility [alt-n]",
"n"
);
$( portletLink ).on( "click", function ( e ) {
e.preventDefault();
toggle_visible();
} );


function getLayoutIndexWithName( name ) {
init_setting( "proofreadpage_numbers_inline", "pagenums_inline", false );
for ( var i = 0; i < State.layouts.length; ++i ) {
// if layouts are not initialized show pagenumbers inline since "beside" view won't work
if ( State.layouts[ i ].name === name ) {
if ( !layout ) self.proofreadpage_numbers_inline = true;
return i;
portletLink = mw.util.addPortletLink(
"p-do",
}
"#",
}
self.proofreadpage_numbers_inline ? ws_msg( "page_numbers_inline" ) : ws_msg( "page_numbers_beside" ),
"d-pageNumbers_inline",
"The current positioning used for embedded link presentation [alt-i]",
"i"
);
$( portletLink ).on( "click", function ( e ) {
e.preventDefault();
toggle_inline();
} );


return -1;
var opacity = "background-color:#000000; opacity:0.2; -ms-filter:alpha(opacity=20); filter:alpha(opacity=20);";
}
// store container for the highlight to shared variable "div_highlight"
div_highlight = $( '<div id= "highlight-area" style= "display:none; position:absolute; width:100%;">'
+ '<div style= "' + opacity + ' float:right; width:0px;"><div class= "clearFix"></div></div>'
+ '<div style= "' + opacity + ' width:100%; height:0px; clear:both;"></div>'
+ '<div style= "' + opacity + ' width:0px;"><div class= "clearFix" style= "float:left; clear:both;"></div></div>'
+ '</div>' );


function toggle() {
// assign new div element to shared variable "div_ss"
var cur = getLayoutIndexWithName( State.layout_name );
div_ss = $( '<div id= "my-ss"><div class= "clearFix"></div></div>' ); //empty span following some text


// disable override for this page only (no persistence)
// put divs in the innermost dynamic layout container
State.allow_default = false;
if ( layout ) {
container = $( "#columnContainer" );
container.append( div_highlight );
$( ".mw-content-ltr" ).append( div_ss );
}
else {
$( ".mw-content-ltr" ).append( div_highlight, div_ss );
}


set_by_number( ( cur + 1 ) % State.layouts.length );
self.pagenum_ml = $( ".pagenum" );
refresh_display();
}


// store the changed layout
function refresh_display () {
mw.cookie.set( 'layout', State.layout_name );
// determine if we need to set things up
}
var init = !pagenumbers_collection;


function updateDefault() {
// JQuery collection of all pagenumber elements
var msg = mw.msg( State.allow_default ? 'default_layout_on' : 'default_layout_off' );
if ( !init ) pagenumbers_collection.remove();
State.cache.$defaultLayoutSwitch.children( 'a' ).html( msg );
pagenumbers_collection = $();


updateLayout();
if ( div_pagenumbers ) div_pagenumbers.remove();
}
if ( !self.proofreadpage_numbers_inline ) {
// html div container for page numbers stored in shared variable div_pagenumbers
div_pagenumbers = $( '<div id= "ct-pagenumbers" style= "position:absolute; top:0px; left:0px; font-size:calc(1rem - 5px); line-height:calc(1rem * 1); font-weight:normal; font-style:normal; text-indent:0em;"></div>' ).appendTo( "div#pageContainer" ); // put pagenumbers container div in the outermost layout container
dp_y = div_pagenumbers.offset().top;
y_prev = { val: -10 };
}
self.pagenum_ml.each( init ? init_elem : setup_elem );


function init() {
if ( self.proofreadpage_numbers_inline )
// do return if we're already set up
pagenumbers_collection.off( "mouseenter mouseleave" );
if ($(".ws-page-container").length) {
else {
return;
pagenumbers_collection.hover( pagenum_in, pagenum_out );
}
}
}


// collect any user or other gadget layouts
function refresh_elem_offset ( page_span, pagenumber ) {
mw.hook( 'ws.layouts.register' ).fire( {
var y = $( page_span ).offset().top;
layouts: standard_layouts
pagenumber.css( "top", y - dp_y );
} );
if ( self.proofreadpage_numbers_visible && y - y_prev.val > 5 ) {
y_prev.val = y;
pagenumber.css( "display", "" );
}
else {
pagenumber.css( "display", "none" );
}
}


State.layouts = standard_layouts;
function refresh_offsets () {
// do nothing if container is not set up
if ( self.proofreadpage_numbers_inline || !div_pagenumbers ) return false;


// If cookie is not set, default layout is first available option.
dp_y = div_pagenumbers.offset().top;
// Use index "0" in case layout name is ever changed.
y_prev = { val: -10 };
State.layout_name = initSetting( 'layout', '0' );
pagenumber = pagenumbers_collection.first();
self.pagenum_ml.each( function ( i, page_span ) {
refresh_elem_offset ( page_span, pagenumber );
pagenumber = pagenumber.next();
} );
return true;
}


State.allow_default = initSetting( 'ws-display-default-layouts', true );
function init_elem ( i, page_span ) {
var name = page_span.getAttribute("data-page-number") || page_span.id;


State.cache.$layoutSwitch = $( mw.util.addPortletLink(
// what if two pages have the same number? increment the id
'p-do',
var pagenumber_id = "pagenumber_" + page_span.id;
'#',
var count;
mw.msg( 'layout' ),
if ( pagenumbers_collection.is( "#" + pagenumber_id ) ) {
'd-textLayout',
count = ( pagenumbers_collection.filter( "[id ^= '" + pagenumber_id + "']" ).length + 1 );
'The designation of the dynamic layout being applied',
page_span.id += ( "_" + count );
'l',
pagenumber_id += ( "_" + count );
'#d-defaultLayouts'
}
) )
$.data( page_span, "pagenumber_id", pagenumber_id );
.on( 'click', function ( e ) {
var page_title = decodeURI( page_span.title ).replace(/%26/g, "&");
var page_url =
mw.config.get( "wgArticlePath" )
.replace( "$1", encodeURIComponent( page_title.replace( / /g, "_" ) ) )
// encodeURIComponent encodes '/', which breaks subpages
.replace( /%2F/g, "/" );


e.preventDefault();
// don't know what the next 2 lines accomplish
toggle();
var ll = page_span.parentNode.nextSibling;
} );
var class_str = ( ll && ll.tagName === "A" && ll.className === "new" ) ? ' class="new" ' : '';


State.cache.$defaultLayoutSwitch = $( mw.util.addPortletLink(
$.data( page_span, "link_str", '<a href= "' + page_url + '"' + class_str + ' title= "' + mw.html.escape( page_title ) + '">' + mw.html.escape( name ) + '</a>' );
'p-do',
'#',
'',
'd-defaultLayouts',
mw.msg( 'default_layout_title' )
) )
.on( 'click', function ( e ) {
State.allow_default = !State.allow_default;


// if we just turned the default off, use the cookie value
setup_elem( i, page_span );
if ( !State.allow_default ) {
}
State.layout_name = mw.cookie.get( 'layout' );
}


updateDefault();
var inline_params = {
saveSetting( 'ws-display-default-layouts', State.allow_default );
elem: "span",
e.preventDefault();
style: "color:#666666; font-size:inherit; line-height:inherit; font-family:monospace; font-weight:600; text-shadow:0em 0em 0.25em #A8A; vertical-align:top;",
} );
link_pre: "&#x0020;[",
link_post: "]"
};
var beside_params = {
elem: "div",
style: "position:absolute;",
link_pre: "[",
link_post: "]"
};


// remove all these classes to maintain backwards-compatibility
function setup_elem ( i, page_span ) {
$classedContainer
var params = self.proofreadpage_numbers_inline ? inline_params : beside_params;
.find( 'div.text, .lefttext, .centertext, .indented-page, .prose' )
var pagenumber =
.removeClass();
$( '<' + params.elem + ' id= "' + $.data( page_span, "pagenumber_id" ) + '" class= "pagenumber noprint" '
+ 'style= "' + ( self.proofreadpage_numbers_visible ? '' : 'display:none; ' ) + params.style + '">'
+ params.link_pre + $.data( page_span, "link_str" ) + params.link_post
+ '</' + params.elem + '>' );


// DynamicFlaw - a independent Div should have been the parent
if ( !self.proofreadpage_numbers_inline ) refresh_elem_offset ( page_span, pagenumber );
// to this 3-into-1 step
page_span.innerHTML = self.proofreadpage_numbers_inline ? '' : '';
var $parserOutput = $('.mw-parser-output', $classedContainer)
pagenumber.appendTo( self.proofreadpage_numbers_inline ? page_span : div_pagenumbers );
.contents().not('.dynlayout-exempt')
.wrapAll(
$('<div>').addClass('ws-page-container').append(
$('<div>').addClass('ws-region-container').append(
$('<div>').addClass('ws-column-container')
)
)
);


// cache the containers
pagenumbers_collection = pagenumbers_collection.add( pagenumber );
containers.$column = $parserOutput.parent();
}
containers.$region = containers.$column.parent();
containers.$page = containers.$region.parent();


// If layouts have changed, the cookie might refer to a missing layout
return {
// in which case, set the first one
init: init,
if ( getLayoutIndexWithName( State.layout_name ) === -1 ) {
refresh_offsets: refresh_offsets
set_by_number( 0, true );
};
}
}();


// set the layout by default (override) layout, or from the user's setting
if ( $.inArray( mw.config.get( "wgAction" ), [ "view", "submit", "purge" ] ) !== -1 ) {
updateDefault();
if ( !self.debug_page_layout

// don't do anything on DoubleWiki or difference comparison views
mw.hook( 'ws.layouts.ready' ).fire();
&& document.URL.indexOf( "match=" ) === -1
}
&& document.URL.indexOf( "diff=" ) === -1

&& ( 'self.proofreadpage_source_href' ) ) {
return {
if ( ! $.isEmptyObject( self.ws_layouts ) )
$.when(
init: init
};
mw.loader.using( 'jquery.cookie' ),
}() ),
$.ready

).then( layout.init );
$( function(){
pagenumbers = ( function () {

if ( $( ".pagenum" ).length ) {
// some shared variables to avoid selecting these elements repeatedly
mw.loader.using( 'jquery.cookie' ).done( pagenumbers.init );
var $div_pagenumbers,
$(window).load( pagenumbers.refresh_offsets );
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= "clearFix"></div></div>' +
'<div style="width:100%; height:0px; clear:both;"></div>' +
'<div style="width:0px;"><div class= "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= "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;
}

// wait for the layouts code to signal that the containers are ready
mw.hook( 'ws.layouts.ready' ).add( function () {
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 ) {

layout.init();
display.init();

$( 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( '#footertemplate' ) );

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

var position = window.location.hash.substring( 1 );
// thws fix: removing &ZeroWidthSpace; from span.ws-pagenum to fix random new line from displaying
if ( position ) {
if ($(".ws-pagenum").length) {
document.getElementById( position ).scrollIntoView();
$(".ws-pagenum").html($(".ws-pagenum").html().replace(/\u200B/g,""));
}
}
}
/* eslint-disable-next-line no-undef */
}( mediaWiki, jQuery ) );

รุ่นแก้ไขเมื่อ 00:36, 10 พฤศจิกายน 2565

/* eslint-disable camelcase */

( 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 = ( function () {

		// My kingdom for Vuex
		var State = {
			serif: false,

			cache: {}
		};

		function updateSerifs() {
			// tthe relevant class on the content
			containers.$page.toggleClass( 'ws-display-serif', State.serif );

			var msg = mw.msg( State.serif ? 'use_sans_serif' : 'use_serif' );
			State.cache.$serifSwitch.children( 'a' ).html( msg );
		}

		function init() {

			State.cache.$serifSwitch = $( mw.util.addPortletLink(
				'p-do', '#', '', 'd-serif', mw.msg( 'serif_text_title' ) )
			)
				.on( 'click', function () {
					State.serif = !State.serif;
					updateSerifs();
					saveSetting( 'ws-display-serif', State.serif );
				} );

			State.serif = initSetting( 'ws-display-serif', false );
			updateSerifs();
		}

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

	var layout = ( function () {
			var State = {
				allow_default: true,
				default_applied: false,
				layout_name: 'Layout 1',
				layouts: [],
				cache: {}
			};

			function set_by_name( name ) {

				var selected_layout;
				for ( var i = 0; i < State.layouts.length; ++i ) {
					if ( State.layouts[ i ].name.toLowerCase() === name.toLowerCase() ) {
						selected_layout = State.layouts[ i ];
					}
				}

				if ( !selected_layout ) {
					return false; // does not exist
				}

				State.layout_name = selected_layout.name;

				var layoutText = selected_layout.name;
				if ( State.allow_default && State.default_applied ) {
					layoutText += ' (' + mw.msg( 'default_layout_suffix' ) + ')';
				}

				State.cache.$layoutSwitch.children( 'a' ).html( layoutText );

				removeClassesWithPrefix( $classedContainer[ 0 ], 'dynlayout-' );
				// eslint-disable-next-line mediawiki/class-doc
				$classedContainer.addClass( 'dynlayout-' + selected_layout.id );

				pagenumbers.refresh_offsets();
				return true;
			}

			function updateLayout() {
				var name;
				State.default_applied = false;
				if ( State.allow_default || !mw.cookie.get( 'layout' ) ) {
					var overrider = State.cache.$overrider || $classedContainer.find( '#dynamic_layout_overrider' );
					name = overrider.text();
					if ( name ) {
						State.default_applied = true;
					}
				} else {
					name = State.layout_name || mw.cookie.get( 'layout' );
				}
				if ( !set_by_name( name || State.layout_name ) ) {
					// failed to set the default: maybe it's not a valid layout
					State.default_applied = false;
					set_by_name( State.layout_name );
				}
			}

			function set_by_number( number ) {
				State.layout_name = State.layouts[ number ].name;
				updateLayout();
			}

			function getLayoutIndexWithName( name ) {
				for ( var i = 0; i < State.layouts.length; ++i ) {
					if ( State.layouts[ i ].name === name ) {
						return i;
					}
				}

				return -1;
			}

			function toggle() {
				var cur = getLayoutIndexWithName( State.layout_name );

				// disable override for this page only (no persistence)
				State.allow_default = false;

				set_by_number( ( cur + 1 ) % State.layouts.length );

				// store the changed layout
				mw.cookie.set( 'layout', State.layout_name );
			}

			function updateDefault() {
				var msg = mw.msg( State.allow_default ? 'default_layout_on' : 'default_layout_off' );
				State.cache.$defaultLayoutSwitch.children( 'a' ).html( msg );

				updateLayout();
			}

			function init() {
				// do return if we're already set up
				if ($(".ws-page-container").length) {
					return;
				}

				// collect any user or other gadget layouts
				mw.hook( 'ws.layouts.register' ).fire( {
					layouts: standard_layouts
				} );

				State.layouts = standard_layouts;

				// If cookie is not set, default layout is first available option.
				// Use index "0" in case layout name is ever changed.
				State.layout_name = initSetting( 'layout', '0' );

				State.allow_default = initSetting( 'ws-display-default-layouts', true );

				State.cache.$layoutSwitch = $( mw.util.addPortletLink(
					'p-do',
					'#',
					mw.msg( 'layout' ),
					'd-textLayout',
					'The designation of the dynamic layout being applied',
					'l',
					'#d-defaultLayouts'
				) )
					.on( 'click', function ( e ) {

						e.preventDefault();
						toggle();
					} );

				State.cache.$defaultLayoutSwitch = $( mw.util.addPortletLink(
					'p-do',
					'#',
					'',
					'd-defaultLayouts',
					mw.msg( 'default_layout_title' )
				) )
					.on( 'click', function ( e ) {
						State.allow_default = !State.allow_default;

						// if we just turned the default off, use the cookie value
						if ( !State.allow_default ) {
							State.layout_name = mw.cookie.get( 'layout' );
						}

						updateDefault();
						saveSetting( 'ws-display-default-layouts', State.allow_default );
						e.preventDefault();
					} );

				// remove all these classes to maintain backwards-compatibility
				$classedContainer
					.find( 'div.text, .lefttext, .centertext, .indented-page, .prose' )
					.removeClass();

				// DynamicFlaw - a independent Div should have been the parent
				// to this 3-into-1 step
				var $parserOutput = $('.mw-parser-output', $classedContainer)
					.contents().not('.dynlayout-exempt')
					.wrapAll(
						$('<div>').addClass('ws-page-container').append(
							$('<div>').addClass('ws-region-container').append(
								$('<div>').addClass('ws-column-container')
							)
						)
					);

				// cache the containers
				containers.$column = $parserOutput.parent();
				containers.$region = containers.$column.parent();
				containers.$page = containers.$region.parent();

				// If layouts have changed, the cookie might refer to a missing layout
				// in which case, set the first one
				if ( getLayoutIndexWithName( State.layout_name ) === -1 ) {
					set_by_number( 0, true );
				}

				// set the layout by default (override) layout, or from the user's setting
				updateDefault();

				mw.hook( 'ws.layouts.ready' ).fire();
			}

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

		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= "clearFix"></div></div>' +
					'<div style="width:100%; height:0px; clear:both;"></div>' +
					'<div style="width:0px;"><div class= "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= "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;
				}

				// wait for the layouts code to signal that the containers are ready
				mw.hook( 'ws.layouts.ready' ).add( function () {
					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 ) {

			layout.init();
			display.init();

			$( 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( '#footertemplate' ) );

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

	// thws fix: removing &ZeroWidthSpace; from span.ws-pagenum to fix random new line from displaying
	if ($(".ws-pagenum").length) {
	    $(".ws-pagenum").html($(".ws-pagenum").html().replace(/\u200B/g,""));
	}
	
/* eslint-disable-next-line no-undef */
}( mediaWiki, jQuery ) );