You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@corinthia.apache.org by ja...@apache.org on 2015/08/17 10:50:15 UTC

[23/28] incubator-corinthia git commit: included MOC compiler for Qt implementation

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/9bf02bb2/experiments/editorFramework/src/Javascript_Layer_0/Lists.js
----------------------------------------------------------------------
diff --git a/experiments/editorFramework/src/Javascript_Layer_0/Lists.js b/experiments/editorFramework/src/Javascript_Layer_0/Lists.js
new file mode 100644
index 0000000..a3a9772
--- /dev/null
+++ b/experiments/editorFramework/src/Javascript_Layer_0/Lists.js
@@ -0,0 +1,553 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 Lists_increaseIndent;
+var Lists_decreaseIndent;
+var Lists_clearList;
+var Lists_setUnorderedList;
+var Lists_setOrderedList;
+
+(function() {
+
+    // private
+    function findLIElements(range)
+    {
+        var listItems = new Array();
+
+        var node = range.start.node;
+        while (node != null) {
+
+            addListItems(listItems,node);
+
+            if (node == range.end.node)
+                break;
+
+            node = nextNode(node);
+        }
+        return listItems;
+
+        function addListItems(array,node)
+        {
+            if (node == null)
+                return;
+
+            if (node._type == HTML_LI) {
+                if (!arrayContains(array,node))
+                    array.push(node);
+                return;
+            }
+
+            if (!isWhitespaceTextNode(node))
+                addListItems(array,node.parentNode);
+        }
+    }
+
+    // public
+    Lists_increaseIndent = function()
+    {
+        Selection_preferElementPositions();
+        Selection_preserveWhileExecuting(function() {
+            var range = Selection_get();
+            if (range == null)
+                return null;
+
+            // Determine the set of LI nodes that are part of the selection
+            // Note that these could be spread out all over the place, e.g. in different lists,
+            // some in table cells etc
+            var listItems = findLIElements(range);
+
+            // For each LI node that is not the first in the list, move it to the child list of
+            // its previous sibling (creating the child list if necessary)
+
+            for (var i = 0; i < listItems.length; i++) {
+                var li = listItems[i];
+                var prevLi = li.previousSibling;
+                while ((prevLi != null) && (prevLi._type != HTML_LI))
+                    prevLi = prevLi.previousSibling;
+                // We can only increase the indentation of the current list item C if there is
+                // another list item P immediately preceding C. In this case, C becomes a child of
+                // another list L, where L is inside P. L may already exist, or we may need to
+                // create it.
+                if (prevLi != null) {
+                    var prevList = lastDescendentList(prevLi);
+                    var childList = firstDescendentList(li);
+                    var childListContainer = null;
+                    if (childList != null) {
+                        // childList may be contained inside one or more wrapper elements, in which
+                        // case we set childListContainer to point to the wrapper element that is a
+                        // child of li. Otherwise childListContainer will just be childList.
+                        childListContainer = childList;
+                        while (childListContainer.parentNode != li)
+                            childListContainer = childListContainer.parentNode;
+                    }
+
+                    if (prevList != null) {
+                        DOM_appendChild(prevList,li);
+                        if (childList != null) {
+                            while (childList.firstChild != null)
+                                DOM_appendChild(prevList,childList.firstChild);
+                            DOM_deleteNode(childListContainer);
+                            // alert("Case 1: prevList and childList");
+                        }
+                        else {
+                            // alert("Case 2: prevList and no childList");
+                        }
+                    }
+                    else {
+                        var newList;
+                        if (childList != null) {
+                            // alert("Case 3: no prevList but childList");
+                            newList = childList;
+                            DOM_appendChild(prevLi,childListContainer);
+                        }
+                        else {
+                            // alert("Case 4: no prevList and no childList");
+                            if (li.parentNode._type == HTML_UL)
+                                newList = DOM_createElement(document,"UL");
+                            else
+                                newList = DOM_createElement(document,"OL");
+                            DOM_appendChild(prevLi,newList);
+                        }
+                        DOM_insertBefore(newList,li,newList.firstChild);
+                    }
+                }
+            }
+        });
+
+        function firstDescendentList(node)
+        {
+            while (true) {
+                var node = firstChildElement(node);
+                if (node == null)
+                    return null;
+                switch (node._type) {
+                case HTML_UL:
+                case HTML_OL:
+                    return node;
+                }
+            }
+        }
+
+        function lastDescendentList(node)
+        {
+            while (true) {
+                var node = lastChildElement(node);
+                if (node == null)
+                    return null;
+                switch (node._type) {
+                case HTML_UL:
+                case HTML_OL:
+                    return node;
+                }
+            }
+        }
+    }
+
+    // public
+    Lists_decreaseIndent = function()
+    {
+        Selection_preferElementPositions();
+        Selection_preserveWhileExecuting(function() {
+            var range = Selection_get();
+            if (range == null)
+                return null;
+
+            // Determine the set of LI nodes that are part of the selection
+            // Note that these could be spread out all over the place, e.g. in different lists,
+            // some in table cells etc
+            var listItems = findLIElements(range);
+
+            // Remove from consideration any list items that have an ancestor that is going to
+            // be moved
+            var i = 0;
+            var changed;
+            while (i < listItems.length) {
+                var node = listItems[i];
+
+                var ancestorToBeRemoved = false;
+                for (var ancestor = node.parentNode;
+                     ancestor != null;
+                     ancestor = ancestor.parentNode) {
+                    if (arrayContains(listItems,ancestor))
+                        ancestorToBeRemoved = true;
+                }
+
+                if (ancestorToBeRemoved)
+                    listItems.splice(i,1);
+                else
+                    i++;
+            }
+
+            function haveContentAfter(node)
+            {
+                for (node = node.nextSibling; node != null; node = node.nextSibling) {
+                    if (nodeHasContent(node))
+                        return true;
+                }
+                return false;
+            }
+
+            // For LI nodes that are in a top-level list, change them to regular paragraphs
+            // For LI nodes that are part of a nested list, move them to the parent (this requires
+            // splitting the child list in two)
+            for (var i = 0; i < listItems.length; i++) {
+                var liNode = listItems[i];
+                var listNode = liNode.parentNode;
+                var containerChild = findContainerChild(listNode);
+
+                if (haveContentAfter(liNode)) {
+                    var secondHalf;
+                    if (listNode._type == HTML_UL)
+                        secondHalf = DOM_createElement(document,"UL");
+                    else
+                        secondHalf = DOM_createElement(document,"OL");
+
+                    DOM_appendChild(liNode,secondHalf);
+
+                    var following = liNode.nextSibling;
+                    while (following != null) {
+                        var next = following.nextSibling;
+                        DOM_appendChild(secondHalf,following);
+                        following = next;
+                    }
+                }
+
+                DOM_insertBefore(containerChild.parentNode,liNode,containerChild.nextSibling);
+                if (!isListNode(liNode.parentNode)) {
+                    Hierarchy_avoidInlineChildren(liNode);
+                    DOM_removeNodeButKeepChildren(liNode);
+                }
+
+                if (!nodeHasContent(listNode))
+                    DOM_deleteNode(listNode);
+            }
+        });
+
+        function findContainerChild(node)
+        {
+            while (node.parentNode != null) {
+                if (isContainerNode(node.parentNode) && (node.parentNode._type != HTML_LI))
+                    return node;
+                node = node.parentNode;
+            }
+        }
+    }
+
+    // private
+    function getListOperationNodes(range)
+    {
+        var detail = Range_detail(range);
+        var dca = detail.commonAncestor;
+        var ds = detail.startAncestor;
+        var de = detail.endAncestor;
+
+        while (isInlineNode(dca)) {
+            ds = dca;
+            de = dca;
+            dca = dca.parentNode;
+        }
+
+        var nodes = new Array();
+        var nodeSet = new NodeSet();
+
+        if (dca._type == HTML_LI)
+            return [dca];
+
+        // If, after moving up the tree until dca is a container node, a single node is selected,
+        // check if it is wholly contained within a single list item. If so, select just that
+        // list item.
+        var isStartLI = ((ds != null) && (ds._type == HTML_LI));
+        var isEndLI = ((de != null) && (de._type == HTML_LI));
+        if (!isStartLI && !isEndLI) {
+            for (var ancestor = dca; ancestor.parentNode != null; ancestor = ancestor.parentNode) {
+                if (ancestor.parentNode._type == HTML_LI) {
+                    var firstElement = true;
+
+                    for (var p = ancestor.previousSibling; p != null; p = p.previousSibling) {
+                        if (p.nodeType == Node.ELEMENT_NODE) {
+                            firstElement = false;
+                            break;
+                        }
+                    }
+
+                    if (firstElement)
+                        return [ancestor.parentNode];
+                }
+            }
+        }
+
+        var end = (de == null) ? null : de.nextSibling;
+
+        for (var child = ds; child != end; child = child.nextSibling) {
+            switch (child._type) {
+            case HTML_UL:
+            case HTML_OL:
+                for (var gc = child.firstChild; gc != null; gc = gc.nextSibling) {
+                    if (!isWhitespaceTextNode(gc))
+                        addNode(gc);
+                }
+                break;
+            default:
+                if ((child._type == HTML_DIV) &&
+                     child.getAttribute("class") == Keys.SELECTION_HIGHLIGHT) {
+                    // skip
+                }
+                else if (!isWhitespaceTextNode(child)) {
+                    addNode(child);
+                }
+                break;
+            }
+        }
+        if ((nodes.length == 0) && isParagraphNode(dca))
+            nodes.push(dca);
+        return nodes;
+
+        function addNode(node)
+        {
+            while (isInlineNode(node) && node.parentNode != document.body)
+                node = node.parentNode;
+            if (!nodeSet.contains(node)) {
+                nodeSet.add(node);
+                nodes.push(node);
+            }
+        }
+    }
+
+    // public
+    Lists_clearList = function()
+    {
+        Selection_preferElementPositions();
+        Selection_preserveWhileExecuting(function() {
+            var range = Selection_get();
+            if (range == null)
+                return;
+            Range_ensureInlineNodesInParagraph(range);
+
+            var nodes = getListOperationNodes(range);
+
+            for (var i = 0; i < nodes.length; i++) {
+                var node = nodes[i];
+                if (node._type == HTML_LI) {
+                    var li = node;
+                    var list = li.parentNode;
+                    var insertionPoint = null;
+
+                    DOM_removeAdjacentWhitespace(li);
+
+                    if (li.previousSibling == null) {
+                        insertionPoint = list;
+                    }
+                    else if (li.nextSibling == null) {
+                        insertionPoint = list.nextSibling;
+                    }
+                    else {
+                        var secondList = DOM_shallowCopyElement(list);
+                        DOM_insertBefore(list.parentNode,secondList,list.nextSibling);
+                        while (li.nextSibling != null) {
+                            DOM_appendChild(secondList,li.nextSibling);
+                            DOM_removeAdjacentWhitespace(li);
+                        }
+
+                        insertionPoint = secondList;
+                    }
+
+                    var parent = null;
+                    var child = li.firstChild;
+                    while (child != null) {
+                        var next = child.nextSibling;
+                        if (isInlineNode(child) && !isWhitespaceTextNode(child)) {
+                            child = Hierarchy_wrapInlineNodesInParagraph(child);
+                            next = child.nextSibling;
+                        }
+                        child = next;
+                    }
+                    DOM_insertBefore(list.parentNode,li,insertionPoint);
+                    DOM_removeNodeButKeepChildren(li);
+
+                    if (list.firstChild == null)
+                        DOM_deleteNode(list);
+                }
+            }
+        });
+
+        var range = Selection_get();
+        if (range == null)
+            return;
+        if (Range_isEmpty(range) &&
+            (range.start.node.nodeType == Node.ELEMENT_NODE) &&
+            (isContainerNode(range.start.node))) {
+
+            var p = DOM_createElement(document,"P");
+
+            var next = range.start.node.childNodes[range.start.offset+1];
+            DOM_insertBefore(range.start.node,p,next);
+
+            Cursor_updateBRAtEndOfParagraph(p);
+            Selection_set(p,0,p,0);
+        }
+    }
+
+    // private
+    function setList(type)
+    {
+        var range = Selection_get();
+        if (range == null)
+            return;
+
+        var nodes = getListOperationNodes(range);
+
+        if (nodes.length == 0) {
+            var text;
+            if (range.start.node.nodeType == Node.TEXT_NODE) {
+                text = range.start.node;
+            }
+            else if (range.start.node.nodeType == Node.ELEMENT_NODE) {
+                text = DOM_createTextNode(document,"");
+                DOM_insertBefore(range.start.node,
+                                 text,
+                                 range.start.node[range.start.offset+1]);
+            }
+            nodes = [text];
+
+            var offset = DOM_nodeOffset(text);
+            Selection_set(text,0,text,0);
+            range = Selection_get();
+        }
+
+        Range_trackWhileExecuting(range,function () {
+            // Set list to UL or OL
+
+            for (var i = 0; i < nodes.length; i++) {
+                var node = nodes[i];
+                var next;
+                var prev;
+                var li = null;
+                var oldList = null;
+                var listInsertionPoint;
+
+                if ((node._type == HTML_LI) && (node.parentNode._type == type)) {
+                    // Already in the correct type of list; don't need to do anything
+                    continue;
+                }
+
+                if (node._type == HTML_LI) {
+                    li = node;
+                    var list = li.parentNode;
+
+                    DOM_removeAdjacentWhitespace(list);
+                    prev = list.previousSibling;
+                    next = list.nextSibling;
+
+
+                    DOM_removeAdjacentWhitespace(li);
+
+                    if (li.previousSibling == null) {
+                        listInsertionPoint = list;
+                        next = null;
+                    }
+                    else if (li.nextSibling == null) {
+                        listInsertionPoint = list.nextSibling;
+                        prev = null;
+                    }
+                    else {
+                        var secondList = DOM_shallowCopyElement(list);
+                        DOM_insertBefore(list.parentNode,secondList,list.nextSibling);
+                        while (li.nextSibling != null) {
+                            DOM_insertBefore(secondList,li.nextSibling,null);
+                            DOM_removeAdjacentWhitespace(li);
+                        }
+
+                        listInsertionPoint = secondList;
+
+                        prev = null;
+                        next = null;
+                    }
+
+                    node = list;
+                    oldList = list;
+                }
+                else {
+                    DOM_removeAdjacentWhitespace(node);
+                    prev = node.previousSibling;
+                    next = node.nextSibling;
+                    listInsertionPoint = node;
+                }
+
+                var list;
+                var itemInsertionPoint;
+
+                if ((prev != null) && (prev._type == type)) {
+                    list = prev;
+                    itemInsertionPoint = null;
+                }
+                else if ((next != null) && (next._type == type)) {
+                    list = next;
+                    itemInsertionPoint = list.firstChild;
+                }
+                else {
+                    if (type == HTML_UL)
+                        list = DOM_createElement(document,"UL");
+                    else
+                        list = DOM_createElement(document,"OL");
+                    DOM_insertBefore(node.parentNode,list,listInsertionPoint);
+                    itemInsertionPoint = null;
+                }
+
+                if (li != null) {
+                    DOM_insertBefore(list,li,itemInsertionPoint);
+                }
+                else {
+                    var li = DOM_createElement(document,"LI");
+                    DOM_insertBefore(list,li,itemInsertionPoint);
+                    DOM_insertBefore(li,node,null);
+                }
+
+
+                if ((oldList != null) && (oldList.firstChild == null))
+                    DOM_deleteNode(oldList);
+
+                // Merge with adjacent list
+                DOM_removeAdjacentWhitespace(list);
+                if ((list.nextSibling != null) && (list.nextSibling._type == type)) {
+                    var followingList = list.nextSibling;
+                    while (followingList.firstChild != null) {
+                        if (isWhitespaceTextNode(followingList.firstChild))
+                            DOM_deleteNode(followingList.firstChild);
+                        else
+                            DOM_insertBefore(list,followingList.firstChild,null);
+                    }
+                    DOM_deleteNode(followingList);
+                }
+            }
+        });
+        Range_ensureValidHierarchy(range);
+        Selection_set(range.start.node,range.start.offset,range.end.node,range.end.offset);
+    }
+
+    // public
+    Lists_setUnorderedList = function()
+    {
+        setList(HTML_UL);
+    }
+
+    // public
+    Lists_setOrderedList = function()
+    {
+        setList(HTML_OL);
+    }
+
+})();

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/9bf02bb2/experiments/editorFramework/src/Javascript_Layer_0/Main.js
----------------------------------------------------------------------
diff --git a/experiments/editorFramework/src/Javascript_Layer_0/Main.js b/experiments/editorFramework/src/Javascript_Layer_0/Main.js
new file mode 100644
index 0000000..f123423
--- /dev/null
+++ b/experiments/editorFramework/src/Javascript_Layer_0/Main.js
@@ -0,0 +1,393 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 Main_getLanguage;
+var Main_setLanguage;
+var Main_setGenerator;
+var Main_isEmptyDocument;
+var Main_prepareForSave;
+var Main_getHTML;
+var Main_getErrorReportingInfo;
+var Main_removeUnsupportedInput;
+var Main_removeSpecial;
+var Main_execute;
+var Main_init;
+
+var Main_clientRectsBug;
+
+(function() {
+
+    // public
+    Main_getLanguage = function()
+    {
+        var lang = document.documentElement.getAttribute("lang");
+        if (lang != null)
+            lang = lang.replace(/-/g,"_");
+        return lang;
+    }
+
+    // public
+    Main_setLanguage = function(lang)
+    {
+        if ((lang == null) || (lang == "")) {
+            DOM_removeAttribute(document.documentElement,"lang");
+        }
+        else {
+            lang = lang.replace(/_/g,"-");
+            DOM_setAttribute(document.documentElement,"lang",lang);
+        }
+    }
+
+    // public
+    Main_removeUnsupportedInput = function()
+    {
+        recurse(document.documentElement);
+
+        function recurse(node)
+        {
+            // Delete comments and processing instructions
+            if ((node.nodeType != Node.TEXT_NODE) &&
+                (node.nodeType != Node.ELEMENT_NODE)) {
+                DOM_deleteNode(node);
+            }
+            else {
+                var next;
+                for (var child = node.firstChild; child != null; child = next) {
+                    next = child.nextSibling;
+                    recurse(child);
+                }
+            }
+        }
+    }
+
+    // private
+    function addMetaCharset()
+    {
+        var head = DOM_documentHead(document);
+        var next;
+        for (var child = head.firstChild; child != null; child = next) {
+            next = child.nextSibling;
+            if ((child._type == HTML_META) && (child.hasAttribute("charset"))) {
+                DOM_deleteNode(child);
+            }
+            else if ((child._type == HTML_META) && child.hasAttribute("http-equiv") &&
+                     (child.getAttribute("http-equiv").toLowerCase() == "content-type")) {
+                DOM_deleteNode(child);
+            }
+        }
+
+        var meta = DOM_createElement(document,"META");
+        DOM_setAttribute(meta,"charset","utf-8");
+        DOM_insertBefore(head,meta,head.firstChild);
+    }
+
+    // public
+    Main_setGenerator = function(generator)
+    {
+        return UndoManager_disableWhileExecuting(function() {
+            var head = DOM_documentHead(document);
+            for (var child = head.firstChild; child != null; child = child.nextSibling) {
+                if ((child._type == HTML_META) &&
+                    child.hasAttribute("name") &&
+                    (child.getAttribute("name").toLowerCase() == "generator")) {
+                    var origGenerator = DOM_getAttribute(child,"content");
+                    DOM_setAttribute(child,"content",generator);
+
+                    if (origGenerator == null)
+                        return "";
+                    else
+                        return origGenerator;
+                }
+            }
+
+            var meta = DOM_createElement(document,"META");
+            DOM_setAttribute(meta,"name","generator");
+            DOM_setAttribute(meta,"content",generator);
+            DOM_insertBefore(head,meta,head.firstChild);
+
+            return "";
+        });
+    }
+
+    // public
+    Main_isEmptyDocument = function()
+    {
+        return !nodeHasContent(document.body);
+    }
+
+    // public
+    Main_prepareForSave = function()
+    {
+        // Force any end-of-group actions to be performed
+        UndoManager_newGroup();
+        return true;
+    }
+
+    // public
+    Main_getHTML = function()
+    {
+        return document.documentElement.outerHTML;
+    }
+
+    // public
+    Main_getErrorReportingInfo = function()
+    {
+        if (document.documentElement == null)
+            return "(document.documentElement is null)";
+        try {
+            var html = htmlWithSelection();
+            cleanse(html);
+            return html.outerHTML;
+        }
+        catch (e) {
+            try {
+                var html = DOM_cloneNode(document.documentElement,true);
+                cleanse(html);
+                return html.outerHTML+"\n[Error getting selection: "+e+"]";
+            }
+            catch (e2) {
+                return "[Error getting HTML: "+e2+"]";
+            }
+        }
+
+        function cleanse(node)
+        {
+            switch (node._type) {
+            case HTML_TEXT:
+            case HTML_COMMENT:
+                DOM_setNodeValue(node,cleanseString(node.nodeValue));
+                break;
+            case HTML_STYLE:
+            case HTML_SCRIPT:
+                return;
+            default:
+                if (node.nodeType == Node.ELEMENT_NODE) {
+                    cleanseAttribute(node,"original");
+                    if (node.hasAttribute("href") && !node.getAttribute("href").match(/^#/))
+                        cleanseAttribute(node,"href");
+                    for (var child = node.firstChild; child != null; child = child.nextSibling)
+                        cleanse(child);
+                }
+                break;
+            }
+        }
+
+        function cleanseAttribute(node,name)
+        {
+            if (node.hasAttribute(name)) {
+                var value = node.getAttribute(name);
+                value = cleanseString(value);
+                DOM_setAttribute(node,name,value);
+            }
+        }
+
+        function cleanseString(str)
+        {
+            return str.replace(/[^\s\.\@\^]/g,"X");
+        }
+
+        function htmlWithSelection()
+        {
+            var selectionRange = Selection_get();
+            if (selectionRange != null) {
+                selectionRange = Range_forwards(selectionRange);
+                var startSave = new Object();
+                var endSave = new Object();
+
+                var html = null;
+
+                Range_trackWhileExecuting(selectionRange,function() {
+                    // We use the strings @@^^ and ^^@@ to represent the selection
+                    // start and end, respectively. The reason for this is that after we have
+                    // cloned the tree, all text will be removed. We keeping the @ and ^
+                    // characters so we have some way to identifiy the selection markers;
+                    // leaving these in is not going to reveal any confidential information.
+
+                    addPositionMarker(selectionRange.end,"^^@@",endSave);
+                    addPositionMarker(selectionRange.start,"@@^^",startSave);
+
+                    html = DOM_cloneNode(document.documentElement,true);
+
+                    removePositionMarker(selectionRange.start,startSave);
+                    removePositionMarker(selectionRange.end,endSave);
+                });
+
+                return html;
+            }
+            else {
+                return DOM_cloneNode(document.documentElement,true);
+            }
+        }
+
+        function addPositionMarker(pos,name,save)
+        {
+            var node = pos.node;
+            var offset = pos.offset;
+            if (node.nodeType == Node.ELEMENT_NODE) {
+                save.tempNode = DOM_createTextNode(document,name);
+                DOM_insertBefore(node,save.tempNode,node.childNodes[offset]);
+            }
+            else if (node.nodeType == Node.TEXT_NODE) {
+                save.originalNodeValue = node.nodeValue;
+                node.nodeValue = node.nodeValue.slice(0,offset) + name + node.nodeValue.slice(offset);
+            }
+        }
+
+        function removePositionMarker(pos,save)
+        {
+            var node = pos.node;
+            var offset = pos.offset;
+            if (pos.node.nodeType == Node.ELEMENT_NODE) {
+                DOM_deleteNode(save.tempNode);
+            }
+            else if (pos.node.nodeType == Node.TEXT_NODE) {
+                node.nodeValue = save.originalNodeValue;
+            }
+        }
+    }
+
+    // public
+    Main_removeSpecial = function(node)
+    {
+        // We process the children first, so that if there are any nested removable elements (e.g.
+        // a selection span inside of an autocorrect span), all levels of nesting are taken care of
+        var next;
+        for (var child = node.firstChild; child != null; child = next) {
+            next = child.nextSibling;
+            Main_removeSpecial(child);
+        }
+
+        var cssClass = null;
+        if ((node.nodeType == Node.ELEMENT_NODE) && node.hasAttribute("class"))
+            cssClass = node.getAttribute("class");
+
+        if ((cssClass == Keys.HEADING_NUMBER) ||
+            (cssClass == Keys.FIGURE_NUMBER) ||
+            (cssClass == Keys.TABLE_NUMBER) ||
+            (cssClass == Keys.AUTOCORRECT_CLASS) ||
+            (cssClass == Keys.SELECTION_CLASS) ||
+            (cssClass == Keys.SELECTION_HIGHLIGHT)) {
+            DOM_removeNodeButKeepChildren(node);
+        }
+        else if ((node._type == HTML_META) &&
+                 node.hasAttribute("name") &&
+                 (node.getAttribute("name").toLowerCase() == "viewport")) {
+            DOM_deleteNode(node);
+        }
+        else if (node._type == HTML_LINK) {
+            if ((node.getAttribute("rel") == "stylesheet") &&
+                (node.getAttribute("href") == Styles_getBuiltinCSSURL())) {
+                DOM_deleteNode(node);
+            }
+        }
+    }
+
+    function simplifyStackString(e)
+    {
+        if (e.stack == null)
+            return "";
+        var lines = e.stack.toString().split(/\n/);
+        for (var i = 0; i < lines.length; i++) {
+            var nameMatch = lines[i].match(/^(.*)@/);
+            var name = (nameMatch != null) ? nameMatch[1] : "(anonymous function)";
+            var locMatch = lines[i].match(/:([0-9]+:[0-9]+)$/);
+            var loc = (locMatch != null) ? locMatch[1] : "?";
+            lines[i] = "stack["+(lines.length-i-1)+"] = "+name+"@"+loc;
+        }
+        return lines.join("\n");
+    }
+
+    // public
+    Main_execute = function(fun)
+    {
+        try {
+            var res = fun();
+            PostponedActions_perform();
+            return res;
+        }
+        catch (e) {
+            var message = (e.message != null) ? e.message : e.toString();
+            var stack = simplifyStackString(e);
+            Editor_error(message+"\n"+stack);
+        }
+    }
+
+    function fixEmptyBody()
+    {
+        for (var child = document.body.firstChild; child != null; child = child.nextSibling) {
+            if (nodeHasContent(child))
+                return;
+        }
+
+        for (var child = document.body.firstChild; child != null; child = child.nextSibling) {
+            if (child._type == HTML_P) {
+                Cursor_updateBRAtEndOfParagraph(child);
+                return;
+            }
+        }
+
+        var p = DOM_createElement(document,"P");
+        var br = DOM_createElement(document,"BR");
+        DOM_appendChild(p,br);
+        DOM_appendChild(document.body,p);
+    }
+
+    // public
+    Main_init = function(width,textScale,cssURL,clientRectsBug)
+    {
+        try {
+            Main_clientRectsBug = clientRectsBug;
+            if (document.documentElement == null)
+                throw new Error("document.documentElement is null");
+            if (document.body == null)
+                throw new Error("document.body is null");
+            var timing = new TimingInfo();
+            timing.start();
+            DOM_assignNodeIds(document);
+            timing.addEntry("DOM_assignNodeIds");
+            Main_removeUnsupportedInput();
+            timing.addEntry("Main_removeUnsupportedInput");
+            addMetaCharset();
+            timing.addEntry("addMetaCharset");
+            fixEmptyBody();
+            timing.addEntry("fixEmptyBody");
+            Outline_init();
+            timing.addEntry("Outline_init");
+            Styles_init(cssURL);
+            timing.addEntry("Styles_init");
+            Viewport_init(width,textScale);
+            timing.addEntry("Viewport_init");
+            AutoCorrect_init();
+            timing.addEntry("AutoCorrect_init");
+
+            PostponedActions_perform();
+            timing.addEntry("PostponedActions_perform");
+            Cursor_moveToStartOfDocument();
+            timing.addEntry("Cursor_moveToStartOfDocument");
+
+            UndoManager_clear();
+            timing.addEntry("UndoManager_clear");
+//            timing.print();
+
+            return true;
+        }
+        catch (e) {
+            return e.toString();
+        }
+    }
+
+})();

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/9bf02bb2/experiments/editorFramework/src/Javascript_Layer_0/Metadata.js
----------------------------------------------------------------------
diff --git a/experiments/editorFramework/src/Javascript_Layer_0/Metadata.js b/experiments/editorFramework/src/Javascript_Layer_0/Metadata.js
new file mode 100644
index 0000000..fce4cca
--- /dev/null
+++ b/experiments/editorFramework/src/Javascript_Layer_0/Metadata.js
@@ -0,0 +1,32 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 Metadata_getMetadata;
+var Metadata_setMetadata;
+
+(function() {
+
+    Metadata_getMetadata = function()
+    {
+        return {};
+    }
+
+    Metadata_setMetadata = function(metadata)
+    {
+    }
+
+})();

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/9bf02bb2/experiments/editorFramework/src/Javascript_Layer_0/NodeSet.js
----------------------------------------------------------------------
diff --git a/experiments/editorFramework/src/Javascript_Layer_0/NodeSet.js b/experiments/editorFramework/src/Javascript_Layer_0/NodeSet.js
new file mode 100644
index 0000000..77b7600
--- /dev/null
+++ b/experiments/editorFramework/src/Javascript_Layer_0/NodeSet.js
@@ -0,0 +1,201 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 NodeSet()
+{
+    this.members = new Object();
+}
+
+NodeSet.prototype.add = function(node)
+{
+    if (node._nodeId == null)
+        throw new Error("NodeSet.add: node "+node.nodeName+" has no _nodeId property");
+    this.members[node._nodeId] = node;
+}
+
+NodeSet.prototype.remove = function(node)
+{
+    if (node._nodeId == null)
+        throw new Error("NodeSet.remove: node "+node.nodeName+" has no _nodeId property");
+    delete this.members[node._nodeId];
+}
+
+NodeSet.prototype.contains = function(node)
+{
+    if (node._nodeId == null)
+        throw new Error("NodeSet.contains: node "+node.nodeName+" has no _nodeId property");
+    return (this.members[node._nodeId] != null);
+}
+
+NodeSet.prototype.toArray = function()
+{
+    var result = new Array();
+    for (var id in this.members)
+        result.push(members[id]);
+    return result;
+}
+
+NodeSet.prototype.forEach = function(fun)
+{
+    var ids = Object.getOwnPropertyNames(this.members);
+    var set = this;
+    ids.forEach(function(id) { fun(set.members[id]); });
+}
+
+NodeSet.prototype.ancestor = function()
+{
+    var result = new NodeSet();
+    this.forEach(function (node) {
+        for (var p = node.parentNode; p != null; p = p.parentNode)
+            result.add(p);
+    });
+    return result;
+}
+
+NodeSet.prototype.ancestorOrSelf = function()
+{
+    var result = new NodeSet();
+    this.forEach(function (node) {
+        for (var p = node; p != null; p = p.parentNode)
+            result.add(p);
+    });
+    return result;
+}
+
+NodeSet.prototype.descendant = function()
+{
+    var result = new NodeSet();
+    this.forEach(function (node) {
+        recurse(node);
+    });
+    return result;
+
+    function recurse(node)
+    {
+        for (var child = node.firstChild; child != null; child = child.nextSibling) {
+            result.add(child);
+            recurse(child);
+        }
+    }
+}
+
+NodeSet.prototype.descendantOrSelf = function()
+{
+    var result = new NodeSet();
+    this.forEach(function (node) {
+        recurse(node);
+    });
+    return result;
+
+    function recurse(node)
+    {
+        result.add(node);
+        for (var child = node.firstChild; child != null; child = child.nextSibling)
+            recurse(child);
+    }
+}
+
+NodeSet.prototype.union = function(other)
+{
+    var result = new NodeSet();
+    this.forEach(function (node) { result.add(node); });
+    other.forEach(function (node) { result.add(node); });
+    return result;
+}
+
+NodeSet.prototype.intersection = function(other)
+{
+    var result = new NodeSet();
+    this.forEach(function (node) { if (other.contains(node)) { result.add(node); } });
+    return result;
+}
+
+NodeSet.fromArray = function(array)
+{
+    var set = new NodeSet();
+    array.forEach(function(node) { set.add(node); });
+    return set;
+}
+
+
+function NodeMap()
+{
+    this.keys = new Object();
+    this.values = new Object();
+}
+
+NodeMap.prototype.clear = function()
+{
+    this.keys = new Object();
+    this.values = new Object();
+}
+
+NodeMap.prototype.get = function(key)
+{
+    if (key._nodeId == null)
+        throw new Error("NodeMap.get: key "+key.keyName+" has no _nodeId property");
+    return this.values[key._nodeId];
+}
+
+NodeMap.prototype.put = function(key,value)
+{
+    if (key._nodeId == null)
+        throw new Error("NodeMap.add: key "+key.keyName+" has no _nodeId property");
+    this.keys[key._nodeId] = key;
+    this.values[key._nodeId] = value;
+}
+
+NodeMap.prototype.remove = function(key)
+{
+    if (key._nodeId == null)
+        throw new Error("NodeMap.remove: key "+key.keyName+" has no _nodeId property");
+    delete this.keys[key._nodeId];
+    delete this.values[key._nodeId];
+}
+
+NodeMap.prototype.containsKey = function(key)
+{
+    if (key._nodeId == null)
+        throw new Error("NodeMap.contains: key "+key.keyName+" has no _nodeId property");
+    return (this.values[key._nodeId] != null);
+}
+
+NodeMap.prototype.getKeys = function()
+{
+    var ids = Object.getOwnPropertyNames(this.values);
+    var result = new Array(ids.length);
+    for (var i = 0; i < ids.length; i++)
+        result[i] = this.keys[ids[i]];
+    return result;
+}
+
+NodeMap.prototype.forEach = function(fun)
+{
+    var ids = Object.getOwnPropertyNames(this.values);
+    var map = this;
+    ids.forEach(function(id) { fun(map.keys[id],map.values[id]); });
+}
+
+NodeMap.fromArray = function(array,fun)
+{
+    var map = new NodeMap();
+    if (fun != null)
+        array.forEach(function(node) { map.put(node,fun(node)); });
+    else
+        array.forEach(function(node) { map.put(node,null); });
+    return map;
+};