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

  • פיירפוקס / ספארי: להחזיק את המקש Shift בעת לחיצה על טעינה מחדש (Reload) או ללחוץ על צירוף המקשים Ctrl-F5 או Ctrl-R (במחשב מק: ⌘-R).
  • גוגל כרום: ללחוץ על צירוף המקשים Ctrl-Shift-R (במחשב מק: ⌘-Shift-R).
  • אדג': להחזיק את המקש Ctrl בעת לחיצה על רענן (Refresh) או ללחוץ על צירוף המקשים Ctrl-F5.
/* Autocomplete for links and templates Written by [[משתמש:ערן]] */ mw.loader.using(['jquery.ui', 'jquery.textSelection'], function() {     //extends jquery with autoCompleteWikiText functionality for autocomplete of links and templates     $.fn.autoCompleteWikiText = function(options) {         var mode = "none",             templateDataCache = {},             ctrl = $(this),             settings = $.extend(true, {             positionMy: $('body').is('.rtl') ? "left top" : "right top", // be default, open below the control             positionAt: $('body').is('.rtl') ? "left bottom" : "right bottom",             positionOf: ctrl,             positionOffset: "0",             filterResponse: function(a) {                 return a;             }, // function that expects array of string and returns array of strings             menuCSS: {                 width: 'auto',                 maxHeight: '30em',                 'overflow-y': 'auto'             },             itemCSS: {                 right: 'inherit'             },             onselected: function(item) {                 var pos = ctrl.textSelection('getCaretPosition') - 1,                     txt = ctrl.val(),                 	open, close, caretBackwards;                  switch (mode) {                     case "none":                         return;                     case "templateValue":                         open = "|";                         close = "";                         caretBackwards = 0;                         break;                     case "templateParams":                         open = "|";                         close = "=";                         caretBackwards = 0;                         break;                     case "template":                         item = item.substr(mw.config.get('wgFormattedNamespaces')[10].length + 1);                         caretBackwards = 2;                         open = "{{";                         close = "|}}";                         break;                     case "link":                         open = "[[";                         close = "]]";                         caretBackwards = 0;                         if (item[item.length - 1] == ')') item += '|';                         break;                 }                 var lastbegin = txt.lastIndexOf(open, pos);                 if (txt[lastbegin + 2] == ':')                     item = ':' + item;                  var newTxt = txt.substr(0, lastbegin) + open + item + close + txt.substr(pos + 1);                 var orgScroll = ctrl.scrollTop();                 ctrl.val(newTxt);                 ctrl.textSelection('setSelection', {                     start: lastbegin + (open + item + close).length - caretBackwards                 });                 ctrl.scrollTop(orgScroll);             }         }, options);          function findLinks(res) {             var pos = ctrl.textSelection('getCaretPosition') - 1;             var txt = ctrl.val();              var lastbegin = txt.lastIndexOf("[[", pos);             var lastend = txt.lastIndexOf("]]", pos);             var isLink = lastbegin > lastend;             if (isLink) {                 mode = 'link';                 fillLinksList(res, txt.substr(lastbegin + 2, pos - lastbegin));             } else {                 lastbegin = txt.lastIndexOf("{{", pos);                 lastend = txt.lastIndexOf("}}", pos);                 var isTemplate = lastbegin > lastend;                 if (isTemplate) {                     var prefixName = mw.config.get('wgFormattedNamespaces')[10] + ':' + txt.substr(lastbegin + 2, pos - lastbegin - 1);                     mode = (prefixName.indexOf('|') > -1) ? 'templateParams' : 'template';                     fillLinksList(res, prefixName);                 } else {                     mode = "none";                     res([]);                 }             }         }           function resolveTempalte(templateName) {             var dfd = new jQuery.Deferred();             if (!templateName) return dfd.reject().promise();             if (templateDataCache[templateName]) return dfd.resolve().promise();             var api = new mw.Api();             api.get({                 action: 'templatedata',                 titles: templateName,                 redirects: 1             }).done(function(data) {                 if (!data.pages) return dfd.reject();                 for (var pageid in data.pages) {                     templateDataCache[templateName] = data.pages[pageid];                     dfd.resolve();                 }                 if (!templateDataCache[templateName]) dfd.reject();             });             return dfd.promise();         }          function resolveApi(queryType, queryValue) {             var dfd = new jQuery.Deferred(),                 api = new mw.Api();              switch (queryType) {                 case 'users':                     api.get({                         action: 'query',                         list: 'allusers',                         auactiveusers: 1,                         auprefix: queryValue                     }).done(function(data) {                         if (data && data.query && data.query.allusers) dfd.resolve($.map(data.query.allusers, function(e) {                             return e.name;                         }));                         else dfd.reject();                     });                     break;                 case 'pages':                     api.get({                         action: 'opensearch',                         search: queryValue                     }).done(function(data) {                         if (data[1]) dfd.resolve(settings.filterResponse(data[1]));                         else dfd.reject();                     });                     break;                 default:                     throw 'unexpected queryType';             }              return dfd.promise();         }          function fillLinksList(res, txt) {             txt = $.trim(txt);             if (txt.length <= 1 || (mode != 'templateParams' && txt.indexOf('|') > -1) || (txt.indexOf('#') > -1 && mw.config.get('wgNamespaceNumber') === 0)) res([]);             else if (mode === 'templateParams') {                 var templateMatch = /(.+?)\|(?:.*\|)?([^=]+$)/.exec(txt);                 $.when(resolveTempalte(templateMatch && templateMatch[1])).done(function() {                     var curTemplateData = templateDataCache[templateMatch[1]],                     	suggestions = [],                     	curParamIndex = txt.split('|').length - 1;                     for (var paramName in curTemplateData.params) {                         if (paramName == curParamIndex) {                             var paramValue = templateMatch[2];                             var dfd;                             switch (curTemplateData.params[paramName].type) {                                 case 'wiki-page-name':                                     dfd = $.when(resolveApi('pages', paramValue));                                     mode = 'templateValue';                                     break;                                 case 'wiki-file-name':                                     dfd = $.when(resolveApi('pages', 'File:' + paramValue));                                     mode = 'templateValue';                                     break;                                 case 'wiki-template-name':                                     dfd = $.when(resolveApi('pages', 'Template:' + paramValue));                                     mode = 'templateValue';                                     break;                                                                     case 'wiki-user-name':                                     dfd = $.when(resolveApi('users', paramValue));                                     mode = 'templateValue';                                     break;                                 default:                                     return res([]); // dont suggest for this indexed param                             }                             return dfd.done(res).fail(function() {                                 res([]);                             });                         }                         if (paramName === '1' || txt.indexOf(paramName) > -1) continue; //dont suggest used params                         suggestions.push(paramName);                     }                     res(suggestions);                 }).fail(res);             } else if (txt.indexOf('#') > -1) {                 var pageTitle = txt.substr(0, txt.indexOf('#'));                 var sectionPrefix = txt.substr(txt.indexOf('#') + 1);                 var api = new mw.Api();                 api.get({                     action: 'parse',                     page: pageTitle,                     prop: 'sections'                 }).done(function(data) {                     if (data && data.parse && data.parse.sections) res($(data.parse.sections).map(function() {                         return this.line.indexOf(sectionPrefix) == 0 ? (pageTitle + '#' + this.line.replace(/[|\[\]\{\}]/g, escape)) : null;                     }));                 });             } else {                 $.when(resolveApi('pages', txt)).done(res).fail(function() {                     res([])                 });             }         }          ctrl.autocomplete({             source: function(request, response) {                 if (fixArrowsBug(this))                     response([]);                 else                     findLinks(response);             },             focus: function() {                 return false;             },             select: function(e, ui) {                 settings.onselected(ui.item.value);                 return false;             },             open: function() {                 $(".ui-autocomplete")                     .css(settings.menuCSS)                     .position({                         my: settings.positionMy,                         at: settings.positionAt,                         of: settings.positionOf,                         offset: settings.positionOffset,                         collision: 'none fit'                     })                     .find('li').css(settings.itemCSS);             }         });         var fixed, stfu, escapes = 0;         //this is hack to prevent known serious bug in autocomplete.js that prevent default of the up and down key which may drive you crazy....         function fixArrowsBug(self) {             if (fixed) return false;             fixed = true;  	   // on click selection may change. close the menu             ctrl.on("click.autocomplete", function(e){ 		clearTimeout(self.searching); 		self.close(); 	   });             ctrl.off("keydown.autocomplete");             ctrl.off("keydown.autocomplete0");             ctrl.on("keydown.autocomplete",                 function(event) {                     var keyCode = $.ui.keyCode;                     // hack to allow cancelling the gadget: mostly useful when editing templates.                     escapes = event.keyCode == keyCode.ESCAPE ? escapes + 1 : 0;                     if ( stfu || ( stfu = escapes >= 3 ) ) {                         self.close(event);                     	return;                     }                     switch (event.keyCode) {                         case keyCode.PAGE_UP:                             self._move("previousPage", event);                             break;                         case keyCode.PAGE_DOWN:                             self._move("nextPage", event);                             break;                         case keyCode.UP:                             if (!self.menu.element.is(":visible")) return;                             self._move("previous", event);                             // prevent moving cursor to beginning of text field in some browsers                             event.preventDefault();                             break;                         case keyCode.DOWN:                             if (!self.menu.element.is(":visible")) return;                             self._move("next", event);                             // prevent moving cursor to end of text field in some browsers                             event.preventDefault();                             break;                         case keyCode.ENTER:                         case keyCode.NUMPAD_ENTER:                             // when menu is open or has focus                             if (self.menu.active) {                                 event.preventDefault();                             }                             //passthrough - ENTER and TAB both select the current element                         case keyCode.TAB:                             if (!self.menu.active) {                                 return;                             }                             self.menu.select(event);                             break;                         case keyCode.ESCAPE:                             self.element.val(self.term);                             self.close(event);                             break;                          case keyCode.SHIFT:                         case keyCode.CONTROL:                         case keyCode.ALT:                         case keyCode.COMMAND:                         case keyCode.COMMAND_RIGHT:                         case keyCode.INSERT:                         case keyCode.CAPS_LOCK:                         case keyCode.END:                         case keyCode.HOME:                         case keyCode.LEFT:                         case keyCode.RIGHT:                        	                             // ignore metakeys (shift, ctrl, alt)                             break;                         default:                             // keypress is triggered before the input value is changed                             clearTimeout(self.searching);                             self.searching = setTimeout(function() {                                 self.search(null, event);                             }, self.options.delay);                             break;                     }                 });             return true;         }     } });  if ($.inArray(mw.config.get('wgAction'), ['edit', 'submit']) + 1)     mw.loader.using(['jquery.ui', 'jquery.textSelection'], function() {         //enable autocomplete for editbox, relative to editform in an offset of -80 vertical         $("#wpTextbox1").autoCompleteWikiText({             positionAt: $('#wpTextbox1').prop('dir') == 'rtl' ? "left top" : "right top",             positionOf: '#editform',             positionOffset: "0 0",             menuCSS: {                 background: '#E0EEF7',                 opacity: 0.8             },             itemCSS: {                 padding: 0,                 margin: 0             }         });     });