📄 kupuhelpers.js
字号:
// perhaps we should do a second pass that removes the rest(?) if (remove && (lastnode.nodeType == 3 || !lastnode.hasChildNodes())) { lastnode.parentNode.removeChild(lastnode); }; }; // and through the clone var iterator = new NodeIterator(clone); var currnode = iterator.next(); var remove = true; while (currnode) { var lastnode = currnode; currnode = iterator.next(); if (lastnode.nodeName.toLowerCase() == 'br' && lastnode.getAttribute('node_splitter') == 'indeed') { // here's the point where we should stop removing lastnode.parentNode.removeChild(lastnode); remove = false; }; if (remove && (lastnode.nodeType == 3 || !lastnode.hasChildNodes())) { lastnode.parentNode.removeChild(lastnode); }; }; // next we need to attach the node to the document if (node.nextSibling) { node.parentNode.insertBefore(clone, node.nextSibling); } else { node.parentNode.appendChild(clone); }; // this will change the selection, so reselect this.reset(); // return a reference to the clone return clone; }; this.selectionInsideNode = function(node) { /* returns a Boolean to indicate if the selection is resided inside the node */ var currnode = self.getSelectedNode(); while (currnode) { if (currnode == node) { return true; }; currnode = currnode.parentNode; }; return false; };};function MozillaSelection(document) { this.document = document; this.selection = document.getWindow().getSelection(); this.selectNodeContents = function(node) { /* select the contents of a node */ this.selection.removeAllRanges(); this.selection.selectAllChildren(node); }; this.collapse = function(collapseToEnd) { try { if (!collapseToEnd) { this.selection.collapseToStart(); } else { this.selection.collapseToEnd(); }; } catch(e) {}; }; this.replaceWithNode = function(node, selectAfterPlace) { // XXX this should be on a range object /* replaces the current selection with a new node returns a reference to the inserted node newnode is the node to replace the content with, selectAfterPlace can either be a DOM node that should be selected after the new node was placed, or some value that resolves to true to select the placed node */ // get the first range of the selection // (there's almost always only one range) var range = this.selection.getRangeAt(0); // deselect everything this.selection.removeAllRanges(); // remove content of current selection from document range.deleteContents(); // get location of current selection var container = range.startContainer; var pos = range.startOffset; // make a new range for the new selection var range = this.document.getDocument().createRange(); if (container.nodeType == 3 && node.nodeType == 3) { // if we insert text in a textnode, do optimized insertion container.insertData(pos, node.nodeValue); // put cursor after inserted text range.setEnd(container, pos + node.length); range.setStart(container, pos + node.length); } else { var afterNode; if (container.nodeType == 3) { // when inserting into a textnode // we create 2 new textnodes // and put the node in between var textNode = container; var container = textNode.parentNode; var text = textNode.nodeValue; // text before the split var textBefore = text.substr(0,pos); // text after the split var textAfter = text.substr(pos); var beforeNode = this.document.getDocument().createTextNode(textBefore); afterNode = this.document.getDocument().createTextNode(textAfter); // insert the 3 new nodes before the old one container.insertBefore(afterNode, textNode); container.insertBefore(node, afterNode); container.insertBefore(beforeNode, node); // remove the old node container.removeChild(textNode); } else { // else simply insert the node afterNode = container.childNodes[pos]; if (afterNode) { container.insertBefore(node, afterNode); } else { container.appendChild(node); }; } range.setEnd(afterNode, 0); range.setStart(afterNode, 0); } if (selectAfterPlace) { // a bit implicit here, but I needed this to be backward // compatible and also I didn't want yet another argument, // JavaScript isn't as nice as Python in that respect (kwargs) // if selectAfterPlace is a DOM node, select all of that node's // contents, else select the newly added node's this.selection = this.document.getWindow().getSelection(); this.selection.addRange(range); if (selectAfterPlace.nodeType == 1) { this.selection.selectAllChildren(selectAfterPlace); } else { if (node.hasChildNodes()) { this.selection.selectAllChildren(node); } else { var range = this.selection.getRangeAt(0).cloneRange(); this.selection.removeAllRanges(); range.selectNode(node); this.selection.addRange(range); }; }; this.document.getWindow().focus(); }; return node; }; this.startOffset = function() { // XXX this should be on a range object var startnode = this.startNode(); var startnodeoffset = 0; if (startnode == this.selection.anchorNode) { startnodeoffset = this.selection.anchorOffset; } else { startnodeoffset = this.selection.focusOffset; }; var parentnode = this.parentElement(); if (startnode == parentnode) { return startnodeoffset; }; var currnode = parentnode.firstChild; var offset = 0; if (!currnode) { // 'Control range', range consists of a single element, so startOffset is 0 if (startnodeoffset != 0) { // just an assertion to see if my assumption about this case is right throw('Start node offset detected in a node without children!'); }; return 0; }; while (currnode != startnode) { if (currnode.nodeType == 3) { offset += currnode.nodeValue.length; }; currnode = currnode.nextSibling; }; return offset + startnodeoffset; }; this.startNode = function() { // XXX this should be on a range object var anode = this.selection.anchorNode; var aoffset = this.selection.anchorOffset; var onode = this.selection.focusNode; var ooffset = this.selection.focusOffset; var arange = this.document.getDocument().createRange(); arange.setStart(anode, aoffset); var orange = this.document.getDocument().createRange(); orange.setStart(onode, ooffset); return arange.compareBoundaryPoints('START_TO_START', orange) <= 0 ? anode : onode; }; this.endOffset = function() { // XXX this should be on a range object var endnode = this.endNode(); var endnodeoffset = 0; if (endnode = this.selection.focusNode) { endnodeoffset = this.selection.focusOffset; } else { endnodeoffset = this.selection.anchorOffset; }; var parentnode = this.parentElement(); var currnode = parentnode.firstChild; var offset = 0; if (parentnode == endnode) { for (var i=0; i < parentnode.childNodes.length; i++) { var child = parentnode.childNodes[i]; if (i == endnodeoffset) { return offset; }; if (child.nodeType == 3) { offset += child.nodeValue.length; }; }; }; if (!currnode) { // node doesn't have any content, so offset is always 0 if (endnodeoffset != 0) { // just an assertion to see if my assumption about this case is right alert('End node offset detected in a node without children!'); throw('End node offset detected in a node without children!'); }; return 0; }; while (currnode != endnode) { if (currnode.nodeType == 3) { // should account for CDATA nodes as well offset += currnode.nodeValue.length; }; currnode = currnode.nextSibling; }; return offset + endnodeoffset; }; this.endNode = function() { // XXX this should be on a range object var anode = this.selection.anchorNode; var aoffset = this.selection.anchorOffset; var onode = this.selection.focusNode; var ooffset = this.selection.focusOffset; var arange = this.document.getDocument().createRange(); arange.setStart(anode, aoffset); var orange = this.document.getDocument().createRange(); orange.setStart(onode, ooffset); return arange.compareBoundaryPoints('START_TO_START', orange) > 0 ? anode : onode; }; this.getContentLength = function() { // XXX this should be on a range object return this.selection.toString().length; }; this.cutChunk = function(startOffset, endOffset) { // XXX this should be on a range object var range = this.selection.getRangeAt(0); // set start point var offsetParent = this.parentElement(); var currnode = offsetParent.firstChild; var curroffset = 0; var startparent = null; var startparentoffset = 0; while (currnode) { if (currnode.nodeType == 3) { // XXX need to add CDATA support var nodelength = currnode.nodeValue.length; if (curroffset + nodelength < startOffset) { curroffset += nodelength; } else { startparent = currnode; startparentoffset = startOffset - curroffset; break; }; }; currnode = currnode.nextSibling; }; // set end point var currnode = offsetParent.firstChild; var curroffset = 0; var endparent = null; var endoffset = 0; while (currnode) { if (currnode.nodeType == 3) { // XXX need to add CDATA support var nodelength = currnode.nodeValue.length; if (curroffset + nodelength < endOffset) { curroffset += nodelength; } else { endparent = currnode; endparentoffset = endOffset - curroffset; break; }; }; currnode = currnode.nextSibling; };
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -