MediaWiki:Gadget-tot.js

Từ điển mở Wiktionary

Chú ý: Sau khi lưu trang này, phải xóa bộ nhớ đệm (cache) của trình duyệt để những thay đổi hiện ra

  • Firefox / Safari: Nhấn giữ phím Shift trong khi nhấn Tải lại (Reload), hoặc nhấn tổ hợp Ctrl-F5 hay Ctrl-R (⌘R trên Mac)
  • Google Chrome: Nhấn tổ hợp Ctrl-Shift-R (⇧⌘R trên Mac)
  • Internet Explorer / Edge: Nhấn giữ phím Ctrl trong khi nhấn Làm tươi (Refresh), hoặc nhấn tổ hợp Ctrl-F5
  • Opera: Nhấn tổ hợp Ctrl-F5.
$(function () {

var ns = mw.config.get("wgNamespaceNumber");
if (ns && !(ns === 2 && mw.config.get("wgPageName").indexOf("/") > 0)) return;
if (mw.config.get("wgCodeEditorCurrentLanguage")) return;
var action = mw.config.get("wgAction");
if (!(action == "edit" || action == "submit")) return;

// In other skins, the edit box is disabled and gets blanked when submitting, so
// only Vector is supported for now.
if (mw.config.get("skin") != "vector") return;

// Configuration

var defaultWidth = '166px';
var textMinimumWidth = '450px';

// Templates that resemble headings but aren't
var blacklist = ["info"];

// Caching and throttling

var unhighlightTimeout;
var lastTemplateHash;

/**
 * @see $.wikiEditor.modules.toc.fn.collapse()
 */
function collapse( event ) {
	var $this = $( this );
	var pT = $this.parent().position().top - 1;
	$(".wikiEditor-ui-toc").data( 'collapsed', true );
	var leftParam = {}, leftChildParam = {};
	leftParam.marginRight = '-1px';
	leftChildParam.marginRight = '1px';
	$( '.wikiEditor-ui-left' )
		.animate( leftParam, 'fast', function() {
			$( this ).css( "marginRight", 0 );
		} )
		.children()
		.animate( leftChildParam, 'fast',  function() {
			$( this ).css( "marginRight", 0 );
		} );
	$( '.wikiEditor-ui-right' )
		.css( {
			'marginTop' : '1px',
			'position' : 'absolute',
			'left' : 'auto',
			'right' : 0,
			'top' : pT } )
		.fadeOut( 'fast', function() {
			$( this ).hide()
				.css( { 'marginTop': '0', 'width': '1px' } );
			$( '.wikiEditor-ui-toc-expandControl' ).fadeIn( 'fast' );
		 } );

	$.cookie( 'wikiEditor-tot-width', 0 );
	return false;
};

function expand( event ) {
	var $this = $( this ),
		openWidth = defaultWidth,
		availableSpace = $("#wpTextbox1").width() - parseFloat( textMinimumWidth );
	if ( availableSpace < parseFloat( textMinimumWidth ) ) return false;
	$(".wikiEditor-ui-toc").data( 'collapsed', false );
	// check if we've got enough room to open to our stored width
	if ( availableSpace < openWidth ) openWidth = availableSpace;
	$( '.wikiEditor-ui-toc-expandControl' ).hide();
	var leftParam = {}, leftChildParam = {};
	leftParam.marginRight = parseFloat( openWidth ) * -1;
	leftChildParam.marginRight = openWidth;
	$( '.wikiEditor-ui-left' )
		.animate( leftParam, 'fast' )
		.children()
		.animate( leftChildParam, 'fast' );
	$( '.wikiEditor-ui-right' )
		.show()
		.css( 'marginTop', '1px' )
		.animate( { 'width' : openWidth }, 'fast', function() {
			$( this ).css( {
				'marginTop' : '0',
				'position' : 'relative',
				'right' : 'auto',
				'left' : 'auto',
				'top': 'auto' } );
		 } );
	$.cookie( 'wikiEditor-tot-width', openWidth );
	return false;
};

/**
 * @see $.wikiEditor.modules.toc.fn.build.buildCollapseControls()
 */
function buildCollapseControls( ) {
	var $collapseControl = $( '<div />' ), $expandControl = $( '<div />' );
	$collapseControl
		.addClass( 'tab' )
		.addClass( 'tab-toc' )
		.css( "background-image",
			"url(" + mw.config.get("wgExtensionAssetsPath") +
			"/WikiEditor/modules/images/toolbar/base.png" + ")" )
		.append( '<a href="#" />' )
		.mousedown( function( e ) {
			// No dragging!
			e.preventDefault();
			return false;
		} )
		.on( 'click.wikiEditor-toc', function( e ) {
			$(".wikiEditor-ui-toc").trigger( 'collapse.wikiEditor-toc' );
			// No dragging!
			e.preventDefault();
			return false;
		} )
		.find( 'a' )
		.text( "Ẩn mục lục" );
	$expandControl
		.addClass( 'wikiEditor-ui-toc-expandControl' )
		.append( '<a href="#" />' )
		.mousedown( function( e ) {
			// No dragging!
			e.preventDefault();
			return false;
		} )
		.on( 'click.wikiEditor-toc', function( e ) {
			$(".wikiEditor-ui-toc").trigger( 'expand.wikiEditor-toc' );
			// No dragging!
			e.preventDefault();
			return false;
		} )
		.hide()
		.find( 'a' )
		.text( "Hiện mục lục" );
	$collapseControl.insertBefore( $(".wikiEditor-ui-toc") );
	$( '.wikiEditor-ui-left .wikiEditor-ui-top' ).append( $expandControl );
}

/**
 * @see $.wikiEditor.modules.toc.fn.build.buildResizeControls()
 */
function buildResizeControls( ) {
	// Bind collapse and expand event handlers to the TOC
	$(".wikiEditor-ui-toc")
		.on( 'collapse.wikiEditor-toc', collapse )
		.on( 'expand.wikiEditor-toc', expand );
	// If the toc-width cookie is set, reset the widths based upon that
	//if ( $.cookie( 'wikiEditor-tot-width' ) == 0 ) {
	//	context.modules.toc.$toc.trigger( 'collapse.wikiEditor-toc' );
	//} else if ( $.cookie( 'wikiEditor-tot-width' ) > 0 ) {
	//	var initialWidth = $.cookie( 'wikiEditor-tot-width' );
	//	if( initialWidth < parseFloat( minimumWidth ) )
	//		initialWidth = parseFloat( minimumWidth ) + 1;
	//	context.modules.toc.$toc.data( 'openWidth', initialWidth + 'px' );
	//}
}

function templateCallsFromText(src) {
	var tmpls = src.match(/\{\{-[^|}\n]+?-(?:\|[^}]*)?\}\}/g);
	return tmpls || [];
}

