// STARTFILE: main.js// **********************************************************************// ** **// ** changes to this file affect many users. **// ** please discuss on the talk page before editing **// ** **// **********************************************************************// ** **// ** if you do edit this file, be sure that your editor recognizes it **// ** as utf8, or the weird and wonderful characters in the namespaces **// ** below will be completely broken. You can check with the show **// ** changes button before submitting the edit. **// ** test: مدیا מיוחד Мэдыя **// ** **// **********************************************************************/* eslint-env browser *//* global $, jQuery, mw, window */
// Fix later/* global log, errlog, popupStrings, wikEdUseWikEd, WikEdUpdateFrame *//* eslint no-mixed-spaces-and-tabs: 0, no-empty: 0 */$(function)'); var match = d.match(anchRe); if (match && match.length > 0 && match[0])
// now try to deal with
-> #foo_baz_boom var lines = d.split('\n'); for (var i = 0; i < lines.length; ++i) return d; }
function killPopup // ENDFILE: actions.js // STARTFILE: domdrag.js /** @fileoverview The object, which enables objects to be dragged around.
************************************************* dom-drag.js 09.25.2001 www.youngpup.net ************************************************** 10.28.2001 - fixed minor bug where events sometimes fired off the handle, not the root. ************************************************* Pared down, some hooks added by [[User:Lupin]] Copyright Aaron Boodman. Saying stupid things daily since March 2001.*/
/** Creates a new Drag object. This is used to make various DOM elements draggable. @constructor */ function Drag
/** Gets an event in a cross-browser manner. @param e @private */ Drag.prototype.fixE = function(e) ; /** Initialises the Drag instance by telling it which object you want to be draggable, and what you want to drag it by. @param o The "handle" by which oRoot
is dragged. @param oRoot The object which moves when o
is dragged, or o
if omitted. */ Drag.prototype.init = function(o, oRoot) ;
/** Starts the drag. @private @param e */ Drag.prototype.start = function(e) ; /** Does the drag. @param e @private */ Drag.prototype.drag = function(e) ;
/** Ends the drag. @private */ Drag.prototype.end = function ; // ENDFILE: domdrag.js // STARTFILE: structures.js //
function copyStructure(oldStructure, newStructure)
copyStructure('original', 'nostalgia'); pg.structures.nostalgia.popupTopLinks = function(x) ; pg.structures.nostalgia.popupRedirTopLinks = pg.structures.nostalgia.popupTopLinks;
/** -- fancy -- **/ copyStructure('original', 'fancy'); pg.structures.fancy.popupTitle = function(x) ; pg.structures.fancy.popupTopLinks = function(x) ; pg.structures.fancy.popupOtherLinks = function(x) ; pg.structures.fancy.popupRedirTitle = pg.structures.fancy.popupTitle; pg.structures.fancy.popupRedirTopLinks = pg.structures.fancy.popupTopLinks; pg.structures.fancy.popupRedirOtherLinks = pg.structures.fancy.popupOtherLinks;
/** -- fancy2 -- **/ // hack for copyStructure('fancy', 'fancy2'); pg.structures.fancy2.popupTopLinks = function(x) ; pg.structures.fancy2.popupLayout = function ;
/** -- menus -- **/ copyStructure('original', 'menus'); pg.structures.menus.popupLayout = function ;
pg.structures.menus.popupTopLinks = function(x, shorter) ;
function menuTitle(s)
pg.structures.menus.popupRedirTitle = pg.structures.menus.popupTitle; pg.structures.menus.popupRedirTopLinks = pg.structures.menus.popupTopLinks;
copyStructure('menus', 'shortmenus'); pg.structures.shortmenus.popupTopLinks = function(x) ; pg.structures.shortmenus.popupRedirTopLinks = pg.structures.shortmenus.popupTopLinks;
// pg.structures.lite = ; pg.structures.lite.popupLayout = function ; pg.structures.lite.popupTitle = function(x) ; // ENDFILE: structures.js // STARTFILE: autoedit.js //
function execCmds(data, cmdList)
function parseCmd(str)
// FIXME: Only used once here, confusing with native (and more widely-used) unescape, should probably be replaced // Then again, unescape is semi-soft-deprecated, so we should look into replacing that too function unEscape(str, sep)
function parseSubstitute(str)
function skipOver(str, sep)
/*eslint-disable*/ function skipToEnd(str, sep) /*eslint-enable */
function findNext(str, ch)
function setCheckbox(param, box)
function autoEdit
function autoEdit2(d)
function autoClickToken
function autoEdit3
function bannerMessage(s)
function getRvSummary(template, json)
// // ENDFILE: autoedit.js // STARTFILE: downloader.js /** @fileoverview, a xmlhttprequest wrapper, and helper functions. */
/** Creates a new Downloader @constructor @class The Downloader class. Create a new instance of this class to download stuff. @param url The url to download. This can be omitted and supplied later. */ function Downloader(url)
new Downloader;
/** Submits the http request. */ Downloader.prototype.send = function(x) ; /** Aborts the download, setting the aborted
field to true. */ Downloader.prototype.abort = function ; /** Returns the downloaded data. */ Downloader.prototype.getData = function ; /** Prepares the download. */ Downloader.prototype.setTarget = function ; /** Gets the state of the download. */ Downloader.prototype.getReadyState = function ;
pg.misc.downloadsInProgress = ;
/** Starts the download. Note that setTarget must be run first */ Downloader.prototype.start = function ;
/** Gets the 'Last-Modified' date from the download headers. Should be run after the download completes. Returns null
on failure. @return */ Downloader.prototype.getLastModifiedDate = function ;
/** Sets the callback function. @param f callback function, called as f(this)
on success */ Downloader.prototype.setCallback = function(f) ;
Downloader.prototype.getStatus = function ;
////////////////////////////////////////////////// // helper functions
/** Creates a new and prepares it for action. @param url The url to download @param id The ID of the object @param callback The callback function invoked on success @return the object created, or 'ohdear' if an unsupported browser */ function newDownload(url, id, callback, onfailure) /** Simulates a download from cached data. The supplied data is put into a as if it had downloaded it. @param url The url. @param id The ID. @param callback The callback, which is invoked immediately as callback(d)
, where d
is the new . @param data The (cached) data. @param lastModified The (cached) last modified date. */ function fakeDownload(url, id, callback, data, lastModified, owner)
/** Starts a download. @param url The url to download @param id The ID of the object @param callback The callback function invoked on success @return the object created, or 'ohdear' if an unsupported browser */ function startDownload(url, id, callback)
/** Aborts all downloads which have been started. */ function abortAllDownloads // ENDFILE: downloader.js // STARTFILE: livepreview.js // TODO: location is often not correct (eg relative links in previews) // NOTE: removed md5 and image and math parsing. was broken, lots of bytes. /** * InstaView - a Mediawiki to HTML converter in JavaScript * Version 0.6.1 * Copyright (C) Pedro Fayolle 2005-2006 * https://en.wikipedia.org/wiki/User:Pilaf * Distributed under the BSD license * * Changelog: * * 0.6.1 * - Fixed problem caused by \r characters * - Improved inline formatting parser * * 0.6 * - Changed name to InstaView * - Some major code reorganizations and factored out some common functions * - Handled conversion of relative links (i.e. /foo) * - Fixed misrendering of adjacent definition list items * - Fixed bug in table headings handling * - Changed date format in signatures to reflect Mediawiki's * - Fixed handling of * - Updated MD5 function (hopefully it will work with UTF-8) * - Fixed bug in handling of links inside images * * To do: * - Better support for math tags * - Full support for * - Parser-based (as opposed to RegExp-based) inline wikicode handling (make it one-pass and bullet-proof) * - Support for templates (through AJAX) * - Support for coloured links (AJAX) */ var Insta = {}; function setupLivePreview { // options Insta.conf = { baseUrl: '', user: {}, wiki: { lang: pg.wiki.lang, interwiki: pg.wiki.interwiki, default_thumb_width: 180 }, paths: { articles: pg.wiki.articlePath + '/', // Only used for Insta previews with images. (not in popups) math: '/math/', images: '//upload.wikimedia.org/wikipedia/en/', // FIXME getImageUrlStart(pg.wiki.hostname), images_fallback: '//upload.wikimedia.org/wikipedia/commons/', }, locale: { user: mw.config.get('wgFormattedNamespaces')[pg.nsUserId], image: mw.config.get('wgFormattedNamespaces')[pg.nsImageId], category: mw.config.get('wgFormattedNamespaces')[pg.nsCategoryId], // shouldn't be used in popup previews, i think months: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] } }; // options with default values or backreferences Insta.conf.user.name = Insta.conf.user.name || 'Wikipedian'; Insta.conf.user.signature = '[[' + Insta.conf.locale.user + ':' + Insta.conf.user.name + '|' + Insta.conf.user.name + ']]'; //Insta.conf.paths.images = '//upload.wikimedia.org/wikipedia/' + Insta.conf.wiki.lang + '/'; // define constants Insta.BLOCK_IMAGE = new RegExp('^\\[\\[(?:File|Image|' + Insta.conf.locale.image + '):.*?\\|.*?(?:frame|thumbnail|thumb|none|right|left|center)', 'i'); } Insta.dump = function(from, to) { if (typeof from == 'string') { from = document.getElementById(from); } if (typeof to == 'string') { to = document.getElementById(to); } to.innerHTML = this.convert(from.value); }; Insta.convert = function(wiki) { var ll = (typeof wiki == 'string') ? wiki.replace(/\r/g, '').split(/\n/) : wiki, // lines of wikicode o = '', // output p = 0, // para flag r; // result of passing a regexp to compareLineStringOrReg // some shorthands function remain { return ll.length; } function sh { return ll.shift; } // shift function ps(s) { o += s; } // push // similar to C's printf, uses ? as placeholders, ?? to escape question marks function f { var i = 1, a = arguments, f = a[0], o = '', c, p; for (; i < a.length; i++) { if ((p = f.indexOf('?')) + 1) { // allow character escaping i -= c = f.charAt(p + 1) == '?' ? 1 : 0; o += f.substring(0, p) + (c ? '?' : a[i]); f = f.substr(p + 1 + c); } else { break; } } return o + f; } function html_entities(s) { return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">"); } // Wiki text parsing to html is a nightmare. // The below functions deliberately don't escape the ampersand since this would make it more difficult, // and we don't absolutely need to for how we need it. // This means that any unescaped ampersands in wikitext will remain unescaped and can cause invalid HTML. // Browsers should all be able to handle it though. // We also escape significant wikimarkup characters to prevent further matching on the processed text function htmlescape_text(s) { return s.replace(/</g, "<").replace(/>/g, ">").replace(/:/g, ":").replace(/\[/g, "[").replace(/]/g, "]"); } function htmlescape_attr(s) { return htmlescape_text(s).replace(/'/g, "'").replace(/"/g, """); } // return the first non matching character position between two strings function str_imatch(a, b) { for (var i = 0, l = Math.min(a.length, b.length); i < l; i++) { if (a.charAt(i) != b.charAt(i)) { break; } } return i; } // compare current line against a string or regexp // if passed a string it will compare only the first string.length characters // if passed a regexp the result is stored in r function compareLineStringOrReg(c) { return (typeof c == 'string') ? (ll[0] && ll[0].substr(0, c.length) == c) : (r = ll[0] && ll[0].match(c)); } function compareLineString(c) { return ll[0] == c; } // compare current line against a string function charAtPoint(p) { return ll[0].charAt(p); } // return char at pos p function endl(s) { ps(s); sh; } function parse_list { var prev = ''; while (remain && compareLineStringOrReg(/^([*#:;]+)(.*)$/)) { var l_match = r; sh; var ipos = str_imatch(prev, l_match[1]); // close uncontinued lists for (var prevPos = prev.length - 1; prevPos >= ipos; prevPos--) { var pi = prev.charAt(prevPos); if (pi == '*') { ps('</ul>'); } else if (pi == '#') { ps('</ol>'); } // close a dl only if the new item is not a dl item (:, ; or empty) else if ($.inArray(l_match[1].charAt(prevPos), ['', '*', '#'])) { ps('</dl>'); } } // open new lists for (var matchPos = ipos; matchPos < l_match[1].length; matchPos++) { var li = l_match[1].charAt(matchPos); if (li == '*') { ps('<ul>'); } else if (li == '#') { ps('<ol>'); } // open a new dl only if the prev item is not a dl item (:, ; or empty) else if ($.inArray(prev.charAt(matchPos), ['', '*', '#'])) { ps('<dl>'); } } switch (l_match[1].charAt(l_match[1].length - 1)) { case '*': case '#': ps('<li>' + parse_inline_nowiki(l_match[2])); break; case ';': ps('<dt>'); var dt_match = l_match[2].match(/(.*?)(:.*?)$/); // handle ;dt :dd format if (dt_match) { ps(parse_inline_nowiki(dt_match[1])); ll.unshift(dt_match[2]); } else ps(parse_inline_nowiki(l_match[2])); break; case ':': ps('<dd>' + parse_inline_nowiki(l_match[2])); } prev = l_match[1]; } // close remaining lists for (var i = prev.length - 1; i >= 0; i--) { ps(f('</?>', (prev.charAt(i) == '*') ? 'ul' : ((prev.charAt(i) == '#') ? 'ol' : 'dl'))); } } function parse_table { endl(f('<table>', compareLineStringOrReg(/^\{\|(.*)$/) ? r[1] : '')); for (; remain;) if (compareLineStringOrReg('|')) switch (charAtPoint(1)) { case '}': endl('</table>'); return; case '-': endl(f('<tr>', compareLineStringOrReg(/\|-*(.*)/)[1])); break; default: parse_table_data; } else if (compareLineStringOrReg('!')) { parse_table_data; } else { sh; } } function parse_table_data { var td_line, match_i; // 1: "|+", '|' or '+' // 2: ?? // 3: attributes ?? // TODO: finish commenting this regexp var td_match = sh.match(/^(\|\+|\||!)((?:([^[|]*?)\|(?!\|))?(.*))$/); if (td_match[1] == '|+') ps('<caption'); else ps('<t' + ((td_match[1] == '|') ? 'd' : 'h')); if (typeof td_match[3] != 'undefined') { //ps(' ' + td_match[3]) match_i = 4; } else match_i = 2; ps('>'); if (td_match[1] != '|+') { // use || or !! as a cell separator depending on context // NOTE: when split is passed a regexp make sure to use non-capturing brackets td_line = td_match[match_i].split((td_match[1] == '|') ? '||' : /(?:\|\||!!)/); ps(parse_inline_nowiki(td_line.shift)); while (td_line.length) ll.unshift(td_match[1] + td_line.pop); } else { ps(parse_inline_nowiki(td_match[match_i])); } var tc = 0, td = []; while (remain) { td.push(sh); if (compareLineStringOrReg('|')) { if (!tc) break; // we're at the outer-most level (no nested tables), skip to td parse else if (charAtPoint(1) == '}') tc--; } else if (!tc && compareLineStringOrReg('!')) break; else if (compareLineStringOrReg('{|')) tc++; } if (td.length) ps(Insta.convert(td)); } function parse_pre { ps('<pre>'); do { endl(parse_inline_nowiki(ll[0].substring(1)) + "\n"); } while (remain && compareLineStringOrReg(' ')); ps('</pre>'); } function parse_block_image { ps(parse_image(sh)); } function parse_image(str) { //<NOLITE> // get what's in between "[[Image:" and "]]" var tag = str.substring(str.indexOf(':') + 1, str.length - 2); /* eslint-disable no-unused-vars */ var width; var attr = [], filename, caption = ''; var thumb = 0, frame = 0, center = 0; var align = ''; /* eslint-enable no-unused-vars */ if (tag.match(/\|/)) { // manage nested links var nesting = 0; var last_attr; for (var i = tag.length - 1; i > 0; i--) { if (tag.charAt(i) == '|' && !nesting) { last_attr = tag.substr(i + 1); tag = tag.substring(0, i); break; } else switch (tag.substr(i - 1, 2)) { case ']]': nesting++; i--; break; case '[[': nesting--; i--; } } attr = tag.split(/\s*\|\s*/); attr.push(last_attr); filename = attr.shift; var w_match; for (; attr.length; attr.shift) { w_match = attr[0].match(/^(\d*)(?:[px]*\d*)?px$/); if (w_match) width = w_match[1]; else switch (attr[0]) { case 'thumb': case 'thumbnail': thumb = true; frame = true; break; case 'frame': frame = true; break; case 'none': case 'right': case 'left': center = false; align = attr[0]; break; case 'center': center = true; align = 'none'; break; default: if (attr.length == 1) caption = attr[0]; } } } else filename = tag; return ''; //</NOLITE> } function parse_inline_nowiki(str) { var start, lastend = 0; var substart = 0, nestlev = 0, open, close, subloop; var html = ''; while (-1 != (start = str.indexOf('<nowiki>', substart))) { html += parse_inline_wiki(str.substring(lastend, start)); start += 8; substart = start; subloop = true; do { open = str.indexOf('<nowiki>', substart); close = str.indexOf('', substart); if (close <= open || open
return html + parse_inline_wiki(str.substr(lastend)); }
function parse_inline_images(str)