<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
	<id>https://www.penguindevelopment.org/index.php?action=history&amp;feed=atom&amp;title=MediaWiki%3AGadget-charinsert.js</id>
	<title>MediaWiki:Gadget-charinsert.js - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://www.penguindevelopment.org/index.php?action=history&amp;feed=atom&amp;title=MediaWiki%3AGadget-charinsert.js"/>
	<link rel="alternate" type="text/html" href="https://www.penguindevelopment.org/index.php?title=MediaWiki:Gadget-charinsert.js&amp;action=history"/>
	<updated>2026-05-23T13:22:50Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://www.penguindevelopment.org/index.php?title=MediaWiki:Gadget-charinsert.js&amp;diff=16&amp;oldid=prev</id>
		<title>Link: Created page with &quot;// copied from mw:User:Alex Smotrov/edittools.js, modified for use on the English Wikipedia. // enableForAllFields() feature from commons:MediaWiki:Edittools.js // com...&quot;</title>
		<link rel="alternate" type="text/html" href="https://www.penguindevelopment.org/index.php?title=MediaWiki:Gadget-charinsert.js&amp;diff=16&amp;oldid=prev"/>
		<updated>2013-08-17T17:05:07Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;// copied from &lt;a href=&quot;http://www.mediawiki.org/wiki/User:Alex_Smotrov/edittools.js&quot; class=&quot;extiw&quot; title=&quot;mw:User:Alex Smotrov/edittools.js&quot;&gt;mw:User:Alex Smotrov/edittools.js&lt;/a&gt;, modified for use on the English Wikipedia. // enableForAllFields() feature from &lt;a href=&quot;http://commons.wikimedia.org/wiki/MediaWiki:Edittools.js&quot; class=&quot;extiw&quot; title=&quot;commons:MediaWiki:Edittools.js&quot;&gt;commons:MediaWiki:Edittools.js&lt;/a&gt; // com...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;// copied from [[mw:User:Alex Smotrov/edittools.js]], modified for use on the English Wikipedia.&lt;br /&gt;
