[ Index ] |
|
Code source de Kupu-1.3.5 |
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, "'"); 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 };
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Sun Feb 25 15:30:41 2007 | par Balluche grâce à PHPXref 0.7 |