function sectionsFromTemplateCalls(tmpls) {
	var sections = [];
	var path = [];
	for (var i = 0; i < tmpls.length; i++) {
		var id = tmpls[i] && tmpls[i].match(/^\{\{-([^|}\n]+?)-(?:\|[^}]*)?\}\}$/);
		if (!(id = id && id[1]) || blacklist.indexOf(id) >= 0) continue;
		var tmpl = ($.wiktviHeaders && $.wiktviHeaders.getHeader(id)) || {level: 1, name: id};
		
		for (var j = 0; j < tmpl.level; j++) {
			if (!path[j]) path[j] = "";
		}
		path.splice(tmpl.level, path.length - tmpl.level, id);
		
		sections.push({
			text: tmpl.name,
			level: tmpl.level,
			path: path.join("/") });
	}
	
	return sections;
}

/**
 * @see $.wikiEditor.modules.toc.fn.build.buildStructure()
 */
function buildStructure( outline, offset, level ) {
	if ( offset == undefined ) offset = 0;
	if ( level == undefined ) level = 1;
	var sections = [];
	for ( var i = offset; i < outline.length; i++ ) {
		if ( outline[i].level == level ) {
			var sub = buildStructure( outline, i + 1, level + 1 );
			if ( sub.length ) {
				outline[i].sections = sub;
			}
			sections[sections.length] = outline[i];
		} else if ( outline[i].level < level ) {
			break;
		}
	}
	return sections;
}

/**
 * @see $.wikiEditor.modules.toc.fn.unhighlight()
 */
function unhighlight() {
	$( '.wikiEditor-ui-toc div.current' ).removeClass( 'current' );
}

