corinthia-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pmke...@apache.org
Subject [40/92] [abbrv] [partial] incubator-corinthia git commit: Add editing code from UX Write
Date Wed, 17 Dec 2014 13:28:50 GMT
http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/src/elementtypes/elements.txt
----------------------------------------------------------------------
diff --git a/Editor/src/elementtypes/elements.txt b/Editor/src/elementtypes/elements.txt
new file mode 100644
index 0000000..bd23f64
--- /dev/null
+++ b/Editor/src/elementtypes/elements.txt
@@ -0,0 +1,113 @@
+#document
+#text
+#comment
+a
+abbr
+address
+area
+article
+aside
+audio
+b
+base
+bdi
+bdo
+blockquote
+body
+br
+button
+canvas
+caption
+cite
+code
+col
+colgroup
+command
+data
+datalist
+dd
+del
+details
+dfn
+dialog
+div
+dl
+dt
+em
+embed
+fieldset
+figcaption
+figure
+footer
+form
+h1
+h2
+h3
+h4
+h5
+h6
+head
+header
+hgroup
+hr
+html
+i
+iframe
+img
+input
+ins
+kbd
+keygen
+label
+legend
+li
+link
+map
+mark
+menu
+meta
+meter
+nav
+noscript
+object
+ol
+optgroup
+option
+output
+p
+param
+pre
+progress
+q
+rp
+rt
+ruby
+s
+samp
+script
+section
+select
+small
+source
+span
+strong
+style
+sub
+summary
+sup
+table
+tbody
+td
+textarea
+tfoot
+th
+thead
+time
+title
+tr
+track
+u
+ul
+var
+video
+wbr

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/src/elementtypes/genelementtypes.pl
----------------------------------------------------------------------
diff --git a/Editor/src/elementtypes/genelementtypes.pl b/Editor/src/elementtypes/genelementtypes.pl
new file mode 100755
index 0000000..46416e1
--- /dev/null
+++ b/Editor/src/elementtypes/genelementtypes.pl
@@ -0,0 +1,36 @@
+#!/usr/bin/perl
+
+$filename = $ARGV[0];
+
+#print "filename $filename\n";
+
+@names = ();
+
+open($fh,"<",$filename) or die "Can't open $filename";
+while ($name = <$fh>) {
+  $name =~ s/\n$//;
+  push(@names,$name);
+}
+close($fh);
+
+print("// Automatically generated from $filename\n");
+print("ElementTypes = {\n");
+$nextId = 1;
+for $name (@names) {
+  $upper = uc($name);
+  $lower = lc($name);
+  print("  \"$upper\": $nextId,\n");
+  print("  \"$lower\": $nextId,\n");
+  $nextId++;
+}
+print("};\n");
+print("\n");
+$nextId = 1;
+for $name (@names) {
+  $temp = $name;
+  $temp =~ s/#//;
+  $upper = uc($temp);
+  print("HTML_$upper = $nextId;\n");
+  $nextId++;
+}
+print("HTML_COUNT = $nextId;\n");

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/src/empty.html
----------------------------------------------------------------------
diff --git a/Editor/src/empty.html b/Editor/src/empty.html
new file mode 100644
index 0000000..42682b4
--- /dev/null
+++ b/Editor/src/empty.html
@@ -0,0 +1 @@
+<html><body></body></html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/src/first.js
----------------------------------------------------------------------
diff --git a/Editor/src/first.js b/Editor/src/first.js
new file mode 100644
index 0000000..953ef4b
--- /dev/null
+++ b/Editor/src/first.js
@@ -0,0 +1,42 @@
+// Copyright 2011-2014 UX Productivity Pty Ltd
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// FIXME: The _PREFIX variables below must be replaced with functions that return the
+// appropriate namespace prefix for the document in question (since we can't rely on the
+// values that LibreOffice/MS Word happen to use by default)
+
+var XML_NAMESPACE = "http://www.w3.org/XML/1998/namespace";
+
+// ODF
+
+var OFFICE_NAMESPACE = "urn:oasis:names:tc:opendocument:xmlns:office:1.0";
+var STYLE_NAMESPACE = "urn:oasis:names:tc:opendocument:xmlns:style:1.0";
+var TEXT_NAMESPACE = "urn:oasis:names:tc:opendocument:xmlns:text:1.0";
+var TABLE_NAMESPACE = "urn:oasis:names:tc:opendocument:xmlns:table:1.0";
+var FO_NAMESPACE = "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0";
+var SVG_NAMESPACE = "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0";
+var XLINK_NAMESPACE = "http://www.w3.org/1999/xlink";
+
+var OFFICE_PREFIX = "office:";
+var STYLE_PREFIX = "style:";
+var TEXT_PREFIX = "text:";
+var TABLE_PREFIX = "table:";
+var FO_PREFIX = "fo:";
+var SVG_PREFIX = "svg:";
+var XLINK_PREFIX = "xlink:";
+
+// OOXML
+
+var WORD_NAMESPACE = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
+var WORD_PREFIX = "w:";

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/src/traversal.js
----------------------------------------------------------------------
diff --git a/Editor/src/traversal.js b/Editor/src/traversal.js
new file mode 100644
index 0000000..40227ea
--- /dev/null
+++ b/Editor/src/traversal.js
@@ -0,0 +1,181 @@
+// Copyright 2011-2014 UX Productivity Pty Ltd
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+function prevNode(node)
+{
+    if (node.previousSibling != null) {
+        node = node.previousSibling;
+        while (node.lastChild != null)
+            node = node.lastChild;
+        return node;
+    }
+    else {
+        return node.parentNode;
+    }
+}
+
+function nextNodeAfter(node,entering,exiting)
+{
+    while (node != null) {
+        if (node.nextSibling != null) {
+            if (exiting != null)
+                exiting(node);
+            node = node.nextSibling;
+            if (entering != null)
+                entering(node);
+            break;
+        }
+
+        if (exiting != null)
+            exiting(node);
+        node = node.parentNode;
+    }
+    return node;
+}
+
+function nextNode(node,entering,exiting)
+{
+    if (node.firstChild) {
+        node = node.firstChild;
+        if (entering != null)
+            entering(node);
+        return node;
+    }
+    else {
+        return nextNodeAfter(node,entering,exiting);
+    }
+}
+
+function prevTextNode(node)
+{
+    do {
+        node = prevNode(node);
+    } while ((node != null) && (node.nodeType != Node.TEXT_NODE));
+    return node;
+}
+
+function nextTextNode(node)
+{
+    do {
+        node = nextNode(node);
+    } while ((node != null) && (node.nodeType != Node.TEXT_NODE));
+    return node;
+}
+
+function firstChildElement(node)
+{
+    var first = node.firstChild;
+    while ((first != null) && (first.nodeType != Node.ELEMENT_NODE))
+        first = first.nextSibling;
+    return first;
+}
+
+function lastChildElement(node)
+{
+    var last = node.lastChild;
+    while ((last != null) && (last.nodeType != Node.ELEMENT_NODE))
+        last = last.previousSibling;
+    return last;
+}
+
+function firstDescendant(node)
+{
+    while (node.firstChild != null)
+        node = node.firstChild;
+    return node;
+}
+
+function lastDescendant(node)
+{
+    while (node.lastChild != null)
+        node = node.lastChild;
+    return node;
+}
+
+function firstDescendantOfType(node,type)
+{
+    if (node._type == type)
+        return node;
+
+    for (var child = node.firstChild; child != null; child = child.nextSibling) {
+        var result = firstDescendantOfType(child,type);
+        if (result != null)
+            return result;
+    }
+    return null;
+}
+
+function firstChildOfType(node,type)
+{
+    for (var child = node.firstChild; child != null; child = child.nextSibling) {
+        if (child._type == type)
+            return child;
+    }
+    return null;
+}
+
+function getNodeDepth(node)
+{
+    var depth = 0;
+    for (; node != null; node = node.parentNode)
+        depth++;
+    return depth;
+}
+
+function getNodeText(node)
+{
+    var strings = new Array();
+    recurse(node);
+    return strings.join("").replace(/\s+/g," ");
+
+    function recurse(node)
+    {
+        if (node.nodeType == Node.TEXT_NODE)
+            strings.push(node.nodeValue);
+
+        for (var child = node.firstChild; child != null; child = child.nextSibling)
+            recurse(child);
+    }
+}
+
+function isWhitespaceTextNode(node)
+{
+    if (node.nodeType != Node.TEXT_NODE)
+        return false;
+    return isWhitespaceString(node.nodeValue);
+}
+
+function isNonWhitespaceTextNode(node)
+{
+    if (node.nodeType != Node.TEXT_NODE)
+        return false;
+    return !isWhitespaceString(node.nodeValue);
+}
+
+function printTree(node,indent,offset)
+{
+    if (indent == null)
+        indent = "";
+    if (offset == null)
+        offset = "";
+    if ((node.nodeType == Node.ELEMENT_NODE) && node.hasAttribute("class"))
+        debug(indent+offset+nodeString(node)+"."+node.getAttribute("class"));
+    else
+        debug(indent+offset+nodeString(node));
+    var childOffset = 0;
+    for (var child = node.firstChild; child != null; child = child.nextSibling) {
+        printTree(child,indent+"    ",childOffset+" ");
+        childOffset++;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/src/types.js
----------------------------------------------------------------------
diff --git a/Editor/src/types.js b/Editor/src/types.js
new file mode 100644
index 0000000..243f5e9
--- /dev/null
+++ b/Editor/src/types.js
@@ -0,0 +1,259 @@
+// Copyright 2011-2014 UX Productivity Pty Ltd
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+var CONTAINER_ELEMENTS = new Array(HTML_COUNT);
+CONTAINER_ELEMENTS[HTML_DOCUMENT] = true;
+CONTAINER_ELEMENTS[HTML_HTML] = true;
+CONTAINER_ELEMENTS[HTML_BODY] = true;
+CONTAINER_ELEMENTS[HTML_UL] = true;
+CONTAINER_ELEMENTS[HTML_OL] = true,
+CONTAINER_ELEMENTS[HTML_LI] = true;
+CONTAINER_ELEMENTS[HTML_TABLE] = true;
+CONTAINER_ELEMENTS[HTML_CAPTION] = true;
+CONTAINER_ELEMENTS[HTML_THEAD] = true;
+CONTAINER_ELEMENTS[HTML_TFOOT] = true;
+CONTAINER_ELEMENTS[HTML_TBODY] = true;
+CONTAINER_ELEMENTS[HTML_TR] = true;
+CONTAINER_ELEMENTS[HTML_TH] = true;
+CONTAINER_ELEMENTS[HTML_TD] = true;
+CONTAINER_ELEMENTS[HTML_COL] = true;
+CONTAINER_ELEMENTS[HTML_FIGURE] = true;
+CONTAINER_ELEMENTS[HTML_FIGCAPTION] = true;
+CONTAINER_ELEMENTS[HTML_NAV] = true;
+
+var PARAGRAPH_ELEMENTS = new Array(HTML_COUNT);
+PARAGRAPH_ELEMENTS[HTML_P] = true;
+PARAGRAPH_ELEMENTS[HTML_H1] = true;
+PARAGRAPH_ELEMENTS[HTML_H2] = true;
+PARAGRAPH_ELEMENTS[HTML_H3] = true;
+PARAGRAPH_ELEMENTS[HTML_H4] = true;
+PARAGRAPH_ELEMENTS[HTML_H5] = true;
+PARAGRAPH_ELEMENTS[HTML_H6] = true;
+PARAGRAPH_ELEMENTS[HTML_DIV] = true;
+PARAGRAPH_ELEMENTS[HTML_PRE] = true;
+PARAGRAPH_ELEMENTS[HTML_BLOCKQUOTE] = true;
+
+var BLOCK_ELEMENTS = new Array(HTML_COUNT);
+for (var i = 0; i < HTML_COUNT; i++)
+    BLOCK_ELEMENTS[i] = (CONTAINER_ELEMENTS[i] || PARAGRAPH_ELEMENTS[i]);
+
+var INLINE_ELEMENTS = new Array(HTML_COUNT);
+for (var i = 0; i < HTML_COUNT; i++)
+    INLINE_ELEMENTS[i] = !BLOCK_ELEMENTS[i];
+
+var HEADING_ELEMENTS = new Array(HTML_COUNT);
+HEADING_ELEMENTS[HTML_H1] = true;
+HEADING_ELEMENTS[HTML_H2] = true;
+HEADING_ELEMENTS[HTML_H3] = true;
+HEADING_ELEMENTS[HTML_H4] = true;
+HEADING_ELEMENTS[HTML_H5] = true;
+HEADING_ELEMENTS[HTML_H6] = true;
+
+var CONTAINERS_ALLOWING_CHILDREN = new Array(HTML_COUNT);
+CONTAINERS_ALLOWING_CHILDREN[HTML_BODY] = true;
+CONTAINERS_ALLOWING_CHILDREN[HTML_LI] = true;
+CONTAINERS_ALLOWING_CHILDREN[HTML_CAPTION] = true;
+CONTAINERS_ALLOWING_CHILDREN[HTML_TH] = true;
+CONTAINERS_ALLOWING_CHILDREN[HTML_TD] = true;
+CONTAINERS_ALLOWING_CHILDREN[HTML_FIGURE] = true;
+CONTAINERS_ALLOWING_CHILDREN[HTML_FIGCAPTION] = true;
+CONTAINERS_ALLOWING_CHILDREN[HTML_NAV] = true;
+
+var OUTLINE_TITLE_ELEMENTS = new Array(HTML_COUNT);
+OUTLINE_TITLE_ELEMENTS[HTML_H1] = true;
+OUTLINE_TITLE_ELEMENTS[HTML_H2] = true;
+OUTLINE_TITLE_ELEMENTS[HTML_H3] = true;
+OUTLINE_TITLE_ELEMENTS[HTML_H4] = true;
+OUTLINE_TITLE_ELEMENTS[HTML_H5] = true;
+OUTLINE_TITLE_ELEMENTS[HTML_H6] = true;
+OUTLINE_TITLE_ELEMENTS[HTML_FIGCAPTION] = true;
+OUTLINE_TITLE_ELEMENTS[HTML_CAPTION] = true;
+
+var Keys = {
+    HEADING_NUMBER: "uxwrite-heading-number",
+    FIGURE_NUMBER: "uxwrite-figure-number",
+    TABLE_NUMBER: "uxwrite-table-number",
+    SECTION_TOC: "tableofcontents",
+    FIGURE_TOC: "listoffigures",
+    TABLE_TOC: "listoftables",
+    SELECTION_HIGHLIGHT: "uxwrite-selection-highlight",
+    AUTOCORRECT_ENTRY: "uxwrite-autocorrect-entry",
+    UXWRITE_PREFIX: "uxwrite-",
+    NONE_STYLE: "__none",
+    AUTOCORRECT_CLASS: "uxwrite-autocorrect",
+    SELECTION_CLASS: "uxwrite-selection",
+    ABSTRACT_ELEMENT: "uxwrite-abstract",
+    SPELLING_CLASS: "uxwrite-spelling",
+    MATCH_CLASS: "uxwrite-match",
+};
+
+var ITEM_NUMBER_CLASSES = {
+    "uxwrite-heading-number": true,
+    "uxwrite-figure-number": true,
+    "uxwrite-table-number": true,
+};
+
+var OPAQUE_NODE_CLASSES = {
+    "uxwrite-heading-number": true,
+    "uxwrite-figure-number": true,
+    "uxwrite-table-number": true,
+    "tableofcontents": true,
+    "listoffigures": true,
+    "listoftables": true,
+    "uxwrite-selection-highlight": true,
+    "uxwrite-field": true,
+};
+
+function isContainerNode(node)
+{
+    return CONTAINER_ELEMENTS[node._type];
+}
+
+function isParagraphNode(node)
+{
+    return PARAGRAPH_ELEMENTS[node._type];
+}
+
+function isHeadingNode(node)
+{
+    return HEADING_ELEMENTS[node._type];
+}
+
+function isBlockNode(node)
+{
+    return BLOCK_ELEMENTS[node._type];
+}
+
+function isInlineNode(node)
+{
+    return INLINE_ELEMENTS[node._type];
+}
+
+function isListNode(node)
+{
+    var type = node._type;
+    return ((type == HTML_UL) || (type == HTML_OL));
+}
+
+function isTableCell(node)
+{
+    switch (node._type) {
+    case HTML_TD:
+    case HTML_TH:
+        return true;
+    default:
+        return false;
+    }
+}
+
+function isRefNode(node)
+{
+    return ((node._type == HTML_A) &&
+            node.hasAttribute("href") &&
+            node.getAttribute("href").charAt(0) == "#");
+}
+
+function isItemNumber(node)
+{
+    if (node.nodeType == Node.TEXT_NODE) {
+        return isItemNumber(node.parentNode);
+    }
+    else if (node.nodeType == Node.ELEMENT_NODE) {
+        if ((node._type == HTML_SPAN) && node.hasAttribute("class")) {
+            return ITEM_NUMBER_CLASSES[node.getAttribute("class")];
+        }
+    }
+    return false;
+}
+
+function isOpaqueNode(node)
+{
+    if (node == null)
+        return false;
+
+    switch (node._type) {
+    case HTML_TEXT:
+    case HTML_COMMENT:
+        return isOpaqueNode(node.parentNode);
+    case HTML_IMG:
+        return true;
+    case HTML_A:
+        return node.hasAttribute("href");
+    case HTML_DOCUMENT:
+        return false;
+    default:
+        if (node.hasAttribute("class") && OPAQUE_NODE_CLASSES[node.getAttribute("class")])
+            return true;
+        else
+            return isOpaqueNode(node.parentNode);
+    }
+}
+
+function isAutoCorrectNode(node)
+{
+    return ((node._type == HTML_SPAN) &&
+            (node.getAttribute("class") == Keys.AUTOCORRECT_CLASS));
+}
+
+function isSelectionHighlight(node)
+{
+    return ((node.nodeType == Node.ELEMENT_NODE) &&
+            node.getAttribute("class") == Keys.SELECTION_CLASS);
+}
+
+function isSelectionSpan(node)
+{
+    return ((node != null) &&
+            (node._type == HTML_SPAN) &&
+            (DOM_getAttribute(node,"class") == Keys.SELECTION_CLASS));
+};
+
+function isTOCNode(node)
+{
+    if (node._type == HTML_NAV) {
+        var cls = node.getAttribute("class");
+        if ((cls == Keys.SECTION_TOC) ||
+            (cls == Keys.FIGURE_TOC) ||
+            (cls == Keys.TABLE_TOC))
+            return true;
+    }
+    return false;
+}
+
+function isInTOC(node)
+{
+    if (isTOCNode(node))
+        return true;
+    if (node.parentNode != null)
+        return isInTOC(node.parentNode);
+    return false;
+}
+
+function isSpecialBlockNode(node)
+{
+    switch (node._type) {
+    case HTML_TABLE:
+    case HTML_FIGURE:
+        return true;
+    case HTML_NAV:
+        return isTOCNode(node);
+    default:
+        return false;
+    }
+}
+
+function isAbstractSpan(node)
+{
+    return ((node._type == HTML_SPAN) && node.hasAttribute(Keys.ABSTRACT_ELEMENT));
+}

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/src/util.js
----------------------------------------------------------------------
diff --git a/Editor/src/util.js b/Editor/src/util.js
new file mode 100644
index 0000000..fbe23e4
--- /dev/null
+++ b/Editor/src/util.js
@@ -0,0 +1,362 @@
+// Copyright 2011-2014 UX Productivity Pty Ltd
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+function arrayContains(array,value)
+{
+    for (var i = 0; i < array.length; i++) {
+        if (array[i] == value)
+            return true;
+    }
+    return false;
+}
+
+// Note: you can use slice() to copy a real javascript array, but this function can be used to copy
+// DOM NodeLists (e.g. as returned by document.getElementsByTagName) as well, since they don't
+// support the slice method
+function arrayCopy(array)
+{
+    if (array == null)
+        return null;
+    var copy = new Array();
+    for (var i = 0; i < array.length; i++)
+        copy.push(array[i]);
+    return copy;
+}
+
+function quoteString(str)
+{
+    if (str == null)
+        return null;
+
+    if (str.indexOf('"') < 0)
+        return str;
+
+    var quoted = "";
+    for (var i = 0; i < str.length; i++) {
+        if (str.charAt(i) == '"')
+            quoted += "\\\"";
+        else
+            quoted += str.charAt(i);
+    }
+    return quoted;
+}
+
+function nodeString(node)
+{
+    if (node == null)
+        return "null";
+    var id = "";
+    if (window.debugIds)
+        id = node._nodeId+":";
+    if (node.nodeType == Node.TEXT_NODE) {
+        return id+JSON.stringify(node.nodeValue);
+    }
+    else if (node.nodeType == Node.ELEMENT_NODE) {
+        var name = (node.namespaceURI == null) ? node.nodeName.toUpperCase() : node.nodeName;
+        if (node.hasAttribute("id"))
+            return id+name+"#"+node.getAttribute("id");
+        else
+            return id+name;
+    }
+    else {
+        return id+node.toString();
+    }
+}
+
+function rectString(rect)
+{
+    if (rect == null)
+        return null;
+    else
+        return "("+rect.left+","+rect.top+") - ("+rect.right+","+rect.bottom+")";
+}
+
+function rectIsEmpty(rect)
+{
+    return ((rect == null) ||
+            ((rect.width == 0) && (rect.height == 0)));
+}
+
+function rectContainsPoint(rect,x,y)
+{
+    return ((x >= rect.left) && (x < rect.right) &&
+            (y >= rect.top) && (y < rect.bottom));
+}
+
+function clone(object)
+{
+    var result = new Object();
+    for (var name in object)
+        result[name] = object[name];
+    return result;
+}
+
+function nodeHasContent(node)
+{
+    switch (node._type) {
+    case HTML_TEXT:
+        return !isWhitespaceString(node.nodeValue);
+    case HTML_IMG:
+    case HTML_TABLE:
+        return true;
+    default:
+        if (isOpaqueNode(node))
+            return true;
+
+        for (var child = node.firstChild; child != null; child = child.nextSibling) {
+            if (nodeHasContent(child))
+                return true;
+        }
+        return false;
+    }
+}
+
+function isWhitespaceString(str)
+{
+    return (str.match(isWhitespaceString.regexp) != null);
+}
+
+isWhitespaceString.regexp = /^\s*$/;
+
+function normalizeWhitespace(str)
+{
+    str = str.replace(/^\s+/,"");
+    str = str.replace(/\s+$/,"");
+    str = str.replace(/\s+/g," ");
+    return str;
+}
+
+function DoublyLinkedList()
+{
+    this.first = null;
+    this.last = null;
+}
+
+DoublyLinkedList.prototype.insertAfter = function(item,after)
+{
+    item.prev = null;
+    item.next = null;
+
+    if (this.first == null) { // empty list
+        this.first = item;
+        this.last = item;
+    }
+    else if (after == null) { // insert at start
+        item.next = this.first;
+        this.first = item;
+    }
+    else {
+        item.next = after.next;
+        item.prev = after;
+        if (this.last == after)
+            this.last = item;
+    }
+
+    if (item.next != null)
+        item.next.prev = item;
+    if (item.prev != null)
+        item.prev.next = item;
+};
+
+DoublyLinkedList.prototype.remove = function(item)
+{
+    if (this.first == item)
+        this.first = this.first.next;
+    if (this.last == item)
+        this.last = this.last.prev;
+    if (item.prev != null)
+        item.prev.next = item.next;
+    if (item.next != null)
+        item.next.prev = item.prev;
+    item.prev = null;
+    item.next = null;
+};
+
+function diff(src,dest)
+{
+    var traces = new Array();
+
+    traces[1] = new DiffEntry(0,0,0,0,null);
+
+    for (var distance = 0; true; distance++) {
+        for (var k = -distance; k <= distance; k += 2) {
+            var srcEnd;
+            var prev;
+
+            var del = traces[k-1];
+            var ins = traces[k+1];
+
+            if (((k == -distance) && ins) ||
+                ((k != distance) && ins && del && (del.srcEnd < ins.srcEnd))) {
+                // Down - insertion
+                prev = ins;
+                srcEnd = prev.srcEnd;
+            }
+            else if (del) {
+                // Right - deletion
+                prev = del;
+                srcEnd = prev.srcEnd+1;
+            }
+            else {
+                traces[k] = null;
+                continue;
+            }
+
+            destEnd = srcEnd - k;
+            var srcStart = srcEnd;
+            var destStart = destEnd;
+            while ((srcEnd < src.length) && (destEnd < dest.length) &&
+                   (src[srcEnd] == dest[destEnd])) {
+                srcEnd++;
+                destEnd++;
+            }
+            if ((srcEnd > src.length) || (destEnd > dest.length))
+                traces[k] = null;
+            else
+                traces[k] = new DiffEntry(srcStart,destStart,srcEnd,destEnd,prev);
+            if ((srcEnd >= src.length) && (destEnd >= dest.length)) {
+                return entryToArray(src,dest,traces[k]);
+            }
+        }
+    }
+
+    function DiffEntry(srcStart,destStart,srcEnd,destEnd,prev)
+    {
+        this.srcStart = srcStart;
+        this.destStart = destStart;
+        this.srcEnd = srcEnd;
+        this.destEnd = destEnd;
+        this.prev = prev;
+    }
+
+    function entryToArray(src,dest,entry)
+    {
+        var results = new Array();
+        results.push(entry);
+        for (entry = entry.prev; entry != null; entry = entry.prev) {
+            if ((entry.srcStart != entry.srcEnd) || (entry.destStart != entry.destEnd))
+                results.push(entry);
+        }
+        return results.reverse();
+    }
+}
+
+function TimingEntry(name,time)
+{
+    this.name = name;
+    this.time = time;
+}
+
+function TimingInfo()
+{
+    this.entries = new Array();
+    this.total = 0;
+    this.lastTime = null;
+}
+
+TimingInfo.prototype.start = function()
+{
+    this.entries.length = 0;
+    this.lastTime = new Date();
+};
+
+TimingInfo.prototype.addEntry = function(name)
+{
+    if (this.lastTime == null)
+        this.start();
+
+    var now = new Date();
+    var interval = now - this.lastTime;
+    this.entries.push(new TimingEntry(name,interval));
+    this.total += interval;
+    this.lastTime = now;
+};
+
+TimingInfo.prototype.print = function(title)
+{
+    debug(title);
+    for (var i = 0; i < this.entries.length; i++) {
+        var entry = this.entries[i];
+        debug("    "+entry.name+": "+entry.time+"ms");
+    }
+};
+
+function readFileApp(filename)
+{
+    var req = new XMLHttpRequest("file:///read/"+filename);
+    req.open("POST","/read/"+encodeURI(filename),false);
+    req.send();
+    if (req.status == 404)
+        return null; // file not found
+    else if ((req.status != 200) && (req.status != 0))
+        throw new Error(req.status+": "+req.responseText);
+    var doc = req.responseXML;
+    if (doc != null)
+        DOM_assignNodeIds(doc);
+    return doc;
+}
+
+function readFileTest(filename)
+{
+    var req = new XMLHttpRequest();
+    req.open("GET",filename,false);
+    req.send();
+    var xml = req.responseXML;
+    if (xml == null)
+        return null;
+    DOM_assignNodeIds(xml.documentElement);
+    return xml;
+}
+
+function fromTokenList(value)
+{
+    var result = new Object();
+    if (value != null) {
+        var components = value.toLowerCase().split(/\s+/);
+        for (var i = 0; i < components.length; i++) {
+            if (components[i].length > 0)
+                result[components[i]] = true;
+        }
+    }
+    return result;
+}
+
+function toTokenList(properties)
+{
+    var tokens = new Array();
+
+    if (properties != null) {
+        // Sort the names to ensure deterministic results in test cases
+        var names = Object.getOwnPropertyNames(properties).sort();
+        for (var i = 0; i < names.length; i++) {
+            var name = names[i];
+            if (properties[name])
+                tokens.push(name);
+        }
+    }
+
+    if (tokens.length == null)
+        return null;
+    else
+        return tokens.join(" ");
+}
+
+function xywhAbsElementRect(element)
+{
+    var rect = element.getBoundingClientRect();
+    return { x: rect.left + window.scrollX,
+             y: rect.top + window.scrollY,
+             width: rect.width,
+             height: rect.height };
+}

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/PrettyPrinter.js
----------------------------------------------------------------------
diff --git a/Editor/tests/PrettyPrinter.js b/Editor/tests/PrettyPrinter.js
new file mode 100644
index 0000000..c39e7e1
--- /dev/null
+++ b/Editor/tests/PrettyPrinter.js
@@ -0,0 +1,201 @@
+// Copyright 2011-2014 UX Productivity Pty Ltd
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+(function() {
+
+    // Applicable options:
+    // keepSelectionHighlights (boolean)
+    // preserveCase (boolean)
+    // showNamespaceDetails (boolean)
+    // separateLines (boolean)
+
+    function getHTML(root,options)
+    {
+        var copy;
+        UndoManager_disableWhileExecuting(function() {
+            if (options == null)
+                options = new Object();
+            copy = DOM_cloneNode(root,true);
+            if (!options.keepSelectionHighlights)
+                removeSelectionSpans(copy);
+            for (var body = copy.firstChild; body != null; body = body.nextSibling) {
+                if (body.nodeName == "BODY") {
+                    DOM_removeAttribute(body,"style");
+                    DOM_removeAttribute(body,"contentEditable");
+                }
+            }
+        });
+
+        var output = new Array();
+        prettyPrint(output,options,copy,"");
+        return output.join("");
+    }
+
+    function removeSelectionSpans(root)
+    {
+        var checkMerge = new Array();
+        recurse(root);
+
+        for (var i = 0; i < checkMerge.length; i++) {
+            if (checkMerge[i].parentNode != null) { // if not already merged
+                Formatting_mergeWithNeighbours(checkMerge[i],{});
+            }
+        }
+
+        function recurse(node) {
+            if (isSelectionHighlight(node)) {
+                checkMerge.push(node.firstChild);
+                checkMerge.push(node.lastChild);
+                DOM_removeNodeButKeepChildren(node);
+            }
+            else {
+                var next;
+                for (var child = node.firstChild; child != null; child = next) {
+                    next = child.nextSibling;
+                    recurse(child);
+                }
+            }
+        }
+    }
+
+    function entityFix(str)
+    {
+        return str.replace(/\u00a0/g,"&nbsp;");
+    }
+
+    function singleDescendents(node)
+    {
+        var count = 0;
+        for (var child = node.firstChild; child != null; child = child.nextSibling) {
+            if ((child.nodeType == Node.TEXT_NODE) && (textNodeDisplayValue(child).length == 0))
+                continue;
+            count++;
+            if (count > 1)
+                return false;
+            if (!singleDescendents(child))
+                return false;
+        }
+        return true;
+    }
+
+    function sortCSSProperties(value)
+    {
+        // Make sure the CSS properties on the "style" attribute appear in a consistent order
+        var items = value.trim().split(/\s*;\s*/);
+        if ((items.length > 0) && (items[items.length-1] == ""))
+            items.length--;
+        items.sort();
+        return items.join("; ");
+    }
+
+    function attributeString(options,node)
+    {
+        // Make sure the attributes appear in a consistent order
+        var names = new Array();
+        for (var i = 0; i < node.attributes.length; i++) {
+            names.push(node.attributes[i].nodeName);
+        }
+        names.sort();
+        var str = "";
+        for (var i = 0; i < names.length; i++) {
+            var name = names[i];
+
+            var value = node.getAttribute(name);
+            if (name == "style")
+                value = sortCSSProperties(value);
+            var attr = node.getAttributeNode(name);
+            if (options.showNamespaceDetails) {
+                if ((attr.namespaceURI != null) || (attr.prefix != null))
+                    name = "{"+attr.namespaceURI+","+attr.prefix+","+attr.localName+"}"+name;
+            }
+            str += " "+name+"=\""+value+"\"";
+        }
+        return str;
+    }
+
+    function textNodeDisplayValue(node)
+    {
+        var value = entityFix(node.nodeValue);
+        if ((node.parentNode != null) &&
+            (node.parentNode.getAttribute("xml:space") != "preserve"))
+            value = value.trim();
+        return value;
+    }
+
+    function prettyPrintOneLine(output,options,node)
+    {
+        if ((node.nodeType == Node.ELEMENT_NODE) && (node.nodeName != "SCRIPT")) {
+            var name = options.preserveCase ? node.nodeName : node.nodeName.toLowerCase();
+            if (node.firstChild == null) {
+                output.push("<" + name + attributeString(options,node) + "/>");
+            }
+            else {
+                output.push("<" + name + attributeString(options,node) + ">");
+                for (var child = node.firstChild; child != null; child = child.nextSibling)
+                    prettyPrintOneLine(output,options,child);
+                output.push("</" + name + ">");
+            }
+        }
+        else if (node.nodeType == Node.TEXT_NODE) {
+            var value = textNodeDisplayValue(node);
+            if (value.length > 0)
+                output.push(value);
+        }
+        else if (node.nodeType == Node.COMMENT_NODE) {
+            output.push("<!--" + entityFix(node.nodeValue) + "-->\n");
+        }
+    }
+
+    function prettyPrint(output,options,node,indent)
+    {
+        if ((node.nodeType == Node.ELEMENT_NODE) && (node.nodeName != "SCRIPT")) {
+            var name = options.preserveCase ? node.nodeName : node.nodeName.toLowerCase();
+            if (node.firstChild == null) {
+                output.push(indent + "<" + name + attributeString(options,node) + "/>\n");
+            }
+            else {
+                if (node._type == HTML_STYLE) {
+                    output.push(indent + "<" + name + attributeString(options,node) + ">\n");
+                    for (var child = node.firstChild; child != null; child = child.nextSibling)
+                        prettyPrint(output,options,child,"");
+                    output.push(indent + "</" + name + ">\n");
+                }
+                else if (!options.separateLines && singleDescendents(node)) {
+                    output.push(indent);
+                    prettyPrintOneLine(output,options,node);
+                    output.push("\n");
+                }
+                else {
+                    output.push(indent + "<" + name + attributeString(options,node) + ">\n");
+                    for (var child = node.firstChild; child != null; child = child.nextSibling)
+                        prettyPrint(output,options,child,indent+"  ");
+                    output.push(indent + "</" + name + ">\n");
+                }
+            }
+        }
+        else if (node.nodeType == Node.TEXT_NODE) {
+            var value = textNodeDisplayValue(node);
+//            var value = JSON.stringify(node.nodeValue);
+            if (value.length > 0)
+                output.push(indent + value + "\n");
+        }
+        else if (node.nodeType == Node.COMMENT_NODE) {
+            output.push(indent + "<!--" + entityFix(node.nodeValue) + "-->\n");
+        }
+    }
+
+    window.PrettyPrinter = new Object();
+    window.PrettyPrinter.getHTML = getHTML;
+
+})();

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/AutoCorrectTests.js
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/AutoCorrectTests.js b/Editor/tests/autocorrect/AutoCorrectTests.js
new file mode 100644
index 0000000..ba514bb
--- /dev/null
+++ b/Editor/tests/autocorrect/AutoCorrectTests.js
@@ -0,0 +1,47 @@
+// Copyright 2011-2014 UX Productivity Pty Ltd
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+function findTextMatching(re)
+{
+    return recurse(document.body);
+
+    function recurse(node)
+    {
+        if (node.nodeType == Node.TEXT_NODE) {
+            if (node.nodeValue.match(re))
+                return node;
+            else
+                return null;
+        }
+        else {
+            for (var child = node.firstChild; child != null; child = child.nextSibling) {
+                var result = recurse(child);
+                if (result != null)
+                    return result;
+            }
+            return null;
+        }
+    }
+}
+
+function showCorrections()
+{
+    var corrections = AutoCorrect_getCorrections();
+    var lines = new Array();
+    lines.push("Corrections:\n");
+    for (var i = 0; i < corrections.length; i++) {
+        lines.push("    "+corrections[i].original+" -> "+corrections[i].replacement+"\n");
+    }
+    return PrettyPrinter.getHTML(document.documentElement)+"\n"+lines.join("");
+}

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/acceptCorrection-undo-expected.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/acceptCorrection-undo-expected.html b/Editor/tests/autocorrect/acceptCorrection-undo-expected.html
new file mode 100644
index 0000000..0460b60
--- /dev/null
+++ b/Editor/tests/autocorrect/acceptCorrection-undo-expected.html
@@ -0,0 +1,48 @@
+<html>
+  <head>
+  </head>
+  <body>
+    ==================== Version 0 ====================
+    <body>
+      <p>
+        one
+        <span class="uxwrite-autocorrect" original="twox">two</span>
+        three
+        <span class="uxwrite-autocorrect" original="fourx">four</span>
+        five
+        <span class="uxwrite-autocorrect" original="sixx">six</span>
+        seven[]
+      </p>
+    </body>
+    ==================== Version 1 ====================
+    <body>
+      <p>
+        one
+        <span class="uxwrite-autocorrect" original="twox">two</span>
+        three
+        <span class="uxwrite-autocorrect" original="fourx">four</span>
+        five six seven[]
+      </p>
+    </body>
+    ==================== Version 2 ====================
+    <body>
+      <p>
+        one
+        <span class="uxwrite-autocorrect" original="twox">two</span>
+        three four five six seven[]
+      </p>
+    </body>
+    ==================== Version 3 ====================
+    <body><p>one two three four five six seven[]</p></body>
+    ===================================================
+    First undo to version 2: OK
+    First undo to version 1: OK
+    First undo to version 0: OK
+    Redo to version 1: OK
+    Redo to version 2: OK
+    Redo to version 3: OK
+    Second undo to version 2: OK
+    Second undo to version 1: OK
+    Second undo to version 0: OK
+  </body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/acceptCorrection-undo-input.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/acceptCorrection-undo-input.html b/Editor/tests/autocorrect/acceptCorrection-undo-input.html
new file mode 100644
index 0000000..a0a703a
--- /dev/null
+++ b/Editor/tests/autocorrect/acceptCorrection-undo-input.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="AutoCorrectTests.js"></script>
+<script src="../undo/UndoTests.js"></script>
+<script>
+function performTest()
+{
+    Outline_init();
+    AutoCorrect_init();
+    PostponedActions_perform();
+
+    Cursor_insertCharacter("one");
+    Cursor_insertCharacter(" twox");
+    AutoCorrect_correctPrecedingWord(4,"two");
+    Cursor_insertCharacter(" three");
+    Cursor_insertCharacter(" fourx");
+    AutoCorrect_correctPrecedingWord(5,"four");
+    Cursor_insertCharacter(" five");
+    Cursor_insertCharacter(" sixx");
+    AutoCorrect_correctPrecedingWord(4,"six");
+    Cursor_insertCharacter(" seven");
+    PostponedActions_perform();
+    showSelection();
+
+    UndoManager_clear();
+    var versions = new Array();
+    versions.push(DOM_cloneNode(document.body,true));
+    for (var i = 0; i < 3; i++) {
+        AutoCorrect_acceptCorrection();
+        PostponedActions_perform();
+        versions.push(DOM_cloneNode(document.body,true));
+    }
+
+    testUndo(versions,document.body);
+}
+</script>
+</head>
+<body>
+<p>[]</p>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/acceptCorrection01-expected.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/acceptCorrection01-expected.html b/Editor/tests/autocorrect/acceptCorrection01-expected.html
new file mode 100644
index 0000000..5311c9e
--- /dev/null
+++ b/Editor/tests/autocorrect/acceptCorrection01-expected.html
@@ -0,0 +1,14 @@
+<html>
+  <head>
+  </head>
+  <body>
+    <p>
+      one
+      <span class="uxwrite-autocorrect" original="twox">two</span>
+      three four five[]
+    </p>
+  </body>
+</html>
+
+Corrections:
+    twox -> two

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/acceptCorrection01-input.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/acceptCorrection01-input.html b/Editor/tests/autocorrect/acceptCorrection01-input.html
new file mode 100644
index 0000000..1fc0ff4
--- /dev/null
+++ b/Editor/tests/autocorrect/acceptCorrection01-input.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="AutoCorrectTests.js"></script>
+<script>
+function performTest()
+{
+    Outline_init();
+    AutoCorrect_init();
+    PostponedActions_perform();
+
+    Cursor_insertCharacter("one");
+    Cursor_insertCharacter(" twox");
+    AutoCorrect_correctPrecedingWord(4,"two");
+    Cursor_insertCharacter(" three");
+    Cursor_insertCharacter(" fourx");
+    AutoCorrect_correctPrecedingWord(5,"four");
+    Cursor_insertCharacter(" five");
+    PostponedActions_perform();
+    showSelection();
+
+    AutoCorrect_acceptCorrection();
+    PostponedActions_perform();
+
+    return showCorrections();
+}
+</script>
+</head>
+<body>
+<p>[]</p>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/acceptCorrection02-expected.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/acceptCorrection02-expected.html b/Editor/tests/autocorrect/acceptCorrection02-expected.html
new file mode 100644
index 0000000..5848dfc
--- /dev/null
+++ b/Editor/tests/autocorrect/acceptCorrection02-expected.html
@@ -0,0 +1,7 @@
+<html>
+  <head>
+  </head>
+  <body><p>one two three four five[]</p></body>
+</html>
+
+Corrections:

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/acceptCorrection02-input.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/acceptCorrection02-input.html b/Editor/tests/autocorrect/acceptCorrection02-input.html
new file mode 100644
index 0000000..96e9be0
--- /dev/null
+++ b/Editor/tests/autocorrect/acceptCorrection02-input.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="AutoCorrectTests.js"></script>
+<script>
+function performTest()
+{
+    Outline_init();
+    AutoCorrect_init();
+    PostponedActions_perform();
+
+    Cursor_insertCharacter("one");
+    Cursor_insertCharacter(" twox");
+    AutoCorrect_correctPrecedingWord(4,"two");
+    Cursor_insertCharacter(" three");
+    Cursor_insertCharacter(" fourx");
+    AutoCorrect_correctPrecedingWord(5,"four");
+    Cursor_insertCharacter(" five");
+    PostponedActions_perform();
+    showSelection();
+
+    AutoCorrect_acceptCorrection();
+    AutoCorrect_acceptCorrection();
+    PostponedActions_perform();
+
+    return showCorrections();
+}
+</script>
+</head>
+<body>
+<p>[]</p>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/acceptCorrection03-expected.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/acceptCorrection03-expected.html b/Editor/tests/autocorrect/acceptCorrection03-expected.html
new file mode 100644
index 0000000..b1afd1f
--- /dev/null
+++ b/Editor/tests/autocorrect/acceptCorrection03-expected.html
@@ -0,0 +1,17 @@
+<html>
+  <head>
+  </head>
+  <body>
+    <p>
+      one two three
+      <span class="uxwrite-autocorrect" original="fourx">four</span>
+      five
+      <span class="uxwrite-autocorrect" original="sixx">six</span>
+      seven[]
+    </p>
+  </body>
+</html>
+
+Corrections:
+    fourx -> four
+    sixx -> six

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/acceptCorrection03-input.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/acceptCorrection03-input.html b/Editor/tests/autocorrect/acceptCorrection03-input.html
new file mode 100644
index 0000000..dc26563
--- /dev/null
+++ b/Editor/tests/autocorrect/acceptCorrection03-input.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="AutoCorrectTests.js"></script>
+<script>
+function performTest()
+{
+    Outline_init();
+    AutoCorrect_init();
+    PostponedActions_perform();
+
+    Cursor_insertCharacter("one");
+    Cursor_insertCharacter(" twox");
+    AutoCorrect_correctPrecedingWord(4,"two");
+    Cursor_insertCharacter(" three");
+    Cursor_insertCharacter(" fourx");
+    AutoCorrect_correctPrecedingWord(5,"four");
+    Cursor_insertCharacter(" five");
+    Cursor_insertCharacter(" sixx");
+    AutoCorrect_correctPrecedingWord(4,"six");
+    Cursor_insertCharacter(" seven");
+    PostponedActions_perform();
+    showSelection();
+
+    var text = findTextMatching("two");
+    Selection_set(text,0,text,0);
+
+    AutoCorrect_acceptCorrection();
+    PostponedActions_perform();
+
+    return showCorrections();
+}
+</script>
+</head>
+<body>
+<p>[]</p>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/acceptCorrection04-expected.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/acceptCorrection04-expected.html b/Editor/tests/autocorrect/acceptCorrection04-expected.html
new file mode 100644
index 0000000..9671757
--- /dev/null
+++ b/Editor/tests/autocorrect/acceptCorrection04-expected.html
@@ -0,0 +1,17 @@
+<html>
+  <head>
+  </head>
+  <body>
+    <p>
+      one
+      <span class="uxwrite-autocorrect" original="twox">two</span>
+      three four five
+      <span class="uxwrite-autocorrect" original="sixx">six</span>
+      seven[]
+    </p>
+  </body>
+</html>
+
+Corrections:
+    twox -> two
+    sixx -> six

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/acceptCorrection04-input.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/acceptCorrection04-input.html b/Editor/tests/autocorrect/acceptCorrection04-input.html
new file mode 100644
index 0000000..8de93eb
--- /dev/null
+++ b/Editor/tests/autocorrect/acceptCorrection04-input.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="AutoCorrectTests.js"></script>
+<script>
+function performTest()
+{
+    Outline_init();
+    AutoCorrect_init();
+    PostponedActions_perform();
+
+    Cursor_insertCharacter("one");
+    Cursor_insertCharacter(" twox");
+    AutoCorrect_correctPrecedingWord(4,"two");
+    Cursor_insertCharacter(" three");
+    Cursor_insertCharacter(" fourx");
+    AutoCorrect_correctPrecedingWord(5,"four");
+    Cursor_insertCharacter(" five");
+    Cursor_insertCharacter(" sixx");
+    AutoCorrect_correctPrecedingWord(4,"six");
+    Cursor_insertCharacter(" seven");
+    PostponedActions_perform();
+    showSelection();
+
+    var text = findTextMatching("four");
+    Selection_set(text,0,text,0);
+
+    AutoCorrect_acceptCorrection();
+    PostponedActions_perform();
+
+    return showCorrections();
+}
+</script>
+</head>
+<body>
+<p>[]</p>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/acceptCorrection05-expected.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/acceptCorrection05-expected.html b/Editor/tests/autocorrect/acceptCorrection05-expected.html
new file mode 100644
index 0000000..00fdf45
--- /dev/null
+++ b/Editor/tests/autocorrect/acceptCorrection05-expected.html
@@ -0,0 +1,17 @@
+<html>
+  <head>
+  </head>
+  <body>
+    <p>
+      one
+      <span class="uxwrite-autocorrect" original="twox">two</span>
+      three
+      <span class="uxwrite-autocorrect" original="fourx">four</span>
+      five six seven[]
+    </p>
+  </body>
+</html>
+
+Corrections:
+    twox -> two
+    fourx -> four

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/acceptCorrection05-input.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/acceptCorrection05-input.html b/Editor/tests/autocorrect/acceptCorrection05-input.html
new file mode 100644
index 0000000..6e724b7
--- /dev/null
+++ b/Editor/tests/autocorrect/acceptCorrection05-input.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="AutoCorrectTests.js"></script>
+<script>
+function performTest()
+{
+    Outline_init();
+    AutoCorrect_init();
+    PostponedActions_perform();
+
+    Cursor_insertCharacter("one");
+    Cursor_insertCharacter(" twox");
+    AutoCorrect_correctPrecedingWord(4,"two");
+    Cursor_insertCharacter(" three");
+    Cursor_insertCharacter(" fourx");
+    AutoCorrect_correctPrecedingWord(5,"four");
+    Cursor_insertCharacter(" five");
+    Cursor_insertCharacter(" sixx");
+    AutoCorrect_correctPrecedingWord(4,"six");
+    Cursor_insertCharacter(" seven");
+    PostponedActions_perform();
+    showSelection();
+
+    var text = findTextMatching("six");
+    Selection_set(text,0,text,0);
+
+    AutoCorrect_acceptCorrection();
+    PostponedActions_perform();
+
+    return showCorrections();
+}
+</script>
+</head>
+<body>
+<p>[]</p>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/changeCorrection01-expected.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/changeCorrection01-expected.html b/Editor/tests/autocorrect/changeCorrection01-expected.html
new file mode 100644
index 0000000..9d04b6a
--- /dev/null
+++ b/Editor/tests/autocorrect/changeCorrection01-expected.html
@@ -0,0 +1,14 @@
+<html>
+  <head>
+  </head>
+  <body>
+    <p>
+      one a three
+      <span class="uxwrite-autocorrect" original="fourx">four</span>
+      five[]
+    </p>
+  </body>
+</html>
+
+Corrections:
+    fourx -> four

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/changeCorrection01-input.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/changeCorrection01-input.html b/Editor/tests/autocorrect/changeCorrection01-input.html
new file mode 100644
index 0000000..45e7519
--- /dev/null
+++ b/Editor/tests/autocorrect/changeCorrection01-input.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="AutoCorrectTests.js"></script>
+<script>
+function performTest()
+{
+    Outline_init();
+    AutoCorrect_init();
+    PostponedActions_perform();
+
+    Cursor_insertCharacter("one");
+    Cursor_insertCharacter(" twox");
+    AutoCorrect_correctPrecedingWord(4,"two");
+    Cursor_insertCharacter(" three");
+    Cursor_insertCharacter(" fourx");
+    AutoCorrect_correctPrecedingWord(5,"four");
+    Cursor_insertCharacter(" five");
+    PostponedActions_perform();
+    showSelection();
+
+    var text = findTextMatching(/two/);
+    text.nodeValue = "a";
+    PostponedActions_perform();
+
+    return showCorrections();
+}
+</script>
+</head>
+<body>
+<p>[]</p>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/changeCorrection02-expected.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/changeCorrection02-expected.html b/Editor/tests/autocorrect/changeCorrection02-expected.html
new file mode 100644
index 0000000..717beb5
--- /dev/null
+++ b/Editor/tests/autocorrect/changeCorrection02-expected.html
@@ -0,0 +1,14 @@
+<html>
+  <head>
+  </head>
+  <body>
+    <p>
+      one
+      <span class="uxwrite-autocorrect" original="twox">two</span>
+      three a five[]
+    </p>
+  </body>
+</html>
+
+Corrections:
+    twox -> two

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/changeCorrection02-input.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/changeCorrection02-input.html b/Editor/tests/autocorrect/changeCorrection02-input.html
new file mode 100644
index 0000000..d3b1943
--- /dev/null
+++ b/Editor/tests/autocorrect/changeCorrection02-input.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="AutoCorrectTests.js"></script>
+<script>
+function performTest()
+{
+    Outline_init();
+    AutoCorrect_init();
+    PostponedActions_perform();
+
+    Cursor_insertCharacter("one");
+    Cursor_insertCharacter(" twox");
+    AutoCorrect_correctPrecedingWord(4,"two");
+    Cursor_insertCharacter(" three");
+    Cursor_insertCharacter(" fourx");
+    AutoCorrect_correctPrecedingWord(5,"four");
+    Cursor_insertCharacter(" five");
+    PostponedActions_perform();
+    showSelection();
+
+    var text = findTextMatching(/four/);
+    text.nodeValue = "a";
+    PostponedActions_perform();
+
+    return showCorrections();
+}
+</script>
+</head>
+<body>
+<p>[]</p>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/correctPrecedingWord01-expected.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/correctPrecedingWord01-expected.html b/Editor/tests/autocorrect/correctPrecedingWord01-expected.html
new file mode 100644
index 0000000..f8ac7aa
--- /dev/null
+++ b/Editor/tests/autocorrect/correctPrecedingWord01-expected.html
@@ -0,0 +1,17 @@
+<html>
+  <head>
+  </head>
+  <body>
+    <p>
+      one
+      <span class="uxwrite-autocorrect" original="twox">two</span>
+      three
+      <span class="uxwrite-autocorrect" original="fourx">four</span>
+      five[]
+    </p>
+  </body>
+</html>
+
+Corrections:
+    twox -> two
+    fourx -> four

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/correctPrecedingWord01-input.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/correctPrecedingWord01-input.html b/Editor/tests/autocorrect/correctPrecedingWord01-input.html
new file mode 100644
index 0000000..7bb437e
--- /dev/null
+++ b/Editor/tests/autocorrect/correctPrecedingWord01-input.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="AutoCorrectTests.js"></script>
+<script>
+function performTest()
+{
+    Outline_init();
+    AutoCorrect_init();
+    PostponedActions_perform();
+
+    Cursor_insertCharacter("one");
+    Cursor_insertCharacter(" twox");
+    AutoCorrect_correctPrecedingWord(4,"two");
+    Cursor_insertCharacter(" three");
+    Cursor_insertCharacter(" fourx");
+    AutoCorrect_correctPrecedingWord(5,"four");
+    Cursor_insertCharacter(" five");
+    PostponedActions_perform();
+    showSelection();
+
+    return showCorrections();
+}
+</script>
+</head>
+<body>
+<p>[]</p>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/removeCorrection01-expected.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/removeCorrection01-expected.html b/Editor/tests/autocorrect/removeCorrection01-expected.html
new file mode 100644
index 0000000..00dd985
--- /dev/null
+++ b/Editor/tests/autocorrect/removeCorrection01-expected.html
@@ -0,0 +1,15 @@
+<html>
+  <head>
+  </head>
+  <body>
+    <p>
+      one
+      three
+      <span class="uxwrite-autocorrect" original="fourx">four</span>
+      five[]
+    </p>
+  </body>
+</html>
+
+Corrections:
+    fourx -> four

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/removeCorrection01-input.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/removeCorrection01-input.html b/Editor/tests/autocorrect/removeCorrection01-input.html
new file mode 100644
index 0000000..929d768
--- /dev/null
+++ b/Editor/tests/autocorrect/removeCorrection01-input.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="AutoCorrectTests.js"></script>
+<script>
+function performTest()
+{
+    Outline_init();
+    AutoCorrect_init();
+    PostponedActions_perform();
+
+    Cursor_insertCharacter("one");
+    Cursor_insertCharacter(" twox");
+    AutoCorrect_correctPrecedingWord(4,"two");
+    Cursor_insertCharacter(" three");
+    Cursor_insertCharacter(" fourx");
+    AutoCorrect_correctPrecedingWord(5,"four");
+    Cursor_insertCharacter(" five");
+    PostponedActions_perform();
+    showSelection();
+
+    var text = findTextMatching(/two/);
+    DOM_deleteNode(text.parentNode);
+    PostponedActions_perform();
+
+    return showCorrections();
+}
+</script>
+</head>
+<body>
+<p>[]</p>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/removeCorrection02-expected.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/removeCorrection02-expected.html b/Editor/tests/autocorrect/removeCorrection02-expected.html
new file mode 100644
index 0000000..350dd7d
--- /dev/null
+++ b/Editor/tests/autocorrect/removeCorrection02-expected.html
@@ -0,0 +1,15 @@
+<html>
+  <head>
+  </head>
+  <body>
+    <p>
+      one
+      <span class="uxwrite-autocorrect" original="twox">two</span>
+      three
+      five[]
+    </p>
+  </body>
+</html>
+
+Corrections:
+    twox -> two

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/removeCorrection02-input.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/removeCorrection02-input.html b/Editor/tests/autocorrect/removeCorrection02-input.html
new file mode 100644
index 0000000..59ce3db
--- /dev/null
+++ b/Editor/tests/autocorrect/removeCorrection02-input.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="AutoCorrectTests.js"></script>
+<script>
+function performTest()
+{
+    Outline_init();
+    AutoCorrect_init();
+    PostponedActions_perform();
+
+    Cursor_insertCharacter("one");
+    Cursor_insertCharacter(" twox");
+    AutoCorrect_correctPrecedingWord(4,"two");
+    Cursor_insertCharacter(" three");
+    Cursor_insertCharacter(" fourx");
+    AutoCorrect_correctPrecedingWord(5,"four");
+    Cursor_insertCharacter(" five");
+    PostponedActions_perform();
+    showSelection();
+
+    var text = findTextMatching(/four/);
+    DOM_deleteNode(text.parentNode);
+    PostponedActions_perform();
+
+    return showCorrections();
+}
+</script>
+</head>
+<body>
+<p>[]</p>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/removedSpan01-expected.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/removedSpan01-expected.html b/Editor/tests/autocorrect/removedSpan01-expected.html
new file mode 100644
index 0000000..f56d240
--- /dev/null
+++ b/Editor/tests/autocorrect/removedSpan01-expected.html
@@ -0,0 +1,11 @@
+<html>
+  <head>
+  </head>
+  <body>
+    <p>the</p>
+    <p>
+      []
+      <br/>
+    </p>
+  </body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/removedSpan01-input.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/removedSpan01-input.html b/Editor/tests/autocorrect/removedSpan01-input.html
new file mode 100644
index 0000000..4ce93b7
--- /dev/null
+++ b/Editor/tests/autocorrect/removedSpan01-input.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="AutoCorrectTests.js"></script>
+<script>
+function performTest()
+{
+    Outline_init();
+    AutoCorrect_init();
+    PostponedActions_perform();
+
+    Cursor_insertCharacter("teh");
+    AutoCorrect_correctPrecedingWord(3,"the");
+    Cursor_insertCharacter(" ");
+    PostponedActions_perform();
+    Cursor_deleteCharacter();
+    Cursor_enterPressed();
+    PostponedActions_perform();
+    showSelection();
+}
+</script>
+</head>
+<body>
+[]
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/removedSpan02-expected.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/removedSpan02-expected.html b/Editor/tests/autocorrect/removedSpan02-expected.html
new file mode 100644
index 0000000..17b33b8
--- /dev/null
+++ b/Editor/tests/autocorrect/removedSpan02-expected.html
@@ -0,0 +1,5 @@
+<html>
+  <head>
+  </head>
+  <body><p>th[]</p></body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/removedSpan02-input.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/removedSpan02-input.html b/Editor/tests/autocorrect/removedSpan02-input.html
new file mode 100644
index 0000000..9870e03
--- /dev/null
+++ b/Editor/tests/autocorrect/removedSpan02-input.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="AutoCorrectTests.js"></script>
+<script>
+function performTest()
+{
+    Outline_init();
+    AutoCorrect_init();
+    PostponedActions_perform();
+
+    Cursor_insertCharacter("teh");
+    AutoCorrect_correctPrecedingWord(3,"the");
+    Cursor_insertCharacter(" ");
+    PostponedActions_perform();
+    Cursor_deleteCharacter();
+    PostponedActions_perform();
+    Cursor_deleteCharacter();
+    PostponedActions_perform();
+    showSelection();
+}
+</script>
+</head>
+<body>
+[]
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/removedSpan03-expected.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/removedSpan03-expected.html b/Editor/tests/autocorrect/removedSpan03-expected.html
new file mode 100644
index 0000000..7bf269f
--- /dev/null
+++ b/Editor/tests/autocorrect/removedSpan03-expected.html
@@ -0,0 +1,5 @@
+<html>
+  <head>
+  </head>
+  <body><p>thex[]</p></body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/removedSpan03-input.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/removedSpan03-input.html b/Editor/tests/autocorrect/removedSpan03-input.html
new file mode 100644
index 0000000..71bcc2c
--- /dev/null
+++ b/Editor/tests/autocorrect/removedSpan03-input.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="AutoCorrectTests.js"></script>
+<script>
+function performTest()
+{
+    Outline_init();
+    AutoCorrect_init();
+    PostponedActions_perform();
+
+    Cursor_insertCharacter("teh");
+    AutoCorrect_correctPrecedingWord(3,"the");
+    Cursor_insertCharacter(" ");
+    PostponedActions_perform();
+    Cursor_deleteCharacter();
+    PostponedActions_perform();
+    Cursor_insertCharacter("x");
+    PostponedActions_perform();
+    showSelection();
+}
+</script>
+</head>
+<body>
+[]
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/replaceCorrection-undo-expected.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/replaceCorrection-undo-expected.html b/Editor/tests/autocorrect/replaceCorrection-undo-expected.html
new file mode 100644
index 0000000..e397207
--- /dev/null
+++ b/Editor/tests/autocorrect/replaceCorrection-undo-expected.html
@@ -0,0 +1,48 @@
+<html>
+  <head>
+  </head>
+  <body>
+    ==================== Version 0 ====================
+    <body>
+      <p>
+        one
+        <span class="uxwrite-autocorrect" original="twox">two</span>
+        three
+        <span class="uxwrite-autocorrect" original="fourx">four</span>
+        five
+        <span class="uxwrite-autocorrect" original="sixx">six</span>
+        seven[]
+      </p>
+    </body>
+    ==================== Version 1 ====================
+    <body>
+      <p>
+        one
+        <span class="uxwrite-autocorrect" original="twox">two</span>
+        three
+        <span class="uxwrite-autocorrect" original="fourx">four</span>
+        five r1 seven[]
+      </p>
+    </body>
+    ==================== Version 2 ====================
+    <body>
+      <p>
+        one
+        <span class="uxwrite-autocorrect" original="twox">two</span>
+        three r2 five r1 seven[]
+      </p>
+    </body>
+    ==================== Version 3 ====================
+    <body><p>one r3 three r2 five r1 seven[]</p></body>
+    ===================================================
+    First undo to version 2: OK
+    First undo to version 1: OK
+    First undo to version 0: OK
+    Redo to version 1: OK
+    Redo to version 2: OK
+    Redo to version 3: OK
+    Second undo to version 2: OK
+    Second undo to version 1: OK
+    Second undo to version 0: OK
+  </body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/replaceCorrection-undo-input.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/replaceCorrection-undo-input.html b/Editor/tests/autocorrect/replaceCorrection-undo-input.html
new file mode 100644
index 0000000..e08e838
--- /dev/null
+++ b/Editor/tests/autocorrect/replaceCorrection-undo-input.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="AutoCorrectTests.js"></script>
+<script src="../undo/UndoTests.js"></script>
+<script>
+function performTest()
+{
+    Outline_init();
+    AutoCorrect_init();
+    PostponedActions_perform();
+
+    Cursor_insertCharacter("one");
+    Cursor_insertCharacter(" twox");
+    AutoCorrect_correctPrecedingWord(4,"two");
+    Cursor_insertCharacter(" three");
+    Cursor_insertCharacter(" fourx");
+    AutoCorrect_correctPrecedingWord(5,"four");
+    Cursor_insertCharacter(" five");
+    Cursor_insertCharacter(" sixx");
+    AutoCorrect_correctPrecedingWord(4,"six");
+    Cursor_insertCharacter(" seven");
+    PostponedActions_perform();
+    showSelection();
+
+    UndoManager_clear();
+    var versions = new Array();
+    versions.push(DOM_cloneNode(document.body,true));
+    for (var i = 0; i < 3; i++) {
+        AutoCorrect_replaceCorrection("r"+(i+1));
+        PostponedActions_perform();
+        versions.push(DOM_cloneNode(document.body,true));
+    }
+
+    testUndo(versions,document.body);
+}
+</script>
+</head>
+<body>
+<p>[]</p>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/replaceCorrection01-expected.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/replaceCorrection01-expected.html b/Editor/tests/autocorrect/replaceCorrection01-expected.html
new file mode 100644
index 0000000..c253fcd
--- /dev/null
+++ b/Editor/tests/autocorrect/replaceCorrection01-expected.html
@@ -0,0 +1,14 @@
+<html>
+  <head>
+  </head>
+  <body>
+    <p>
+      one
+      <span class="uxwrite-autocorrect" original="twox">two</span>
+      three A five[]
+    </p>
+  </body>
+</html>
+
+Corrections:
+    twox -> two

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/replaceCorrection01-input.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/replaceCorrection01-input.html b/Editor/tests/autocorrect/replaceCorrection01-input.html
new file mode 100644
index 0000000..04574d8
--- /dev/null
+++ b/Editor/tests/autocorrect/replaceCorrection01-input.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="AutoCorrectTests.js"></script>
+<script>
+function performTest()
+{
+    Outline_init();
+    AutoCorrect_init();
+    PostponedActions_perform();
+
+    Cursor_insertCharacter("one");
+    Cursor_insertCharacter(" twox");
+    AutoCorrect_correctPrecedingWord(4,"two");
+    Cursor_insertCharacter(" three");
+    Cursor_insertCharacter(" fourx");
+    AutoCorrect_correctPrecedingWord(5,"four");
+    Cursor_insertCharacter(" five");
+    PostponedActions_perform();
+    showSelection();
+
+    AutoCorrect_replaceCorrection("A");
+    PostponedActions_perform();
+
+    return showCorrections();
+}
+</script>
+</head>
+<body>
+<p>[]</p>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/replaceCorrection02-expected.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/replaceCorrection02-expected.html b/Editor/tests/autocorrect/replaceCorrection02-expected.html
new file mode 100644
index 0000000..32f3134
--- /dev/null
+++ b/Editor/tests/autocorrect/replaceCorrection02-expected.html
@@ -0,0 +1,7 @@
+<html>
+  <head>
+  </head>
+  <body><p>one B three A five[]</p></body>
+</html>
+
+Corrections:

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/replaceCorrection02-input.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/replaceCorrection02-input.html b/Editor/tests/autocorrect/replaceCorrection02-input.html
new file mode 100644
index 0000000..d6fb6d0
--- /dev/null
+++ b/Editor/tests/autocorrect/replaceCorrection02-input.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="AutoCorrectTests.js"></script>
+<script>
+function performTest()
+{
+    Outline_init();
+    AutoCorrect_init();
+    PostponedActions_perform();
+
+    Cursor_insertCharacter("one");
+    Cursor_insertCharacter(" twox");
+    AutoCorrect_correctPrecedingWord(4,"two");
+    Cursor_insertCharacter(" three");
+    Cursor_insertCharacter(" fourx");
+    AutoCorrect_correctPrecedingWord(5,"four");
+    Cursor_insertCharacter(" five");
+    PostponedActions_perform();
+    showSelection();
+
+    AutoCorrect_replaceCorrection("A");
+    AutoCorrect_replaceCorrection("B");
+    PostponedActions_perform();
+
+    return showCorrections();
+}
+</script>
+</head>
+<body>
+<p>[]</p>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/replaceCorrection03-expected.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/replaceCorrection03-expected.html b/Editor/tests/autocorrect/replaceCorrection03-expected.html
new file mode 100644
index 0000000..024b644
--- /dev/null
+++ b/Editor/tests/autocorrect/replaceCorrection03-expected.html
@@ -0,0 +1,17 @@
+<html>
+  <head>
+  </head>
+  <body>
+    <p>
+      one A three
+      <span class="uxwrite-autocorrect" original="fourx">four</span>
+      five
+      <span class="uxwrite-autocorrect" original="sixx">six</span>
+      seven[]
+    </p>
+  </body>
+</html>
+
+Corrections:
+    fourx -> four
+    sixx -> six

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/replaceCorrection03-input.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/replaceCorrection03-input.html b/Editor/tests/autocorrect/replaceCorrection03-input.html
new file mode 100644
index 0000000..7e49201
--- /dev/null
+++ b/Editor/tests/autocorrect/replaceCorrection03-input.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="AutoCorrectTests.js"></script>
+<script>
+function performTest()
+{
+    Outline_init();
+    AutoCorrect_init();
+    PostponedActions_perform();
+
+    Cursor_insertCharacter("one");
+    Cursor_insertCharacter(" twox");
+    AutoCorrect_correctPrecedingWord(4,"two");
+    Cursor_insertCharacter(" three");
+    Cursor_insertCharacter(" fourx");
+    AutoCorrect_correctPrecedingWord(5,"four");
+    Cursor_insertCharacter(" five");
+    Cursor_insertCharacter(" sixx");
+    AutoCorrect_correctPrecedingWord(4,"six");
+    Cursor_insertCharacter(" seven");
+    PostponedActions_perform();
+    showSelection();
+
+    var text = findTextMatching("two");
+    Selection_set(text,0,text,0);
+
+    AutoCorrect_replaceCorrection("A");
+    PostponedActions_perform();
+
+    return showCorrections();
+}
+</script>
+</head>
+<body>
+<p>[]</p>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/replaceCorrection04-expected.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/replaceCorrection04-expected.html b/Editor/tests/autocorrect/replaceCorrection04-expected.html
new file mode 100644
index 0000000..ebc4b54
--- /dev/null
+++ b/Editor/tests/autocorrect/replaceCorrection04-expected.html
@@ -0,0 +1,17 @@
+<html>
+  <head>
+  </head>
+  <body>
+    <p>
+      one
+      <span class="uxwrite-autocorrect" original="twox">two</span>
+      three A five
+      <span class="uxwrite-autocorrect" original="sixx">six</span>
+      seven[]
+    </p>
+  </body>
+</html>
+
+Corrections:
+    twox -> two
+    sixx -> six

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/replaceCorrection04-input.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/replaceCorrection04-input.html b/Editor/tests/autocorrect/replaceCorrection04-input.html
new file mode 100644
index 0000000..9a47a03
--- /dev/null
+++ b/Editor/tests/autocorrect/replaceCorrection04-input.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="AutoCorrectTests.js"></script>
+<script>
+function performTest()
+{
+    Outline_init();
+    AutoCorrect_init();
+    PostponedActions_perform();
+
+    Cursor_insertCharacter("one");
+    Cursor_insertCharacter(" twox");
+    AutoCorrect_correctPrecedingWord(4,"two");
+    Cursor_insertCharacter(" three");
+    Cursor_insertCharacter(" fourx");
+    AutoCorrect_correctPrecedingWord(5,"four");
+    Cursor_insertCharacter(" five");
+    Cursor_insertCharacter(" sixx");
+    AutoCorrect_correctPrecedingWord(4,"six");
+    Cursor_insertCharacter(" seven");
+    PostponedActions_perform();
+    showSelection();
+
+    var text = findTextMatching("four");
+    Selection_set(text,0,text,0);
+
+    AutoCorrect_replaceCorrection("A");
+    PostponedActions_perform();
+
+    return showCorrections();
+}
+</script>
+</head>
+<body>
+<p>[]</p>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/replaceCorrection05-expected.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/replaceCorrection05-expected.html b/Editor/tests/autocorrect/replaceCorrection05-expected.html
new file mode 100644
index 0000000..5650843
--- /dev/null
+++ b/Editor/tests/autocorrect/replaceCorrection05-expected.html
@@ -0,0 +1,17 @@
+<html>
+  <head>
+  </head>
+  <body>
+    <p>
+      one
+      <span class="uxwrite-autocorrect" original="twox">two</span>
+      three
+      <span class="uxwrite-autocorrect" original="fourx">four</span>
+      five A seven[]
+    </p>
+  </body>
+</html>
+
+Corrections:
+    twox -> two
+    fourx -> four

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/replaceCorrection05-input.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/replaceCorrection05-input.html b/Editor/tests/autocorrect/replaceCorrection05-input.html
new file mode 100644
index 0000000..1d3b2ea
--- /dev/null
+++ b/Editor/tests/autocorrect/replaceCorrection05-input.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="AutoCorrectTests.js"></script>
+<script>
+function performTest()
+{
+    Outline_init();
+    AutoCorrect_init();
+    PostponedActions_perform();
+
+    Cursor_insertCharacter("one");
+    Cursor_insertCharacter(" twox");
+    AutoCorrect_correctPrecedingWord(4,"two");
+    Cursor_insertCharacter(" three");
+    Cursor_insertCharacter(" fourx");
+    AutoCorrect_correctPrecedingWord(5,"four");
+    Cursor_insertCharacter(" five");
+    Cursor_insertCharacter(" sixx");
+    AutoCorrect_correctPrecedingWord(4,"six");
+    Cursor_insertCharacter(" seven");
+    PostponedActions_perform();
+    showSelection();
+
+    var text = findTextMatching("six");
+    Selection_set(text,0,text,0);
+
+    AutoCorrect_replaceCorrection("A");
+    PostponedActions_perform();
+
+    return showCorrections();
+}
+</script>
+</head>
+<body>
+<p>[]</p>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/undo01-expected.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/undo01-expected.html b/Editor/tests/autocorrect/undo01-expected.html
new file mode 100644
index 0000000..f8ac7aa
--- /dev/null
+++ b/Editor/tests/autocorrect/undo01-expected.html
@@ -0,0 +1,17 @@
+<html>
+  <head>
+  </head>
+  <body>
+    <p>
+      one
+      <span class="uxwrite-autocorrect" original="twox">two</span>
+      three
+      <span class="uxwrite-autocorrect" original="fourx">four</span>
+      five[]
+    </p>
+  </body>
+</html>
+
+Corrections:
+    twox -> two
+    fourx -> four

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/undo01-input.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/undo01-input.html b/Editor/tests/autocorrect/undo01-input.html
new file mode 100644
index 0000000..35900a2
--- /dev/null
+++ b/Editor/tests/autocorrect/undo01-input.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="AutoCorrectTests.js"></script>
+<script>
+function performTest()
+{
+    Outline_init();
+    AutoCorrect_init();
+    PostponedActions_perform();
+
+    Cursor_insertCharacter("one");
+    Cursor_insertCharacter(" twox");
+    AutoCorrect_correctPrecedingWord(4,"two");
+    PostponedActions_perform();
+    Cursor_insertCharacter(" three");
+    Cursor_insertCharacter(" fourx");
+    AutoCorrect_correctPrecedingWord(5,"four");
+    PostponedActions_perform();
+    Cursor_insertCharacter(" five");
+
+    for (var i = 0; i < 0; i++) {
+        UndoManager_undo();
+    }
+
+    showSelection();
+
+    return showCorrections();
+}
+</script>
+</head>
+<body>
+<p>[]</p>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/undo02-expected.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/undo02-expected.html b/Editor/tests/autocorrect/undo02-expected.html
new file mode 100644
index 0000000..52d8d22
--- /dev/null
+++ b/Editor/tests/autocorrect/undo02-expected.html
@@ -0,0 +1,14 @@
+<html>
+  <head>
+  </head>
+  <body>
+    <p>
+      one
+      <span class="uxwrite-autocorrect" original="twox">two</span>
+      []
+    </p>
+  </body>
+</html>
+
+Corrections:
+    twox -> two

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/undo02-input.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/undo02-input.html b/Editor/tests/autocorrect/undo02-input.html
new file mode 100644
index 0000000..5dc1bc8
--- /dev/null
+++ b/Editor/tests/autocorrect/undo02-input.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="AutoCorrectTests.js"></script>
+<script>
+function performTest()
+{
+    Outline_init();
+    AutoCorrect_init();
+    PostponedActions_perform();
+
+    Cursor_insertCharacter("one");
+    Cursor_insertCharacter(" twox");
+    AutoCorrect_correctPrecedingWord(4,"two");
+    PostponedActions_perform();
+    Cursor_insertCharacter(" three");
+    Cursor_insertCharacter(" fourx");
+    AutoCorrect_correctPrecedingWord(5,"four");
+    PostponedActions_perform();
+    Cursor_insertCharacter(" five");
+
+    for (var i = 0; i < 3; i++) {
+        UndoManager_undo();
+    }
+
+    showSelection();
+
+    return showCorrections();
+}
+</script>
+</head>
+<body>
+<p>[]</p>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/undo03-expected.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/undo03-expected.html b/Editor/tests/autocorrect/undo03-expected.html
new file mode 100644
index 0000000..6900e6d
--- /dev/null
+++ b/Editor/tests/autocorrect/undo03-expected.html
@@ -0,0 +1,7 @@
+<html>
+  <head>
+  </head>
+  <body><p>one twox[]</p></body>
+</html>
+
+Corrections:

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/undo03-input.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/undo03-input.html b/Editor/tests/autocorrect/undo03-input.html
new file mode 100644
index 0000000..3e14c8d
--- /dev/null
+++ b/Editor/tests/autocorrect/undo03-input.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="AutoCorrectTests.js"></script>
+<script>
+function performTest()
+{
+    Outline_init();
+    AutoCorrect_init();
+    PostponedActions_perform();
+
+    Cursor_insertCharacter("one");
+    Cursor_insertCharacter(" twox");
+    AutoCorrect_correctPrecedingWord(4,"two");
+    PostponedActions_perform();
+    Cursor_insertCharacter(" three");
+    Cursor_insertCharacter(" fourx");
+    AutoCorrect_correctPrecedingWord(5,"four");
+    PostponedActions_perform();
+    Cursor_insertCharacter(" five");
+
+    for (var i = 0; i < 4; i++) {
+        UndoManager_undo();
+    }
+
+    showSelection();
+
+    return showCorrections();
+}
+</script>
+</head>
+<body>
+<p>[]</p>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/undo04-expected.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/undo04-expected.html b/Editor/tests/autocorrect/undo04-expected.html
new file mode 100644
index 0000000..f8ac7aa
--- /dev/null
+++ b/Editor/tests/autocorrect/undo04-expected.html
@@ -0,0 +1,17 @@
+<html>
+  <head>
+  </head>
+  <body>
+    <p>
+      one
+      <span class="uxwrite-autocorrect" original="twox">two</span>
+      three
+      <span class="uxwrite-autocorrect" original="fourx">four</span>
+      five[]
+    </p>
+  </body>
+</html>
+
+Corrections:
+    twox -> two
+    fourx -> four

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/undo04-input.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/undo04-input.html b/Editor/tests/autocorrect/undo04-input.html
new file mode 100644
index 0000000..84b9809
--- /dev/null
+++ b/Editor/tests/autocorrect/undo04-input.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="AutoCorrectTests.js"></script>
+<script>
+function performTest()
+{
+    Outline_init();
+    AutoCorrect_init();
+    PostponedActions_perform();
+
+    Cursor_insertCharacter("one");
+    Cursor_insertCharacter(" twox");
+    AutoCorrect_correctPrecedingWord(4,"two");
+    PostponedActions_perform();
+    Cursor_insertCharacter(" three");
+    Cursor_insertCharacter(" fourx");
+    AutoCorrect_correctPrecedingWord(5,"four");
+    PostponedActions_perform();
+    Cursor_insertCharacter(" five");
+
+    for (var i = 0; i < 4; i++) {
+        UndoManager_undo();
+    }
+    for (var i = 0; i < 4; i++) {
+        UndoManager_redo();
+    }
+
+    showSelection();
+
+    return showCorrections();
+}
+</script>
+</head>
+<body>
+<p>[]</p>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/undo05-expected.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/undo05-expected.html b/Editor/tests/autocorrect/undo05-expected.html
new file mode 100644
index 0000000..c664a24
--- /dev/null
+++ b/Editor/tests/autocorrect/undo05-expected.html
@@ -0,0 +1,52 @@
+<html>
+  <head>
+  </head>
+  <body>
+    ==================== Version 0 ====================
+    <p></p>
+    ==================== Version 1 ====================
+    <p>one twox</p>
+    ==================== Version 2 ====================
+    <p>
+      one
+      <span class="uxwrite-autocorrect" original="twox">two</span>
+    </p>
+    ==================== Version 3 ====================
+    <p>
+      one
+      <span class="uxwrite-autocorrect" original="twox">two</span>
+      three fourx
+    </p>
+    ==================== Version 4 ====================
+    <p>
+      one
+      <span class="uxwrite-autocorrect" original="twox">two</span>
+      three
+      <span class="uxwrite-autocorrect" original="fourx">four</span>
+    </p>
+    ==================== Version 5 ====================
+    <p>
+      one
+      <span class="uxwrite-autocorrect" original="twox">two</span>
+      three
+      <span class="uxwrite-autocorrect" original="fourx">four</span>
+      five
+    </p>
+    ===================================================
+    First undo to version 4: OK
+    First undo to version 3: OK
+    First undo to version 2: OK
+    First undo to version 1: OK
+    First undo to version 0: OK
+    Redo to version 1: OK
+    Redo to version 2: OK
+    Redo to version 3: OK
+    Redo to version 4: OK
+    Redo to version 5: OK
+    Second undo to version 4: OK
+    Second undo to version 3: OK
+    Second undo to version 2: OK
+    Second undo to version 1: OK
+    Second undo to version 0: OK
+  </body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/03bd5af0/Editor/tests/autocorrect/undo05-input.html
----------------------------------------------------------------------
diff --git a/Editor/tests/autocorrect/undo05-input.html b/Editor/tests/autocorrect/undo05-input.html
new file mode 100644
index 0000000..9acc3db
--- /dev/null
+++ b/Editor/tests/autocorrect/undo05-input.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="AutoCorrectTests.js"></script>
+<script src="../undo/UndoTests.js"></script>
+<script>
+function performTest()
+{
+    Outline_init();
+    AutoCorrect_init();
+    PostponedActions_perform();
+
+    UndoManager_clear();
+    var p = document.getElementsByTagName("P")[0];
+    var versions = new Array();
+    versions.push(DOM_cloneNode(p,true));
+    Cursor_insertCharacter("one");
+    Cursor_insertCharacter(" twox");
+    versions.push(DOM_cloneNode(p,true));
+    AutoCorrect_correctPrecedingWord(4,"two");
+    PostponedActions_perform();
+    versions.push(DOM_cloneNode(p,true));
+    Cursor_insertCharacter(" three");
+    Cursor_insertCharacter(" fourx");
+    versions.push(DOM_cloneNode(p,true));
+    AutoCorrect_correctPrecedingWord(5,"four");
+    PostponedActions_perform();
+    versions.push(DOM_cloneNode(p,true));
+    Cursor_insertCharacter(" five");
+    versions.push(DOM_cloneNode(p,true));
+
+    testUndo(versions,p);
+}
+</script>
+</head>
+<body>
+<p>[]</p>
+</body>
+</html>


Mime
View raw message