⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 richtextcanvas.js

📁 javascript 很酷的类库
💻 JS
📖 第 1 页 / 共 5 页
字号:
                startLineNum = 0;                startLine = this.getLine(0);            }            html = startLine.innerHTML;        } else {            var endLine = this.getSelectionStartLine();            var endLineNum = this.getLineNumber(endLine);            if (endLineNum < startLineNum) {                startLine = endLine;                startLineNum = endLineNum;            }//            this.logWarn("endLine: " + endLine.innerHTML);//            this.logWarn("nextSibling: " + isc.Log.echoAll(endLine.nextSibling));            var currentLine = startLine;            var numLines = 0;            while (currentLine && currentLine != endLine) {                if (currentLine.innerHTML) {                    html += currentLine.innerHTML;                                    //                    this.logWarn("html is now: " + html);                }                numLines++;                currentLine = currentLine.nextSibling;            }            // repair bonus BR that gets shunted out of the original line span by FF                        var nextNode = endLine.nextSibling;            if (nextNode && nextNode.tagName.toLowerCase() == "br") {                nextNode.parentNode.removeChild(nextNode);                endLine.appendChild(nextNode);//                this.logWarn("repaired br, endline is now: " + endLine.innerHTML);            }            html += endLine.innerHTML;            // if we pasted a line span into the middle of another line span, then it will be            // fragmented - pick up the trailing fragment            if (!html.replace(/\n|\r/g, isc.emptyString).match(/<br>$/i)) {                if (endLine.nextSibling) {                    html += endLine.nextSibling.innerHTML;                    numLines++;                }            }        }  //        this.logWarn("linesChanged: " + html);        if (!oldVal) {            oldVal = this.contents;            newVal = this.getContents();        }        // fire linesChanged if it's defined        if (this.linesChanged) {            this.linesChanged(oldVal, newVal, startLineNum, numLines, html, selectionId);        } else if (this.syntaxHiliter) {            // currently syntaxHiliter is not compatible with linesChanged - use one or the other.            this.doSyntaxHilite(oldVal, newVal, startLineNum, numLines, html, selectionId);        }    },    doSyntaxHilite : function (oldVal, newVal, startLineNum, numLines, changedHTML, selectionId) {        // keeping a marker in the code sent to the colorizer, breaks some colorization cases -        // specifically, this happens if the marker is in the middle of something that would be        // matched by a regex.  For example in XML colorization of the marker is next to the        // equal sign in this expression: foo="bar", then that expression won't colorize until        // something else is edited such that the selection marker moves.//        this.logWarn("source before html removal: " + changedHTML);        // remove markup, but keep the selectionSpan so we can extract its index for        // repositioning the selection correctly after syntax hiliting        var source = this.removeMarkup(changedHTML, true);        //        this.logWarn("source after html removal: " + source);            // save off the index of the locationMarker        var selectionMarkerIndex = this.getSelectionMarkerIndex(source);        if (selectionMarkerIndex == -1) {            // marker has been wiped out by a select-all, re-hilite everything            this.doFullSyntaxHilite();            return;        }        // remove the selectionMarker from the source        source = this.removeMarkup(changedHTML);        // if the modified source contains a token that requires us to reformat queue a full        // hilite, but still do the partial update immediately//        if (this.syntaxHiliter.containsMultilineToken(source)) this.queueFullHilite();        // apply the syntax hiliting to just the lines passed in        var newLines = this.syntaxHiliter.hilite(source, true, selectionMarkerIndex,                                                  this._getSelectionSpanHTML(selectionId));        this.overwriteLines(startLineNum, numLines, newLines);        this.moveSelectionToMarker(selectionId);    },    doFullSyntaxHilite : function () {//        this.logWarn("full syntax hilite running");        var selectionId = this.markCurrentSelection();        var contents = this._getContents();        var source = this.removeMarkup(contents, true);                var selectionMarkerIndex = this.getSelectionMarkerIndex(source);        if (selectionMarkerIndex == -1) {            selectionMarkerIndex = contents.length;        }        // remove the selectionMarker from the source        source = this.removeMarkup(contents);        this.setContents(source, true, selectionMarkerIndex, this._getSelectionSpanHTML(selectionId));            this.moveSelectionToMarker(selectionId);        delete this.fullHiliteTimer;    },    queueFullHilite : function () {//        this.logWarn("(re)queueing full hilite");        if (this.fullHiliteTimer) isc.Timer.clearTimeout(this.fullHiliteTimer);        this.fullHiliteTimer = this.delayCall("doFullSyntaxHilite", [], this.fullSyntaxHiliteDelay);    },    selectionIsCollapsed : function () {        if (isc.Browser.isIE) {            var range = document.selection.createRange();            return range.text.length == 0;        } else if (isc.Browser.isMoz) {            var selection = this.getContentWindow().getSelection();            return selection.isCollapsed;        }    },    rememberSelectionStartLine : function () {        this.startLineNum = this.getLineNumber(this.getSelectionStartLine());    },    getLastSelectionStartLine : function () {        return this.startLineNum;    },    _setPasteTimer : function () {        this._pasteTimer = this.delayCall("doLinesChanged", [], 0);    },    // onpaste/onbeforepaste for IE - caching theset strings    _getOnBeforePaste : function () {        if (!this._onBeforePaste)             this._onBeforePaste = this.getID()+".rememberSelectionStartLine();event.returnValue=true";        return this._onBeforePaste;    },    _getOnPaste : function () {        if (!this._onPaste) this._onPaste = this.getID()+"._setPasteTimer();event.returnValue=true"        return this._onPaste;    },        // line span HTML caching    _getLineSpanHTML : function () {        if (!this._lineSpanHTML) {            this._lineSpanHTML = "<span isLine='true'";            // prevent the "bouncing line" effect where adding a space on a line that's clipped            // causes it to be broken into two lines by the browser (since that space is the first            // available place to wrap it).  The rendering then snaps back into a single line when            // the syntaxHiliter converts the space into an &nbsp;            if (this.syntaxHiliter && !this.syntaxHiliter.autoWrap)                 this._lineSpanHTML +=" style='white-space:nowrap'";            if (isc.Browser.isIE) {                this._lineSpanHTML += " onbeforepaste='"+this._getOnBeforePaste()                    +"' onpaste='"+this._getOnPaste()+"'"            }            this._lineSpanHTML += ">$1</span>";        }        return this._lineSpanHTML;    },    createLine : function (contents) {        var doc = this.getContentDocument();        var line = doc.createElement("span");        line.setAttribute("isLine", "true");        // prevent the "bouncing line" effect where adding a space on a line that's clipped        // causes it to be broken into two lines by the browser (since that space is the first        // available place to wrap it).  The rendering then snaps back into a single line when        // the syntaxHiliter converts the space into an &nbsp;        if (this.syntaxHiliter && !this.syntaxHiliter.autoWrap)             line.setAttribute("style", "white-space:nowrap");        if (isc.Browser.isIE) {            line.setAttribute("onbeforepaste", this._getOnBeforePaste());            line.setAttribute("onpaste", this._getOnPaste());        }        line.innerHTML = contents ? contents : "<br>";        return line;    },    // returns a string containing an incrementing counter usable unique identifier for the    // selection span.    _getNextSelectionId : function () {        if (!this.selectionIdSequence) this.selectionIdSequence = 0;        return this.getID()+"_selection_"+this.selectionIdSequence++;    },    // returns the DOM node that is the line span containing the start of the current selection.    getSelectionStartLine : function () {        var doc = this.getContentDocument();        var line;        if (isc.Browser.isIE) {            var selectionId = this._getNextSelectionId();            var range = doc.selection.createRange();            // collapse the selection range to the start of the current selection            range.collapse();            range.pasteHTML("<span id='"+selectionId+"'></span>");            var selNode = doc.getElementById(selectionId);            line = selNode.parentNode;//            this.logWarn("startLine: " + line.outerHTML);            line.removeChild(selNode);        } else if (isc.Browser.isMoz) {            var selection = this.getContentWindow().getSelection();            var line = selection.anchorNode;        }//        this.logWarn("anchorNode: " + Log.echo(line));        // IE will paste the isLine spans into the current line, so we need to find the        // top-most element that is actually a line        var lastLine = line;        while(line.parentNode != null) {            if (line.getAttribute && line.getAttribute("isLine") != null) lastLine = line;            line = line.parentNode;        }        return lastLine;    },    _getSelectionSpanHTML : function (selectionId) {        return "<span isSelectionSpan='true' id='"+selectionId+"'></span>";    },    // inserts an HTML marker at the start of the current selection.  In IE, the marker will be    // inserted immediately before the current selection.  In FF, immediately after.  FF can be    // made to work as IE for collapsed selections, but for multichar selections it may be    // impossible.  See the notes below for enabling IE-style behavior in FF for collapsed    // selections.    markCurrentSelection : function () {        var selectionId = this._getNextSelectionId();        var doc = this.getContentDocument();        if (isc.Browser.isIE) {            var range = doc.selection.createRange();            // collapse the selection range to the start of the current selection            range.collapse();            // insert our marker span            range.pasteHTML(this._getSelectionSpanHTML(selectionId));        } else if (isc.Browser.isMoz) {            // create the selection span            var selectionNode = doc.createElement("span");            selectionNode.setAttribute('isSelectionSpan', "true");            selectionNode.setAttribute('id', selectionId);            // grab the current selection range            var selection = this.getContentWindow().getSelection();            var range = selection.getRangeAt(0);            if (selection.isCollapsed) {                range.insertNode(selectionNode);            } else {                // create a new range whose start and end match the selection range start boundary                            var collapsedRange = range.cloneRange();                        // collapse the new range to the end of the selection                collapsedRange.collapse(false);                // insert the selection node at the collapsed range                collapsedRange.insertNode(selectionNode);                collapsedRange.detach();                /*                // The code below will insert the selection marker immediately before the start                // of the current selection, but it only works for a collapsed selection.  This                // is because range.insertNode() puts the new node right after the start of the                // selection which means that we need to jump the start of the selection over                // the newly inserted node.  This works fine for a collapsed selection, but a                // multicharacter selection gets destroyed by insertNode() - at least when the                // start and end of the multichar selection are in one text node that is                // fragmented by insertNode().  After insertNode(), the selection reflects                // the character immediately before the previous start of the selection!                // Weird FF bug - we need to clear the selection range and then re-add it after                // we're done manipulating our clone selection - because if we don't it expands                // to the parentNode for no apparent reason.                selection.removeAllRanges();                // create a new range whose start and end match the selection range start boundary                var collapsedRange = doc.createRange();                collapsedRange.setStart(range.startContainer, range.startOffset);                collapsedRange.setEnd(range.startContainer, range.startOffset);                // insert the selection node at the collapsed range                collapsedRange.insertNode(selectionNode);                collapsedRange.detach();                                // the above should have been all, but unfortunately the above insertion happened                // AFTER the start of the current selection range, so now we need to move the                // current selection range start to after the node we inserted                    if(range.startContainer.nodeType == 3) {                        // if it's a text node, then the above insertion fragmented the text node into                        // a two, so just jump over the selectionNode we just inserted.                        range.setEnd(range.startContainer.nextSibling.nextSibling, 0);                        range.setStart(range.startContainer.nextSibling.nextSibling, 0);                    } else {                        range.setEndAfter(selectionNode);                            range.setStartAfter(selectionNode);                    }                // add the modified range back so the cursor shows up.                selection.addRange(range);                */            }        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -