WordPress.org

Make WordPress Core

Ticket #16695: 16695.3.diff

File 16695.3.diff, 29.4 KB (added by garyc40, 10 years ago)

completely refactor quicktags.dev

  • wp-admin/js/edit-comments.dev.js

    diff --git wp-admin/js/edit-comments.dev.js wp-admin/js/edit-comments.dev.js
    index b81b397..58e3924 100644
    $(document).ready(function(){ 
    507507        commentReply.init();
    508508        $(document).delegate('span.delete a.delete', 'click', function(){return false;});
    509509
    510         if ( typeof QTags != 'undefined' )
    511                 ed_reply = new QTags('ed_reply', 'replycontent', 'replycontainer', 'more');
     510        if ( typeof QuickTags != 'undefined' )
     511                ed_reply = new QuickTags('ed_reply', 'replycontent', 'replycontainer', 'more');
    512512
    513513        if ( typeof $.table_hotkeys != 'undefined' ) {
    514514                make_hotkeys_redirect = function(which) {
  • wp-admin/js/editor.dev.js

    diff --git wp-admin/js/editor.dev.js wp-admin/js/editor.dev.js
    index cf58279..13877ec 100644
    var switchEditors = { 
    103103
    104104                        P.className = 'active';
    105105                        H.className = '';
    106                         edCloseAllTags(); // :-(
     106                        QuickTags.getInstance(id).closeAllTags(); // :-(
    107107                        qt.style.display = 'none';
    108108
    109109                        ta.style.color = '#FFF';
  • wp-includes/general-template.php

    diff --git wp-includes/general-template.php wp-includes/general-template.php
    index 19194f2..a9104a5 100644
    function the_editor($content, $id = 'content', $prev_id = 'title', $media_button 
    18271827?>
    18281828        <div id="quicktags"><?php
    18291829        wp_print_scripts( 'quicktags' ); ?>
    1830         <script type="text/javascript">edToolbar()</script>
     1830        <script type="text/javascript">QuickTags.init('<?php echo esc_js($id); ?>');</script>
    18311831        </div>
    18321832
    18331833<?php
  • wp-includes/js/quicktags.dev.js

    diff --git wp-includes/js/quicktags.dev.js wp-includes/js/quicktags.dev.js
    index 48b7b6a..0dd28eb 100644
     
     1/*globals quicktagsL10n */
     2
    13// new edit toolbar used with permission
    24// by Alex King
    35// http://www.alexking.org/
    46
    5 var edButtons = new Array(), edLinks = new Array(), edOpenTags = new Array(), now = new Date(), datetime;
    6 
    7 function edButton(id, display, tagStart, tagEnd, access, open) {
    8         this.id = id;                           // used to name the toolbar button
    9         this.display = display;         // label on button
    10         this.tagStart = tagStart;       // open tag
    11         this.tagEnd = tagEnd;           // close tag
    12         this.access = access;           // access key
    13         this.open = open;                       // set to -1 if tag does not need to be closed
    14 }
    15 
    16 function zeroise(number, threshold) {
    17         // FIXME: or we could use an implementation of printf in js here
    18         var str = number.toString();
    19         if (number < 0) { str = str.substr(1, str.length) }
    20         while (str.length < threshold) { str = "0" + str }
    21         if (number < 0) { str = '-' + str }
    22         return str;
    23 }
    24 
    25 datetime = now.getUTCFullYear() + '-' +
    26 zeroise(now.getUTCMonth() + 1, 2) + '-' +
    27 zeroise(now.getUTCDate(), 2) + 'T' +
    28 zeroise(now.getUTCHours(), 2) + ':' +
    29 zeroise(now.getUTCMinutes(), 2) + ':' +
    30 zeroise(now.getUTCSeconds() ,2) +
    31 '+00:00';
    32 
    33 edButtons[edButtons.length] =
    34 new edButton('ed_strong'
    35 ,'b'
    36 ,'<strong>'
    37 ,'</strong>'
    38 ,'b'
    39 );
    40 
    41 edButtons[edButtons.length] =
    42 new edButton('ed_em'
    43 ,'i'
    44 ,'<em>'
    45 ,'</em>'
    46 ,'i'
    47 );
    48 
    49 edButtons[edButtons.length] =
    50 new edButton('ed_link'
    51 ,'link'
    52 ,''
    53 ,'</a>'
    54 ,'a'
    55 ); // special case
    56 
    57 edButtons[edButtons.length] =
    58 new edButton('ed_block'
    59 ,'b-quote'
    60 ,'\n\n<blockquote>'
    61 ,'</blockquote>\n\n'
    62 ,'q'
    63 );
    64 
    65 
    66 edButtons[edButtons.length] =
    67 new edButton('ed_del'
    68 ,'del'
    69 ,'<del datetime="' + datetime + '">'
    70 ,'</del>'
    71 ,'d'
    72 );
    73 
    74 edButtons[edButtons.length] =
    75 new edButton('ed_ins'
    76 ,'ins'
    77 ,'<ins datetime="' + datetime + '">'
    78 ,'</ins>'
    79 ,'s'
    80 );
    81 
    82 edButtons[edButtons.length] =
    83 new edButton('ed_img'
    84 ,'img'
    85 ,''
    86 ,''
    87 ,'m'
    88 ,-1
    89 ); // special case
    90 
    91 edButtons[edButtons.length] =
    92 new edButton('ed_ul'
    93 ,'ul'
    94 ,'<ul>\n'
    95 ,'</ul>\n\n'
    96 ,'u'
    97 );
    98 
    99 edButtons[edButtons.length] =
    100 new edButton('ed_ol'
    101 ,'ol'
    102 ,'<ol>\n'
    103 ,'</ol>\n\n'
    104 ,'o'
    105 );
     7var QuickTags;
    1068
    107 edButtons[edButtons.length] =
    108 new edButton('ed_li'
    109 ,'li'
    110 ,'\t<li>'
    111 ,'</li>\n'
    112 ,'l'
    113 );
    114 
    115 edButtons[edButtons.length] =
    116 new edButton('ed_code'
    117 ,'code'
    118 ,'<code>'
    119 ,'</code>'
    120 ,'c'
    121 );
    122 
    123 edButtons[edButtons.length] =
    124 new edButton('ed_more'
    125 ,'more'
    126 ,'<!--more-->'
    127 ,''
    128 ,'t'
    129 ,-1
    130 );
    131 /*
    132 edButtons[edButtons.length] =
    133 new edButton('ed_next'
    134 ,'page'
    135 ,'<!--nextpage-->'
    136 ,''
    137 ,'p'
    138 ,-1
    139 );
    140 */
    141 function edLink() {
    142         this.display = '';
    143         this.URL = '';
    144         this.newWin = 0;
    145 }
    146 
    147 edLinks[edLinks.length] = new edLink('WordPress'
    148                                     ,'http://wordpress.org/'
    149                                     );
    150 
    151 edLinks[edLinks.length] = new edLink('alexking.org'
    152                                     ,'http://www.alexking.org/'
    153                                     );
    154 
    155 function edShowButton(button, i) {
    156         if (button.id == 'ed_img') {
    157                 document.write('<input type="button" id="' + button.id + '" accesskey="' + button.access + '" class="ed_button" onclick="edInsertImage(edCanvas);" value="' + button.display + '" />');
    158         }
    159         else if (button.id == 'ed_link') {
    160                 document.write('<input type="button" id="' + button.id + '" accesskey="' + button.access + '" class="ed_button" onclick="edInsertLink(edCanvas, ' + i + ');" value="' + button.display + '" />');
    161         }
    162         else {
    163                 document.write('<input type="button" id="' + button.id + '" accesskey="' + button.access + '" class="ed_button" onclick="edInsertTag(edCanvas, ' + i + ');" value="' + button.display + '"  />');
    164         }
    165 }
    166 
    167 function edShowLinks() {
    168         var tempStr = '<select onchange="edQuickLink(this.options[this.selectedIndex].value, this);"><option value="-1" selected>' + quicktagsL10n.quickLinks + '</option>', i;
    169         for (i = 0; i < edLinks.length; i++) {
    170                 tempStr += '<option value="' + i + '">' + edLinks[i].display + '</option>';
    171         }
    172         tempStr += '</select>';
    173         document.write(tempStr);
    174 }
    175 
    176 function edAddTag(button) {
    177         if (edButtons[button].tagEnd != '') {
    178                 edOpenTags[edOpenTags.length] = button;
    179                 document.getElementById(edButtons[button].id).value = '/' + document.getElementById(edButtons[button].id).value;
    180         }
    181 }
    182 
    183 function edRemoveTag(button) {
    184         for (var i = 0; i < edOpenTags.length; i++) {
    185                 if (edOpenTags[i] == button) {
    186                         edOpenTags.splice(i, 1);
    187                         document.getElementById(edButtons[button].id).value =           document.getElementById(edButtons[button].id).value.replace('/', '');
    188                 }
    189         }
    190 }
    191 
    192 function edCheckOpenTags(button) {
    193         var tag = 0, i;
    194         for (i = 0; i < edOpenTags.length; i++) {
    195                 if (edOpenTags[i] == button) {
    196                         tag++;
    197                 }
    198         }
    199         if (tag > 0) {
    200                 return true; // tag found
    201         }
    202         else {
    203                 return false; // tag not found
    204         }
    205 }
     9(function(){
     10        // private stuff is prefixed with an underscore
     11        var _domReady = function(func) {
     12                if (typeof jQuery != 'undefined') {
     13                        jQuery(document).ready(func);
     14                } else {
     15                        var t = _domReady, DOMContentLoaded, top;
     16                                t.funcs = [];
     17
     18                        t.ready = function() {
     19                                if (! t.isReady) {
     20                                        t.isReady = true;
     21                                        for (var i=0; i < t.funcs.length; i++) {
     22                                                t.funcs[i]();
     23                                        }
     24                                }
     25                        };
    20626
    207 function edCloseAllTags() {
    208         var count = edOpenTags.length, o;
    209         for (o = 0; o < count; o++) {
    210                 edInsertTag(edCanvas, edOpenTags[edOpenTags.length - 1]);
    211         }
    212 }
     27                        if (t.isReady) {
     28                                func();
     29                        } else {
     30                                t.funcs.push(func);
     31                        }
    21332
    214 function edQuickLink(i, thisSelect) {
    215         if (i > -1) {
    216                 var newWin = '', tempStr;
    217                 if (edLinks[i].newWin == 1) {
    218                         newWin = ' target="_blank"';
    219                 }
    220                 tempStr = '<a href="' + edLinks[i].URL + '"' + newWin + '>'
    221                             + edLinks[i].display
    222                             + '</a>';
    223                 thisSelect.selectedIndex = 0;
    224                 edInsertContent(edCanvas, tempStr);
    225         }
    226         else {
    227                 thisSelect.selectedIndex = 0;
    228         }
    229 }
     33                        if ( ! t.eventAttached ) {
     34                                if (document.addEventListener) {
     35                                        DOMContentLoaded = function(){document.removeEventListener('DOMContentLoaded', DOMContentLoaded, false);t.ready();};
     36                                        document.addEventListener('DOMContentLoaded', DOMContentLoaded, false);
     37                                        window.addEventListener('load', t.ready, false);
     38                                } else if (document.attachEvent) {
     39                                        DOMContentLoaded = function(){if (document.readyState === 'complete'){ document.detachEvent('onreadystatechange', DOMContentLoaded);t.ready();}};
     40                                        document.attachEvent('onreadystatechange', DOMContentLoaded);
     41                                        window.attachEvent('onload', t.ready);
     42
     43                                        (function(){
     44                                                try {
     45                                                        document.documentElement.doScroll("left");
     46                                                } catch(e) {
     47                                                        setTimeout(arguments.callee, 50);
     48                                                        return;
     49                                                }
     50
     51                                                t.ready();
     52                                        })();
     53                                }
    23054
    231 function edSpell(myField) {
    232         var word = '', sel, startPos, endPos;
    233         if (document.selection) {
    234                 myField.focus();
    235             sel = document.selection.createRange();
    236                 if (sel.text.length > 0) {
    237                         word = sel.text;
     55                                t.eventAttached = true;
     56                        }
    23857                }
    239         }
    240         else if (myField.selectionStart || myField.selectionStart == '0') {
    241                 startPos = myField.selectionStart;
    242                 endPos = myField.selectionEnd;
    243                 if (startPos != endPos) {
    244                         word = myField.value.substring(startPos, endPos);
     58        };
     59       
     60        var _zeroise = function(number, threshold) {
     61                // FIXME: or we could use an implementation of printf in js here
     62                var str = number.toString();
     63                if (! threshold) {
     64                        threshold = 2;
    24565                }
    246         }
    247         if (word == '') {
    248                 word = prompt(quicktagsL10n.wordLookup, '');
    249         }
    250         if (word !== null && /^\w[\w ]*$/.test(word)) {
    251                 window.open('http://www.answers.com/' + escape(word));
    252         }
    253 }
    254 
    255 function edToolbar() {
    256         document.write('<div id="ed_toolbar">');
    257         for (var i = 0; i < edButtons.length; i++) {
    258                 edShowButton(edButtons[i], i);
    259         }
    260         document.write('<input type="button" id="ed_spell" class="ed_button" onclick="edSpell(edCanvas);" title="' + quicktagsL10n.dictionaryLookup + '" value="' + quicktagsL10n.lookup + '" />');
    261         document.write('<input type="button" id="ed_close" class="ed_button" onclick="edCloseAllTags();" title="' + quicktagsL10n.closeAllOpenTags + '" value="' + quicktagsL10n.closeTags + '" />');
    262 //      edShowLinks(); // disabled by default
    263         document.write('</div>');
    264 }
    265 
    266 // insertion code
    267 
    268 function edInsertTag(myField, i) {
    269         //IE support
    270         if (document.selection) {
    271                 myField.focus();
    272             var sel = document.selection.createRange();
    273                 if (sel.text.length > 0) {
    274                         sel.text = edButtons[i].tagStart + sel.text + edButtons[i].tagEnd;
     66                if (number < 0) { str = str.substr(1, str.length); }
     67                while (str.length < threshold) { str = "0" + str; }
     68                if (number < 0) { str = '-' + str; }
     69                return str;
     70        };
     71       
     72        var _dateToString = function(d) {
     73                return '' +
     74                        d.getUTCFullYear() + '-' +
     75                        _zeroise(d.getUTCMonth() + 1, 2) + '-' +
     76                        _zeroise(d.getUTCDate(), 2) + 'T' +
     77                        _zeroise(d.getUTCHours(), 2) + ':' +
     78                        _zeroise(d.getUTCMinutes(), 2) + ':' +
     79                        _zeroise(d.getUTCSeconds() ,2) +
     80                        '+00:00';
     81        };
     82       
     83        var _instances = [],
     84                _now = new Date(),
     85                _datetime = _dateToString(_now),               
     86                _customButtons = {}, qt;
     87       
     88        qt = QuickTags = function(name, id, container, disabled) {
     89                var t = this,
     90                        cont = document.getElementById(container),
     91                        buttons = {},
     92                        links = [],
     93                        openTags = [],
     94                        i, c, p, tb, html, canvas;
     95                       
     96                t.name = name;
     97                t.id = id;
     98
     99                disabled = (typeof disabled == 'undefined') ? '' : ',' + disabled + ',';
     100               
     101                // default buttons
     102                buttons = {
     103                        'strong' : new qt.TagButton('strong','b','<strong>','</strong>','b'),
     104                        'em' : new qt.TagButton('em','i','<em>','</em>','i'),
     105                        'link' : new qt.LinkButton(), // special case
     106                        'block' : new qt.TagButton('block','b-quote','\n\n<blockquote>','</blockquote>\n\n','q'),
     107                        'del' : new qt.TagButton('del','del','<del datetime="' + _datetime + '">','</del>','d'),
     108                        'ins' : new qt.TagButton('ins','ins','<ins datetime="' + _datetime + '">','</ins>','s'),
     109                        'img' : new qt.ImgButton(), // special case
     110                        'ul' : new qt.TagButton('ul','ul','<ul>\n','</ul>\n\n','u'),
     111                        'ol' : new qt.TagButton('ol','ol','<ol>\n','</ol>\n\n','o'),
     112                        'li' : new qt.TagButton('li','li','\t<li>','</li>\n','l'),
     113                        'code' : new qt.TagButton('code','code','<code>','</code>','c'),
     114                        'more' : new qt.TagButton('more','more','<!--more-->','','t',-1),
     115                        'spell' : new qt.SpellButton(),
     116                        'close' : new qt.CloseButton()
     117                };
     118               
     119                // add custom buttons
     120                for (i in _customButtons) {
     121                        buttons[i] = new _customButtons[i]();
    275122                }
    276                 else {
    277                         if (!edCheckOpenTags(i) || edButtons[i].tagEnd == '') {
    278                                 sel.text = edButtons[i].tagStart;
    279                                 edAddTag(i);
     123               
     124                html = '<div id="' + name + '_toolbar">';
     125                for (i in buttons) {
     126                        if (disabled && (disabled.indexOf(',' + buttons[i].id + ',') != -1)) {
     127                                continue;
    280128                        }
    281                         else {
    282                                 sel.text = edButtons[i].tagEnd;
    283                                 edRemoveTag(i);
    284                         }
    285                 }
    286                 myField.focus();
    287         }
    288         //MOZILLA/NETSCAPE support
    289         else if (myField.selectionStart || myField.selectionStart == '0') {
    290                 var startPos = myField.selectionStart, endPos = myField.selectionEnd, cursorPos = endPos, scrollTop = myField.scrollTop;
    291 
    292                 if (startPos != endPos) {
    293                         myField.value = myField.value.substring(0, startPos)
    294                                       + edButtons[i].tagStart
    295                                       + myField.value.substring(startPos, endPos)
    296                                       + edButtons[i].tagEnd
    297                                       + myField.value.substring(endPos, myField.value.length);
    298                         cursorPos += edButtons[i].tagStart.length + edButtons[i].tagEnd.length;
     129                        html += buttons[i].html(name + '_');
    299130                }
    300                 else {
    301                         if (!edCheckOpenTags(i) || edButtons[i].tagEnd == '') {
    302                                 myField.value = myField.value.substring(0, startPos)
    303                                               + edButtons[i].tagStart
    304                                               + myField.value.substring(endPos, myField.value.length);
    305                                 edAddTag(i);
    306                                 cursorPos = startPos + edButtons[i].tagStart.length;
    307                         }
    308                         else {
    309                                 myField.value = myField.value.substring(0, startPos)
    310                                               + edButtons[i].tagEnd
    311                                               + myField.value.substring(endPos, myField.value.length);
    312                                 edRemoveTag(i);
    313                                 cursorPos = startPos + edButtons[i].tagEnd.length;
     131                html += "</div>";
     132                cont.innerHTML = html + cont.innerHTML;
     133               
     134                // listen for click events
     135                this.toolbar = tb = document.getElementById(name + '_toolbar');
     136               
     137               
     138                var onclick = function(e) {
     139                        e = e || window.event;
     140                        var target = e.target || e.srcElement, i;
     141
     142                        // as long as it has the class ed_button, execute the callback
     143                        if (/\s+ed_button\s+/.test(' ' + target.className + ' ')) {
     144                                // we have to reassign canvas here
     145                                t.canvas = canvas = document.getElementById(id);
     146                                i = target.id.replace(name + '_', '');
     147                                if (buttons[i]) {
     148                                        buttons[i].callback.call(buttons[i], target, canvas, t);
     149                                }
    314150                        }
     151                };
     152               
     153                if (tb.addEventListener) {
     154                        tb.addEventListener('click', onclick, false);
     155                } else if (tb.attachEvent) {
     156                        tb.attachEvent('onclick', onclick);
    315157                }
    316                 myField.focus();
    317                 myField.selectionStart = cursorPos;
    318                 myField.selectionEnd = cursorPos;
    319                 myField.scrollTop = scrollTop;
    320         }
    321         else {
    322                 if (!edCheckOpenTags(i) || edButtons[i].tagEnd == '') {
    323                         myField.value += edButtons[i].tagStart;
    324                         edAddTag(i);
    325                 }
    326                 else {
    327                         myField.value += edButtons[i].tagEnd;
    328                         edRemoveTag(i);
    329                 }
    330                 myField.focus();
    331         }
    332 }
    333 
    334 function edInsertContent(myField, myValue) {
    335         var sel, startPos, endPos, scrollTop;
    336 
    337         //IE support
    338         if (document.selection) {
    339                 myField.focus();
    340                 sel = document.selection.createRange();
    341                 sel.text = myValue;
    342                 myField.focus();
    343         }
    344         //MOZILLA/NETSCAPE support
    345         else if (myField.selectionStart || myField.selectionStart == '0') {
    346                 startPos = myField.selectionStart;
    347                 endPos = myField.selectionEnd;
    348                 scrollTop = myField.scrollTop;
    349                 myField.value = myField.value.substring(0, startPos)
    350                               + myValue
    351                       + myField.value.substring(endPos, myField.value.length);
    352                 myField.focus();
    353                 myField.selectionStart = startPos + myValue.length;
    354                 myField.selectionEnd = startPos + myValue.length;
    355                 myField.scrollTop = scrollTop;
    356         } else {
    357                 myField.value += myValue;
    358                 myField.focus();
    359         }
    360 }
    361 
    362 function edInsertLink(myField, i, defaultValue) {
    363         if (!defaultValue) {
    364                 defaultValue = 'http://';
    365         }
    366         if (!edCheckOpenTags(i)) {
    367                 var URL = prompt(quicktagsL10n.enterURL, defaultValue);
    368                 if (URL) {
    369                         edButtons[i].tagStart = '<a href="' + URL + '">';
    370                         edInsertTag(myField, i);
    371                 }
    372         }
    373         else {
    374                 edInsertTag(myField, i);
    375         }
    376 }
    377 
    378 function edInsertImage(myField) {
    379         var myValue = prompt(quicktagsL10n.enterImageURL, 'http://');
    380         if (myValue) {
    381                 myValue = '<img src="'
    382                                 + myValue
    383                                 + '" alt="' + prompt(quicktagsL10n.enterImageDescription, '')
    384                                 + '" />';
    385                 edInsertContent(myField, myValue);
    386         }
    387 }
    388 
    389 
    390 // Allow multiple instances.
    391 // Name = unique value, id = textarea id, container = container div.
    392 // Can disable some buttons by passing comma delimited string as 4th param.
    393 var QTags = function(name, id, container, disabled) {
    394         var t = this, cont = document.getElementById(container), i, tag, tb, html, sel;
    395 
    396         t.Buttons = [];
    397         t.Links = [];
    398         t.OpenTags = [];
    399         t.Canvas = document.getElementById(id);
    400 
    401         if ( ! t.Canvas || ! cont )
    402                 return;
    403 
    404         disabled = ( typeof disabled != 'undefined' ) ? ','+disabled+',' : '';
    405 
    406         t.edShowButton = function(button, i) {
    407                 if ( disabled && (disabled.indexOf(','+button.display+',') != -1) )
    408                         return '';
    409                 else if ( button.id == name+'_img' )
    410                         return '<input type="button" id="' + button.id + '" accesskey="' + button.access + '" class="ed_button" onclick="edInsertImage('+name+'.Canvas);" value="' + button.display + '" />';
    411                 else if (button.id == name+'_link')
    412                         return '<input type="button" id="' + button.id + '" accesskey="' + button.access + '" class="ed_button" onclick="'+name+'.edInsertLink('+i+');" value="'+button.display+'" />';
    413                 else
    414                         return '<input type="button" id="' + button.id + '" accesskey="'+button.access+'" class="ed_button" onclick="'+name+'.edInsertTag('+i+');" value="'+button.display+'" />';
     158               
     159                t.getButton = function(id){
     160                        return buttons[id];
     161                };
     162               
     163                _instances[id] = t;
    415164        };
    416 
    417         t.edAddTag = function(button) {
    418                 if ( t.Buttons[button].tagEnd != '' ) {
    419                         t.OpenTags[t.OpenTags.length] = button;
    420                         document.getElementById(t.Buttons[button].id).value = '/' + document.getElementById(t.Buttons[button].id).value;
    421                 }
     165       
     166        qt.registerButton = function(id, btnClass) {
     167                _customButtons[id] = btnClass;
    422168        };
    423 
    424         t.edRemoveTag = function(button) {
    425                 for ( i = 0; i < t.OpenTags.length; i++ ) {
    426                         if ( t.OpenTags[i] == button ) {
    427                                 t.OpenTags.splice(i, 1);
    428                                 document.getElementById(t.Buttons[button].id).value = document.getElementById(t.Buttons[button].id).value.replace('/', '');
    429                         }
    430                 }
     169       
     170        qt.getInstance = function(id) {
     171                return _instances[id];
    431172        };
    432 
    433         t.edCheckOpenTags = function(button) {
    434                 tag = 0;
    435                 for ( var i = 0; i < t.OpenTags.length; i++ ) {
    436                         if ( t.OpenTags[i] == button )
    437                                 tag++;
    438                 }
    439                 if ( tag > 0 ) return true; // tag found
    440                 else return false; // tag not found
     173       
     174        // when used with the_editor()
     175        qt.init = function(id){
     176                _domReady(function(){
     177                        var instance = new QuickTags('ed', id, 'quicktags');
     178                });
    441179        };
    442 
    443         this.edCloseAllTags = function() {
    444                 var count = t.OpenTags.length;
    445                 for ( var o = 0; o < count; o++ )
    446                         t.edInsertTag(t.OpenTags[t.OpenTags.length - 1]);
     180       
     181        // a plain, dumb button
     182        qt.Button = function(id, display, access) {
     183                var t = this;
     184                t.id = id;
     185                t.display = display;
     186                t.access = access;
    447187        };
    448 
    449         this.edQuickLink = function(i, thisSelect) {
    450                 if ( i > -1 ) {
    451                         var newWin = '', tempStr;
    452                         if ( Links[i].newWin == 1 ) {
    453                                 newWin = ' target="_blank"';
     188        qt.Button.prototype.html = function(idPrefix) {
     189                var access = this.access ? ' accesskey="' + this.access + '"' : '';
     190                return '<input type="button" id="' + idPrefix + this.id + '"' + access + ' class="ed_button" value="' + this.display + '" />';
     191        };
     192        qt.Button.prototype.callback = function(canvas) {};
     193       
     194        // a button that inserts HTML tag
     195        qt.TagButton = function(id, display, tagStart, tagEnd, access, open) {
     196                var t = this;
     197                qt.Button.call(t, id, display, access);
     198                t.tagStart = tagStart;
     199                t.tagEnd = tagEnd;
     200                t.open = open;         
     201        };
     202        qt.TagButton.prototype = new qt.Button();
     203        qt.TagButton.prototype.openTag = function(e, tb) {
     204                var t = this;
     205                t.isOpen = true;
     206                if (! tb._openTags) {
     207                        tb._openTags = [];
     208                }
     209                if (t.tagEnd) {
     210                        tb._openTags.push(t.id);
     211                        e.value = '/' + e.value;
     212                }
     213        };
     214        qt.TagButton.prototype.closeTag = function(e, tb) {
     215                var t = this, i;
     216                t.isOpen = false;
     217                if (tb._openTags) {
     218                        for (i=0; i < tb._openTags.length; i ++ ) {
     219                                if (tb._openTags[i] == t.id) {
     220                                        tb._openTags.splice(i, 1);
     221                                }
    454222                        }
    455                         tempStr = '<a href="' + Links[i].URL + '"' + newWin + '>'
    456                                     + Links[i].display
    457                                     + '</a>';
    458                         thisSelect.selectedIndex = 0;
    459                         edInsertContent(t.Canvas, tempStr);
    460                 } else {
    461                         thisSelect.selectedIndex = 0;
    462223                }
     224                e.value = t.display;
    463225        };
     226        qt.TagButton.prototype.callback = function(element, canvas, toolbar) {
     227                var t = this, startPos, endPos, cursorPos, scrollTop, v, l, r, i, sel;
     228
     229                v = canvas.value;
    464230
    465         // insertion code
    466         t.edInsertTag = function(i) {
    467                 //IE support
    468                 if ( document.selection ) {
    469                         t.Canvas.focus();
    470                     sel = document.selection.createRange();
    471                         if ( sel.text.length > 0 ) {
    472                                 sel.text = t.Buttons[i].tagStart + sel.text + t.Buttons[i].tagEnd;
     231                // IE support
     232                if (document.selection) {
     233                        canvas.focus();
     234                        sel = document.selection.createRange();
     235                        if (sel.text.length > 0) {
     236                                sel.text = t.tagStart + sel.text + t.tagEnd;
    473237                        } else {
    474                                 if ( ! t.edCheckOpenTags(i) || t.Buttons[i].tagEnd == '' ) {
    475                                         sel.text = t.Buttons[i].tagStart;
    476                                         t.edAddTag(i);
     238                                if (! t.isOpen || t.tagEnd === '') {
     239                                        sel.text = t.tagStart;
     240                                        t.openTag(element, toolbar);
    477241                                } else {
    478                                         sel.text = t.Buttons[i].tagEnd;
    479                                         t.edRemoveTag(i);
     242                                        sel.text = t.tagEnd;
     243                                        t.closeTag(element, toolbar);
    480244                                }
    481245                        }
    482                         t.Canvas.focus();
    483                 } else if ( t.Canvas.selectionStart || t.Canvas.selectionStart == '0' ) { //MOZILLA/NETSCAPE support
    484                         var startPos = t.Canvas.selectionStart, endPos = t.Canvas.selectionEnd, cursorPos = endPos, scrollTop = t.Canvas.scrollTop;
    485 
    486                         if ( startPos != endPos ) {
    487                                 t.Canvas.value = t.Canvas.value.substring(0, startPos)
    488                                               + t.Buttons[i].tagStart
    489                                               + t.Canvas.value.substring(startPos, endPos)
    490                                               + t.Buttons[i].tagEnd
    491                                               + t.Canvas.value.substring(endPos, t.Canvas.value.length);
    492                                 cursorPos += t.Buttons[i].tagStart.length + t.Buttons[i].tagEnd.length;
     246                        canvas.focus();
     247                }
     248                // moz, webkit, opera
     249                else if (canvas.selectionStart || canvas.selectionStart == '0') {
     250                        startPos = canvas.selectionStart;
     251                        endPos = canvas.selectionEnd;
     252                        cursorPos = endPos;
     253                        scrollTop = canvas.scrollTop;
     254                        l = v.substring(0, startPos); // left of the selection
     255                        r = v.substring(endPos, v.length); // right of the selection
     256                        i = v.substring(startPos, endPos); // inside the selection
     257                        if (startPos != endPos) {
     258                                canvas.value = l + t.tagStart + i + t.tagEnd + r;
     259                                if (t.tagEnd === '') {
     260                                        cursorPos = startPos;
     261                                }
     262                                cursorPos += t.tagStart.length + t.tagEnd.length;
    493263                        } else {
    494                                 if ( !t.edCheckOpenTags(i) || t.Buttons[i].tagEnd == '' ) {
    495                                         t.Canvas.value = t.Canvas.value.substring(0, startPos)
    496                                                       + t.Buttons[i].tagStart
    497                                                       + t.Canvas.value.substring(endPos, t.Canvas.value.length);
    498                                         t.edAddTag(i);
    499                                         cursorPos = startPos + t.Buttons[i].tagStart.length;
     264                                if (! t.isOpen || t.tagEnd === '') {
     265                                        canvas.value = l + t.tagStart + r;
     266                                        t.openTag(element, toolbar);
     267                                        cursorPos = startPos + t.tagStart.length;
    500268                                } else {
    501                                         t.Canvas.value = t.Canvas.value.substring(0, startPos)
    502                                                       + t.Buttons[i].tagEnd
    503                                                       + t.Canvas.value.substring(endPos, t.Canvas.value.length);
    504                                         t.edRemoveTag(i);
    505                                         cursorPos = startPos + t.Buttons[i].tagEnd.length;
     269                                        canvas.value = l + t.tagEnd + r;
     270                                        cursorPos = startPos + t.tagEnd.length;
     271                                        t.closeTag(element, toolbar);
    506272                                }
    507273                        }
    508                         t.Canvas.focus();
    509                         t.Canvas.selectionStart = cursorPos;
    510                         t.Canvas.selectionEnd = cursorPos;
    511                         t.Canvas.scrollTop = scrollTop;
    512                 } else {
    513                         if ( ! t.edCheckOpenTags(i) || t.Buttons[i].tagEnd == '' ) {
    514                                 t.Canvas.value += Buttons[i].tagStart;
    515                                 t.edAddTag(i);
     274
     275                        canvas.focus();
     276                        canvas.selectionStart = cursorPos;
     277                        canvas.selectionEnd = cursorPos;
     278                        canvas.scrollTop = scrollTop;
     279                }
     280                // other browsers
     281                else {
     282                        if (t.isOpen || t.tagEnd === '') {
     283                                canvas.value += t.tagStart;
     284                                t.openTag(element, toolbar);
    516285                        } else {
    517                                 t.Canvas.value += Buttons[i].tagEnd;
    518                                 t.edRemoveTag(i);
     286                                canvas.value += t.tagEnd;
     287                                t.closeTag(element, toolbar);
    519288                        }
    520                         t.Canvas.focus();
     289                        canvas.focus();
    521290                }
    522291        };
    523 
    524         this.edInsertLink = function(i, defaultValue) {
    525                 if ( ! defaultValue )
     292       
     293        // the spell button
     294        qt.SpellButton = function() {
     295                qt.Button.call(this, 'spell', quicktagsL10n.lookup, '');
     296        };
     297        qt.SpellButton.prototype = new qt.Button();
     298        qt.SpellButton.prototype.callback = function(element, canvas, toolbar) {
     299                var word = '', sel, startPos, endPos;
     300               
     301                if (document.selection) {
     302                        canvas.focus();
     303                        sel = document.selection.createRange();
     304                        if (sel.text.length > 0) {
     305                                word = sel.text;
     306                        }
     307                }
     308                else if (canvas.selectionStart || canvas.selectionStart == '0') {
     309                        startPos = canvas.selectionStart;
     310                        endPos = canvas.selectionEnd;
     311                        if (startPos != endPos) {
     312                                word = canvas.value.substring(startPos, endPos);
     313                        }
     314                }
     315               
     316                if (word === '') {
     317                        word = prompt(quicktagsL10n.wordLookup, '');
     318                }
     319               
     320                if (word !== null && /^\w[\w ]*$/.test(word)) {
     321                        window.open('http://www.answers.com/' + encodeURIComponent(word));
     322                }
     323        };
     324       
     325        // the close button
     326        qt.CloseButton = function() {
     327                qt.Button.call(this, 'close', quicktagsL10n.closeAllOpenTags, '');
     328        };
     329        qt.CloseButton.prototype = new qt.Button();
     330        qt.CloseButton.prototype.callback = function(e, c, tb) {
     331                var button, i, element;
     332                if (tb._openTags) {
     333                        while (tb._openTags.length > 0) {
     334                                button = tb.getButton(tb._openTags[tb._openTags.length - 1]);
     335                                element = document.getElementById(tb.name + '_' + button.id);
     336                                button.callback.call(button, element, c, tb);
     337                        }
     338                }
     339        };
     340        qt.prototype.closeAllTags = function() {
     341                var btn = this.getButton('close');
     342                btn.callback.call(btn, '', this.canvas, this.toolbar);
     343        };
     344       
     345        // the link button
     346        qt.LinkButton = function() {
     347                qt.TagButton.call(this, 'link', 'link', '', '</a>', 'a');
     348        };
     349        qt.LinkButton.prototype = new qt.TagButton();
     350        qt.LinkButton.prototype.callback = function(e, c, tb, defaultValue) {
     351                var URL, t = this;
     352               
     353                if (! defaultValue) {
    526354                        defaultValue = 'http://';
    527 
    528                 if ( ! t.edCheckOpenTags(i) ) {
    529                         var URL = prompt(quicktagsL10n.enterURL, defaultValue);
    530                         if ( URL ) {
    531                                 t.Buttons[i].tagStart = '<a href="' + URL + '">';
    532                                 t.edInsertTag(i);
     355                }
     356               
     357                if (! t.isOpen) {
     358                        URL = prompt(quicktagsL10n.enterURL, defaultValue);console.log(URL);
     359                        if (URL) {
     360                                t.tagStart = '<a href="' + URL + '">';
     361                                qt.TagButton.prototype.callback.call(t, e, c, tb);
    533362                        }
    534363                } else {
    535                         t.edInsertTag(i);
     364                        qt.TagButton.prototype.callback.call(t, e, c, tb);
    536365                }
    537366        };
    538 
    539         this.edInsertImage = function() {
    540                 var myValue = prompt(quicktagsL10n.enterImageURL, 'http://');
    541                 if ( myValue ) {
    542                         myValue = '<img src="'
    543                                         + myValue
    544                                         + '" alt="' + prompt(quicktagsL10n.enterImageDescription, '')
    545                                         + '" />';
    546                         edInsertContent(t.Canvas, myValue);
     367       
     368        // the img button
     369        qt.ImgButton = function() {
     370                qt.TagButton.call(this, 'img', 'img', '', '', 'm', -1);
     371        };
     372        qt.ImgButton.prototype = new qt.TagButton();
     373        qt.ImgButton.prototype.callback = function(e, c, tb, defaultValue) {
     374                if (! defaultValue) {
     375                        defaultValue = 'http://';
     376                }
     377                var src = prompt(quicktagsL10n.enterImageURL, defaultValue), alt;
     378                if (src) {
     379                        alt = prompt(quicktagsL10n.enterImageDescription, '');
     380                        this.tagStart = '<img src="' + src + '" alt="' + alt + '" />';
     381                        qt.TagButton.prototype.callback.call(this, e, c, tb);
    547382                }
    548383        };
    549 
    550         t.Buttons[t.Buttons.length] = new edButton(name+'_strong','b','<strong>','</strong>','b');
    551         t.Buttons[t.Buttons.length] = new edButton(name+'_em','i','<em>','</em>','i');
    552         t.Buttons[t.Buttons.length] = new edButton(name+'_link','link','','</a>','a'); // special case
    553         t.Buttons[t.Buttons.length] = new edButton(name+'_block','b-quote','\n\n<blockquote>','</blockquote>\n\n','q');
    554         t.Buttons[t.Buttons.length] = new edButton(name+'_del','del','<del datetime="' + datetime + '">','</del>','d');
    555         t.Buttons[t.Buttons.length] = new edButton(name+'_ins','ins','<ins datetime="' + datetime + '">','</ins>','s');
    556         t.Buttons[t.Buttons.length] = new edButton(name+'_img','img','','','m',-1); // special case
    557         t.Buttons[t.Buttons.length] = new edButton(name+'_ul','ul','<ul>\n','</ul>\n\n','u');
    558         t.Buttons[t.Buttons.length] = new edButton(name+'_ol','ol','<ol>\n','</ol>\n\n','o');
    559         t.Buttons[t.Buttons.length] = new edButton(name+'_li','li','\t<li>','</li>\n','l');
    560         t.Buttons[t.Buttons.length] = new edButton(name+'_code','code','<code>','</code>','c');
    561         t.Buttons[t.Buttons.length] = new edButton(name+'_more','more','<!--more-->','','t',-1);
    562 //      t.Buttons[t.Buttons.length] = new edButton(name+'_next','page','<!--nextpage-->','','p',-1);
    563 
    564         tb = document.createElement('div');
    565         tb.id = name+'_qtags';
    566 
    567         html = '<div id="'+name+'_toolbar">';
    568         for (i = 0; i < t.Buttons.length; i++)
    569                 html += t.edShowButton(t.Buttons[i], i);
    570 
    571         html += '<input type="button" id="'+name+'_ed_spell" class="ed_button" onclick="edSpell('+name+'.Canvas);" title="' + quicktagsL10n.dictionaryLookup + '" value="' + quicktagsL10n.lookup + '" />';
    572         html += '<input type="button" id="'+name+'_ed_close" class="ed_button" onclick="'+name+'.edCloseAllTags();" title="' + quicktagsL10n.closeAllOpenTags + '" value="' + quicktagsL10n.closeTags + '" /></div>';
    573 
    574         tb.innerHTML = html;
    575         cont.parentNode.insertBefore(tb, cont);
    576 
    577 };
     384})();
     385 No newline at end of file