User:Ilmari Karonen/edittools.js
From Wikipedia, the free encyclopedia
Note: After saving, you have to bypass your browser's cache to see the changes. In Internet Explorer and Firefox, hold down the Ctrl key and click the Refresh or Reload button. Opera users have to clear their caches through Tools→Preferences, see the instructions for Opera. Konqueror and Safari users can just click the Reload button.
// copied from [[mw:User:Alex Smotrov/edittools.js]], modified for use on the English Wikipedia. // enableForAllFields() feature from [[commons:MediaWiki:Edittools.js]] // <source lang="javascript"> if (typeof (EditTools_set_focus) == 'undefined') var EditTools_set_focus = true; if (typeof (EditTools_set_focus_initially) == 'undefined') var EditTools_set_focus_initially = EditTools_set_focus; var EditTools = { charinsert : { 'Standard': '[+] [[+]] [[+|+]] {{+}} – — “+” ‘+’ «+» ‹+› „+“ ‚+‘ … ~ | ° ≈ ≠ ≤ ≥ ± − × ÷ ← → ² ³ ½ · § \n [[Category:+]] [[:Image:+]] +<includeonly> +<noinclude> #REDIRECT[[+]] {{DEFAULTSORT:+}}', 'Latin': 'ÁáĆćÉéÍíÓóŚśÚúÝýǾǿ ÀàÈèÌìÒòÙù ÂâĈĉÊêĜĝĤĥÎîĴĵÔôŝŜÛû ÄäËëÏïÖöÜüÿ ÃãÑñÕõ Å å Ç ç Č芚ŭ Ł ł ŐőŰű Ø ø ĀāĒēĪīŌōŪū ß ÆæŒœ ÐðÞþ|', 'Greek': 'ΑΆΒΓΔΕΈΖΗΉΘΙΊΚΛΜΝΞΟΌΠΡΣΤΥΎΦΧΨΩΏ αάβγδεέζηήθιίκλμνξοόπρσςτυύφχψωώ', 'IPA': 'ʈɖɟɡɢʡʔ ɸʃʒɕʑʂʐʝɣʁʕʜʢɦ ɱɳɲŋɴ ʋɹɻɰ ʙʀɾɽ ɫɬɮɺɭʎʟ ɥʍɧ ɓɗʄɠʛ ʘǀǃǂǁ ɨʉɯ ɪʏʊ ɘɵɤ ɚ ɛɜɝɞʌɔ ɐɶɑɒ ʰʷʲˠˤⁿˡ ˈˌːˑ', 'Arabic': 'ابتثجحخدذرزسشصضطظعغفقكلمنهوي ﺍﺑﺗﺛﺟﺣﺧﺩﺫﺭﺯﺳﺷﺻﺿﻃﻇﻋﻏﻓﻗﻛﻟﻣﻧﻫﻭﻳ\ ﺍﺒﺘﺜﺠﺤﺨﺪﺬﺮﺰﺴﺸﺼﻀﻄﻈﻌﻐﻔﻘﻜﻠﻤﻨﻬﻮﻴ ﺎﺐﺖﺚﺞﺢﺦﺪﺬﺮﺰﺲﺶﺺﺾﻂﻆﻊﻎﻒﻖﻚﻞﻢﻦﻪﻮﻲ \ ء- ّ- ْ- ً- ِ- آأإةؤئى پچژگﭪڠ۰۱۲۳٤٥٦٧۸۹', 'Cyrillic': 'АБВГДЂЕЁЖЗЅИЙЈКЛЉМНЊОПРСТЋУФХЦЧЏШЩЪЫЬЭЮЯ абвгдђеёжзѕийјклљмнњопрстћуфхцчџшщъыьэюя', 'Catalan': 'ÁáÀàÇçÉéÈèËëÍíÏïÓóÒòÖöÚúÙù', 'Czech': 'ÁáČčĎďÉéĚěÍíŇňÓóŘřŠšŤťÚúŮůÝýŽž', 'Devanagari': 'ँ ं ः अ आ इ ई उ ऊ ऋ ऌ ऍ ऎ ए ऐ ऑ ऒ ओ औ क क़ ख ख़ ग ग़ घ ङ च छ ज ज़ झ ञ ट ठ ड ड़ द ढ ढ़ ण त थ ध न ऩ प फ फ़ ब भ म य य़ र ऱ ल ळ ऴ व श ष स ह ़ ऽ ा ि ॊ ो ौ ् ी ु ू ृ ॄ ॅ ॆ े ै ॉ ॐ ॑ ॒ ॓ ॔ ॠ ॡ ॢ ॣ । ॥ ॰', 'Esperanto': 'ĈĉĜĝĤĥĴĵŜŝŬŭ', 'Estonian': 'ČčŠšŽžÕõÄäÖöÜü', 'French': 'ÀàÂâÇçÉéÈèÊêËëÎîÏïÔôŒœÙùÛûÜüŸÿ', 'German': 'ÄäÖöÜüß', 'Hawaiian': 'ĀāĒēĪīŌōŪūʻ', 'Hebrew': 'אבגדהוזחטיכךלמםנןסעפףצץקרשת־״׳', 'Hungarian': 'ŐőŰű', 'Icelandic': 'ÁáÐðÉéÍíÓóÚúÝýÞþÆæÖö', 'Italian': 'ÁáÀàÉéÈèÍíÌìÓóÒòÚúÙù', 'Latvian': 'ĀāČčĒēĢģĪīĶķĻļŅņŠšŪūŽž', 'Lithuanian': 'ĄąČčĘęĖėĮįŠšŲųŪūŽž', 'Maltese': 'ĊċĠġĦħŻż', 'Old English': 'Ā⯿ǢǣǼǽĊċÐðĒēĠġĪīŌōŪūǷƿȲȳÞþȜȝ', 'Pinyin': 'ÁáÀàǍǎĀāÉéÈèĚěĒēÍíÌìǏǐĪīÓóÒòǑǒŌōÚúÙùÜüǓǔŪūǗǘǛǜǙǚǕǖ', 'Polish': 'ąĄćĆęĘłŁńŃóÓśŚźŹżŻ', 'Portuguese': 'ÁáÀàÂâÃãÇçÉéÊêÍíÓóÔôÕõÚúÜü', 'Romaji': 'ĀāĒēĪīŌōŪū', 'Romanian': 'ĂăÂâÎŢţ', 'Scandinavian': 'ÀàÉéÅ寿Ä䨸Öö', 'Serbian': 'АаБбВвГгДдЂђЕеЖжЗзИиЈјКкЛлЉљМмНнЊњОоПпРрСсТтЋћУуФфХхЦцЧчЏџШш', 'Spanish': 'ÁáÉéÍíÑñÓóÚúÜü¡¿', 'Turkish': 'ÇçĞğİıÖöŞşÜüÂâÎîÛû', 'Vietnamese': 'ÀàẢảÁáẠạÃãĂăẰằẲẳẴẵẮắẶặÂâẦầẨẩẪẫẤấẬậĐđÈèẺẻẼẽÉéẸẹÊêỀềỂểỄễẾếỆệỈỉĨĩÍíỊịÌìỎỏÓóỌọÒòÕõÔôỒồỔổỖỗỐốỘộƠơỜờỞởỠỡỚớỢợÙùỦủŨũÚúỤụƯưỪừỬửỮữỨứỰựỲỳỶỷỸỹỴỵÝý', 'Welsh': 'ÁáÀàÂâÄäÉéÈèÊêËëÌìÎîÏïÓóÒòÔôÖöÙùÛûẀẁŴŵẄẅÝýỲỳŶŷŸÿ', 'Yiddish': 'א אַ אָ ב בֿ ג ד ה ו וּ װ ױ ז זש ח ט י יִ ײ ײַ כ ך כּ ל ל מ ם נ ן ס ע ע פ פּ פֿ ף צ ץ ק ר ש שׂ תּ ת ׳ ״ ־' }, charinsertDivider : '·', extraCSS : '\ #editpage-newstyle {text-align:center;\ border:1px solid #aaa;\ font-size:120%;\ padding:1px;\ margin-top:10px;\ }\ #editpage-newstyle a {\ color: black !important;\ background-color: #ccddee;\ font-weight: bold;\ font-size: 0.9em;\ text-decoration: none !important;\ border: 1px #006699 outset;\ padding: 0 0.1em 0.1em 0.1em;\ }\ #editpage-newstyle a:hover {\ background-color: #bbccdd;\ border: 1px #F0F0F0 inset;\ }\ ', appendExtraCSS : function () { appendCSS(EditTools.extraCSS); }, createEditTools : function (placeholder) { var box = document.createElement("div"); box.id = "editpage-newstyle"; box.title = 'Click on the character or tag to insert it into edit window'; //append user-defined sets if (window.charinsertCustom) for (id in charinsertCustom) if (EditTools.charinsert[id]) EditTools.charinsert[id] += ' ' + charinsertCustom[id]; else EditTools.charinsert[id] = charinsertCustom[id]; //create drop-down select var prevSubset = 0, curSubset = 0; var sel = document.createElement('select'), id; for (id in EditTools.charinsert) sel.options[sel.options.length] = new Option(id, id); sel.selectedIndex = 0; sel.style.cssFloat = sel.style.styleFloat = 'left'; sel.style.marginRight = '5px'; sel.title = 'Choose character subset'; sel.onchange = sel.onkeyup = selectSubset; box.appendChild(sel); //create "recall" switch if (window.editToolsRecall) { var recall = document.createElement('span'); recall.appendChild(document.createTextNode('↕')); // ↔ recall.onclick = function () { sel.selectedIndex = prevSubset; selectSubset(); } with (recall.style) { cssFloat = styleFloat = 'left'; marginRight = '5px'; cursor = 'pointer'; } box.appendChild(recall); } placeholder.parentNode.replaceChild(box, placeholder); selectSubset(); return; function selectSubset () { //remember previous (for "recall" button) prevSubset = curSubset; curSubset = sel.selectedIndex; //hide other subsets var pp = box.getElementsByTagName('p') ; for (var i=0; i<pp.length; i++) pp[i].style.display = 'none'; //show/create current subset var id = sel.options[curSubset].value; var p = document.getElementById(id); if (!p){ p = document.createElement('p'); p.id = id; if (id == 'Arabic'){ p.style.fontSize = '120%'; p.dir = 'rtl'; } EditTools.createTokens(p, EditTools.charinsert[id]); box.appendChild(p); } p.style.display = 'inline'; } }, createTokens : function (paragraph, str) { var tokens = str.split(' '), token, i, n; for (i = 0; i < tokens.length; i++) { token = tokens[i]; n = token.indexOf('+'); if (token == '' || token == '_') addText(EditTools.charinsertDivider + ' '); else if (token == '\n') paragraph.appendChild(document.createElement('br')); else if (token == '___') paragraph.appendChild(document.createElement('hr')); else if (token.charAt(token.length-1) == ':') // : at the end means just text addBold(token); else if (n == 0) // +<tag> -> <tag>+</tag> addLink(token.substring(1), '</' + token.substring(2), token.substring(1)); else if (n > 0) // <tag>+</tag> addLink(token.substring(0,n), token.substring(n+1)); else if (token.length > 2 && token.charCodeAt(0) > 127) //a string of insertable characters for (var j=0; j < token.length; j++) addLink(token.charAt(j), ''); else addLink(token, ''); } return; function addLink (tagOpen, tagClose, name) { var a = document.createElement('a'); tagOpen = tagOpen.replace(/\./g,' '); tagClose = tagClose ? tagClose.replace(/_/g,' ') : ''; name = name || tagOpen + tagClose; name = name.replace(/\\n/g,''); a.appendChild(document.createTextNode(name)); a.href = "javascript:insertTags('" + tagOpen + "','" + tagClose + "','')"; paragraph.appendChild(a); addText(' '); } function addBold (text) { var b = document.createElement('b'); b.appendChild(document.createTextNode(text.replace(/_/g,' '))); paragraph.appendChild(b); addText(' '); } function addText (txt) { paragraph.appendChild(document.createTextNode(txt)); } }, enableForAllFields : function () { if (typeof (insertTags) != 'function') return; // insertTags from the site-wide /skins-1.5/common/edit.js just inserts in the first // textarea in the document. Evidently, that's not good if we have multiple textareas. // My first idea was to simply add a hidden textarea as the first one, and redefine // insertTags such that it copied first the last active textareas contents over to that hidden // field, set the cursor or selection there, let the standard insertTags do its thing, and // then copy the hidden field's text, cursor position and selection back to the currently // active field. Unfortunately, that is just as complex as simply copying the whole code // from wikibits to here and let it work on the right text field in the first place. var texts = document.getElementsByTagName ('textarea'); for (var i = 0; i < texts.length; i++) { addHandler (texts[i], 'focus', EditTools.registerTextField); } // While we're at it, also enable it for input fields texts = document.getElementsByTagName ('input'); for (var i = 0; i < texts.length; i++) { if (texts[i].type == 'text') addHandler (texts[i], 'focus', EditTools.registerTextField); } insertTags = EditTools.insertTags; // Redefine the global insertTags }, last_active_textfield : null, registerTextField : function (evt) { var e = evt || window.event; var node = e.target || e.srcElement; if (!node) return; EditTools.last_active_textfield = node.id; return true; }, getTextArea : function () { var txtarea = null; if (EditTools.last_active_textfield && EditTools.last_active_textfield != "") txtarea = document.getElementById (EditTools.last_active_textfield); if (!txtarea) { // Fallback option: old behaviour if (document.editform) { txtarea = document.editform.wpTextbox1; } else { // Some alternate form? Take the first one we can find txtarea = document.getElementsByTagName ('textarea'); if (txtarea.length > 0) txtarea = txtarea[0]; else txtarea = null; } } return txtarea; }, insertTags : function (tagOpen, tagClose, sampleText) { var txtarea = EditTools.getTextArea (); if (!txtarea) return; var selText, isSample = false; function checkSelectedText () { if (!selText) { selText = sampleText; isSample = true; } else if (selText.charAt (selText.length - 1) == ' ') { // Exclude ending space char selText = selText.substring (0, selText.length - 1); tagClose += ' '; } } if (document.selection && document.selection.createRange) { // IE/Opera // Save window scroll position var winScroll = 0; if (document.documentElement && document.documentElement.scrollTop) winScroll = document.documentElement.scrollTop; else if (document.body) winScroll = document.body.scrollTop; // Get current selection txtarea.focus(); var range = document.selection.createRange(); selText = range.text; // Insert tags checkSelectedText (); range.text = tagOpen + selText + tagClose; // Mark sample text as selected if (isSample && range.moveStart) { if (window.opera) tagClose = tagClose.replace (/\n/g, ""); range.moveStart( 'character', - tagClose.length - selText.length); range.moveEnd ('character', - tagClose.length); } range.select (); // Restore window scroll position if (document.documentElement && document.documentElement.scrollTop) document.documentElement.scrollTop = winScroll; else if (document.body) document.body.scrollTop = winScroll; } else if (txtarea.selectionStart || txtarea.selectionStart == '0') { // Mozilla // Save textarea scroll position var textScroll = txtarea.scrollTop; // Get current selection txtarea.focus(); var startPos = txtarea.selectionStart; var endPos = txtarea.selectionEnd; selText = txtarea.value.substring (startPos, endPos); // Insert tags checkSelectedText (); txtarea.value = txtarea.value.substring (0, startPos) + tagOpen + selText + tagClose + txtarea.value.substring (endPos); // Set new selection if (isSample) { txtarea.selectionStart = startPos + tagOpen.length; txtarea.selectionEnd = startPos + tagOpen.length + selText.length; } else { txtarea.selectionStart = startPos + tagOpen.length + selText.length + tagClose.length; txtarea.selectionEnd = txtarea.selectionStart; } // Restore textarea scroll position txtarea.scrollTop = textScroll; } }, // end insertTags setup : function () { var placeholder = document.getElementById("editpage-specialchars"); if (!placeholder) return; // has this already been run once? EditTools.appendExtraCSS (); EditTools.createEditTools (placeholder); EditTools.enableForAllFields (); } }; // end EditTools // Do not use addOnloadHook; it runs *before* the onload event fires. At that time, onclick or // onfocus handlers may not yet be set up properly. hookEvent ('load', EditTools.setup); if (!window.appendCSS) // while waiting for a scap... { window.appendCSS = function (text) { var s = document.createElement('style'); s.setAttribute('type', 'text/css'); if (s.styleSheet) s.styleSheet.cssText = text; // IE else s.appendChild(document.createTextNode(text)); document.getElementsByTagName('head')[0].appendChild(s); return s; }; } // </source>