// enableForAllFields() feature from [[commons:MediaWiki:Edittools.js]]&lt;br /&gt;
// combined and modified by [[User:Ilmari Karonen]]&lt;br /&gt;
&lt;br /&gt;
// Configuration (to be set from [[Special:MyPage/common.js]]):&lt;br /&gt;
//   window.charinsertCustom – Object. Merged into the default charinsert list. For example, setting&lt;br /&gt;
//       this to { Symbols: &amp;#039;‽&amp;#039; } will add the interrobang to the end of the Symbols section.&lt;br /&gt;
//   window.editToolsRecall – Boolean. Set true to create a recall switch.&lt;br /&gt;
//   window.charinsertDontMove – Boolean. Set true to leave the box in its default position, rather&lt;br /&gt;
//       than moving it above the edit summary.&lt;br /&gt;
//   window.updateEditTools() – Function. Call after updating window.charinsertCustom to regenerate the&lt;br /&gt;
//       EditTools window.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
window.updateEditTools = function () {&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
jQuery( document ).ready( function ( $ ) {&lt;br /&gt;
    var EditTools = {&lt;br /&gt;
        // Entries prefixed with ␥ (U+2425 SYMBOL FOR DELETE FORM TWO) will not appear in the article namespace (namespace 0).&lt;br /&gt;
        // Please make any changes to [[MediaWiki:Edittools]] as well, however, instead of using the ␥ symbol, use {{#ifeq:{{NAMESPACE}}|{{ns:0}}| | }}.&lt;br /&gt;
        charinsert: {&lt;br /&gt;
            &amp;#039;Insert&amp;#039;: &amp;#039; – — ° ″ ′ ≈ ≠ ≤ ≥ ± − × ÷ ← → · §  ␥Sign_your_posts_on_talk_pages: ␥~~\~~  Cite_your_sources: &amp;lt;ref&amp;gt;+&amp;lt;/ref&amp;gt;&amp;#039;,&lt;br /&gt;
            &amp;#039;Wiki markup&amp;#039;: &amp;#039;Insert:  – — ° ″ ′ ≈ ≠ ≤ ≥ ± − × ÷ ← → · § ␥~~\~~ &amp;lt;ref&amp;gt;+&amp;lt;/ref&amp;gt;  Wiki_markup:  {\{+}}  {\{\{+}}}  |  [+]  [\[+]]  [\[Category:+]]  #REDIRECT.[\[+]]  &amp;amp;nb&amp;#039;+&amp;#039;sp;  &amp;lt;s&amp;gt;+&amp;lt;/s&amp;gt;  &amp;lt;sup&amp;gt;+&amp;lt;/sup&amp;gt;  &amp;lt;sub&amp;gt;+&amp;lt;/sub&amp;gt;  &amp;lt;code&amp;gt;+&amp;lt;/code&amp;gt;  &amp;lt;pre&amp;gt;+&amp;lt;/pre&amp;gt;  &amp;lt;blockquote&amp;gt;+&amp;lt;/blockquote&amp;gt;  &amp;lt;ref.name=&amp;quot;+&amp;quot;_/&amp;gt;  {\{#tag:ref|+|group=&amp;quot;nb&amp;quot;|name=&amp;quot;&amp;quot;}}  {\{Reflist}}  &amp;lt;references./&amp;gt;  &amp;lt;includeonly&amp;gt;+&amp;lt;/includeonly&amp;gt;  &amp;lt;noinclude&amp;gt;+&amp;lt;/noinclude&amp;gt;  {\{DEFAULTSORT:+}}  &amp;lt;nowiki&amp;gt;+&amp;lt;/nowiki&amp;gt;  &amp;lt;!--.+_--&amp;gt;  &amp;lt;span.class=&amp;quot;plainlinks&amp;quot;&amp;gt;+&amp;lt;/span&amp;gt;&amp;#039;,&lt;br /&gt;
            &amp;#039;Symbols&amp;#039;: &amp;#039;~ | ¡¿†‡↔↑↓•¶#∞  ‘+’ “+” ‹+› «+» ⟨+⟩  ¤₳฿₵¢₡₢$₫₯€₠₣ƒ₴₭₤ℳ₥₦№₧₰£៛₨₪৳₮₩¥  ♠♣♥♦  ♭♯♮  ©®™ ◌ {\{Unicode|+}}&amp;#039;,&lt;br /&gt;
            &amp;#039;Latin&amp;#039;: &amp;#039;A a Á á À à Â â Ä ä Ǎ ǎ Ă ă Ā ā Ã ã Å å Ą ą Æ æ Ǣ ǣ  B b  C c Ć ć Ċ ċ Ĉ ĉ Č č Ç ç  D d Ď ď Đ đ Ḍ ḍ Ð ð  E e É é È è Ė ė Ê ê Ë ë Ě ě Ĕ ĕ Ē ē Ẽ ẽ Ę ę Ẹ ẹ Ɛ ɛ Ə ə  F f  G g Ġ ġ Ĝ ĝ Ğ ğ Ģ ģ  H h Ĥ ĥ Ħ ħ Ḥ ḥ  I i İ ı Í í Ì ì Î î Ï ï Ǐ ǐ Ĭ ĭ Ī ī Ĩ ĩ Į į Ị ị  J j Ĵ ĵ  K k Ķ ķ  L l Ĺ ĺ Ŀ ŀ Ľ ľ Ļ ļ Ł ł Ḷ ḷ Ḹ ḹ  M m Ṃ ṃ  N n Ń ń Ň ň Ñ ñ Ņ ņ Ṇ ṇ Ŋ ŋ  O o Ó ó Ò ò Ô ô Ö ö Ǒ ǒ Ŏ ŏ Ō ō Õ õ Ǫ ǫ Ọ ọ Ő ő Ø ø Œ œ  Ɔ ɔ  P p  Q q  R r Ŕ ŕ Ř ř Ŗ ŗ Ṛ ṛ Ṝ ṝ  S s Ś ś Ŝ ŝ Š š Ş ş Ș ș Ṣ ṣ ß  T t Ť ť Ţ ţ Ț ț Ṭ ṭ Þ þ  U u Ú ú Ù ù Û û Ü ü Ǔ ǔ Ŭ ŭ Ū ū Ũ ũ Ů ů Ų ų Ụ ụ Ű ű Ǘ ǘ Ǜ ǜ Ǚ ǚ Ǖ ǖ  V v  W w Ŵ ŵ  X x  Y y Ý ý Ŷ ŷ Ÿ ÿ Ỹ ỹ Ȳ ȳ  Z z Ź ź Ż ż Ž ž  ß Ð ð Þ þ Ŋ ŋ Ə ə  {\{Unicode|+}}&amp;#039;,&lt;br /&gt;
            &amp;#039;Greek&amp;#039;: &amp;#039;ΆάΈέΉήΊίΌόΎύΏώ  ΑαΒβΓγΔδ  ΕεΖζΗηΘθ  ΙιΚκΛλΜμ  ΝνΞξΟοΠπ  ΡρΣσςΤτΥυ  ΦφΧχΨψΩω  ᾼᾳᾴᾺὰᾲᾶᾷἈἀᾈᾀἉἁᾉᾁἌἄᾌᾄἊἂᾊᾂἎἆᾎᾆἍἅᾍᾅἋἃᾋᾃἏἇᾏᾇ  ῈὲἘἐἙἑἜἔἚἒἝἕἛἓ  ῌῃῄῊὴῂῆῇἨἠᾘᾐἩἡᾙᾑἬἤᾜᾔἪἢᾚᾒἮἦᾞᾖἭἥᾝᾕἫἣᾛᾓἯἧᾟᾗ  ῚὶῖἸἰἹἱἼἴἺἲἾἶἽἵἻἳἿἷ  ῸὸὈὀὉὁὌὄὊὂὍὅὋὃ  ῤῬῥ  ῪὺῦὐὙὑὔὒὖὝὕὛὓὟὗ  ῼῳῴῺὼῲῶῷὨὠᾨᾠὩὡᾩᾡὬὤᾬᾤὪὢᾪᾢὮὦᾮᾦὭὥᾭᾥὫὣᾫᾣὯὧᾯᾧ   {\{Polytonic|+}}&amp;#039;,&lt;br /&gt;
            &amp;#039;Cyrillic&amp;#039;: &amp;#039;АаБбВвГг  ҐґЃѓДдЂђ  ЕеЁёЄєЖж  ЗзЅѕИиІі  ЇїЙйЈјКк  ЌќЛлЉљМм  НнЊњОоПп  РрСсТтЋћ  УуЎўФфХх  ЦцЧчЏџШш  ЩщЪъЫыЬь  ЭэЮюЯя ӘәӨөҒғҖҗ ҚқҜҝҢңҮү ҰұҲҳҸҹҺһ  ҔҕӢӣӮӯҘҙ  ҠҡҤҥҪҫӐӑ  ӒӓӔӕӖӗӰӱ  ӲӳӸӹӀ  ҞҟҦҧҨҩҬҭ  ҴҵҶҷҼҽҾҿ  ӁӂӃӄӇӈӋӌ  ӚӛӜӝӞӟӠӡ  ӤӥӦӧӪӫӴӵ  ́&amp;#039;,&lt;br /&gt;
            &amp;#039;Hebrew&amp;#039;: &amp;#039;אבגדהוזחטיךכלםמןנסעףפץצקרשת  ׳ ״  װױײ&amp;#039;,&lt;br /&gt;
            &amp;#039;Arabic&amp;#039;: &amp;#039;  Transcription: ʾ ṯ ḥ ḫ ẖ ḏ š ṣ ḍ ṭ ẓ ʿ ġ ẗ ا ﺁ ب ت ث ج ح خ د ذ ر ز س ش ص ض ط ظ ع غ ف ق ك ل م ن ه ة و ي ى ء أ إ ؤ ئ&amp;#039;,&lt;br /&gt;
            &amp;#039;IPA (English)&amp;#039;: &amp;#039;ˈ ˌ ŋ ɡ tʃ dʒ ʃ ʒ θ ð ʔ  iː ɪ uː ʊ ʌ ɜr eɪ ɛ æ oʊ ɒ ɔː ɔɪ ɔr ɑː ɑr aɪ aʊ  ə ər ɨ ɵ ʉ ⟨+⟩  {\{IPAc-en|+}} {\{IPA-en|+}} {\{IPA|/+/}}&amp;#039;,&lt;br /&gt;
            &amp;#039;IPA&amp;#039;: &amp;#039;t̪ d̪ ʈɖɟɡɢʡʔ  ɸβθðʃʒɕʑʂʐçʝɣχʁħʕʜʢɦ  ɱɳɲŋɴ  ʋɹɻɰ  ʙⱱʀɾɽ  ɫɬɮɺɭʎʟ  ʍɥɧ  ʼ ɓɗʄɠʛ  ʘǀǃǂǁ  ɨʉɯ ɪʏʊ øɘɵɤ ə ɚ ɛœɜɝɞʌɔ æ ɐɶɑɒ  ʰʱʷʲˠˤˀ ᵊ k̚ ⁿˡ  ˈˌːˑ t̪ d̪ s̺ s̻ θ̼ s̬ n̥ ŋ̊ a̤ a̰  β̞ ˕ r̝ ˔ o˞ ɚ ɝ e̘ e̙ u̟ i̠ ɪ̈ e̽ ɔ̹ ɔ̜ n̩ ə̆ ə̯ ə̃ ȷ̃ ɫ z̴ ə̋ ə́ ə̄ ə̀ ə̏ ə̌ ə̂ ə᷄ ə᷅ ə᷇ ə᷆ ə᷈ ə᷉ t͡ʃ d͡ʒ t͜ɬ ‿  ˥ ˦ ˧ ˨ ˩ ꜛ ꜜ | ‖ ↗ ↘  k͈ s͎ {\{IPA|+}}&amp;#039;,&lt;br /&gt;
            &amp;#039;Math and logic&amp;#039;: &amp;#039;− × ÷ ⋅ ° ∗ ∘ ± ∓ ≤ ≥ ≠ ≡ ≅ ≜ ≝ ≐ ≃ ≈ ⊕ ⊗ ⇐ ⇔ ⇒ ∞ ← ↔ → ≪ ≫ ∝ √ ∤ ≀ ◅ ▻ ⋉ ⋊ ⋈ ∴ ∵ ↦ ¬ ∧ ∨ ⊻ ∀ ∃ ∈ ∉ ∋ ⊆ ⊈ ⊊ ⊂ ⊄ ⊇ ⊉ ⊋ ⊃ ⊅ ∪ ∩ ∑ ∏ ∐ ′ ∫ ∬ ∭ ∮ ∇ ∂ ∆ ∅ ℂ ℍ ℕ ℙ ℚ ℝ ℤ ℵ ⌊ ⌋ ⌈ ⌉ ⊤ ⊥ ⊢ ⊣ ⊧ □ ∠ ⟨ ⟩ {\{frac|+|}} &amp;amp;nb&amp;#039;+&amp;#039;sp; &amp;amp;minus; &amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt; {\{math|+}}&amp;#039;&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        charinsertDivider: &amp;quot;\240&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
        cookieName: &amp;#039;edittoolscharsubset&amp;#039;,&lt;br /&gt;
&lt;br /&gt;
        createEditTools: function ( placeholder ) {&lt;br /&gt;
            var sel, id;&lt;br /&gt;
            var box = document.createElement( &amp;quot;div&amp;quot; );&lt;br /&gt;
            var prevSubset = 0, curSubset = 0;&lt;br /&gt;
            box.id = &amp;quot;editpage-specialchars&amp;quot;;&lt;br /&gt;
            box.title = &amp;#039;Click on the character or tag to insert it into the edit window&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
            // append user-defined sets&lt;br /&gt;
            if ( window.charinsertCustom ) {&lt;br /&gt;
                for ( id in charinsertCustom ) {&lt;br /&gt;
                    if ( !EditTools.charinsert[id] ) {&lt;br /&gt;
                        EditTools.charinsert[id] = &amp;#039;&amp;#039;;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // create drop-down select&lt;br /&gt;
            sel = document.createElement( &amp;#039;select&amp;#039; );&lt;br /&gt;
            for ( id in EditTools.charinsert ) {&lt;br /&gt;
                sel.options[sel.options.length] = new Option( id, id );&lt;br /&gt;
            }&lt;br /&gt;
            sel.selectedIndex = 0;&lt;br /&gt;
            sel.style.marginRight = &amp;#039;.3em&amp;#039;;&lt;br /&gt;
            sel.title = &amp;#039;Choose character subset&amp;#039;;&lt;br /&gt;
            sel.onchange = sel.onkeyup = selectSubset;&lt;br /&gt;
            box.appendChild( sel );&lt;br /&gt;
&lt;br /&gt;
            // create &amp;quot;recall&amp;quot; switch&lt;br /&gt;
            if ( window.editToolsRecall ) {&lt;br /&gt;
                var recall = document.createElement( &amp;#039;span&amp;#039; );&lt;br /&gt;
                recall.appendChild( document.createTextNode( &amp;#039;↕&amp;#039; ) ); // ↔&lt;br /&gt;
                recall.onclick = function() {&lt;br /&gt;
                    sel.selectedIndex = prevSubset;&lt;br /&gt;
                    selectSubset();&lt;br /&gt;
                }&lt;br /&gt;
                with ( recall.style ) {&lt;br /&gt;
                    cssFloat = styleFloat = &amp;#039;left&amp;#039;;&lt;br /&gt;
                    marginRight = &amp;#039;5px&amp;#039;;&lt;br /&gt;
                    cursor = &amp;#039;pointer&amp;#039;;&lt;br /&gt;
                }&lt;br /&gt;
                box.appendChild( recall );&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // load latest selection from cookies&lt;br /&gt;
            try {&lt;br /&gt;
                var cookieRe = new RegExp( &amp;quot;(?:^|;)\\s*&amp;quot; + EditTools.cookieName + &amp;quot;=(\\d+)\\s*(?:;|$)&amp;quot; );&lt;br /&gt;
                var m = cookieRe.exec( document.cookie );&lt;br /&gt;
                if ( m &amp;amp;&amp;amp; m.length &amp;gt; 1 &amp;amp;&amp;amp; parseInt( m[1] ) &amp;lt; sel.options.length ) {&lt;br /&gt;
                    sel.selectedIndex = parseInt( m[1] );&lt;br /&gt;
                }&lt;br /&gt;
            } catch ( err ) {&lt;br /&gt;
                // ignore&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            placeholder.parentNode.replaceChild( box, placeholder );&lt;br /&gt;
            selectSubset();&lt;br /&gt;
            return;&lt;br /&gt;
&lt;br /&gt;
            function selectSubset() {&lt;br /&gt;
                // remember previous (for &amp;quot;recall&amp;quot; button)&lt;br /&gt;
                prevSubset = curSubset;&lt;br /&gt;
                curSubset = sel.selectedIndex;&lt;br /&gt;
                //save into cookies for persistence&lt;br /&gt;
                try {&lt;br /&gt;
                    var expires = new Date();&lt;br /&gt;
                    expires.setTime( expires.getTime() + 30 * 24 * 60 * 60 * 1000 );  // + 30 days&lt;br /&gt;
                    document.cookie = EditTools.cookieName + &amp;quot;=&amp;quot; + curSubset + &amp;quot;;path=/;expires=&amp;quot; + expires.toUTCString();&lt;br /&gt;
                } catch ( err ) {&lt;br /&gt;
                    // ignore&lt;br /&gt;
                }&lt;br /&gt;
                //hide other subsets&lt;br /&gt;
                var pp = box.getElementsByTagName( &amp;#039;p&amp;#039; ) ;&lt;br /&gt;
                for ( var i = 0; i &amp;lt; pp.length; i++ ) {&lt;br /&gt;
                    pp[i].style.display = &amp;#039;none&amp;#039;;&lt;br /&gt;
                }&lt;br /&gt;
                //show/create current subset&lt;br /&gt;
                var id = sel.options[curSubset].value;&lt;br /&gt;
                var p = document.getElementById( id );&lt;br /&gt;
                if ( !p ) {&lt;br /&gt;
                    p = document.createElement( &amp;#039;p&amp;#039; );&lt;br /&gt;
                    p.id = id;&lt;br /&gt;
                    if ( id == &amp;#039;Arabic&amp;#039; || id == &amp;#039;Hebrew&amp;#039; ) {&lt;br /&gt;
                        p.style.fontSize = &amp;#039;120%&amp;#039;;&lt;br /&gt;
                        p.dir = &amp;#039;rtl&amp;#039;;&lt;br /&gt;
                    }&lt;br /&gt;
                    var tokens = EditTools.charinsert[id];&lt;br /&gt;
                    if ( window.charinsertCustom &amp;amp;&amp;amp; charinsertCustom[id] ) {&lt;br /&gt;
                        if ( tokens.length &amp;gt; 0 ) {&lt;br /&gt;
                            tokens += &amp;#039; &amp;#039;;&lt;br /&gt;
                        }&lt;br /&gt;
                        tokens += charinsertCustom[id];&lt;br /&gt;
                    }&lt;br /&gt;
                    EditTools.createTokens( p, tokens );&lt;br /&gt;
                    box.appendChild( p );&lt;br /&gt;
                }&lt;br /&gt;
                p.style.display = &amp;#039;inline&amp;#039;;&lt;br /&gt;
            }&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        createTokens: function ( paragraph, str ) {&lt;br /&gt;
            var tokens = str.split( &amp;#039; &amp;#039; ), token, i, n;&lt;br /&gt;
            for ( i = 0; i &amp;lt; tokens.length; i++ ) {&lt;br /&gt;
                token = tokens[i];&lt;br /&gt;
                n = token.indexOf( &amp;#039;+&amp;#039; );&lt;br /&gt;
                if ( token.charAt( 0 ) === &amp;#039;␥&amp;#039; ) {&lt;br /&gt;
                    if ( token.length &amp;gt; 1 &amp;amp;&amp;amp; mw.config.get( &amp;#039;wgNamespaceNumber&amp;#039; ) === 0 ) {&lt;br /&gt;
                        continue;&lt;br /&gt;
                    } else {&lt;br /&gt;
                        token = token.substring( 1 );&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                if ( token == &amp;#039;&amp;#039; || token == &amp;#039;_&amp;#039; ) {&lt;br /&gt;
                    addText( EditTools.charinsertDivider + &amp;#039; &amp;#039; );&lt;br /&gt;
                } else if ( token == &amp;#039;\n&amp;#039; ) {&lt;br /&gt;
                    paragraph.appendChild( document.createElement( &amp;#039;br&amp;#039; ) );&lt;br /&gt;
                } else if ( token == &amp;#039;___&amp;#039; ) {&lt;br /&gt;
                    paragraph.appendChild( document.createElement( &amp;#039;hr&amp;#039; ) );&lt;br /&gt;
                } else if ( token.charAt( token.length-1 ) == &amp;#039;:&amp;#039; ) { // : at the end means just text&lt;br /&gt;
                    addBold( token );&lt;br /&gt;
                } else if ( n == 0 ) { // +&amp;lt;tag&amp;gt;  -&amp;gt;   &amp;lt;tag&amp;gt;+&amp;lt;/tag&amp;gt;&lt;br /&gt;
                    addLink( token.substring( 1 ), &amp;#039;&amp;lt;/&amp;#039; + token.substring( 2 ), token.substring( 1 ) );&lt;br /&gt;
                } else if ( n &amp;gt; 0 ) { // &amp;lt;tag&amp;gt;+&amp;lt;/tag&amp;gt;&lt;br /&gt;
                    addLink( token.substring( 0, n ), token.substring( n+1 ) );&lt;br /&gt;
                } else if ( token.length &amp;gt; 2 &amp;amp;&amp;amp; token.charCodeAt( 0 ) &amp;gt; 127 ) { // a string of insertable characters&lt;br /&gt;
                    for ( var j = 0; j &amp;lt; token.length; j++ ) {&lt;br /&gt;
                        addLink( token.charAt( j ), &amp;#039;&amp;#039; );&lt;br /&gt;
                    }&lt;br /&gt;
                } else {&lt;br /&gt;
                    addLink( token, &amp;#039;&amp;#039; );&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            return;&lt;br /&gt;
&lt;br /&gt;
            function addLink( tagOpen, tagClose, name ) {&lt;br /&gt;
                var handler;&lt;br /&gt;
                var dle = tagOpen.indexOf( &amp;#039;\x10&amp;#039; );&lt;br /&gt;
                if ( dle &amp;gt; 0 ) {&lt;br /&gt;
                    var path = tagOpen.substring( dle + 1 ).split( &amp;#039;.&amp;#039; );&lt;br /&gt;
                    tagOpen = tagOpen.substring( 0, dle );&lt;br /&gt;
                    var handler = window;&lt;br /&gt;
                    for ( var i = 0; i &amp;lt; path.length; i++ ) {&lt;br /&gt;
                        handler = handler[path[i]];&lt;br /&gt;
                    }&lt;br /&gt;
                } else {&lt;br /&gt;
                    tagOpen = tagOpen.replace( /\./g,&amp;#039; &amp;#039; );&lt;br /&gt;
                    tagClose = tagClose ? tagClose.replace( /_/g,&amp;#039; &amp;#039; ) : &amp;#039;&amp;#039;;&lt;br /&gt;
                    handler = new Function(&lt;br /&gt;
                        &amp;quot;evt&amp;quot;,&lt;br /&gt;
                        &amp;quot;insertTags(&amp;#039;&amp;quot; + tagOpen + &amp;quot;&amp;#039;, &amp;#039;&amp;quot; + tagClose + &amp;quot;&amp;#039;, &amp;#039;&amp;#039;); return killEvt( evt );&amp;quot;&lt;br /&gt;
                    );&lt;br /&gt;
                }&lt;br /&gt;
                var a = document.createElement( &amp;#039;a&amp;#039; );&lt;br /&gt;
                name = name || tagOpen + tagClose;&lt;br /&gt;
                name = name.replace( /\\n/g,&amp;#039;&amp;#039; );&lt;br /&gt;
                a.appendChild( document.createTextNode( name ) );&lt;br /&gt;
                a.href = &amp;quot;#&amp;quot;;&lt;br /&gt;
                addHandler( a, &amp;#039;click&amp;#039;, handler );&lt;br /&gt;
                paragraph.appendChild( a );&lt;br /&gt;
                addText( &amp;#039; &amp;#039; );&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            function addBold( text ) {&lt;br /&gt;
                var b = document.createElement( &amp;#039;b&amp;#039; );&lt;br /&gt;
                b.appendChild( document.createTextNode( text.replace( /_/g,&amp;#039; &amp;#039; ) ) );&lt;br /&gt;
                paragraph.appendChild( b );&lt;br /&gt;
                addText( &amp;#039; &amp;#039; );&lt;br /&gt;
            }&lt;br /&gt;
            function addText( txt ) {&lt;br /&gt;
                paragraph.appendChild( document.createTextNode( txt ) );&lt;br /&gt;
            }&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        enableForAllFields: function () {&lt;br /&gt;
            if ( typeof( insertTags ) != &amp;#039;function&amp;#039; || window.WikEdInsertTags ) {&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            // insertTags from the site-wide /skins-1.5/common/edit.js just inserts in the first&lt;br /&gt;
            // textarea in the document. Evidently, that&amp;#039;s not good if we have multiple textareas.&lt;br /&gt;
            // My first idea was to simply add a hidden textarea as the first one, and redefine&lt;br /&gt;
            // insertTags such that it copied first the last active textareas contents over to that hidden&lt;br /&gt;
            // field, set the cursor or selection there, let the standard insertTags do its thing, and&lt;br /&gt;
            // then copy the hidden field&amp;#039;s text, cursor position and selection back to the currently&lt;br /&gt;
            // active field. Unfortunately, that is just as complex as simply copying the whole code&lt;br /&gt;
            // from wikibits to here and let it work on the right text field in the first place.&lt;br /&gt;
            var texts = document.getElementsByTagName( &amp;#039;textarea&amp;#039; );&lt;br /&gt;
            for ( var i = 0; i &amp;lt; texts.length; i++ ) {&lt;br /&gt;
                addHandler( texts[i], &amp;#039;focus&amp;#039;, EditTools.registerTextField );&lt;br /&gt;
            }&lt;br /&gt;
            // While we&amp;#039;re at it, also enable it for input fields&lt;br /&gt;
            texts = document.getElementsByTagName( &amp;#039;input&amp;#039; );&lt;br /&gt;
            for ( var i = 0; i &amp;lt; texts.length; i++ ) {&lt;br /&gt;
                if ( texts[i].type == &amp;#039;text&amp;#039; ) {&lt;br /&gt;
                    addHandler( texts[i], &amp;#039;focus&amp;#039;, EditTools.registerTextField );&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            insertTags = EditTools.insertTags; // Redefine the global insertTags&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        last_active_textfield: null,&lt;br /&gt;
&lt;br /&gt;
        registerTextField: function ( evt ) {&lt;br /&gt;
            var e = evt || window.event;&lt;br /&gt;
            var node = e.target || e.srcElement;&lt;br /&gt;
            if ( !node ) {&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            EditTools.last_active_textfield = node.id;&lt;br /&gt;
            return true;&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        getTextArea: function () {&lt;br /&gt;
            var txtarea = null;&lt;br /&gt;
            if ( EditTools.last_active_textfield &amp;amp;&amp;amp; EditTools.last_active_textfield != &amp;quot;&amp;quot; )&lt;br /&gt;
                txtarea = document.getElementById( EditTools.last_active_textfield );&lt;br /&gt;
            if ( !txtarea ) {&lt;br /&gt;
                // Fallback option: old behaviour&lt;br /&gt;
                if ( document.editform ) {&lt;br /&gt;
                    txtarea = document.editform.wpTextbox1;&lt;br /&gt;
                } else {&lt;br /&gt;
                    // Some alternate form? Take the first one we can find&lt;br /&gt;
                    txtarea = document.getElementsByTagName( &amp;#039;textarea&amp;#039; );&lt;br /&gt;
                    if ( txtarea.length &amp;gt; 0 ) {&lt;br /&gt;
                        txtarea = txtarea[0];&lt;br /&gt;
                    } else {&lt;br /&gt;
                        txtarea = null;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            return txtarea;&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        insertTags: function ( tagOpen, tagClose, sampleText ) {&lt;br /&gt;
            var txtarea = EditTools.getTextArea();&lt;br /&gt;
            if ( !txtarea ) {&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            /* Usability initiative compatibility */&lt;br /&gt;
            if ( typeof $j != &amp;#039;undefined&amp;#039; &amp;amp;&amp;amp; typeof $j.fn.textSelection != &amp;#039;undefined&amp;#039; ) {&lt;br /&gt;
                $j( txtarea ).textSelection(&lt;br /&gt;
                    &amp;#039;encapsulateSelection&amp;#039;,&lt;br /&gt;
                    { &amp;#039;pre&amp;#039;: tagOpen, &amp;#039;peri&amp;#039;: sampleText, &amp;#039;post&amp;#039;: tagClose }&lt;br /&gt;
                );&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            var selText, isSample = false;&lt;br /&gt;
&lt;br /&gt;
            function checkSelectedText() {&lt;br /&gt;
                if ( !selText ) {&lt;br /&gt;
                    selText = sampleText;&lt;br /&gt;
                    isSample = true;&lt;br /&gt;
                } else if ( selText.charAt( selText.length - 1 ) == &amp;#039; &amp;#039; ) { // Exclude ending space char&lt;br /&gt;
                    selText = selText.substring( 0, selText.length - 1 );&lt;br /&gt;
                    tagClose += &amp;#039; &amp;#039;;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            if ( document.selection &amp;amp;&amp;amp; document.selection.createRange ) { // IE/Opera&lt;br /&gt;
                // Save window scroll position&lt;br /&gt;
                var winScroll = 0;&lt;br /&gt;
                if ( document.documentElement &amp;amp;&amp;amp; document.documentElement.scrollTop ) {&lt;br /&gt;
                    winScroll = document.documentElement.scrollTop;&lt;br /&gt;
                } else if ( document.body ) {&lt;br /&gt;
                    winScroll = document.body.scrollTop;&lt;br /&gt;
                }&lt;br /&gt;
                // Get current selection&lt;br /&gt;
                txtarea.focus();&lt;br /&gt;
                var range = document.selection.createRange();&lt;br /&gt;
                selText = range.text;&lt;br /&gt;
                // Insert tags&lt;br /&gt;
                checkSelectedText();&lt;br /&gt;
                range.text = tagOpen + selText + tagClose;&lt;br /&gt;
                // Mark sample text as selected&lt;br /&gt;
                if ( isSample &amp;amp;&amp;amp; range.moveStart ) {&lt;br /&gt;
                    if ( window.opera ) {&lt;br /&gt;
                        tagClose = tagClose.replace( /\n/g, &amp;quot;&amp;quot; );&lt;br /&gt;
                    }&lt;br /&gt;
                    range.moveStart( &amp;#039;character&amp;#039;, - tagClose.length - selText.length );&lt;br /&gt;
                    range.moveEnd( &amp;#039;character&amp;#039;, - tagClose.length );&lt;br /&gt;
                }&lt;br /&gt;
                range.select();&lt;br /&gt;
                // Restore window scroll position&lt;br /&gt;
                if ( document.documentElement &amp;amp;&amp;amp; document.documentElement.scrollTop ) {&lt;br /&gt;
                    document.documentElement.scrollTop = winScroll;&lt;br /&gt;
                } else if ( document.body ) {&lt;br /&gt;
                    document.body.scrollTop = winScroll;&lt;br /&gt;
                }&lt;br /&gt;
            } else if ( txtarea.selectionStart || txtarea.selectionStart == &amp;#039;0&amp;#039; ) { // Mozilla&lt;br /&gt;
                // Save textarea scroll position&lt;br /&gt;
                var textScroll = txtarea.scrollTop;&lt;br /&gt;
                // Get current selection&lt;br /&gt;
                txtarea.focus();&lt;br /&gt;
                var startPos = txtarea.selectionStart;&lt;br /&gt;
                var endPos = txtarea.selectionEnd;&lt;br /&gt;
                selText = txtarea.value.substring( startPos, endPos );&lt;br /&gt;
                // Insert tags&lt;br /&gt;
                checkSelectedText();&lt;br /&gt;
                txtarea.value = txtarea.value.substring( 0, startPos ) + tagOpen + selText&lt;br /&gt;
                    + tagClose + txtarea.value.substring( endPos );&lt;br /&gt;
                // Set new selection&lt;br /&gt;
                if ( isSample ) {&lt;br /&gt;
                    txtarea.selectionStart = startPos + tagOpen.length;&lt;br /&gt;
                    txtarea.selectionEnd = startPos + tagOpen.length + selText.length;&lt;br /&gt;
                } else {&lt;br /&gt;
                    txtarea.selectionStart = startPos + tagOpen.length + selText.length + tagClose.length;&lt;br /&gt;
                    txtarea.selectionEnd = txtarea.selectionStart;&lt;br /&gt;
                }&lt;br /&gt;
                // Restore textarea scroll position&lt;br /&gt;
                txtarea.scrollTop = textScroll;&lt;br /&gt;
            }&lt;br /&gt;
        }, // end insertTags&lt;br /&gt;
&lt;br /&gt;
        setup: function () {&lt;br /&gt;
            var placeholder;&lt;br /&gt;
            if ( $( &amp;#039;#editpage-specialchars&amp;#039; ).length ) {&lt;br /&gt;
                placeholder = $( &amp;#039;#editpage-specialchars&amp;#039; )[0];&lt;br /&gt;
            } else {&lt;br /&gt;
                placeholder = $( &amp;#039;&amp;lt;div id=&amp;quot;editpage-specialchars&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&amp;#039; ).prependTo( &amp;#039;.mw-editTools&amp;#039; )[0];&lt;br /&gt;
            }&lt;br /&gt;
            if ( !placeholder ) {&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if ( !window.charinsertDontMove ) {&lt;br /&gt;
                $( &amp;#039;.editOptions&amp;#039; ).before( placeholder );&lt;br /&gt;
            }&lt;br /&gt;
            EditTools.createEditTools( placeholder );&lt;br /&gt;
            EditTools.enableForAllFields();&lt;br /&gt;
            window.updateEditTools = function () {&lt;br /&gt;
                EditTools.createEditTools( $( &amp;#039;#editpage-specialchars&amp;#039; )[0] );&lt;br /&gt;
            };&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }; // end EditTools&lt;br /&gt;
&lt;br /&gt;
    EditTools.setup();&lt;br /&gt;
} );&lt;/div&gt;</summary>
		<author><name>Link</name></author>
	</entry>
</feed>