function jumpToPath(path) {
	path = path.split("/");
	var src = $("#wpTextbox1").val();
	if (!src) return;
	
	var idx = 0;
	for (var i = 0; i < path.length; i++) {
		if (!path[i]) continue;
        var callRe = new RegExp("\{\{-" + path[i] + "-(?:\|[^}]*)?\}\}");
        var callIdx = src.substr(idx > 0 ? idx : 0).search(callRe);
        if (callIdx >= 0 && idx >= 0) idx = callIdx + idx;
	}
	if (idx < 0) return;
	
	var textbox = $("#wpTextbox1");
	if (!textbox.length) return;
	
	textbox[0].focus();
	
    var endIdx = src.indexOf("}}", idx) + 2;
	textbox.textSelection("setSelection", {start: idx, end: endIdx})
		.textSelection("scrollToCaretPosition", {force: true});
}

/**
 * @see $.wikiEditor.modules.toc.fn.build.buildList()
 */
function buildList( structure ) {
	var list = $( '<ul />' );
	for ( var i = 0; i < structure.length; i++ ) {
		var path = structure[i].path || "";
		var div = $( '<div />' )
			.addClass( 'section-' + structure[i].level )
			.data( 'path', path )
			.mousedown( function() {
				// No dragging!
				return false;
			} )
			.click( function( event ) {
				// Bring user's eyes to the point we've now jumped to
				jumpToPath($(this).data("path"));
				
				// Highlight the clicked link
				//remove highlighting of toc after a second. Temporary hack till the highlight works --pdhanda
				unhighlight();
				clearTimeout(unhighlightTimeout);
				$( this ).addClass( 'current' );
				unhighlightTimeout = setTimeout( unhighlight, 1000 );
				event.preventDefault();
				} )
			.text( structure[i].text )
			.attr( 'title', structure[i].text );
		if ( structure[i].text == '' )
			div.html( '&nbsp;' );
		var item = $( '<li />' ).append( div );
		if ( structure[i].sections !== undefined ) {
			item.append( buildList( structure[i].sections ) );
		}
		list.append( item );
	}
	return list;
}

function update() {
	if ($(".wikiEditor-ui-toc").data( 'collapsed' )) return;
	
	var height = $(".wikiEditor-ui-bottom").height();
	$(".wikiEditor-ui-toc").css("height", height);
	
	var templateCalls = templateCallsFromText($("#wpTextbox1").val());
	var templateHash = templateCalls.join("");
	if (lastTemplateHash && templateHash == lastTemplateHash) return;
	lastTemplateHash = templateHash;
	
	// Recursively build the structure and add special item for
	// section 0, if needed
	var sections = sectionsFromTemplateCalls(templateCalls);
	var structure = buildStructure(sections);
	if ( $( 'input[name=wpSection]' ).val() == '' ) {
		structure.unshift( { text: mw.config.get( 'wgPageName' ).replace( /_/g, ' ' ), level: 0 } );
	} 
	$(".wikiEditor-ui-toc").html(buildList(structure));
	
	$(".wikiEditor-ui-toc").find( 'div' ).css( 'text-overflow', 'ellipsis' );
}

function build() {
	$(".wikiEditor-ui-right").append("<div class='wikiEditor-ui-toc-resize-grip'></div>")
		.append("<div class='wikiEditor-ui-toc' style='height: 536px;'></div>");
	
	$(".wikiEditor-ui-toc").css("width", defaultWidth);
	$(".wikiEditor-ui-left").css("marginRight", "-167px");
	$(".wikiEditor-ui-left").children().css("marginRight", "167px");
	
	buildResizeControls();
	buildCollapseControls();
	
	mw.loader.using("ext.gadget.headers", function () {
		$.wiktviHeaders.get(function () {
			// Clear the cache and update the table, this time with names.
			lastTemplateHash = [];
			update();
		});
	});
	
	// For now, just display the raw template names in a flat list.
	update();
    
    $("#wpTextbox1").blur(unhighlight);
    $("#wpTextbox1").change(update);
    setInterval(update, 5 * 1000 /* ms */);
}

mw.loader.using("ext.wikiEditor", function () {
	setTimeout(build, 1000);
});

});