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:06 UTC
[14/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/Layer0_Javascript/Clipboard.js
----------------------------------------------------------------------
diff --git a/experiments/editorFramework/src/Layer0_Javascript/Clipboard.js b/experiments/editorFramework/src/Layer0_Javascript/Clipboard.js
deleted file mode 100644
index 03efdcc..0000000
--- a/experiments/editorFramework/src/Layer0_Javascript/Clipboard.js
+++ /dev/null
@@ -1,757 +0,0 @@
-// 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 Markdown_htmlToMarkdown;
-var Clipboard_htmlToText;
-var Clipboard_cut;
-var Clipboard_copy;
-var Clipboard_pasteText;
-var Clipboard_pasteHTML;
-var Clipboard_pasteNodes;
-
-(function() {
-
- // private
- function blockToText(md,node,indent,nextIndent,listType,listNo)
- {
- var linesBetweenChildren = 1;
- var childIndent = indent;
- switch (node._type) {
- case HTML_LI:
- if (listType == "OL") {
- var listMarker;
- if (listNo.value < 10)
- listMarker = listNo.value+". ";
- else
- listMarker = listNo.value+". ";
- beginParagraph(md,0,indent,nextIndent,listMarker);
- nextIndent += " ";
- }
- else {
- beginParagraph(md,0,indent,nextIndent," - ");
- nextIndent += " ";
- }
- listNo.value++;
- break;
- case HTML_UL:
- listType = "UL";
- listNo = { value: 1 };
- beginParagraph(md,1,indent,nextIndent);
- linesBetweenChildren = 0;
- break;
- case HTML_OL:
- listType = "OL";
- listNo = { value: 1 };
- beginParagraph(md,1,indent,nextIndent);
- linesBetweenChildren = 0;
- break;
- case HTML_H1:
- beginParagraph(md,1,indent,nextIndent,"# "," #");
- break;
- case HTML_H2:
- beginParagraph(md,1,indent,nextIndent,"## "," ##");
- break;
- case HTML_H3:
- beginParagraph(md,1,indent,nextIndent,"### "," ###");
- break;
- case HTML_H4:
- beginParagraph(md,1,indent,nextIndent,"#### "," ####");
- break;
- case HTML_H5:
- beginParagraph(md,1,indent,nextIndent,"##### "," #####");
- break;
- case HTML_H6:
- beginParagraph(md,1,indent,nextIndent,"###### "," ######");
- break;
- case HTML_BLOCKQUOTE:
- beginParagraph(md,1,indent,nextIndent,"> ");
- nextIndent += "> ";
- break;
- case HTML_PRE:
- md.preDepth++;
- break;
- }
-
- var foundNonWhitespaceChild = false;
- for (var child = node.firstChild; child != null; child = child.nextSibling) {
- if (isContainerNode(child) || isParagraphNode(child)) {
- beginParagraph(md,linesBetweenChildren,indent,nextIndent);
- blockToText(md,child,indent,nextIndent,listType,listNo);
- beginParagraph(md,linesBetweenChildren);
- indent = nextIndent;
- foundNonWhitespaceChild = false;
- }
- else {
- if (!foundNonWhitespaceChild) {
- if (isWhitespaceTextNode(child))
- continue;
- beginParagraph(md,0,indent,nextIndent);
- indent = nextIndent;
- foundNonWhitespaceChild = true;
- }
-
- inlineToText(md,child);
- }
- }
-
- if (node._type == HTML_PRE)
- md.preDepth--;
- }
-
- // private
- function shipOutParagraph(md)
- {
- var text = md.buildParagraph.join("");
- if (md.buildPre) {
- text = text.replace(/\n$/,"");
- text = " "+text.replace(/\n/g,"\n"+md.nextIndent+" ");
- }
- else {
- text = normalizeWhitespace(text);
- }
- if (md.allText.length > 0) {
- for (var i = 0; i < md.buildLines; i++)
- md.allText.push("\n");
- }
- md.allText.push(md.indent+md.buildPrefix+text+md.buildSuffix+"\n");
- resetBuild(md);
- }
-
- // private
- function beginParagraph(md,blankLines,indent,nextIndent,paraPrefix,paraSuffix)
- {
- if (blankLines == null)
- blankLines = 1;
- if (indent == null)
- indent = "";
- if (nextIndent == null)
- nextIndent = "";
- if (paraPrefix == null)
- paraPrefix = "";
- if (paraSuffix == null)
- paraSuffix = "";
-
- if (md == null)
- throw new Error("beginParagraph: md is null");
- if (md.buildParagraph == null)
- throw new Error("beginParagraph: md.buildParagraph is null");
-
- if (md.buildParagraph.length > 0) {
- shipOutParagraph(md);
- }
-
- if (md.buildLines < blankLines)
- md.buildLines = blankLines;
- if (md.indent.length < indent.length)
- md.indent = indent;
- if (md.nextIndent.length < nextIndent.length)
- md.nextIndent = nextIndent;
- md.buildPrefix += paraPrefix;
- md.buildSuffix = paraSuffix + md.buildSuffix;
- if (md.preDepth > 0)
- md.buildPre = true;
- }
-
- // private
- function inlineToText(md,node)
- {
- switch (node._type) {
- case HTML_TEXT: {
- var text = node.nodeValue;
- if (md.preDepth == 0) {
- text = text.replace(/\\/g,"\\\\");
- text = text.replace(/\*/g,"\\*");
- text = text.replace(/\[/g,"\\[");
- text = text.replace(/\]/g,"\\]");
- }
- md.buildParagraph.push(text);
- break;
- }
- case HTML_I:
- case HTML_EM:
- md.buildParagraph.push("*");
- processChildren();
- md.buildParagraph.push("*");
- break;
- case HTML_B:
- case HTML_STRONG:
- md.buildParagraph.push("**");
- processChildren();
- md.buildParagraph.push("**");
- break;
- case HTML_A:
- if (node.hasAttribute("href")) {
- md.buildParagraph.push("[");
- processChildren();
- md.buildParagraph.push("]("+node.getAttribute("href")+")");
- }
- break;
- default:
- processChildren();
- break;
- }
-
- function processChildren()
- {
- for (var child = node.firstChild; child != null; child = child.nextSibling) {
- inlineToText(md,child);
- }
- }
- }
-
- // private
- function resetBuild(md)
- {
- md.buildParagraph = new Array();
- md.buildLines = 0;
- md.buildPrefix = "";
- md.buildSuffix = "";
- md.buildPre = false;
- md.indent = "";
- md.nextIndent = "";
- }
-
- // private
- function MarkdownBuilder()
- {
- }
-
- // public
- Markdown_htmlToMarkdown = function(node)
- {
- var md = new MarkdownBuilder();
- md.allText = new Array();
- md.preDepth = 0;
- resetBuild(md);
-
- if (isContainerNode(node) || isParagraphNode(node)) {
- blockToText(md,node,"","","UL",{value: 1});
- beginParagraph(md);
- return md.allText.join("");
- }
- else {
- inlineToText(md,node);
- return normalizeWhitespace(md.buildParagraph.join(""));
- }
- }
-
-})();
-
-(function() {
-
- function expandRangeForCopy(range)
- {
- if (range == null)
- return range;
-
- var startInLI = null;
- for (var node = range.start.node; node != null; node = node.parentNode) {
- if (node._type == HTML_LI)
- startInLI = node;
- }
-
- var endInLI = null;
- for (var node = range.end.node; node != null; node = node.parentNode) {
- if (node._type == HTML_LI)
- endInLI = node;
- }
-
- if ((startInLI != null) && (startInLI == endInLI)) {
- var beforeRange = new Range(startInLI,0,
- range.start.node,range.start.offset);
- var afterRange = new Range(range.end.node,range.end.offset,
- endInLI,DOM_maxChildOffset(endInLI));
- var contentBefore = Range_hasContent(beforeRange);
- var contentAfter = Range_hasContent(afterRange);
-
- if (!contentBefore && !contentAfter) {
- var li = startInLI;
- var offset = DOM_nodeOffset(li);
- range = new Range(li.parentNode,offset,li.parentNode,offset+1);
- }
- }
- return range;
- }
-
- function copyRange(range)
- {
- var html = "";
- var text = "";
-
- if (range != null) {
- var nodes;
- var region = Tables_regionFromRange(range);
- if (region != null) {
- nodes = [Tables_cloneRegion(region)];
- }
- else {
- nodes = Range_cloneContents(range);
- };
-
- var div = DOM_createElement(document,"DIV");
- for (var i = 0; i < nodes.length; i++)
- DOM_appendChild(div,nodes[i]);
- Main_removeSpecial(div);
-
- html = div.innerHTML;
- text = Clipboard_htmlToText(div);
- }
-
- return { "text/html": html,
- "text/plain": text };
- }
-
- // public (FIXME: temp: for testing)
- Clipboard_htmlToText = function(node)
- {
- return Markdown_htmlToMarkdown(node);
- }
-
- // public
- Clipboard_cut = function()
- {
- UndoManager_newGroup("Cut");
- var content;
-
- var range = Selection_get();
- range = expandRangeForCopy(range);
- content = copyRange(range);
-
- Selection_set(range.start.node,range.start.offset,range.end.node,range.end.offset);
- Selection_deleteContents(false);
- var selRange = Selection_get();
- if (selRange != null) {
- Range_trackWhileExecuting(selRange,function() {
- var node = Position_closestActualNode(selRange.start);
- while (node != null) {
- var parent = node.parentNode;
- switch (node._type) {
- case HTML_LI:
- if (!nodeHasContent(node))
- DOM_deleteNode(node);
- break;
- case HTML_UL:
- case HTML_OL: {
- var haveLI = false;
- for (var c = node.firstChild; c != null; c = c.nextSibling) {
- if (c._type == HTML_LI) {
- haveLI = true;
- break;
- }
- }
- if (!haveLI)
- DOM_deleteNode(node);
- break;
- }
- }
- node = parent;
- }
- });
-
- var pos = Position_closestMatchForwards(selRange.start,Position_okForMovement);
- Selection_set(pos.node,pos.offset,pos.node,pos.offset);
- }
-
- Cursor_ensureCursorVisible();
-
- PostponedActions_perform(UndoManager_newGroup);
- return content;
- }
-
- // public
- Clipboard_copy = function()
- {
- var range = Selection_get();
- range = expandRangeForCopy(range);
- return copyRange(range);
- }
-
- // public
- Clipboard_pasteText = function(text)
- {
- var converter = new Showdown.converter();
- var html = converter.makeHtml(text);
- UndoManager_newGroup("Paste");
- Clipboard_pasteHTML(html);
- UndoManager_newGroup();
- }
-
- // public
- Clipboard_pasteHTML = function(html)
- {
- if (html.match(/^\s*<thead/i))
- html = "<table>" + html + "</table>";
- else if (html.match(/^\s*<tbody/i))
- html = "<table>" + html + "</table>";
- else if (html.match(/^\s*<tfoot/i))
- html = "<table>" + html + "</table>";
- else if (html.match(/^\s*<tr/i))
- html = "<table>" + html + "</table>";
- else if (html.match(/^\s*<td/i))
- html = "<table><tr>" + html + "</tr></table>";
- else if (html.match(/^\s*<th/i))
- html = "<table><tr>" + html + "</tr></table>";
- else if (html.match(/^\s*<li/i))
- html = "<ul>" + html + "</ul>";
-
- var div = DOM_createElement(document,"DIV");
- div.innerHTML = html;
- for (var child = div.firstChild; child != null; child = child.nextSibling)
- DOM_assignNodeIds(child);
-
- var nodes = new Array();
- for (var child = div.firstChild; child != null; child = child.nextSibling)
- nodes.push(child);
-
- UndoManager_newGroup("Paste");
- var region = Tables_regionFromRange(Selection_get(),true);
- if ((region != null) && (nodes.length == 1) && (nodes[0]._type == HTML_TABLE))
- pasteTable(nodes[0],region);
- else
- Clipboard_pasteNodes(nodes);
- UndoManager_newGroup();
- }
-
- function pasteTable(srcTable,dest)
- {
- var src = Tables_analyseStructure(srcTable);
-
- // In the destination table, the region into which we will paste the cells will the
- // the same size as that of the source table, regardless of how many rows and columns
- // were selected - i.e. we only pay attention to the top-left most cell, ignoring
- // whatever the bottom-right is set to
- dest.bottom = dest.top + src.numRows - 1;
- dest.right = dest.left + src.numCols - 1;
-
- // Make sure the destination table is big enough to hold all the cells we want to paste.
- // This will add rows and columns as appropriate, with empty cells that only contain a
- // <p><br></p> (to ensure they have non-zero height)
- if (dest.structure.numRows < dest.bottom + 1)
- dest.structure.numRows = dest.bottom + 1;
- if (dest.structure.numCols < dest.right + 1)
- dest.structure.numCols = dest.right + 1;
- dest.structure = Table_fix(dest.structure);
-
- // To simplify the paste, split any merged cells that are in the region of the destination
- // table we're pasting into. We have to re-analyse the table structure after this to
- // get the correct cell array.
- TableRegion_splitCells(dest);
- dest.structure = Tables_analyseStructure(dest.structure.element);
-
- // Do the actual paste
- Selection_preserveWhileExecuting(function() {
- replaceCells(src,dest.structure,dest.top,dest.left);
- });
-
- // If any new columns were added, calculate a width for them
- Table_fixColumnWidths(dest.structure);
-
- // Remove duplicate ids
- var found = new Object();
- removeDuplicateIds(dest.structure.element,found);
-
- // Place the cursor in the bottom-right cell that was pasted
- var bottomRightCell = Table_get(dest.structure,dest.bottom,dest.right);
- var node = bottomRightCell.element;
- Selection_set(node,node.childNodes.length,node,node.childNodes.length);
- }
-
- function replaceCells(src,dest,destRow,destCol)
- {
- // By this point, all of the cells have been split. So it is guaranteed that every cell
- // in dest will have rowspan = 1 and colspan = 1.
- for (var srcRow = 0; srcRow < src.numRows; srcRow++) {
- for (var srcCol = 0; srcCol < src.numCols; srcCol++) {
- var srcCell = Table_get(src,srcRow,srcCol);
- var destCell = Table_get(dest,srcRow+destRow,srcCol+destCol);
-
- if ((srcRow != srcCell.row) || (srcCol != srcCell.col))
- continue;
-
- if (destCell.rowspan != 1)
- throw new Error("unexpected rowspan: "+destCell.rowspan);
- if (destCell.colspan != 1)
- throw new Error("unexpected colspan: "+destCell.colspan);
-
- DOM_insertBefore(destCell.element.parentNode,srcCell.element,destCell.element);
-
- var destTop = destRow + srcRow;
- var destLeft = destCol + srcCol;
- var destBottom = destTop + srcCell.rowspan - 1;
- var destRight = destLeft + srcCell.colspan - 1;
- Table_setRegion(dest,destTop,destLeft,destBottom,destRight,srcCell);
- }
- }
- }
-
- function insertChildrenBefore(parent,child,nextSibling,pastedNodes)
- {
- var next;
- for (var grandChild = child.firstChild; grandChild != null; grandChild = next) {
- next = grandChild.nextSibling;
- pastedNodes.push(grandChild);
- DOM_insertBefore(parent,grandChild,nextSibling);
- }
- }
-
- function fixParagraphStyles(node,paragraphClass)
- {
- if (isParagraphNode(node)) {
- if (node._type == HTML_P) {
- var className = DOM_getAttribute(node,"class");
- if ((className == null) || (className == "")) {
- debug("Setting paragraph class to "+paragraphClass);
- DOM_setAttribute(node,"class",paragraphClass);
- }
- }
- }
- else {
- for (var child = node.firstChild; child != null; child = child.nextSibling) {
- fixParagraphStyles(child,paragraphClass);
- }
- }
- }
-
- // public
- Clipboard_pasteNodes = function(nodes)
- {
- if (nodes.length == 0)
- return;
-
- var paragraphClass = Styles_getParagraphClass();
- if (paragraphClass != null) {
- for (var i = 0; i < nodes.length; i++) {
- fixParagraphStyles(nodes[i],paragraphClass);
- }
- }
-
- // Remove any elements which don't belong in the document body (in case an entire
- // HTML document is being pasted in)
- var i = 0;
- while (i < nodes.length) {
- switch (nodes[i]._type) {
- case HTML_HTML:
- case HTML_BODY:
- case HTML_META:
- case HTML_TITLE:
- case HTML_SCRIPT:
- case HTML_STYLE:
- nodes.splice(i,1);
- break;
- default:
- i++;
- }
- }
-
- var found = new Object();
- for (var i = 0; i < nodes.length; i++)
- removeDuplicateIds(nodes[i],found);
-
-// if ((nodes.length == 0) && (nodes[0]._type == HTML_TABLE)) {
-// // FIXME: this won't work; selectionRange is not defined
-// var fromRegion = Tables_getTableRegionFromTable(nodes[0]);
-// var toRegion = Tables_regionFromRange(selectionRange);
-// if (toRegion != null) {
-// return;
-// }
-// }
-
- Selection_deleteContents(true);
- var range = Selection_get();
- if (range == null)
- throw new Error("No current selection");
-
- var parent;
- var previousSibling;
- var nextSibling;
-
- var start = range.start;
- start = Position_preferElementPosition(start);
- if (start.node.nodeType == Node.ELEMENT_NODE) {
- parent = start.node;
- nextSibling = start.node.childNodes[start.offset];
- previousSibling = start.node.childNodes[start.offset-1];
- }
- else {
- Formatting_splitTextAfter(start);
- parent = start.node.parentNode;
- nextSibling = start.node.nextSibling;
- previousSibling = start.node;
- }
-
- var prevLI = null;
- var inItem = null;
- var inList = null;
- var containerParent = null;
-
- for (var temp = parent; temp != null; temp = temp.parentNode) {
- if (isContainerNode(temp)) {
- switch (temp._type) {
- case HTML_LI:
- inItem = temp;
- break;
- case HTML_UL:
- case HTML_OL:
- inList = temp;
- break;
- }
- containerParent = temp.parentNode;
- break;
- }
- }
-
- var pastedNodes;
- if (inItem) {
- pastedNodes = new Array();
- for (var i = 0; i < nodes.length; i++) {
- var child = nodes[i];
-
- var offset = DOM_nodeOffset(nextSibling,parent);
-
- switch (child._type) {
- case HTML_UL:
- case HTML_OL:
- Formatting_movePreceding(new Position(parent,offset),
- function(x) { return (x == containerParent); });
- insertChildrenBefore(inItem.parentNode,child,inItem,pastedNodes);
- break;
- case HTML_LI:
- Formatting_movePreceding(new Position(parent,offset),
- function(x) { return (x == containerParent); });
- DOM_insertBefore(inItem.parentNode,child,inItem);
- pastedNodes.push(child);
- break;
- default:
- DOM_insertBefore(parent,child,nextSibling);
- pastedNodes.push(child);
- break;
- }
- }
- }
- else if (inList) {
- pastedNodes = new Array();
- for (var i = 0; i < nodes.length; i++) {
- var child = nodes[i];
-
- var offset = DOM_nodeOffset(nextSibling,parent);
-
- switch (child._type) {
- case HTML_UL:
- case HTML_OL:
- insertChildrenBefore(parent,child,nextSibling,pastedNodes);
- prevLI = null;
- break;
- case HTML_LI:
- DOM_insertBefore(parent,child,nextSibling);
- pastedNodes.push(child);
- prevLI = null;
- break;
- default:
- if (!isWhitespaceTextNode(child)) {
- if (prevLI == null)
- prevLI = DOM_createElement(document,"LI");
- DOM_appendChild(prevLI,child);
- DOM_insertBefore(parent,prevLI,nextSibling);
- pastedNodes.push(child);
- }
- }
- }
- }
- else {
- pastedNodes = nodes;
- for (var i = 0; i < nodes.length; i++) {
- var child = nodes[i];
- DOM_insertBefore(parent,child,nextSibling);
- }
- }
-
- var prevOffset;
- if (previousSibling == null)
- prevOffset = 0;
- else
- prevOffset = DOM_nodeOffset(previousSibling);
- var nextOffset = DOM_nodeOffset(nextSibling,parent);
-
- var origRange = new Range(parent,prevOffset,parent,nextOffset);
-
- var firstPasted = pastedNodes[0];
- var lastPasted = pastedNodes[pastedNodes.length-1];
- var pastedRange = new Range(firstPasted,0,lastPasted,DOM_maxChildOffset(lastPasted));
- Range_trackWhileExecuting(origRange,function() {
- Range_trackWhileExecuting(pastedRange,function() {
- if (previousSibling != null)
- Formatting_mergeWithNeighbours(previousSibling,Formatting_MERGEABLE_INLINE);
- if (nextSibling != null)
- Formatting_mergeWithNeighbours(nextSibling,Formatting_MERGEABLE_INLINE);
-
- Cursor_updateBRAtEndOfParagraph(parent);
-
- Range_ensureValidHierarchy(pastedRange,true);
- })});
-
- var pos = new Position(origRange.end.node,origRange.end.offset);
- Range_trackWhileExecuting(pastedRange,function() {
- Position_trackWhileExecuting(pos,function() {
- while (true) {
- if (pos.node == document.body)
- break;
- if (isContainerNode(pos.node) && (pos.node._type != HTML_LI))
- break;
- if (!nodeHasContent(pos.node)) {
- var oldNode = pos.node;
- pos = new Position(pos.node.parentNode,DOM_nodeOffset(pos.node));
- DOM_deleteNode(oldNode);
- }
- else
- break;
- }
- });
- });
-
- pos = new Position(pastedRange.end.node,pastedRange.end.offset);
- while (isOpaqueNode(pos.node))
- pos = new Position(pos.node.parentNode,DOM_nodeOffset(pos.node)+1);
- pos = Position_closestMatchBackwards(pos,Position_okForInsertion);
-
- Selection_set(pos.node,pos.offset,pos.node,pos.offset);
- Cursor_ensureCursorVisible();
- }
-
- function removeDuplicateIds(node,found)
- {
- if ((node.nodeType == Node.ELEMENT_NODE) && node.hasAttribute("id")) {
- var id = node.getAttribute("id");
-
- var existing = document.getElementById(id);
- if (existing == null)
- existing = found[id];
-
- if ((existing != null) && (existing != node))
- DOM_removeAttribute(node,"id");
- else
- found[id] = node;
- }
- for (var child = node.firstChild; child != null; child = child.nextSibling)
- removeDuplicateIds(child,found);
- }
-
- function pasteImage(href)
- {
- // FIXME
- }
-
-})();
http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/9bf02bb2/experiments/editorFramework/src/Layer0_Javascript/Cursor.js
----------------------------------------------------------------------
diff --git a/experiments/editorFramework/src/Layer0_Javascript/Cursor.js b/experiments/editorFramework/src/Layer0_Javascript/Cursor.js
deleted file mode 100644
index 7362a9e..0000000
--- a/experiments/editorFramework/src/Layer0_Javascript/Cursor.js
+++ /dev/null
@@ -1,1050 +0,0 @@
-// 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 Cursor_ensurePositionVisible;
-var Cursor_ensureCursorVisible;
-var Cursor_scrollDocumentForY;
-var Cursor_positionCursor;
-var Cursor_getCursorPosition;
-var Cursor_moveLeft;
-var Cursor_moveRight;
-var Cursor_moveToStartOfDocument;
-var Cursor_moveToEndOfDocument;
-var Cursor_updateBRAtEndOfParagraph;
-var Cursor_insertReference;
-var Cursor_insertLink;
-var Cursor_insertCharacter;
-var Cursor_deleteCharacter;
-var Cursor_enterPressed;
-var Cursor_getPrecedingWord;
-var Cursor_getAdjacentNodeWithType;
-var Cursor_getLinkProperties;
-var Cursor_setLinkProperties;
-var Cursor_setReferenceTarget;
-var Cursor_makeContainerInsertionPoint;
-var Cursor_set;
-var Cursor_insertFootnote;
-var Cursor_insertEndnote;
-
-(function() {
-
- var cursorX = null;
-
- Cursor_ensurePositionVisible = function(pos,center)
- {
- // If we can't find the cursor rect for some reason, just don't do anything.
- // This is better than using an incorrect position or throwing an exception.
- var rect = Position_displayRectAtPos(pos)
- if (rect != null) {
- var extraSpace = 4;
-
- var cursorTop = rect.top + window.scrollY - extraSpace;
- var cursorBottom = rect.top + rect.height + window.scrollY + extraSpace;
-
- var windowTop = window.scrollY;
- var windowBottom = window.scrollY + window.innerHeight;
-
- if (center) {
- var newY = Math.floor(cursorTop + rect.height/2 - window.innerHeight/2);
- window.scrollTo(window.scrollX,newY);
- }
- else if (cursorTop < windowTop) {
- window.scrollTo(window.scrollX,cursorTop);
- }
- else if (cursorBottom > windowBottom) {
- window.scrollTo(window.scrollX,cursorBottom - window.innerHeight);
- }
- }
- }
-
- // public
- Cursor_ensureCursorVisible = function(center)
- {
- var selRange = Selection_get();
- if (selRange != null)
- Cursor_ensurePositionVisible(selRange.end,center);
- }
-
- Cursor_scrollDocumentForY = function(y)
- {
- var absY = window.scrollY + y;
- if (absY-44 < window.scrollY) {
- window.scrollTo(window.scrollX,absY-44);
- y = absY - window.scrollY;
- }
- else if (absY+44 >= window.scrollY + window.innerHeight) {
- window.scrollTo(window.scrollX,absY+44 - window.innerHeight);
- y = absY - window.scrollY;
- }
- return y;
- }
-
- // public
- Cursor_positionCursor = function(x,y,wordBoundary)
- {
- if (UndoManager_groupType() != "Cursor movement")
- UndoManager_newGroup("Cursor movement");
-
- y = Cursor_scrollDocumentForY(y);
-
- var result = null;
- var position = Position_atPoint(x,y);
- if (position == null)
- return null;
-
- var node = Position_closestActualNode(position);
- for (; node != null; node = node.parentNode) {
- var type = node._type;
- if ((type == HTML_A) &&
- (node.hasAttribute("href")) &&
- (result == null)) {
-
- var arange = new Range(node,0,node,node.childNodes.length);
- var rects = Range_getClientRects(arange);
- var insideLink = false;
- for (var i = 0; i < rects.length; i++) {
- if (rectContainsPoint(rects[i],x,y))
- insideLink = true;
- }
-
- if (insideLink) {
- var href = node.getAttribute("href");
- if ((href != null) && (href.charAt(0) == "#")) {
- if (isInTOC(node))
- result = "intocreference-"+href.substring(1);
- else
- result = "inreference";
- }
- else {
- result = "inlink";
- }
- }
- }
- else if ((type == HTML_IMG) && (result == null)) {
- for (var anc = node; anc != null; anc = anc.parentNode) {
- if (anc._type == HTML_FIGURE) {
- result = "infigure";
- break;
- }
- }
- }
- else if (isAutoCorrectNode(node) && (result == null)) {
- result = "incorrection";
- }
- else if (isTOCNode(node)) {
- var rect = node.getBoundingClientRect();
- if (x >= rect.left + rect.width/2)
- position = new Position(node.parentNode,DOM_nodeOffset(node)+1);
- else
- position = new Position(node.parentNode,DOM_nodeOffset(node));
- break;
- }
- }
-
- var position = Position_closestMatchForwards(position,Position_okForMovement);
- if ((position != null) && isOpaqueNode(position.node))
- position = Position_nextMatch(position,Position_okForMovement);
- if (position == null)
- return false;
-
- var selectionRange = Selection_get();
- var samePosition = ((selectionRange != null) && Range_isEmpty(selectionRange) &&
- (position.node == selectionRange.start.node) &&
- (position.offset == selectionRange.start.offset));
- if (samePosition && (result == null))
- result = "same";
-
- if (wordBoundary) {
- var startOfWord = Selection_posAtStartOfWord(position);
- var endOfWord = Selection_posAtEndOfWord(position);
- if ((startOfWord.node != position.node) || (startOfWord.node != position.node))
- throw new Error("Word boundary in different node");
- var distanceBefore = position.offset - startOfWord.offset;
- var distanceAfter = endOfWord.offset - position.offset;
- if (distanceBefore <= distanceAfter)
- position = startOfWord;
- else
- position = endOfWord;
- }
-
- Cursor_set(position.node,position.offset);
- return result;
- }
-
- // public
- Cursor_getCursorPosition = function()
- {
- var selRange = Selection_get();
- if (selRange == null)
- return null;
-
- // FIXME: in the cases where this is called from Objective C, test what happens if we
- // return a null rect
- var rect = Position_displayRectAtPos(selRange.end);
- if (rect == null)
- return null;
-
- var left = rect.left + window.scrollX;
- var top = rect.top + window.scrollY;
- var height = rect.height;
- return { x: left, y: top, width: 0, height: height };
- }
-
- // public
- Cursor_moveLeft = function()
- {
- var range = Selection_get();
- if (range == null)
- return;
-
- var pos = Position_prevMatch(range.start,Position_okForMovement);
- if (pos != null)
- Cursor_set(pos.node,pos.offset);
- Cursor_ensureCursorVisible();
- }
-
- // public
- Cursor_moveRight = function()
- {
- var range = Selection_get();
- if (range == null)
- return;
-
- var pos = Position_nextMatch(range.start,Position_okForMovement);
- if (pos != null)
- Cursor_set(pos.node,pos.offset);
- Cursor_ensureCursorVisible();
- }
-
- // public
- Cursor_moveToStartOfDocument = function()
- {
- var pos = new Position(document.body,0);
- pos = Position_closestMatchBackwards(pos,Position_okForMovement);
- Cursor_set(pos.node,pos.offset);
- Cursor_ensureCursorVisible();
- }
-
- // public
- Cursor_moveToEndOfDocument = function()
- {
- var pos = new Position(document.body,document.body.childNodes.length);
- pos = Position_closestMatchForwards(pos,Position_okForMovement);
- Cursor_set(pos.node,pos.offset);
- Cursor_ensureCursorVisible();
- }
-
- // An empty paragraph does not get shown and cannot be edited. We can fix this by adding
- // a BR element as a child
- // public
- Cursor_updateBRAtEndOfParagraph = function(node)
- {
- var paragraph = node;
- while ((paragraph != null) && !isParagraphNode(paragraph))
- paragraph = paragraph.parentNode;
- if (paragraph != null) {
-
- var br = null;
- var last = paragraph;
- do {
-
- var child = last;
- while ((child != null) && isWhitespaceTextNode(child))
- child = child.previousSibling;
-
- if ((child != null) && (child._type == HTML_BR))
- br = child;
-
- last = last.lastChild;
-
- } while ((last != null) && isInlineNode(last));
-
- if (nodeHasContent(paragraph)) {
- // Paragraph has content: don't want BR at end
- if (br != null) {
- DOM_deleteNode(br);
- }
- }
- else {
- // Paragraph consists only of whitespace: must have BR at end
- if (br == null) {
- br = DOM_createElement(document,"BR");
- DOM_appendChild(paragraph,br);
- }
- }
- }
- }
-
- // public
- Cursor_insertReference = function(itemId)
- {
- var a = DOM_createElement(document,"A");
- DOM_setAttribute(a,"href","#"+itemId);
- Clipboard_pasteNodes([a]);
- }
-
- // public
- Cursor_insertLink = function(text,url)
- {
- var a = DOM_createElement(document,"A");
- DOM_setAttribute(a,"href",url);
- DOM_appendChild(a,DOM_createTextNode(document,text));
- Clipboard_pasteNodes([a]);
- }
-
- var nbsp = String.fromCharCode(160);
-
- function spaceToNbsp(pos)
- {
- var node = pos.node;
- var offset = pos.offset;
-
- if ((node.nodeType == Node.TEXT_NODE) && (offset > 0) &&
- (isWhitespaceString(node.nodeValue.charAt(offset-1)))) {
- // Insert first, to preserve any tracked positions
- DOM_insertCharacters(node,offset-1,nbsp);
- DOM_deleteCharacters(node,offset,offset+1);
- }
- }
-
- function nbspToSpace(pos)
- {
- var node = pos.node;
- var offset = pos.offset;
-
- if ((node.nodeType == Node.TEXT_NODE) && (offset > 0) &&
- (node.nodeValue.charAt(offset-1) == nbsp)) {
- // Insert first, to preserve any tracked positions
- DOM_insertCharacters(node,offset-1," ");
- DOM_deleteCharacters(node,offset,offset+1);
- }
- }
-
- function checkNbsp()
- {
- Selection_preserveWhileExecuting(function() {
- var selRange = Selection_get();
- if (selRange != null)
- nbspToSpace(selRange.end);
- });
- }
-
- function isPosAtStartOfParagraph(pos)
- {
- if ((pos.node.nodeType == Node.ELEMENT_NODE) && (pos.offset == 0) &&
- !isInlineNode(pos.node)) {
- return true;
- }
-
-
-
- while (pos != null) {
- if (pos.node.nodeType == Node.ELEMENT_NODE) {
- if ((pos.offset == 0) && !isInlineNode(pos.node))
- return true;
- else
- pos = Position_prev(pos);
- }
- else if (pos.node.nodeType == Node.TEXT_NODE) {
- if (pos.offset > 0)
- return false;
- else
- pos = Position_prev(pos);
- }
- else {
- return false;
- }
- }
-
- return false;
- }
-
- // public
- Cursor_insertCharacter = function(str,allowInvalidPos,allowNoParagraph)
- {
- var firstInsertion = (UndoManager_groupType() != "Insert text");
-
- if (firstInsertion)
- UndoManager_newGroup("Insert text",checkNbsp);
-
- if (str == "-") {
- var preceding = Cursor_getPrecedingWord();
- if (preceding.match(/[0-9]\s*$/))
- str = String.fromCharCode(0x2013); // en dash
- else if (preceding.match(/\s+$/))
- str = String.fromCharCode(0x2014); // em dash
- }
-
- var selRange = Selection_get();
- if (selRange == null)
- return;
-
- if (!Range_isEmpty(selRange)) {
- Selection_deleteContents(true);
- selRange = Selection_get();
- }
- var pos = selRange.start;
- pos = Position_preferTextPosition(pos);
- if ((str == " ") && isPosAtStartOfParagraph(pos))
- return;
- if (!allowInvalidPos && !Position_okForInsertion(pos)) {
- var elemPos = Position_preferElementPosition(pos);
- if (Position_okForInsertion(elemPos)) {
- pos = elemPos;
- }
- else {
- var oldPos = pos;
- pos = Position_closestMatchForwards(selRange.start,Position_okForInsertion);
- var difference = new Range(oldPos.node,oldPos.offset,pos.node,pos.offset);
- difference = Range_forwards(difference);
- Position_trackWhileExecuting([pos],function() {
- if (!Range_hasContent(difference)) {
- Selection_deleteRangeContents(difference,true);
- }
- });
- }
- }
- var node = pos.node;
- var offset = pos.offset;
-
- if ((str == " ") &&
- !firstInsertion &&
- (node.nodeType == Node.TEXT_NODE) &&
- (offset > 0) &&
- (node.nodeValue.charAt(offset-1) == nbsp)) {
-
- if (!node.nodeValue.substring(0,offset).match(/\.\s+$/)) {
- DOM_deleteCharacters(node,offset-1,offset);
- DOM_insertCharacters(node,offset-1,".");
- }
- }
-
- if (isWhitespaceString(str) && (node.nodeType == Node.TEXT_NODE) && (offset > 0)) {
- var prevChar = node.nodeValue.charAt(offset-1);
- if (isWhitespaceString(prevChar) || (prevChar == nbsp)) {
- Selection_update();
- Cursor_ensureCursorVisible();
- return;
- }
- }
-
- nbspToSpace(pos);
-
- // If the user enters two double quotes in succession (open and close), replace them with
- // just one plain double quote character
- if ((str == "”") && (node.nodeType == Node.TEXT_NODE) &&
- (offset > 0) && (node.nodeValue.charAt(offset-1) == "“")) {
- DOM_deleteCharacters(node,offset-1,offset);
- offset--;
- str = "\"";
- }
-
- if (node.nodeType == Node.ELEMENT_NODE) {
- var emptyTextNode = DOM_createTextNode(document,"");
- if (offset >= node.childNodes.length)
- DOM_appendChild(node,emptyTextNode);
- else
- DOM_insertBefore(node,emptyTextNode,node.childNodes[offset]);
- node = emptyTextNode;
- offset = 0;
- }
-
- if (str == " ")
- DOM_insertCharacters(node,offset,nbsp);
- else
- DOM_insertCharacters(node,offset,str);
-
- // must be done *after* inserting the text
- if (!allowNoParagraph) {
- switch (node.parentNode._type) {
- case HTML_CAPTION:
- case HTML_FIGCAPTION:
- // Do nothing
- break;
- default:
- Hierarchy_ensureInlineNodesInParagraph(node,true);
- break;
- }
- }
-
- offset += str.length;
-
- pos = new Position(node,offset);
- Position_trackWhileExecuting([pos],function() {
- Formatting_mergeWithNeighbours(pos.node,Formatting_MERGEABLE_INLINE);
- });
-
- Cursor_set(pos.node,pos.offset);
- Range_trackWhileExecuting(Selection_get(),function() {
- Cursor_updateBRAtEndOfParagraph(pos.node);
- });
-
- Selection_update();
- Cursor_ensureCursorVisible();
- }
-
- function tryDeleteEmptyCaption(pos)
- {
- var caption = Position_captionAncestor(pos);
- if ((caption == null) || nodeHasContent(caption))
- return false;
-
- var container = Position_figureOrTableAncestor(pos);
- if (container == null)
- return false;
-
- Cursor_set(container.parentNode,DOM_nodeOffset(container)+1);
- Selection_preserveWhileExecuting(function() {
- DOM_deleteNode(caption);
- });
-
- return true;
- }
-
- function tryDeleteEmptyNote(pos)
- {
- var note = Position_noteAncestor(pos);
- if ((note == null) || nodeHasContent(note))
- return false;
-
- var parent = note.parentNode;
- Cursor_set(note.parentNode,DOM_nodeOffset(note)+1);
- Selection_preserveWhileExecuting(function() {
- DOM_deleteNode(note);
- });
-
- return true;
- }
-
- // public
- Cursor_deleteCharacter = function()
- {
- if (UndoManager_groupType() != "Delete text")
- UndoManager_newGroup("Delete text",checkNbsp);
-
- Selection_preferElementPositions();
- var selRange = Selection_get();
- if (selRange == null)
- return;
-
- if (!Range_isEmpty(selRange)) {
- Selection_deleteContents(true);
- }
- else {
- var currentPos = selRange.start;
-
- // Special cases of pressing backspace after a table, figure, TOC, hyperlink,
- // footnote, or endnote. For each of these we delete the whole thing.
- var back = Position_closestMatchBackwards(currentPos,Position_okForMovement);
- if ((back != null) && (back.node.nodeType == Node.ELEMENT_NODE) && (back.offset > 0)) {
- var prevNode = back.node.childNodes[back.offset-1];
- if (isSpecialBlockNode(prevNode)) {
- var p = DOM_createElement(document,"P");
- DOM_insertBefore(prevNode.parentNode,p,prevNode);
- DOM_deleteNode(prevNode);
- Cursor_updateBRAtEndOfParagraph(p);
- Cursor_set(p,0);
- Cursor_ensureCursorVisible();
- return;
- }
- if ((prevNode._type == HTML_A) || isNoteNode(prevNode)) {
- Cursor_set(back.node,back.offset-1);
- Selection_preserveWhileExecuting(function() {
- DOM_deleteNode(prevNode);
- });
- return;
- }
- }
-
- // Backspace inside an empty figure or table caption
- if (tryDeleteEmptyCaption(currentPos))
- return;
-
- currentPos = Position_preferTextPosition(currentPos);
- var prevPos = Position_prevMatch(currentPos,Position_okForMovement);
-
- // Backspace inside or just after a footnote or endnote
- if (tryDeleteEmptyNote(currentPos))
- return;
- if ((prevPos != null) && tryDeleteEmptyNote(prevPos))
- return;
-
- if (prevPos != null) {
- var startBlock = firstBlockAncestor(Position_closestActualNode(prevPos));
- var endBlock = firstBlockAncestor(Position_closestActualNode(selRange.end));
- if ((startBlock != endBlock) &&
- isParagraphNode(startBlock) && !nodeHasContent(startBlock)) {
- DOM_deleteNode(startBlock);
- Cursor_set(selRange.end.node,selRange.end.offset)
- }
- else {
- var range = new Range(prevPos.node,prevPos.offset,
- selRange.end.node,selRange.end.offset);
- Selection_deleteRangeContents(range,true);
- }
- }
- }
-
- selRange = Selection_get();
- if (selRange != null)
- spaceToNbsp(selRange.end);
- Selection_update();
- Cursor_ensureCursorVisible();
-
- function firstBlockAncestor(node)
- {
- while (isInlineNode(node))
- node = node.parentNode;
- return node;
- }
- }
-
- // public
- Cursor_enterPressed = function()
- {
- UndoManager_newGroup("New paragraph");
-
- Selection_preferElementPositions();
- var selRange = Selection_get();
- if (selRange == null)
- return;
-
- Range_trackWhileExecuting(selRange,function() {
- if (!Range_isEmpty(selRange))
- Selection_deleteContents(true);
- });
-
- // Are we inside a figure or table caption? If so, put an empty paragraph directly after it
- var inCaption = false;
- var inFigCaption = false;
- var closestNode = Position_closestActualNode(selRange.start);
- for (var ancestor = closestNode; ancestor != null; ancestor = ancestor.parentNode) {
- switch (ancestor._type) {
- case HTML_CAPTION:
- inCaption = true;
- break;
- case HTML_FIGCAPTION:
- inFigCaption = true;
- break;
- case HTML_TABLE:
- case HTML_FIGURE:
- if ((inCaption && (ancestor._type == HTML_TABLE)) ||
- (inFigCaption && (ancestor._type == HTML_FIGURE))) {
- var p = DOM_createElement(document,"P");
- DOM_insertBefore(ancestor.parentNode,p,ancestor.nextSibling);
- Cursor_updateBRAtEndOfParagraph(p);
- Selection_set(p,0,p,0);
- return;
- }
- break;
- }
- }
-
- // Are we inside a footnote or endnote? If so, move the cursor immediately after it
- var note = null;
- if (selRange.start.node.nodeType == Node.TEXT_NODE) {
- note = Position_noteAncestor(selRange.start);
- }
- else {
- // We can't use Position_noteAncestor in this case, because we want to to break
- // the paragraph *before* the note, not after
- var checkNode = selRange.start.node;
- for (var anc = checkNode; anc != null; anc = anc.parentNode) {
- if (isNoteNode(anc)) {
- note = anc;
- break;
- }
- }
- }
- if (note != null) {
- var noteOffset = DOM_nodeOffset(note);
- selRange = new Range(note.parentNode,noteOffset+1,note.parentNode,noteOffset+1);
- }
-
- var check = Position_preferElementPosition(selRange.start);
- if (check.node.nodeType == Node.ELEMENT_NODE) {
- var before = check.node.childNodes[check.offset-1];
- var after = check.node.childNodes[check.offset];
- if (((before != null) && isSpecialBlockNode(before)) ||
- ((after != null) && isSpecialBlockNode(after))) {
- var p = DOM_createElement(document,"P");
- DOM_insertBefore(check.node,p,check.node.childNodes[check.offset]);
- Cursor_updateBRAtEndOfParagraph(p);
- Cursor_set(p,0);
- Cursor_ensureCursorVisible();
- return;
- }
- }
-
- Range_trackWhileExecuting(selRange,function() {
- Range_ensureInlineNodesInParagraph(selRange);
- Range_ensureValidHierarchy(selRange);
- });
-
- var pos = selRange.start;
-
- var detail = Range_detail(selRange);
- switch (detail.startParent._type) {
- case HTML_OL:
- case HTML_UL: {
- var li = DOM_createElement(document,"LI");
- DOM_insertBefore(detail.startParent,li,detail.startChild);
-
- Cursor_set(li,0);
- Cursor_ensureCursorVisible();
- return;
- }
- }
-
- if (isAutoCorrectNode(pos.node)) {
- pos = Position_preferTextPosition(pos);
- selRange.start = selRange.end = pos;
- }
-
- Range_trackWhileExecuting(selRange,function() {
-
- // If we're directly in a container node, add a paragraph, so we have something to
- // split.
- if (isContainerNode(pos.node) && (pos.node._type != HTML_LI)) {
- var p = DOM_createElement(document,"P");
- DOM_insertBefore(pos.node,p,pos.node.childNodes[pos.offset]);
- pos = new Position(p,0);
- }
-
- var blockToSplit = getBlockToSplit(pos);
- var stopAt = blockToSplit.parentNode;
-
- if (positionAtStartOfHeading(pos)) {
- var container = getContainerOrParagraph(pos.node);
- pos = new Position(container,0);
- pos = Formatting_movePreceding(pos,function(n) { return (n == stopAt); },true);
- }
- else if (pos.node.nodeType == Node.TEXT_NODE) {
- pos = Formatting_splitTextAfter(pos,function(n) { return (n == stopAt); },true);
- }
- else {
- pos = Formatting_moveFollowing(pos,function(n) { return (n == stopAt); },true);
- }
- });
-
- Cursor_set(pos.node,pos.offset);
- selRange = Selection_get();
-
- Range_trackWhileExecuting(selRange,function() {
- if ((pos.node.nodeType == Node.TEXT_NODE) && (pos.node.nodeValue.length == 0)) {
- DOM_deleteNode(pos.node);
- }
-
- var detail = Range_detail(selRange);
-
- // If a preceding paragraph has become empty as a result of enter being pressed
- // while the cursor was in it, then update the BR at the end of the paragraph
- var start = detail.startChild ? detail.startChild : detail.startParent;
- for (var ancestor = start; ancestor != null; ancestor = ancestor.parentNode) {
- var prev = ancestor.previousSibling;
- if ((prev != null) && isParagraphNode(prev) && !nodeHasContent(prev)) {
- DOM_deleteAllChildren(prev);
- Cursor_updateBRAtEndOfParagraph(prev);
- break;
- }
- else if ((prev != null) && (prev._type == HTML_LI) && !nodeHasContent(prev)) {
- var next;
- for (var child = prev.firstChild; child != null; child = next) {
- next = child.nextSibling;
- if (isWhitespaceTextNode(child))
- DOM_deleteNode(child);
- else
- Cursor_updateBRAtEndOfParagraph(child);
- }
- break;
- }
- }
-
- for (var ancestor = start; ancestor != null; ancestor = ancestor.parentNode) {
-
- if (isParagraphNode(ancestor)) {
- var nextSelector = Styles_nextSelectorAfter(ancestor);
- if (nextSelector != null) {
- var nextElementName = null;
- var nextClassName = null;
-
-
- var dotIndex = nextSelector.indexOf(".");
- if (dotIndex >= 0) {
- nextElementName = nextSelector.substring(0,dotIndex);
- nextClassName = nextSelector.substring(dotIndex+1);
- }
- else {
- nextElementName = nextSelector;
- }
-
- ancestor = DOM_replaceElement(ancestor,nextElementName);
- DOM_removeAttribute(ancestor,"id");
- DOM_setAttribute(ancestor,"class",nextClassName);
- }
- }
-
- if (isParagraphNode(ancestor) && !nodeHasContent(ancestor)) {
- Cursor_updateBRAtEndOfParagraph(prev);
- break;
- }
- else if ((ancestor._type == HTML_LI) && !nodeHasContent(ancestor)) {
- DOM_deleteAllChildren(ancestor);
- break;
- }
- }
-
- Cursor_updateBRAtEndOfParagraph(Range_singleNode(selRange));
- });
-
- Selection_set(selRange.start.node,selRange.start.offset,
- selRange.end.node,selRange.end.offset);
- cursorX = null;
- Cursor_ensureCursorVisible();
-
- function getBlockToSplit(pos)
- {
- var blockToSplit = null;
- for (var n = pos.node; n != null; n = n.parentNode) {
- if (n._type == HTML_LI) {
- blockToSplit = n;
- break;
- }
- }
- if (blockToSplit == null) {
- blockToSplit = pos.node;
- while (isInlineNode(blockToSplit))
- blockToSplit = blockToSplit.parentNode;
- }
- return blockToSplit;
- }
-
- function getContainerOrParagraph(node)
- {
- while ((node != null) && isInlineNode(node))
- node = node.parentNode;
- return node;
- }
-
- function positionAtStartOfHeading(pos)
- {
- var container = getContainerOrParagraph(pos.node);
- if (isHeadingNode(container)) {
- var startOffset = 0;
- if (isOpaqueNode(container.firstChild))
- startOffset = 1;
- var range = new Range(container,startOffset,pos.node,pos.offset);
- return !Range_hasContent(range);
- }
- else
- return false;
- }
- }
-
- Cursor_getPrecedingWord = function() {
- var selRange = Selection_get();
- if ((selRange == null) && !Range_isEmpty(selRange))
- return "";
-
- var node = selRange.start.node;
- var offset = selRange.start.offset;
- if (node.nodeType != Node.TEXT_NODE)
- return "";
-
- return node.nodeValue.substring(0,offset);
- }
-
- Cursor_getAdjacentNodeWithType = function(type)
- {
- var selRange = Selection_get();
- var pos = Position_preferElementPosition(selRange.start);
- var node = pos.node;
- var offset = pos.offset;
-
- while (true) {
-
- if (node._type == type)
- return node;
-
- if (node.nodeType == Node.ELEMENT_NODE) {
- var before = node.childNodes[offset-1];
- if ((before != null) && (before._type == type))
- return before;
-
- var after = node.childNodes[offset];
- if ((after != null) && (after._type == type))
- return after;
- }
-
- if (node.parentNode == null)
- return null;
-
- offset = DOM_nodeOffset(node);
- node = node.parentNode;
- }
- }
-
- Cursor_getLinkProperties = function()
- {
- var a = Cursor_getAdjacentNodeWithType(HTML_A);
- if (a == null)
- return null;
-
- return { href: a.getAttribute("href"),
- text: getNodeText(a) };
- }
-
- Cursor_setLinkProperties = function(properties)
- {
- var a = Cursor_getAdjacentNodeWithType(HTML_A);
- if (a == null)
- return null;
-
- Selection_preserveWhileExecuting(function() {
- DOM_setAttribute(a,"href",properties.href);
- DOM_deleteAllChildren(a);
- DOM_appendChild(a,DOM_createTextNode(document,properties.text));
- });
- }
-
- Cursor_setReferenceTarget = function(itemId)
- {
- var a = Cursor_getAdjacentNodeWithType(HTML_A);
- if (a != null)
- Outline_setReferenceTarget(a,itemId);
- }
-
- // Deletes the current selection contents and ensures that the cursor is located directly
- // inside the nearest container element, i.e. not inside a paragraph or inline node. This
- // is intended for preventing things like inserting a table of contants inside a heading
- Cursor_makeContainerInsertionPoint = function()
- {
- var selRange = Selection_get();
- if (selRange == null)
- return;
-
- if (!Range_isEmpty(selRange)) {
- Selection_deleteContents();
- selRange = Selection_get();
- }
-
- var parent;
- var previousSibling;
- var nextSibling;
-
- if (selRange.start.node.nodeType == Node.ELEMENT_NODE) {
- parent = selRange.start.node;
- nextSibling = selRange.start.node.childNodes[selRange.start.offset];
- }
- else {
- if (selRange.start.offset > 0)
- Formatting_splitTextBefore(selRange.start);
- parent = selRange.start.node.parentNode;
- nextSibling = selRange.start.node;
- }
-
- var offset = DOM_nodeOffset(nextSibling,parent);
-
- if (isContainerNode(parent)) {
- Cursor_set(parent,offset);
- return;
- }
-
- if ((offset > 0) && isItemNumber(parent.childNodes[offset-1]))
- offset--;
-
- Formatting_moveFollowing(new Position(parent,offset),isContainerNode);
- Formatting_movePreceding(new Position(parent,offset),isContainerNode);
-
- offset = 0;
- while (!isContainerNode(parent)) {
- var old = parent;
- offset = DOM_nodeOffset(parent);
- parent = parent.parentNode;
- DOM_deleteNode(old);
- }
-
- Cursor_set(parent,offset);
- cursorX = null;
- }
-
- Cursor_set = function(node,offset,keepCursorX)
- {
- Selection_set(node,offset,node,offset);
- if (!keepCursorX)
- cursorX = null;
- }
-
- function moveRangeOutsideOfNote(range)
- {
- var node = range.start.node;
- var offset = range.start.offset;
-
- for (var anc = node; anc != null; anc = anc.parentNode) {
- if (isNoteNode(anc) && (anc.parentNode != null)) {
- node = anc.parentNode;
- offset = DOM_nodeOffset(anc)+1;
- return new Range(node,offset,node,offset);
- }
- }
-
- return range;
- }
-
- function insertNote(className,content)
- {
- var footnote = DOM_createElement(document,"span");
- DOM_setAttribute(footnote,"class",className);
- DOM_appendChild(footnote,DOM_createTextNode(document,content));
-
- var range = Selection_get();
- range = moveRangeOutsideOfNote(range);
- Formatting_splitAroundSelection(range,false);
-
- // If we're part-way through a text node, splitAroundSelection will give us an
- // empty text node between the before and after text. For formatting purposes that's
- // fine (not sure if necessary), but when inserting a footnote or endnote we want
- // to avoid this as it causes problems with cursor movement - specifically, the cursor
- // is allowed to go inside the empty text node, and this doesn't show up in the correct
- // position on screen.
- var pos = range.start;
- if ((pos.node._type == HTML_TEXT) &&
- (pos.node.nodeValue.length == 0)) {
- var empty = pos.node;
- pos = new Position(empty.parentNode,DOM_nodeOffset(empty));
- DOM_deleteNode(empty);
- }
- else {
- pos = Position_preferElementPosition(pos);
- }
-
- DOM_insertBefore(pos.node,footnote,pos.node.childNodes[pos.offset]);
- Selection_set(footnote,0,footnote,footnote.childNodes.length);
- Cursor_updateBRAtEndOfParagraph(footnote);
- }
-
- Cursor_insertFootnote = function(content)
- {
- insertNote("footnote",content);
- }
-
- Cursor_insertEndnote = function(content)
- {
- insertNote("endnote",content);
- }
-
-})();