|
|
Line 1: |
Line 1: |
| //Syntax highlighter with various advantages
| | |
|
| |
| mw.loader.load((function () {
| |
| "use strict";
| |
|
| |
| //variables that are preserved between function calls
| |
| var textboxContainer;
| |
| var wpTextbox0;
| |
| var wpTextbox1;
| |
| var syntaxStyleTextNode;
| |
| var lastText;
| |
| var maxSpanNumber = -1; //the number of the last span available, used to tell if creating additional spans is necessary
| |
| var highlightSyntaxIfNeededIntervalID;
| |
|
| |
| /* Define context-specific regexes, one for every common token that ends the
| |
| current context.
| |
|
| |
| An attempt has been made to search for the most common syntaxes first,
| |
| thus maximizing performance. Syntaxes that begin with the same character
| |
| are searched for at the same time.
| |
|
| |
| Wiki syntaxes from most common to least common:
| |
| [[internal link]] [http:// named external link]
| |
| {{template}} {{{template parameter}}} {| table |}
| |
| <tag> <!-- comment -->
| |
| http:// bare external link
| |
| =Heading= * unordered list # ordered list : indent ; small heading pre ---- horizontal line
| |
| ''italic'' '''bold'''
| |
| three tildes username four tildes signature five tildes timestamp
| |
| &entity;
| |
|
| |
| The tag-matching regex follows the XML standard closely so that users
| |
| won't feel like they have to escape sequences that MediaWiki will never
| |
| consider to be tags.
| |
|
| |
| Only entities for characters which need to be escaped or cannot be
| |
| unambiguously represented in a monospace font are highlighted. Use of
| |
| other entities is discouraged as a matter of style. For the same reasons,
| |
| numeric entities should be in hexadecimal (giving character codes in
| |
| decimal only adds confusion).
| |
|
| |
| Flags: g for global search, m for make ^ match the beginning of each line
| |
| and $ the end of each line
| |
| */
| |
| var breakerRegexBase = "\\[(?:\\[|(?:https?:|ftp:)?//|mailto:)|\\{(?:\\{\\{?|\\|)|<(?:[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:\\w\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD-\\.\u00B7\u0300-\u036F\u203F-\u203F-\u2040]*|!--[^]*?-->)|(?:https?://|ftp://|mailto:)[^\\s\"<>[\\]{-}]*[^\\s\",\\.:;<>[\\]{-}]|^(?:=|[*#:;]+|-{4,})|\\\\'\\\\'(?:\\\\')?|&(?:(?:n(?:bsp|dash)|mdash|lt|e[mn]sp|thinsp|amp|quot|gt|shy|zwn?j|lrm|rlm|Alpha|Beta|Epsilon|Zeta|Eta|Iota|Kappa|Mu|Nu|Omicron|Rho|Tau|Upsilon|Chi)|#x[0-9a-fA-F]+);|~{3,5}";
| |
| function breakerRegexWithPrefix(prefix)
| |
| {
| |
| //the stop token has to be at the beginning of the regex so that it takes precedence over substrings of itself.
| |
| //suck up newlines into the end token to avoid creating spans with nothing but newlines in them
| |
| return new RegExp("(" + prefix + ")\n*|" + breakerRegexBase, "gm");
| |
| }
| |
| var defaultBreakerRegex = new RegExp(breakerRegexBase, "gm");
| |
| var wikilinkBreakerRegex = breakerRegexWithPrefix("]][a-zA-Z]*");
| |
| var namedExternalLinkBreakerRegex = breakerRegexWithPrefix("]");
| |
| var parameterBreakerRegex = breakerRegexWithPrefix("}}}");
| |
| var templateBreakerRegex = breakerRegexWithPrefix("}}");
| |
| var tableBreakerRegex = breakerRegexWithPrefix("\\|}");
| |
| var headingBreakerRegex = breakerRegexWithPrefix("\n");
| |
| var boldBreakerRegex = breakerRegexWithPrefix("\\\\'\\\\'\\\\'");
| |
| var italicBreakerRegex = breakerRegexWithPrefix("\\\\'\\\\'");
| |
| var tagBreakerRegexCache = {};
| |
|
| |
| //browser workaround triggers
| |
| var gecko = ($.client.profile().layout == "gecko");
| |
| var presto = ($.client.profile().layout == "presto");
| |
| var trident = ($.client.profile().layout == "trident");
| |
|
| |
| function highlightSyntax()
| |
| {
| |
| lastText = wpTextbox1.value;
| |
| /* Backslashes and apostrophes are CSS-escaped at the beginning and all
| |
| parsing regexes and functions are designed to match. On the other hand,
| |
| newlines are not escaped until written so that in the regexes ^ and $
| |
| work for both newlines and the beginning or end of the string. */
| |
| var text = lastText.replace(/['\\]/g, "\\$&") + "\n"; //add a newline to fix scrolling and parsing issues
| |
| var i = 0; //the location of the parser as it goes through var text
| |
|
| |
| var css = "";
| |
| var spanNumber = 0;
| |
| var lastColor;
| |
| var before = true;
| |
|
| |
| //workaround for Opera
| |
| //there are two problems here:
| |
| // <textarea>.scrollLeft is automatically scrolled beyond the value limit that http://www.w3.org/TR/cssom-view/#scroll-an-element specifies
| |
| // <div> will hide a character or two underneath the scrollbar instead of adding a scrollbar
| |
| //this workaround forces wpTextbox0 to allow scrolling arbitrarily
| |
| if (presto)
| |
| {
| |
| text += new Array(wpTextbox1.scrollWidth).join(" ");
| |
| }
| |
|
| |
| //writes text into to-be-created span elements of wpTextbox0 using :before and :after pseudo-elements
| |
| //both :before and :after are used because using two pseudo-elements per span is significantly faster than doubling the number of spans required
| |
| function writeText(text, color)
| |
| {
| |
| //no need to use another span if using the same color
| |
| if (color != lastColor)
| |
| {
| |
| //whitespace is omitted in the hope of increasing performance
| |
| css += "'}#s" + spanNumber; //spans will be created with IDs s0 through sN
| |
| if (before)
| |
| {
| |
| css += ":before{";
| |
| before = false;
| |
| }
| |
| else
| |
| {
| |
| css += ":after{";
| |
| before = true;
| |
| ++spanNumber;
| |
| }
| |
| if (color)
| |
| {
| |
| //"background-color" is 6 characters longer than "background" but the browser processes it faster
| |
| css += "background-color:" + color + ";";
| |
| }
| |
| css += "content:'";
| |
| lastColor = color;
| |
| }
| |
| css += text;
| |
| }
| |
|
| |
| function highlightBlock(color, breakerRegex)
| |
| {
| |
| var match;
| |
|
| |
| for (breakerRegex.lastIndex = i; match = breakerRegex.exec(text); breakerRegex.lastIndex = i)
| |
| {
| |
| if (match[1])
| |
| {
| |
| //end token found
| |
| writeText(text.substring(i, breakerRegex.lastIndex), color);
| |
| i = breakerRegex.lastIndex;
| |
| return;
| |
| }
| |
|
| |
| var endIndexOfLastColor = breakerRegex.lastIndex - match[0].length;
| |
| if (i < endIndexOfLastColor) //avoid calling writeText with text == "" to improve performance
| |
| {
| |
| writeText(text.substring(i, endIndexOfLastColor), color);
| |
| }
| |
|
| |
| i = breakerRegex.lastIndex;
| |
|
| |
| switch (match[0].charAt(0)) //cases in this switch should be arranged from most common to least common
| |
| {
| |
| case "[":
| |
| if (match[0].charAt(1) == "[")
| |
| {
| |
| //wikilink
| |
| writeText("[[", syntaxHighlighterConfig.wikilinkColor || color);
| |
| highlightBlock(syntaxHighlighterConfig.wikilinkColor || color, wikilinkBreakerRegex);
| |
| }
| |
| else
| |
| {
| |
| //named external link
| |
| writeText(match[0], syntaxHighlighterConfig.externalLinkColor || color);
| |
| highlightBlock(syntaxHighlighterConfig.externalLinkColor || color, namedExternalLinkBreakerRegex);
| |
| }
| |
| break;
| |
| case "{":
| |
| if (match[0].charAt(1) == "{")
| |
| {
| |
| if (match[0].length == 3)
| |
| {
| |
| //parameter
| |
| writeText("{{{", syntaxHighlighterConfig.parameterColor || color);
| |
| highlightBlock(syntaxHighlighterConfig.parameterColor || color, parameterBreakerRegex);
| |
| }
| |
| else
| |
| {
| |
| //template
| |
| writeText("{{", syntaxHighlighterConfig.templateColor || color);
| |
| highlightBlock(syntaxHighlighterConfig.templateColor || color, templateBreakerRegex);
| |
| }
| |
| }
| |
| else //|
| |
| {
| |
| //table
| |
| writeText("{|", syntaxHighlighterConfig.tableColor || color);
| |
| highlightBlock(syntaxHighlighterConfig.tableColor || color, tableBreakerRegex);
| |
| }
| |
| break;
| |
| case "<":
| |
| if (match[0].charAt(1) == "!")
| |
| {
| |
| //comment tag
| |
| writeText(match[0], syntaxHighlighterConfig.commentColor || color);
| |
| break;
| |
| }
| |
| else
| |
| {
| |
| //some other kind of tag, search for its end
| |
| //the search is made easier because XML attributes may not contain the character ">"
| |
| var tagEnd = text.indexOf(">", i) + 1;
| |
| if (tagEnd == 0)
| |
| {
| |
| //not a tag, just a "<" with some text after it
| |
| writeText("<", color);
| |
| i = i - match[0].length + 1;
| |
| break;
| |
| }
| |
|
| |
| if (text.charAt(tagEnd - 2) == "/")
| |
| {
| |
| //empty tag
| |
| writeText(text.substring(i - match[0].length, tagEnd), syntaxHighlighterConfig.tagColor || color);
| |
| i = tagEnd;
| |
| }
| |
| else
| |
| {
| |
| var tagName = match[0].substring(1);
| |
| var stopAfter = "</" + tagName + ">";
| |
|
| |
| //again, cases are ordered from most common to least common
| |
| if (/^(?:nowiki|pre|math|syntaxhighlight|source|timeline|hiero)$/.test(tagName))
| |
| {
| |
| //tag that can contain only plain text
| |
| var endIndex = text.indexOf(stopAfter, i);
| |
| if (endIndex == -1)
| |
| {
| |
| endIndex = text.length;
| |
| }
| |
| else
| |
| {
| |
| endIndex += stopAfter.length;
| |
| }
| |
| writeText(text.substring(i - match[0].length, endIndex), syntaxHighlighterConfig.tagColor || color);
| |
| i = endIndex;
| |
| }
| |
| else
| |
| {
| |
| //ordinary tag
| |
| writeText(text.substring(i - match[0].length, tagEnd), syntaxHighlighterConfig.tagColor || color);
| |
| i = tagEnd;
| |
| if (!tagBreakerRegexCache[tagName])
| |
| {
| |
| tagBreakerRegexCache[tagName] = breakerRegexWithPrefix(stopAfter);
| |
| }
| |
| highlightBlock(syntaxHighlighterConfig.tagColor || color, tagBreakerRegexCache[tagName]);
| |
| }
| |
| }
| |
| }
| |
| break;
| |
| case "h":
| |
| case "f":
| |
| case "m":
| |
| //bare external link
| |
| writeText(match[0], syntaxHighlighterConfig.externalLinkColor || color);
| |
| break;
| |
| case "=":
| |
| if (/[^=]=+$/.test(text.substring(i, text.indexOf("\n", i)))) //the line begins and ends with an equals sign and has something else in the middle
| |
| {
| |
| //heading
| |
| writeText("=", syntaxHighlighterConfig.headingColor || color);
| |
| highlightBlock(syntaxHighlighterConfig.headingColor || color, headingBreakerRegex);
| |
| }
| |
| else
| |
| {
| |
| writeText("=", color); //move on, process this line as regular wikitext
| |
| }
| |
| break;
| |
| case "*":
| |
| case "#":
| |
| case ":":
| |
| //unordered list, ordered list, indent, small heading
| |
| //just highlight the marker
| |
| writeText(match[0], syntaxHighlighterConfig.listAndIndentColor || color);
| |
| break;
| |
| case ";":
| |
| //small heading
| |
| writeText(";", syntaxHighlighterConfig.headingColor || color);
| |
| highlightBlock(syntaxHighlighterConfig.headingColor || color, headingBreakerRegex);
| |
| break;
| |
| case "-":
| |
| //horizontal line
| |
| writeText(match[0], syntaxHighlighterConfig.hrColor || color);
| |
| break;
| |
| case "\\":
| |
| if (match[0].length == 6)
| |
| {
| |
| //bold
| |
| writeText("\\'\\'\\'", syntaxHighlighterConfig.boldColor || color);
| |
| highlightBlock(syntaxHighlighterConfig.boldColor || color, boldBreakerRegex);
| |
| }
| |
| else
| |
| {
| |
| //italic
| |
| writeText("\\'\\'", syntaxHighlighterConfig.italicColor || color);
| |
| highlightBlock(syntaxHighlighterConfig.italicColor || color, italicBreakerRegex);
| |
| }
| |
| break;
| |
| case "&":
| |
| //entity
| |
| writeText(match[0], syntaxHighlighterConfig.entityColor || color);
| |
| break;
| |
| case "~":
| |
| //username, signature, timestamp
| |
| writeText(match[0], syntaxHighlighterConfig.signatureColor || color);
| |
| }
| |
| }
| |
| }
| |
|
| |
|
| |
| //start!
| |
| var startTime = Date.now();
| |
| highlightBlock("", defaultBreakerRegex);
| |
|
| |
| //output the leftovers (if any) to make sure whitespace etc. matches
| |
| if (i < text.length)
| |
| {
| |
| writeText(text.substring(i), "");
| |
| }
| |
|
| |
| //do we have enough span elements to match the generated CSS?
| |
| while (maxSpanNumber < spanNumber)
| |
| {
| |
| wpTextbox0.appendChild(document.createElement("span")).id = "s" + ++maxSpanNumber;
| |
| }
| |
|
| |
| /* finish CSS: move the extra '} from the beginning to the end and CSS-
| |
| escape newlines. CSS ignores the space after the hex code of the
| |
| escaped character */
| |
| syntaxStyleTextNode.nodeValue = css.substring(2).replace(/\n/g, "\\A ") + "'}";
| |
|
| |
| //if highlighting took too long, disable it.
| |
| var endTime = Date.now();
| |
| /*if (typeof(bestTime) == "undefined")
| |
| {
| |
| window.bestTime = 10000;
| |
| highlightSyntaxIfNeededIntervalID = setInterval(highlightSyntax, 250);
| |
| }
| |
| else
| |
| {
| |
| if (endTime - startTime < bestTime)
| |
| {
| |
| bestTime = endTime - startTime;
| |
| document.title = bestTime;
| |
| }
| |
| }//*/
| |
| if (endTime - startTime > syntaxHighlighterConfig.timeout)
| |
| {
| |
| clearInterval(highlightSyntaxIfNeededIntervalID);
| |
| syntaxStyleTextNode.nodeValue = "";
| |
| wpTextbox1.removeEventListener("input", highlightSyntax);
| |
|
| |
| var errorMessage = {};
| |
| errorMessage["ca"] = "S'ha desactivat el remarcar de sintaxi en aquesta pàgina perquè ha tardat massa. El temps màxim permès per a remarcar és $1ms, i el teu ordinador ha trigat $2ms. Prova tancar algunes pestanyes i programes i fer clic en \"Mostra la previsualització\" o \"Mostra els canvis\". Si no funciona això, prova altre navegador web, i si això no funciona, prova un ordinador més ràpid.";
| |
| errorMessage["en"] = "Syntax highlighting on this page was disabled because it took too long. The maximum allowed highlighting time is $1ms, and your computer took $2ms. Try closing some tabs and programs and clicking \"Show preview\" or \"Show changes\". If that doesn't work, try a different web browser, and if that doesn't work, try a faster computer.";
| |
| errorMessage["es"] = "Se desactivó el resaltar de sintaxis en esta página porque tardó demasiado. El tiempo máximum permitido para resaltar es $1ms, y tu ordenador tardó $2ms. Prueba cerrar algunas pestañas y programas y hacer clic en \"Mostrar previsualización\" o \"Mostrar cambios\". Si no funciona esto, prueba otro navegador web, y si eso no funciona, prueba un ordenador más rápido.";
| |
| errorMessage["io"] = "Sintaxo-hailaitar en ca pagino esis nekapabligata pro ke konsumis tro multa tempo. La maxima permisata hailaitala tempo es $1ms, e tua ordinatro konsumis $2ms. Probez klozar kelka tabi e programi e kliktar \"Previdar\" o \"Montrez chanji\". Se to ne funcionas, probez altra brauzero, e se to ne funcionas, probez plu rapida ordinatro.";
| |
| errorMessage["pt"] = "O marcador de sintaxe foi desativado nesta pagina porque demorou demais. O tempo máximo permitido para marcar e $1ms, e seu computador demorou $2ms. Tenta sair de alguns programas e clique em \"Mostrar previsão\" ou \"Mostrar alterações\". Se isso não funciona, tenta usar uma outra navegador web, e se ainda não funciona, procura um computador mais rápido.";
| |
|
| |
| errorMessage = errorMessage[wgUserLanguage] || errorMessage[wgUserLanguage.substring(0, wgUserLanguage.indexOf("-"))] || errorMessage["en"];
| |
|
| |
| wpTextbox1.style.backgroundColor = "";
| |
| wpTextbox1.style.position = "";
| |
| wpTextbox0.style.color = "red";
| |
| wpTextbox0.style.fontFamily = "";
| |
| wpTextbox0.style.fontWeight = "bold";
| |
| wpTextbox0.style.height = "";
| |
|
| |
| var range = document.createRange();
| |
| range.selectNode(wpTextbox0); //chrome can't live without this
| |
| wpTextbox0.appendChild(range.createContextualFragment(errorMessage.replace("$1", syntaxHighlighterConfig.timeout).replace("$2", endTime - startTime)));
| |
| }
| |
| }
| |
|
| |
| function syncScrollX()
| |
| {
| |
| wpTextbox0.scrollLeft = wpTextbox1.scrollLeft;
| |
| }
| |
|
| |
| function syncScrollY()
| |
| {
| |
| wpTextbox0.scrollTop = wpTextbox1.scrollTop;
| |
| }
| |
|
| |
| //this function runs once every 500ms to detect changes to wpTextbox1's text that the input event does not catch
| |
| //this happens when another script changes the text without knowing that the syntax highlighter needs to be informed
| |
| function highlightSyntaxIfNeeded()
| |
| {
| |
| if (wpTextbox1.value != lastText)
| |
| {
| |
| highlightSyntax();
| |
| }
| |
| if (wpTextbox1.scrollLeft != wpTextbox0.scrollLeft)
| |
| {
| |
| syncScrollX();
| |
| }
| |
| if (wpTextbox1.scrollTop != wpTextbox0.scrollTop)
| |
| {
| |
| syncScrollY();
| |
| }
| |
| }
| |
|
| |
| function setup()
| |
| {
| |
| function configureColor(parameterName, hardcodedFallback)
| |
| {
| |
| if (syntaxHighlighterConfig[parameterName] == "normal")
| |
| {
| |
| syntaxHighlighterConfig[parameterName] = hardcodedFallback;
| |
| }
| |
| else if (syntaxHighlighterConfig[parameterName])
| |
| {
| |
| return;
| |
| }
| |
| else if (typeof(syntaxHighlighterConfig.defaultColor) != "undefined")
| |
| {
| |
| syntaxHighlighterConfig[parameterName] = syntaxHighlighterConfig.defaultColor;
| |
| }
| |
| else
| |
| {
| |
| syntaxHighlighterConfig[parameterName] = hardcodedFallback;
| |
| }
| |
| }
| |
|
| |
| window.syntaxHighlighterConfig = window.syntaxHighlighterConfig || {};
| |
|
| |
| //use 3-digit colors instead of 6-digit colors for performance
| |
| configureColor("commentColor", "#EFE"); //green
| |
| configureColor("boldColor", "#EEE"); //gray
| |
| configureColor("entityColor", "#DFD"); //green
| |
| configureColor("externalLinkColor", "#EFF"); //cyan
| |
| configureColor("italicColor", "#EEE"); //gray
| |
| configureColor("headingColor", "#EEE"); //gray
| |
| configureColor("hrColor", "#EEE"); //gray
| |
| configureColor("listAndIndentColor", "#EFE"); //green
| |
| configureColor("parameterColor", "#FC6"); //orange
| |
| configureColor("signatureColor", "#FC6"); //orange
| |
| configureColor("tagColor", "#FEF"); //pink
| |
| configureColor("tableColor", "#FFC"); //yellow
| |
| configureColor("templateColor", "#FFC"); //yellow
| |
| configureColor("wikilinkColor", "#EEF"); //blue
| |
|
| |
| syntaxHighlighterConfig.timeout = syntaxHighlighterConfig.timeout || 100;
| |
|
| |
| textboxContainer = document.createElement("div");
| |
| wpTextbox0 = document.createElement("div");
| |
| wpTextbox1 = document.getElementById("wpTextbox1");
| |
|
| |
| var syntaxStyleElement = document.createElement("style");
| |
| syntaxStyleElement.type = "text/css";
| |
| syntaxStyleTextNode = syntaxStyleElement.appendChild(document.createTextNode(""));
| |
|
| |
| //the styling of the textbox and the background div must be kept very similar
| |
| wpTextbox0.style.backgroundColor = window.getComputedStyle(wpTextbox1).backgroundColor;
| |
| if (wpTextbox0.style.backgroundColor == "transparent")
| |
| {
| |
| //Opera and perhaps others return "transparent" instead of "white" if the background color is not specified
| |
| //http://www.w3.org/TR/1998/REC-CSS2-19980512/cascade.html#computed-value is ambiguous as to what should happen
| |
| wpTextbox0.style.backgroundColor = "white";
| |
| }
| |
| wpTextbox0.style.border = "1px solid transparent";
| |
| wpTextbox0.style.boxSizing = "border-box";
| |
| wpTextbox0.style.MozBoxSizing = "border-box";
| |
| wpTextbox0.style.color = "transparent"; //makes it look just a little bit smoother
| |
| wpTextbox0.style.direction = window.getComputedStyle(wpTextbox1).direction; //because your UI language set in Preferences may have a different direction than the edit box
| |
| wpTextbox0.style.fontFamily = window.getComputedStyle(wpTextbox1).fontFamily;
| |
| wpTextbox0.style.fontSize = window.getComputedStyle(wpTextbox1).fontSize;
| |
| wpTextbox0.style.lineHeight = "normal";
| |
| wpTextbox0.style.overflowX = "auto";
| |
| wpTextbox0.style.overflowY = "scroll";
| |
| wpTextbox0.style.whiteSpace = "pre-wrap";
| |
| wpTextbox0.style.width = "100%";
| |
| wpTextbox0.style.wordWrap = "normal"; //see below
| |
|
| |
| wpTextbox1.style.backgroundColor = "transparent";
| |
| wpTextbox1.style.border = "1px inset gray";
| |
| wpTextbox1.style.boxSizing = "border-box";
| |
| wpTextbox1.style.MozBoxSizing = "border-box";
| |
| wpTextbox1.style.lineHeight = "normal";
| |
| wpTextbox1.style.margin = 0; //firefox wants to put a 1px margin on the top and bottom of the textbox, which throws it out of alignment with wpTextbox0
| |
| wpTextbox1.style.overflowX = "auto";
| |
| wpTextbox1.style.overflowY = "scroll";
| |
| wpTextbox1.style.padding = 0;
| |
| wpTextbox1.style.position = "absolute";
| |
| wpTextbox1.style.resize = "none";
| |
| wpTextbox1.style.left = 0;
| |
| wpTextbox1.style.top = 0;
| |
| wpTextbox1.style.width = "100%";
| |
| wpTextbox1.style.wordWrap = "normal"; //overall more visually appealing, and essential for Opera
| |
|
| |
| wpTextbox0.style.height = wpTextbox1.offsetHeight + "px";
| |
|
| |
| if (gecko) //workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=157846
| |
| {
| |
| wpTextbox0.style.paddingLeft = "1px";
| |
| wpTextbox0.style.paddingRight = "1px";
| |
| }
| |
| else if (presto) //workaround for Opera
| |
| {
| |
| //wpTextbox0 must allow arbitrary scrolling on Opera (see above), so wpTextbox1 must also be given a horizontal scrollbar
| |
| //also, if overflowX is auto then when the window is resized the standard line breaking algorithm is not followed
| |
| wpTextbox1.style.overflowX = "scroll";
| |
| }
| |
|
| |
| textboxContainer.style.position = "relative";
| |
| wpTextbox1.parentNode.insertBefore(textboxContainer, wpTextbox1);
| |
| textboxContainer.appendChild(wpTextbox1);
| |
| textboxContainer.appendChild(wpTextbox0);
| |
|
| |
| //fix drop-downs in editing toolbar
| |
| $('.tool-select *').css({zIndex: 5});
| |
|
| |
| document.head.appendChild(syntaxStyleElement);
| |
|
| |
| wpTextbox1.addEventListener("input", highlightSyntax);
| |
| wpTextbox1.addEventListener("scroll", syncScrollX);
| |
| wpTextbox1.addEventListener("scroll", syncScrollY);
| |
| highlightSyntaxIfNeededIntervalID = setInterval(highlightSyntaxIfNeeded, 500);
| |
| highlightSyntax();
| |
| }
| |
|
| |
| function queueSetup()
| |
| {
| |
| setTimeout(setup, 0);
| |
| }
| |
|
| |
|
| |
| //enable the highlighter only when editing wikitext pages
| |
| //in the future a separate parser could be added for CSS and JS pages
| |
| //blacklist Internet Explorer, it's just too broken
| |
| if ((wgAction == "edit" || wgAction == "submit") && wgPageContentModel == "wikitext" && !trident)
| |
| {
| |
| /* The highlighter has to run after any other script (such as the
| |
| editing toolbar) that reparents wpTextbox1. We make sure that
| |
| everything else has run by waiting for the page to completely load
| |
| and then adding a call to the setup function to the end of the event
| |
| queue, so that the setup function runs after any other triggers set
| |
| on the load event. */
| |
| if (document.readyState == "complete")
| |
| {
| |
| queueSetup();
| |
| }
| |
| else
| |
| {
| |
| $(window).load(queueSetup);
| |
| }
| |
| }
| |
| })(););
| |