3,554
edits
(Created page) |
(Updated script.) |
||
Line 5: | Line 5: | ||
//variables that are preserved between function calls | //variables that are preserved between function calls | ||
var wpTextbox0; | var wpTextbox0; | ||
var wpTextbox1; | var wpTextbox1; | ||
Line 12: | Line 11: | ||
var maxSpanNumber = -1; //the number of the last span available, used to tell if creating additional spans is necessary | var maxSpanNumber = -1; //the number of the last span available, used to tell if creating additional spans is necessary | ||
var highlightSyntaxIfNeededIntervalID; | var highlightSyntaxIfNeededIntervalID; | ||
var attributeObserver; | |||
/* Define context-specific regexes, one for every common token that ends the | /* Define context-specific regexes, one for every common token that ends the | ||
Line 20: | Line 20: | ||
are searched for at the same time. | are searched for at the same time. | ||
Supported wiki syntaxes from most common to least common: | |||
[[internal link]] [http:// named external link] | [[internal link]] [http:// named external link] | ||
{{template}} {{{template parameter}}} {| table |} | {{template}} {{{template parameter}}} {| table |} | ||
<tag> <!-- comment --> | <tag> <!-- comment --> | ||
http:// bare external link | http:// bare external link | ||
=Heading= * unordered list # ordered list : indent ; small heading | =Heading= * unordered list # ordered list : indent ; small heading ---- horizontal line | ||
''italic'' '''bold''' | ''italic'' '''bold''' | ||
three tildes username four tildes signature five tildes timestamp | three tildes username four tildes signature five tildes timestamp | ||
Line 35: | Line 35: | ||
Only entities for characters which need to be escaped or cannot be | Only entities for characters which need to be escaped or cannot be | ||
unambiguously represented in a monospace font are highlighted. Use of | unambiguously represented in a monospace font are highlighted, such as | ||
Greek letters that strongly resemble Latin letters. 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). | |||
Newlines are sucked up into ending tokens (including comments, bare | |||
external links, lists, horizontal lines, signatures, entities, etc.) to | |||
avoid creating spans with nothing but newlines in them. | |||
Flags: g for global search, m for make ^ match the beginning of each line | Flags: g for global search, m for make ^ match the beginning of each line | ||
and $ the end 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)| | 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]*(?=/?>| |\n)|!--[^]*?-->\n*)|(?:https?://|ftp://|mailto:)[^\\s\"<>[\\]{-}]*[^\\s\",\\.:;<>[\\]{-}]\n*|^(?:=|[*#:;]+\n*|-{4,}\n*)|\\\\'\\\\'(?:\\\\')?|~{3,5}\n*|&(?:(?:n(?:bsp|dash)|m(?:dash|inus)|lt|e[mn]sp|thinsp|amp|quot|gt|shy|zwn?j|lrm|rlm|Alpha|Beta|Epsilon|Zeta|Eta|Iota|Kappa|[Mm]u|micro|Nu|[Oo]micron|[Rr]ho|Tau|Upsilon|Chi)|#x[0-9a-fA-F]+);\n*"; | ||
function breakerRegexWithPrefix(prefix) | function breakerRegexWithPrefix(prefix) | ||
{ | { | ||
//the stop token has to be at the beginning of the regex so that it takes precedence over substrings of itself. | //the stop token has to be at the beginning of the regex so that it takes precedence over substrings of itself. | ||
return new RegExp("(" + prefix + ")\n*|" + breakerRegexBase, "gm"); | return new RegExp("(" + prefix + ")\n*|" + breakerRegexBase, "gm"); | ||
} | } | ||
Line 57: | Line 61: | ||
var tableBreakerRegex = breakerRegexWithPrefix("\\|}"); | var tableBreakerRegex = breakerRegexWithPrefix("\\|}"); | ||
var headingBreakerRegex = breakerRegexWithPrefix("\n"); | var headingBreakerRegex = breakerRegexWithPrefix("\n"); | ||
var tagBreakerRegexCache = {}; | var tagBreakerRegexCache = {}; | ||
function highlightSyntax() | function highlightSyntax() | ||
Line 81: | Line 78: | ||
var before = true; | var before = true; | ||
/ | /* Highlighting bold or italic markup presents a special challenge | ||
because the actual MediaWiki parser uses multiple passes to determine | |||
which ticks represent start tags and which represent end tags. | |||
Because that would be too slow for us here, we instead keep track of | |||
what kinds of unclosed opening ticks have been encountered and use | |||
that to make a good guess as to whether the next ticks encountered | |||
are an opening tag or a closing tag. | |||
The major downsides to this method are that '''apostrophe italic'' | |||
and ''italic apostrophe''' are not highlighted correctly, and bold | |||
and italic are both highlighted in the same color. */ | |||
var assumedBold = false; | |||
var assumedItalic = false; | |||
//writes text into to-be-created span elements of wpTextbox0 using :before and :after pseudo-elements | //writes text into to-be-created span elements of wpTextbox0 using :before and :after pseudo-elements | ||
Line 212: | Line 213: | ||
{ | { | ||
var tagName = match[0].substring(1); | var tagName = match[0].substring(1); | ||
//again, cases are ordered from most common to least common | //again, cases are ordered from most common to least common | ||
Line 218: | Line 218: | ||
{ | { | ||
//tag that can contain only plain text | //tag that can contain only plain text | ||
var stopAfter = "</" + tagName + ">"; | |||
var endIndex = text.indexOf(stopAfter, i); | var endIndex = text.indexOf(stopAfter, i); | ||
if (endIndex == -1) | if (endIndex == -1) | ||
Line 237: | Line 238: | ||
if (!tagBreakerRegexCache[tagName]) | if (!tagBreakerRegexCache[tagName]) | ||
{ | { | ||
tagBreakerRegexCache[tagName] = breakerRegexWithPrefix( | tagBreakerRegexCache[tagName] = breakerRegexWithPrefix("</" + tagName + ">"); | ||
} | } | ||
highlightBlock(syntaxHighlighterConfig.tagColor || color, tagBreakerRegexCache[tagName]); | highlightBlock(syntaxHighlighterConfig.tagColor || color, tagBreakerRegexCache[tagName]); | ||
Line 267: | Line 268: | ||
//unordered list, ordered list, indent, small heading | //unordered list, ordered list, indent, small heading | ||
//just highlight the marker | //just highlight the marker | ||
writeText(match[0], syntaxHighlighterConfig. | writeText(match[0], syntaxHighlighterConfig.listOrIndentColor || color); | ||
break; | break; | ||
case ";": | case ";": | ||
Line 279: | Line 280: | ||
break; | break; | ||
case "\\": | case "\\": | ||
writeText(match[0], syntaxHighlighterConfig.boldOrItalicColor || color); | |||
if (match[0].length == 6) | if (match[0].length == 6) | ||
{ | { | ||
//bold | //bold | ||
if (assumedBold) | |||
highlightBlock(syntaxHighlighterConfig. | { | ||
//end tag | |||
assumedBold = false; | |||
return; | |||
} | |||
else | |||
{ | |||
//start tag | |||
assumedBold = true; | |||
highlightBlock(syntaxHighlighterConfig.boldOrItalicColor || color, defaultBreakerRegex); | |||
} | |||
} | } | ||
else | else | ||
{ | { | ||
//italic | //italic | ||
if (assumedItalic) | |||
highlightBlock(syntaxHighlighterConfig. | { | ||
//end tag | |||
assumedItalic = false; | |||
return; | |||
} | |||
else | |||
{ | |||
//start tag | |||
assumedItalic = true; | |||
highlightBlock(syntaxHighlighterConfig.boldOrItalicColor || color, defaultBreakerRegex); | |||
} | |||
} | } | ||
break; | break; | ||
Line 313: | Line 335: | ||
writeText(text.substring(i), ""); | writeText(text.substring(i), ""); | ||
} | } | ||
//if highlighting took too long, disable it. | //if highlighting took too long, disable it. | ||
Line 329: | Line 340: | ||
/*if (typeof(bestTime) == "undefined") | /*if (typeof(bestTime) == "undefined") | ||
{ | { | ||
window.bestTime = | window.bestTime = endTime - startTime; | ||
document.title = bestTime; | |||
highlightSyntaxIfNeededIntervalID = setInterval(highlightSyntax, 250); | highlightSyntaxIfNeededIntervalID = setInterval(highlightSyntax, 250); | ||
} | } | ||
Line 343: | Line 355: | ||
{ | { | ||
clearInterval(highlightSyntaxIfNeededIntervalID); | clearInterval(highlightSyntaxIfNeededIntervalID); | ||
wpTextbox1.removeEventListener("input", highlightSyntax); | |||
wpTextbox1.removeEventListener("scroll", syncScrollX); | |||
wpTextbox1.removeEventListener("scroll", syncScrollY); | |||
attributeObserver.disconnect(); | |||
syntaxStyleTextNode.nodeValue = ""; | syntaxStyleTextNode.nodeValue = ""; | ||
var errorMessage = { | var errorMessage = { | ||
ca: "S'ha desactivat el remarcar de sintaxi en aquesta pàgina perquè ha trigat massa temps. El temps màxim permès per a remarcar és $1ms, i el vostre ordinador ha trigat $2ms. Proveu tancar algunes pestanyes i programes i fer clic en \"Mostra la previsualització\" o \"Mostra els canvis\". Si no funciona això, proveu un altre navegador web, i si això no funciona, proveu un ordinador més ràpid.", | |||
de: "Die Syntaxhervorhebung wurde auf dieser Seite deaktiviert, da diese zu lange gedauert hat. Die maximal erlaubte Zeit zur Hervorhebung beträgt $1ms und dein Computer benötigte $2ms. Versuche einige Tabs und Programme zu schließen und klicke \"Vorschau zeigen\" oder \"Änderungen zeigen\". Wenn das nicht funktioniert, probiere einen anderen Webbrowser und wenn immer noch nicht, probiere einen schnelleren Computer.", | |||
el: "Η έμφαση σύνταξης έχει απενεργοποιηθεί σε αυτήν τη σελίδα γιατί αργούσε πολύ. Ο μέγιστος επιτρεπτός χρόνος για την έμφαση σύνταξης είναι $1ms και ο υπολογιστής σας έκανε $2ms. Δοκιμάστε να κλείσετε μερικές καρτέλες και προγράμματα και να κάνετε κλικ στην «Εμφάνιση προεπισκόπησης» ή στην «Εμφάνιση αλλαγών». Αν αυτό δεν δουλέψει, δοκιμάστε έναν διαφορετικό περιηγητή και αν ούτε αυτό δουλέψει, δοκιμάστε έναν ταχύτερο υπολογιστή.", | |||
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.", | |||
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.", | |||
fa: "از آنجایی که زمان زیادی صرف آن میشد، برجستهسازی نحو در این صفحه غیرفعال شده است. بیشینهٔ زمان برجستهسازی برای ابزار $1ms تعریف شده در حالی که رایانهٔ شما $2ms زمان نیاز داشت. میتوانید بستن برخی سربرگها و برنامهها و سپس کلیککردن دکمهٔ «پیشنمایش» یا «نمایش تغییرات» را بیازمایید. اگر جواب نداد مرورگر دیگری را امتحان کنید؛ و اگر باز هم جواب نداد، رایانهٔ سریعتری را بیازمایید.", | |||
fr: "La coloration syntaxique a été désactivée sur cette page en raison d'un temps de chargement trop important ($2ms). Le temps maximum autorisé est $1ms. Vous pouvez essayer de fermer certains onglets et programmes et cliquez sur \"Prévisualisation\" ou \"Voir mes modifications\". Si cela ne fonctionne pas, essayez un autre navigateur web, et si cela ne fonctionne toujours pas, essayez un ordinateur plus rapide.", | |||
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.", | |||
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.", | |||
}; | |||
var wgUserLanguage = mw.config.get("wgUserLanguage"); | |||
errorMessage = errorMessage[wgUserLanguage] || errorMessage[wgUserLanguage.substring(0, wgUserLanguage.indexOf("-"))] || errorMessage | errorMessage = errorMessage[wgUserLanguage] || errorMessage[wgUserLanguage.substring(0, wgUserLanguage.indexOf("-"))] || errorMessage.en; | ||
wpTextbox1.style.backgroundColor = ""; | wpTextbox1.style.backgroundColor = ""; | ||
wpTextbox1.style.position = ""; | wpTextbox1.style.position = ""; | ||
wpTextbox0. | wpTextbox0.removeAttribute("dir"); | ||
wpTextbox0. | wpTextbox0.removeAttribute("lang"); | ||
wpTextbox0.style | wpTextbox0.style = "color:red; font-size:small"; | ||
wpTextbox0.textContent = errorMessage.replace("$1", syntaxHighlighterConfig.timeout).replace("$2", endTime - startTime); | |||
return; | |||
wpTextbox0. | |||
} | } | ||
//do we have enough span elements to match the generated CSS? | |||
//this step isn't included in the above benchmark because it takes a highly variable amount of time | |||
if (maxSpanNumber < spanNumber) | |||
{ | |||
var fragment = document.createDocumentFragment(); | |||
do | |||
{ | |||
fragment.appendChild(document.createElement("span")).id = "s" + ++maxSpanNumber; | |||
} | |||
while (maxSpanNumber < spanNumber) | |||
wpTextbox0.appendChild(fragment); | |||
} | |||
/* 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 ") + "'}"; | |||
} | } | ||
Line 376: | Line 413: | ||
{ | { | ||
wpTextbox0.scrollTop = wpTextbox1.scrollTop; | wpTextbox0.scrollTop = wpTextbox1.scrollTop; | ||
} | |||
function syncTextDirection() | |||
{ | |||
wpTextbox0.dir = wpTextbox1.dir; | |||
} | } | ||
Line 393: | Line 435: | ||
{ | { | ||
syncScrollY(); | syncScrollY(); | ||
} | |||
if (wpTextbox1.offsetHeight != wpTextbox0.offsetHeight) | |||
{ | |||
wpTextbox0.style.height = wpTextbox1.offsetHeight + "px"; | |||
} | } | ||
} | } | ||
Line 404: | Line 450: | ||
syntaxHighlighterConfig[parameterName] = hardcodedFallback; | syntaxHighlighterConfig[parameterName] = hardcodedFallback; | ||
} | } | ||
else if (syntaxHighlighterConfig[parameterName]) | else if (typeof(syntaxHighlighterConfig[parameterName]) != "undefined") | ||
{ | { | ||
return; | return; | ||
Line 421: | Line 467: | ||
//use 3-digit colors instead of 6-digit colors for performance | //use 3-digit colors instead of 6-digit colors for performance | ||
configureColor("boldOrItalicColor", "#EEE"); //gray | |||
configureColor("commentColor", "#EFE"); //green | configureColor("commentColor", "#EFE"); //green | ||
configureColor("entityColor", "#DFD"); //green | configureColor("entityColor", "#DFD"); //green | ||
configureColor("externalLinkColor", "#EFF"); //cyan | configureColor("externalLinkColor", "#EFF"); //cyan | ||
configureColor("headingColor", "#EEE"); //gray | configureColor("headingColor", "#EEE"); //gray | ||
configureColor("hrColor", "#EEE"); //gray | configureColor("hrColor", "#EEE"); //gray | ||
configureColor(" | configureColor("listOrIndentColor", "#EFE"); //green | ||
configureColor("parameterColor", "#FC6"); //orange | configureColor("parameterColor", "#FC6"); //orange | ||
configureColor("signatureColor", "#FC6"); //orange | configureColor("signatureColor", "#FC6"); //orange | ||
Line 436: | Line 481: | ||
configureColor("wikilinkColor", "#EEF"); //blue | configureColor("wikilinkColor", "#EEF"); //blue | ||
syntaxHighlighterConfig.timeout = syntaxHighlighterConfig.timeout || | syntaxHighlighterConfig.timeout = syntaxHighlighterConfig.timeout || 50; | ||
textboxContainer = document.createElement("div"); | var textboxContainer = document.createElement("div"); | ||
wpTextbox0 = document.createElement("div"); | wpTextbox0 = document.createElement("div"); | ||
wpTextbox1 = document.getElementById("wpTextbox1"); | wpTextbox1 = document.getElementById("wpTextbox1"); | ||
var syntaxStyleElement = document.createElement("style"); | var syntaxStyleElement = document.createElement("style"); | ||
syntaxStyleTextNode = syntaxStyleElement.appendChild(document.createTextNode("")); | syntaxStyleTextNode = syntaxStyleElement.appendChild(document.createTextNode("")); | ||
//the styling of the textbox and the background div must be kept very similar | //the styling of the textbox and the background div must be kept very similar | ||
var wpTextbox1Style = window.getComputedStyle(wpTextbox1); | |||
var scrollTop = wpTextbox1.scrollTop; | |||
var focus = (document.activeElement == wpTextbox1); | |||
wpTextbox0.dir = wpTextbox1.dir; | |||
wpTextbox0.lang = wpTextbox1.lang; //lang determines which font "monospace" is | |||
wpTextbox0.style.backgroundColor = wpTextbox1Style.backgroundColor; | |||
wpTextbox0.style.border = "1px solid transparent"; | wpTextbox0.style.border = "1px solid transparent"; | ||
wpTextbox0.style.boxSizing = "border-box"; | wpTextbox0.style.boxSizing = "border-box"; | ||
wpTextbox0.style.color = "transparent"; //makes it look just a little bit smoother | wpTextbox0.style.color = "transparent"; //makes it look just a little bit smoother | ||
wpTextbox0.style.fontFamily = wpTextbox1Style.fontFamily; | |||
wpTextbox0.style.fontFamily = | wpTextbox0.style.fontSize = wpTextbox1Style.fontSize; | ||
wpTextbox0.style.fontSize = | |||
wpTextbox0.style.lineHeight = "normal"; | wpTextbox0.style.lineHeight = "normal"; | ||
wpTextbox0.style.marginBottom = wpTextbox1Style.marginBottom; | |||
wpTextbox0.style.marginLeft = "0"; | |||
wpTextbox0.style.marginRight = "0"; | |||
wpTextbox0.style.marginTop = wpTextbox1Style.marginTop; | |||
wpTextbox0.style.overflowX = "auto"; | wpTextbox0.style.overflowX = "auto"; | ||
wpTextbox0.style.overflowY = "scroll"; | wpTextbox0.style.overflowY = "scroll"; | ||
//horizontal resize would look horribly choppy, better to make the user resize the browser window instead | |||
wpTextbox0.style.resize = (wpTextbox1Style.resize == "vertical" || wpTextbox1Style.resize == "both" ? "vertical" : "none"); | |||
wpTextbox0.style.tabSize = wpTextbox1Style.tabSize; | |||
wpTextbox0.style.whiteSpace = "pre-wrap"; | wpTextbox0.style.whiteSpace = "pre-wrap"; | ||
wpTextbox0.style.width = "100%"; | wpTextbox0.style.width = "100%"; | ||
Line 471: | Line 520: | ||
wpTextbox1.style.border = "1px inset gray"; | wpTextbox1.style.border = "1px inset gray"; | ||
wpTextbox1.style.boxSizing = "border-box"; | wpTextbox1.style.boxSizing = "border-box"; | ||
wpTextbox1.style. | wpTextbox1.style.fontSize = wpTextbox1Style.fontSize; //resolves alignment problems on mobile chrome | ||
wpTextbox1.style.lineHeight = "normal"; | wpTextbox1.style.lineHeight = "normal"; | ||
wpTextbox1.style.margin = 0; | wpTextbox1.style.left = "0"; | ||
wpTextbox1.style.margin = "0"; | |||
wpTextbox1.style.overflowX = "auto"; | wpTextbox1.style.overflowX = "auto"; | ||
wpTextbox1.style.overflowY = "scroll"; | wpTextbox1.style.overflowY = "scroll"; | ||
wpTextbox1.style.padding = 0; | wpTextbox1.style.padding = "0"; | ||
wpTextbox1.style.position = "absolute"; | wpTextbox1.style.position = "absolute"; | ||
wpTextbox1.style.resize = | wpTextbox1.style.resize = wpTextbox0.style.resize; | ||
wpTextbox1.style.top = "0"; | |||
wpTextbox1.style.top = 0; | |||
wpTextbox1.style.width = "100%"; | wpTextbox1.style.width = "100%"; | ||
wpTextbox1.style.wordWrap = "normal"; //overall more visually appealing | wpTextbox1.style.wordWrap = "normal"; //overall more visually appealing | ||
//lock both heights to pixel values so that the browser zoom feature works better | |||
wpTextbox0.style.height = wpTextbox1.offsetHeight + "px"; | wpTextbox0.style.height = wpTextbox1.offsetHeight + "px"; | ||
wpTextbox1.style.height = wpTextbox0.style.height; | |||
textboxContainer.style.clear = "both"; | |||
textboxContainer.style.position = "relative"; | |||
wpTextbox1.parentNode.insertBefore(textboxContainer, wpTextbox1); | wpTextbox1.parentNode.insertBefore(textboxContainer, wpTextbox1); | ||
textboxContainer.appendChild(wpTextbox1); | textboxContainer.appendChild(wpTextbox1); | ||
textboxContainer.appendChild(wpTextbox0); | textboxContainer.appendChild(wpTextbox0); | ||
//changing the parent resets scrollTop to 0 and removes focus, so we have to bring that back | |||
wpTextbox0.scrollTop = scrollTop; | |||
wpTextbox1.scrollTop = scrollTop; | |||
if (focus) wpTextbox1.focus(); | |||
//fix drop-downs in editing toolbar | //fix drop-downs in editing toolbar | ||
Line 511: | Line 557: | ||
wpTextbox1.addEventListener("scroll", syncScrollX); | wpTextbox1.addEventListener("scroll", syncScrollX); | ||
wpTextbox1.addEventListener("scroll", syncScrollY); | wpTextbox1.addEventListener("scroll", syncScrollY); | ||
attributeObserver = new MutationObserver(syncTextDirection); | |||
attributeObserver.observe(wpTextbox1, {attributes: true}); | |||
highlightSyntaxIfNeededIntervalID = setInterval(highlightSyntaxIfNeeded, 500); | highlightSyntaxIfNeededIntervalID = setInterval(highlightSyntaxIfNeeded, 500); | ||
highlightSyntax(); | highlightSyntax(); | ||
Line 524: | Line 572: | ||
//in the future a separate parser could be added for CSS and JS pages | //in the future a separate parser could be added for CSS and JS pages | ||
//blacklist Internet Explorer, it's just too broken | //blacklist Internet Explorer, it's just too broken | ||
if ((wgAction == "edit" || wgAction == "submit") && wgPageContentModel == "wikitext" && !trident) | var wgAction = mw.config.get("wgAction"); | ||
if ((wgAction == "edit" || wgAction == "submit") && mw.config.get("wgPageContentModel") == "wikitext" && $.client.profile().layout != "trident") | |||
{ | { | ||
/* The highlighter has to run after any other script (such as the | /* The highlighter has to run after any other script (such as the |