Annotation of kupuMPIWG/common/kupuspellchecker.js, revision 1.1.1.1

1.1       dwinter     1: function KupuSpellChecker(buttonid, scripturl, spanstyle, 
                      2:                             winwidth, winheight, skip_tags) {
                      3:     this.button = document.getElementById(buttonid);
                      4:     this.scripturl = scripturl;
                      5:     this.spanstyle = spanstyle || 'color: red; ' +
                      6:                                     'text-decoration: underline;';
                      7:     this.winwidth = winwidth || '600';
                      8:     this.winheight = winheight || '400';
                      9:     this.skip_tags = skip_tags || ['head', 'script'];
                     10: };
                     11: 
                     12: KupuSpellChecker.prototype = new KupuTool;
                     13: 
                     14: KupuSpellChecker.prototype.initialize = function(editor) {
                     15:     this.editor = editor;
                     16:     addEventHandler(this.button, 'click', this.check, this);
                     17: };
                     18: 
                     19: KupuSpellChecker.prototype.check = function() {
                     20:     var request = new XMLHttpRequest();
                     21:     request.open('POST', this.scripturl, true);
                     22:     request.setRequestHeader('Content-Type', 
                     23:                                 'application/x-www-form-urlencoded');
                     24:     request.onreadystatechange = new ContextFixer(
                     25:                                     this.stateChangeHandler,
                     26:                                     this,
                     27:                                     request).execute;
                     28:     var result = this.getCurrentContents();
                     29:     result = escape(result.strip().replace('\n', ' ').reduceWhitespace());
                     30:     request.send('text=' + result);
                     31: };
                     32: 
                     33: KupuSpellChecker.prototype.stateChangeHandler = function(request) {
                     34:     if (request.readyState == 4) {
                     35:         if (request.status == '200') {
                     36:             var result = request.responseXML;
                     37:             result = this.xmlToMapping(result);
                     38:             if (!result) {
                     39:                 alert(_('There were no errors.'));
                     40:             } else {
                     41:                 this.displayUnrecognized(result);
                     42:             };
                     43:         } else {
                     44:             alert(_('Error loading data, status ${status}',
                     45:                     {'status': request.status}));
                     46:         };
                     47:     };
                     48: };
                     49: 
                     50: KupuSpellChecker.prototype.getCurrentContents = function() {
                     51:     var doc = this.editor.getInnerDocument().documentElement;
                     52:     var iterator = new NodeIterator(doc);
                     53:     var bits = [];
                     54:     while (true) {
                     55:         var node = iterator.next();
                     56:         if (!node) {
                     57:             break;
                     58:         };
                     59:         while (this.skip_tags.contains(node.nodeName.toLowerCase())) {
                     60:             node = node.nextSibling;
                     61:             iterator.setCurrent(node);
                     62:         };
                     63:         if (node.nodeType == 3) {
                     64:             bits.push(node.nodeValue);
                     65:         };
                     66:     };
                     67:     return bits.join(' ');
                     68: };
                     69: 
                     70: KupuSpellChecker.prototype.displayUnrecognized = function(mapping) {
                     71:     // copy the current editable document into a new window
                     72:     var doc = this.editor.getInnerDocument();
                     73:     var docel = doc.documentElement;
                     74:     var win = window.open('kupublank.html', 'spellchecker', 
                     75:                             'width=' + this.winwidth + ',' +
                     76:                             'height=' + this.winheight + ',toolbar=no,' +
                     77:                             'menubar=no,scrollbars=yes,status=yes');
                     78:     if (!win) {
                     79:         alert(
                     80:             _('This feature requires pop-ups to be enabled on your browser!'));
                     81:         return;
                     82:     };
                     83:     var html = docel.innerHTML;
                     84:     // when Moz tries to set the content-type, for some reason leaving this
                     85:     // in breaks the feature(?!?)
                     86:     html = html.replace(/<meta[^>]*http-equiv="[Cc]ontent-[Tt]ype"[^>]*>/gm, 
                     87:                         '');
                     88:     win.document.write('<html>' + html + '</html>');
                     89:     win.deentitize = function(str) {return str.deentitize()};
                     90:     win.document.close();
                     91:     if (!win.document.getElementsByTagName('body').length) {
                     92:         addEventHandler(win, 'load', this.continueDisplay, this, win, mapping);
                     93:     } else {
                     94:         this.continueDisplay(win, mapping);
                     95:     };
                     96: };
                     97: 
                     98: KupuSpellChecker.prototype.continueDisplay = function(win, mapping) {
                     99:     /* walk through all elements of the body, colouring the text nodes */
                    100:     // start it all with a timeout to make Mozilla render the content first
                    101:     timer_instance.registerFunction(this, this.continueDisplayHelper,
                    102:                                     1000, win, mapping);
                    103: };
                    104: 
                    105: KupuSpellChecker.prototype.continueDisplayHelper = function(win, mapping) {
                    106:     var body = win.document.getElementsByTagName('body')[0];
                    107:     body.setAttribute('contentEditable', 'false');
                    108:     var iterator = new NodeIterator(body);
                    109:     var node = iterator.next();
                    110:     timer_instance.registerFunction(this, this.displayHelperNodeLoop,
                    111:                                     10, iterator, node, win, mapping);
                    112: };
                    113: 
                    114: KupuSpellChecker.prototype.displayHelperNodeLoop = function(iterator, node, 
                    115:                                                                 win, mapping) {
                    116:     if (!node) {
                    117:         return;
                    118:     };
                    119:     var next = iterator.next();
                    120:     if (node.nodeType == 3) {
                    121:         if (win.closed) {
                    122:             return;
                    123:         };
                    124:         var span = win.document.createElement('span');
                    125:         var before = node.nodeValue;
                    126:         var after = this.colourText(before, mapping);
                    127:         if (before != after) {
                    128:             span.innerHTML = after;
                    129:             var last = span.lastChild;
                    130:             var parent = node.parentNode;
                    131:             parent.replaceChild(last, node);
                    132:             while (span.hasChildNodes()) {
                    133:                 parent.insertBefore(span.firstChild, last);
                    134:             };
                    135:         };
                    136:     } else if (node.nodeType == 1 && node.nodeName.toLowerCase() == 'a') {
                    137:         var cancelEvent = function(e) {
                    138:             if (e.preventDefault) {
                    139:                 e.preventDefault();
                    140:             } else {
                    141:                 e.returnValue = false;
                    142:             };
                    143:             return false;
                    144:         };
                    145:         addEventHandler(node, 'click', cancelEvent);
                    146:         addEventHandler(node, 'mousedown', cancelEvent);
                    147:         addEventHandler(node, 'mouseup', cancelEvent);
                    148:     };
                    149:     // using a timeout here makes Moz render the coloring while it's busy, and
                    150:     // will make it stop popping up 'do you want to continue' prompts...
                    151:     timer_instance.registerFunction(this, this.displayHelperNodeLoop,
                    152:                                     10, iterator, next, win, mapping);
                    153: };
                    154: 
                    155: KupuSpellChecker.prototype.colourText = function(text, mapping) {
                    156:     var currtext = text;
                    157:     var newtext = '';
                    158:     for (var word in mapping) {
                    159:         var replacements = mapping[word];
                    160:         replacements = replacements.entitize();
                    161:         replacements = replacements.replace(/\'/g, "&apos;");
                    162:         var reg = new RegExp('^(.*\\\W)?(' + word + ')(\\\W.*)?$', 'mg');
                    163:         while (true) {
                    164:             var match = reg.exec(currtext);
                    165:             if (!match) {
                    166:                 newtext += currtext;
                    167:                 currtext = newtext;
                    168:                 newtext = '';
                    169:                 break;
                    170:             };
                    171:             var m = (match[1] || '') + match[2];
                    172:             newtext += currtext.substr(0, currtext.indexOf(m));
                    173:             newtext += (match[1] || '') +
                    174:                         '<span style="' + this.spanstyle + '" ' +
                    175:                         'onclick="alert(deentitize(\'' + 
                    176:                         replacements + '\'));" ' +
                    177:                         'title="' + replacements + '">' +
                    178:                         match[2] +
                    179:                         '</span>';
                    180:             currtext = currtext.substr(currtext.indexOf(m) + m.length);
                    181:         };
                    182:     };
                    183:     return currtext;
                    184: };
                    185: 
                    186: KupuSpellChecker.prototype.xmlToMapping = function(docnode) {
                    187:     var docel = docnode.documentElement;
                    188:     var result = {};
                    189:     var incorrect = docel.getElementsByTagName('incorrect');
                    190:     for (var i=0; i < incorrect.length; i++) {
                    191:         var word = incorrect[i].firstChild.firstChild.nodeValue;
                    192:         var replacements = '';
                    193:         if (incorrect[i].lastChild.hasChildNodes()) {
                    194:             replacements = incorrect[i].lastChild.firstChild.nodeValue;
                    195:         };
                    196:         result[word] = replacements;
                    197:     };
                    198:     var attrs = [];
                    199:     return result;
                    200: };

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>