Revision: 8932
http://languagetool.svn.sourceforge.net/languagetool/?rev=8932&view=rev
Author: dnaber
Date: 2013-01-09 21:00:49 +0000 (Wed, 09 Jan 2013)
Log Message:
-----------
online check: change the way we check the text: ieterate over all text and
collect it, then add spans with error information, then set that whole text at
once
Modified Paths:
--------------
trunk/website/www/online-check/tiny_mce/plugins/atd-tinymce/editor_plugin.js
trunk/website/www/online-check/tiny_mce/plugins/atd-tinymce/src/atd.core.js
trunk/website/www/online-check/tiny_mce/plugins/atd-tinymce/src/editor_plugin.js
Modified:
trunk/website/www/online-check/tiny_mce/plugins/atd-tinymce/editor_plugin.js
===================================================================
---
trunk/website/www/online-check/tiny_mce/plugins/atd-tinymce/editor_plugin.js
2013-01-09 20:53:17 UTC (rev 8931)
+++
trunk/website/www/online-check/tiny_mce/plugins/atd-tinymce/editor_plugin.js
2013-01-09 21:00:49 UTC (rev 8932)
@@ -21,6 +21,14 @@
/* Localized strings */
this.i18n = {};
+
+ /* We have to mis-use an existing valid HTML attribute to get our meta
information
+ * about errors in the text:
+ */
+ this.surrogateAttribute = "onkeypress";
+ this.surrogateAttributeDelimiter = "---#---";
+
+ this.newText = "";
};
/*
@@ -124,13 +132,13 @@
suggestion["suggestions"] = suggestionsStr;
}
var context = errors[i].getAttribute("context");
- var errorOffset = errors[i].getAttribute("offset");
- var errorLength = errors[i].getAttribute("errorlength");
+ var errorOffset = parseInt(errors[i].getAttribute("offset"));
+ var errorLength = parseInt(errors[i].getAttribute("errorlength"));
var startInContext = errors[i].getAttribute("contextoffset");
var errorString = context.substr(startInContext, errorLength);
var errorContext = "";
- var replaceString = errorString.replace(/\s+/, this._getSeparators());
+ var replaceString = errorString.replace(/\s+/, this._getSeparators());
// TODO: delete???
replaceString = RegExp.escape(replaceString);
suggestion["matcher"] = new RegExp('^' + replaceString + '$');
suggestion["string"] = errorString;
@@ -168,117 +176,74 @@
AtDCore.prototype.findSuggestion = function(element) {
var text = element.innerHTML;
+ var metaInfo = element.getAttribute(this.surrogateAttribute);
+ var metaInfoElements = metaInfo.split(this.surrogateAttributeDelimiter)
var errorDescription = {};
- errorDescription["description"] = element.getAttribute("desc");
- var suggestions = element.getAttribute("suggestions");
+ errorDescription["description"] = metaInfoElements[0];
+ var suggestions = metaInfoElements[1];
if (suggestions) {
errorDescription["suggestions"] = suggestions.split("#");
} else {
errorDescription["suggestions"] = "";
}
- var infoUrl = element.getAttribute("url");
- if (infoUrl) {
- errorDescription["moreinfo"] = infoUrl;
+ if (metaInfoElements.length == 3) {
+ errorDescription["moreinfo"] = metaInfoElements[2];
}
return errorDescription;
};
/*
- * code to manage highlighting of errors
+ * code to manage highlighting of errors
*/
AtDCore.prototype.markMyWords = function(container_nodes) {
- var seps = new RegExp(this._getSeparators());
- var nl = new Array();
- var ecount = 0; /* track number of highlighted errors */
- var parent = this;
-
- /* Collect all text nodes */
- /* Our goal--ignore nodes that are already wrapped */
-
- //console.log("========== MARK My WORDS =================");
-
- this._walk(container_nodes, function(n) {
- if (n.nodeType == 3 && !parent.isMarkedNode(n))
- nl.push(n);
- });
-
- /* walk through the relevant nodes */
-
- var iterator;
- var pos = 0;
-
- //var newText = "";
- this.map(nl, function(n) {
- if (n.nodeType == 3) {
- var nodeValue = n.nodeValue;
- //console.log("##------------------------------");
- //console.log("##nodeValue: '" + nodeValue + "' (len: " +
nodeValue.length + ", type: " + n.nodeType + ")");
- var i;
- var cleanNodeValue = "";
- for (i = 0; i < nodeValue.length; i++) {
- if (nodeValue.charCodeAt(i) != 65279) { // cursor has its
own node, ignore it
- cleanNodeValue += nodeValue.charAt(i);
- }
+ this.newText = "";
+ this._walkNodesAndSetText(container_nodes);
+
+ var previousSpanStart = -1;
+ // iterate backwards as we change the text and thus modify positions:
+ for (var suggestionIndex = this.suggestions.length-1; suggestionIndex >=
0; suggestionIndex--) {
+ var suggestion = this.suggestions[suggestionIndex];
+ if (!suggestion.used) {
+ var spanStart = suggestion.offset;
+ var spanEnd = spanStart + suggestion.errorlength;
+ if (previousSpanStart != -1 && spanEnd >= previousSpanStart) {
+ // overlapping errors - these are not supported by our
underline approach,
+ // as we would need overlapping <span>s for that, so skip the
error:
+ continue;
}
- var newString = cleanNodeValue;
- var previousSpanStart = -1;
- // as we modify the string we work backwards so we don't mess with
the positions:
- for (var suggestionIndex = parent.suggestions.length-1;
suggestionIndex >= 0; suggestionIndex--) {
- var suggestion = parent.suggestions[suggestionIndex];
- if (!suggestion.used) {
- var currentNodeStart = pos;
- var currentNodeEnd = pos + nodeValue.length;
- var suggestionStart = parseInt(suggestion.offset);
- var suggestionEnd = suggestionStart +
parseInt(suggestion.errorlength);
- if (suggestionStart >= currentNodeStart && suggestionEnd
<= currentNodeEnd) {
- var spanStart = suggestionStart - currentNodeStart;
- //console.log("pos: " + pos + ", spanStart: " +
suggestionStart + " - " + currentNodeStart + " + 1 => " + spanStart);
- var spanEnd = suggestionEnd - currentNodeStart;
- if (previousSpanStart != -1 && spanEnd >=
previousSpanStart) {
- // overlapping errors - these are not supported by
our underline approach,
- // as we would need overlapping <span>s for that,
so skip the error:
- continue;
- }
- previousSpanStart = spanStart;
- var urlAttribute = "";
- if (suggestion.moreinfo) {
- urlAttribute = ' url="' + suggestion.moreinfo +
'"';
- }
-
- var ruleId = suggestion.ruleid;
- var cssName;
- if (ruleId.indexOf("SPELLER_RULE") >= 0 ||
ruleId.indexOf("MORFOLOGIK_RULE") == 0 || ruleId == "HUNSPELL_NO_SUGGEST_RULE"
|| ruleId == "HUNSPELL_RULE") {
- cssName = "hiddenSpellError";
- }
- else {
- cssName = "hiddenGrammarError";
- }
- newString = newString.substring(0, spanStart)
- + '<span class="' + cssName + '" desc="' +
suggestion.description
- + '" suggestions="' + suggestion.suggestions +
'"'
- + urlAttribute
- + '>'
- + newString.substring(spanStart, spanEnd)
- + '</span>'
- + newString.substring(spanEnd);
- suggestion.used = true;
- }
- }
+ previousSpanStart = spanStart;
+
+ var ruleId = suggestion.ruleid;
+ var cssName;
+ if (ruleId.indexOf("SPELLER_RULE") >= 0 ||
ruleId.indexOf("MORFOLOGIK_RULE") == 0 || ruleId == "HUNSPELL_NO_SUGGEST_RULE"
|| ruleId == "HUNSPELL_RULE") {
+ cssName = "hiddenSpellError";
}
- //newText += newString;
- var newNode = parent.create(newString, false);
- //console.log("##newString: '" + newString + "'");
- parent.replaceWith(n, newNode);
- pos += cleanNodeValue.length;
- } else {
- //console.log("##IGNORED nodeValue: '" + nodeValue + "' (len: " +
nodeValue.length + ")");
+ else {
+ cssName = "hiddenGrammarError";
+ }
+ // TODO: escape metaInfo!?
+ var metaInfo = suggestion.description +
this.surrogateAttributeDelimiter + suggestion.suggestions;
+ if (suggestion.moreinfo) {
+ metaInfo += this.surrogateAttributeDelimiter +
suggestion.moreinfo;
+ }
+ this.newText = this.newText.substring(0, spanStart)
+ + '<span ' + this.surrogateAttribute + '="' + metaInfo +
'" class="' + cssName + '">'
+ + this.newText.substring(spanStart, spanEnd)
+ + '</span>'
+ + this.newText.substring(spanEnd);
+ suggestion.used = true;
}
- });
+ }
- //tinyMCE.activeEditor.setContent('<span>' + newText + '</span>');
- //console.log("========>"+newText);
-
- return ecount;
+ tinyMCE.activeEditor.setContent(this.newText);
+
+ //
+ // TODO??:
+ // 1. "ignore all" doesn't work
+ // 2. text with markup (even bold) messes up everything
+ // 3. cursor position gets lost on check
+ // fixed:. current cursor position is ignored when incorrect (it has its
own node)
+ //
};
AtDCore.prototype._walk = function(elements, f) {
@@ -287,8 +252,23 @@
f.call(f, elements[i]);
this._walk(this.contents(elements[i]), f);
}
-};
+};
+AtDCore.prototype._walkNodesAndSetText = function(elements) {
+ var i;
+ for (i = 0; i < elements.length; i++) {
+ var node = elements[i];
+ if (node.nodeType == 1) {
+ this._walkNodesAndSetText(this.contents(node));
+ } else if (node.nodeType == 3) {
+ if (node.nodeValue.length == 1 && node.nodeValue.charCodeAt(0) ==
65279) { // cursor has its own node, ignore it
+ continue;
+ }
+ this.newText += node.nodeValue;
+ }
+ }
+};
+
AtDCore.prototype.removeWords = function(node, w) {
var count = 0;
var parent = this;
@@ -467,6 +447,10 @@
/* add a command to request a document check and process the results.
*/
editor.addCommand('mceWritingImprovementTool', function(languageCode)
{
+
+ if (plugin.menuVisible) {
+ plugin._menu.hideMenu();
+ }
/* checks if a global var for click stats exists and increments it
if it does... */
if (typeof AtD_proofread_click_count != "undefined")
@@ -526,7 +510,9 @@
editor.onClick.add(plugin._showMenu, plugin);
/* we're showing some sort of menu, no idea what */
- editor.onContextMenu.add(plugin._showMenu, plugin);
+ //editor.onContextMenu.add(plugin._showMenu, plugin);
+ // without this, the context menu opens but nothing in it can be
selected:
+ editor.onContextMenu.add(plugin._doNotShowMenu, plugin);
/* strip out the markup before the contents is serialized (and do it
on a copy of the markup so we don't affect the user experience) */
editor.onPreProcess.add(function(sender, object)
@@ -590,12 +576,16 @@
var ed = this.editor;
var se = ed.selection, b = se.getBookmark();
- var ecount =
ed.core.markMyWords(ed.core.contents(this.editor.getBody()));
+ ed.core.markMyWords(ed.core.contents(this.editor.getBody()));
se.moveToBookmark(b);
- return ecount;
},
+ _doNotShowMenu : function(ed, e)
+ {
+ return tinymce.dom.Event.cancel(e);
+ },
+
_showMenu : function(ed, e)
{
var t = this, ed = t.editor, m = t._menu, p1, dom = ed.dom, vp =
dom.getViewPort(ed.getWin());
@@ -787,7 +777,7 @@
_done : function()
{
var plugin = this;
- plugin._removeWords();
+ //plugin._removeWords();
if (plugin._menu)
{
Modified:
trunk/website/www/online-check/tiny_mce/plugins/atd-tinymce/src/atd.core.js
===================================================================
--- trunk/website/www/online-check/tiny_mce/plugins/atd-tinymce/src/atd.core.js
2013-01-09 20:53:17 UTC (rev 8931)
+++ trunk/website/www/online-check/tiny_mce/plugins/atd-tinymce/src/atd.core.js
2013-01-09 21:00:49 UTC (rev 8932)
@@ -21,6 +21,14 @@
/* Localized strings */
this.i18n = {};
+
+ /* We have to mis-use an existing valid HTML attribute to get our meta
information
+ * about errors in the text:
+ */
+ this.surrogateAttribute = "onkeypress";
+ this.surrogateAttributeDelimiter = "---#---";
+
+ this.newText = "";
};
/*
@@ -124,13 +132,13 @@
suggestion["suggestions"] = suggestionsStr;
}
var context = errors[i].getAttribute("context");
- var errorOffset = errors[i].getAttribute("offset");
- var errorLength = errors[i].getAttribute("errorlength");
+ var errorOffset = parseInt(errors[i].getAttribute("offset"));
+ var errorLength = parseInt(errors[i].getAttribute("errorlength"));
var startInContext = errors[i].getAttribute("contextoffset");
var errorString = context.substr(startInContext, errorLength);
var errorContext = "";
- var replaceString = errorString.replace(/\s+/, this._getSeparators());
+ var replaceString = errorString.replace(/\s+/, this._getSeparators());
// TODO: delete???
replaceString = RegExp.escape(replaceString);
suggestion["matcher"] = new RegExp('^' + replaceString + '$');
suggestion["string"] = errorString;
@@ -168,117 +176,74 @@
AtDCore.prototype.findSuggestion = function(element) {
var text = element.innerHTML;
+ var metaInfo = element.getAttribute(this.surrogateAttribute);
+ var metaInfoElements = metaInfo.split(this.surrogateAttributeDelimiter)
var errorDescription = {};
- errorDescription["description"] = element.getAttribute("desc");
- var suggestions = element.getAttribute("suggestions");
+ errorDescription["description"] = metaInfoElements[0];
+ var suggestions = metaInfoElements[1];
if (suggestions) {
errorDescription["suggestions"] = suggestions.split("#");
} else {
errorDescription["suggestions"] = "";
}
- var infoUrl = element.getAttribute("url");
- if (infoUrl) {
- errorDescription["moreinfo"] = infoUrl;
+ if (metaInfoElements.length == 3) {
+ errorDescription["moreinfo"] = metaInfoElements[2];
}
return errorDescription;
};
/*
- * code to manage highlighting of errors
+ * code to manage highlighting of errors
*/
AtDCore.prototype.markMyWords = function(container_nodes) {
- var seps = new RegExp(this._getSeparators());
- var nl = new Array();
- var ecount = 0; /* track number of highlighted errors */
- var parent = this;
-
- /* Collect all text nodes */
- /* Our goal--ignore nodes that are already wrapped */
-
- //console.log("========== MARK My WORDS =================");
-
- this._walk(container_nodes, function(n) {
- if (n.nodeType == 3 && !parent.isMarkedNode(n))
- nl.push(n);
- });
-
- /* walk through the relevant nodes */
-
- var iterator;
- var pos = 0;
-
- //var newText = "";
- this.map(nl, function(n) {
- if (n.nodeType == 3) {
- var nodeValue = n.nodeValue;
- //console.log("##------------------------------");
- //console.log("##nodeValue: '" + nodeValue + "' (len: " +
nodeValue.length + ", type: " + n.nodeType + ")");
- var i;
- var cleanNodeValue = "";
- for (i = 0; i < nodeValue.length; i++) {
- if (nodeValue.charCodeAt(i) != 65279) { // cursor has its
own node, ignore it
- cleanNodeValue += nodeValue.charAt(i);
- }
+ this.newText = "";
+ this._walkNodesAndSetText(container_nodes);
+
+ var previousSpanStart = -1;
+ // iterate backwards as we change the text and thus modify positions:
+ for (var suggestionIndex = this.suggestions.length-1; suggestionIndex >=
0; suggestionIndex--) {
+ var suggestion = this.suggestions[suggestionIndex];
+ if (!suggestion.used) {
+ var spanStart = suggestion.offset;
+ var spanEnd = spanStart + suggestion.errorlength;
+ if (previousSpanStart != -1 && spanEnd >= previousSpanStart) {
+ // overlapping errors - these are not supported by our
underline approach,
+ // as we would need overlapping <span>s for that, so skip the
error:
+ continue;
}
- var newString = cleanNodeValue;
- var previousSpanStart = -1;
- // as we modify the string we work backwards so we don't mess with
the positions:
- for (var suggestionIndex = parent.suggestions.length-1;
suggestionIndex >= 0; suggestionIndex--) {
- var suggestion = parent.suggestions[suggestionIndex];
- if (!suggestion.used) {
- var currentNodeStart = pos;
- var currentNodeEnd = pos + nodeValue.length;
- var suggestionStart = parseInt(suggestion.offset);
- var suggestionEnd = suggestionStart +
parseInt(suggestion.errorlength);
- if (suggestionStart >= currentNodeStart && suggestionEnd
<= currentNodeEnd) {
- var spanStart = suggestionStart - currentNodeStart;
- //console.log("pos: " + pos + ", spanStart: " +
suggestionStart + " - " + currentNodeStart + " + 1 => " + spanStart);
- var spanEnd = suggestionEnd - currentNodeStart;
- if (previousSpanStart != -1 && spanEnd >=
previousSpanStart) {
- // overlapping errors - these are not supported by
our underline approach,
- // as we would need overlapping <span>s for that,
so skip the error:
- continue;
- }
- previousSpanStart = spanStart;
- var urlAttribute = "";
- if (suggestion.moreinfo) {
- urlAttribute = ' url="' + suggestion.moreinfo +
'"';
- }
-
- var ruleId = suggestion.ruleid;
- var cssName;
- if (ruleId.indexOf("SPELLER_RULE") >= 0 ||
ruleId.indexOf("MORFOLOGIK_RULE") == 0 || ruleId == "HUNSPELL_NO_SUGGEST_RULE"
|| ruleId == "HUNSPELL_RULE") {
- cssName = "hiddenSpellError";
- }
- else {
- cssName = "hiddenGrammarError";
- }
- newString = newString.substring(0, spanStart)
- + '<span class="' + cssName + '" desc="' +
suggestion.description
- + '" suggestions="' + suggestion.suggestions +
'"'
- + urlAttribute
- + '>'
- + newString.substring(spanStart, spanEnd)
- + '</span>'
- + newString.substring(spanEnd);
- suggestion.used = true;
- }
- }
+ previousSpanStart = spanStart;
+
+ var ruleId = suggestion.ruleid;
+ var cssName;
+ if (ruleId.indexOf("SPELLER_RULE") >= 0 ||
ruleId.indexOf("MORFOLOGIK_RULE") == 0 || ruleId == "HUNSPELL_NO_SUGGEST_RULE"
|| ruleId == "HUNSPELL_RULE") {
+ cssName = "hiddenSpellError";
}
- //newText += newString;
- var newNode = parent.create(newString, false);
- //console.log("##newString: '" + newString + "'");
- parent.replaceWith(n, newNode);
- pos += cleanNodeValue.length;
- } else {
- //console.log("##IGNORED nodeValue: '" + nodeValue + "' (len: " +
nodeValue.length + ")");
+ else {
+ cssName = "hiddenGrammarError";
+ }
+ // TODO: escape metaInfo!?
+ var metaInfo = suggestion.description +
this.surrogateAttributeDelimiter + suggestion.suggestions;
+ if (suggestion.moreinfo) {
+ metaInfo += this.surrogateAttributeDelimiter +
suggestion.moreinfo;
+ }
+ this.newText = this.newText.substring(0, spanStart)
+ + '<span ' + this.surrogateAttribute + '="' + metaInfo +
'" class="' + cssName + '">'
+ + this.newText.substring(spanStart, spanEnd)
+ + '</span>'
+ + this.newText.substring(spanEnd);
+ suggestion.used = true;
}
- });
+ }
- //tinyMCE.activeEditor.setContent('<span>' + newText + '</span>');
- //console.log("========>"+newText);
-
- return ecount;
+ tinyMCE.activeEditor.setContent(this.newText);
+
+ //
+ // TODO??:
+ // 1. "ignore all" doesn't work
+ // 2. text with markup (even bold) messes up everything
+ // 3. cursor position gets lost on check
+ // fixed:. current cursor position is ignored when incorrect (it has its
own node)
+ //
};
AtDCore.prototype._walk = function(elements, f) {
@@ -287,8 +252,23 @@
f.call(f, elements[i]);
this._walk(this.contents(elements[i]), f);
}
-};
+};
+AtDCore.prototype._walkNodesAndSetText = function(elements) {
+ var i;
+ for (i = 0; i < elements.length; i++) {
+ var node = elements[i];
+ if (node.nodeType == 1) {
+ this._walkNodesAndSetText(this.contents(node));
+ } else if (node.nodeType == 3) {
+ if (node.nodeValue.length == 1 && node.nodeValue.charCodeAt(0) ==
65279) { // cursor has its own node, ignore it
+ continue;
+ }
+ this.newText += node.nodeValue;
+ }
+ }
+};
+
AtDCore.prototype.removeWords = function(node, w) {
var count = 0;
var parent = this;
Modified:
trunk/website/www/online-check/tiny_mce/plugins/atd-tinymce/src/editor_plugin.js
===================================================================
---
trunk/website/www/online-check/tiny_mce/plugins/atd-tinymce/src/editor_plugin.js
2013-01-09 20:53:17 UTC (rev 8931)
+++
trunk/website/www/online-check/tiny_mce/plugins/atd-tinymce/src/editor_plugin.js
2013-01-09 21:00:49 UTC (rev 8932)
@@ -119,6 +119,10 @@
/* add a command to request a document check and process the results.
*/
editor.addCommand('mceWritingImprovementTool', function(languageCode)
{
+
+ if (plugin.menuVisible) {
+ plugin._menu.hideMenu();
+ }
/* checks if a global var for click stats exists and increments it
if it does... */
if (typeof AtD_proofread_click_count != "undefined")
@@ -178,7 +182,9 @@
editor.onClick.add(plugin._showMenu, plugin);
/* we're showing some sort of menu, no idea what */
- editor.onContextMenu.add(plugin._showMenu, plugin);
+ //editor.onContextMenu.add(plugin._showMenu, plugin);
+ // without this, the context menu opens but nothing in it can be
selected:
+ editor.onContextMenu.add(plugin._doNotShowMenu, plugin);
/* strip out the markup before the contents is serialized (and do it
on a copy of the markup so we don't affect the user experience) */
editor.onPreProcess.add(function(sender, object)
@@ -242,12 +248,16 @@
var ed = this.editor;
var se = ed.selection, b = se.getBookmark();
- var ecount =
ed.core.markMyWords(ed.core.contents(this.editor.getBody()));
+ ed.core.markMyWords(ed.core.contents(this.editor.getBody()));
se.moveToBookmark(b);
- return ecount;
},
+ _doNotShowMenu : function(ed, e)
+ {
+ return tinymce.dom.Event.cancel(e);
+ },
+
_showMenu : function(ed, e)
{
var t = this, ed = t.editor, m = t._menu, p1, dom = ed.dom, vp =
dom.getViewPort(ed.getWin());
@@ -439,7 +449,7 @@
_done : function()
{
var plugin = this;
- plugin._removeWords();
+ //plugin._removeWords();
if (plugin._menu)
{
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
Master Java SE, Java EE, Eclipse, Spring, Hibernate, JavaScript, jQuery
and much more. Keep your Java skills current with LearnJavaNow -
200+ hours of step-by-step video tutorials by Java experts.
SALE $49.99 this month only -- learn more at:
http://p.sf.net/sfu/learnmore_122612
_______________________________________________
Languagetool-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/languagetool-commits