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

📄 richtextcanvas.js

📁 javascript 很酷的类库
💻 JS
📖 第 1 页 / 共 5 页
字号:
        // apply the properties (keyName, etc.) to EH.lastEvent             isc.EH.getKeyEventProperties(event);         return isc.EH.handleKeyDown(event, {keyTarget:this});            },        _iFrameKeyUp : function (event) {                // apply the properties (keyName, etc.) to EH.lastEvent             isc.EH.getKeyEventProperties(event);         return isc.EH.handleKeyUp(event, {keyTarget:this});            },            // If using designMode, we need a handler for the native scroll event on our IFRAME    // to update the stored scroll position of the handle on scroll.    // The standard handleCSSScroll method will handle scrolling (as it will check the    // scroll position of this.getScrollHandle() - which points at the IFRAME).    _iFrameScroll : function (event) {        return this._handleCSSScroll(event);    },        // Adjust overflow on keypress - updates recorded scroll width/height    _$br:"<BR>",    _$Enter:"Enter",    // set of keys that are ignored by handleKeyPress because they can't modify the contents of    // the editable area.  This isn't exhaustive - the main reason to have these is to    // eliminate gratuitous syntax hilighting while e.g. the user is using arrow keys to    // navigate around the document.    ignoreKeys : ["Arrow_Up", "Arrow_Down", "Arrow_Left", "Arrow_Right", "Ctrl", "Alt"],    handleKeyPress : function (event, eventInfo) {        var key = isc.EH.getKey();                if (this.ignoreKeys.contains(key)) return isc.EH.STOP_BUBBLING;        // figure out the start line number of the current selection before the key stroke so        // we can extract the modified line(s) later.        if (this.countLines) this.rememberSelectionStartLine();                this._queueContentsChanged();        var returnVal = this.Super("handleKeyPress", arguments);                // in IE, we set a timer onpaste to do syntax hiliting - this enalbes us to respond to        // a paste command initiated via the context menu or "Edit" menu, but when a user hits        // a keyboard shortcut to paste, we also get a key press.  So if we're responding to a        // keypress and there's a paste timer, we delete it so we don't process the paste twice.        if (isc.Browser.isIE && this._pasteTimer) {            isc.Timer.clearTimeout(this._pasteTimer);            delete this._pasteTimer;        }                if (returnVal != false && isc.Browser.isIE && key == this._$Enter) {            this._rememberSelection();            this._savedSelection.pasteHTML(this._$br);                        this._savedSelection.collapse(true);            this._savedSelection.select();            returnVal = false;        }        return returnVal;    },        _queueContentsChanged : function () {        if (!this._dirtyContent) {            this._dirtyContent = true;            if (!this._changedHandlerName) this._changedHandlerName = "_contentsChanged";            isc.Page.setEvent(isc.EH.IDLE, this, isc.Page.FIRE_ONCE, this._changedHandlerName);        }    },    //_contentsChanged - fired when the contents is edited.    // Not fired in response to explicit 'setContents' call.        _contentsChanged : function () {        delete this._dirtyContent;                var oldVal = this.contents,            newVal = this.getContents();        if (oldVal == newVal) return;        // if we're counting lines, then call doLinesChanged().  We're also checking for        // selectionIsCollapsed() here because Ctrl-A, which causes all contents to be selected        // should not fire doLinesChanged() - and that's the only known way to get a multichar        // selection after a keystroke/paste event        if (this.countLines && this.selectionIsCollapsed()) this.doLinesChanged(oldVal, newVal);        // AdjustOverflow - our scroll-size is likely to have changed        this.adjustOverflow("edited");                // Fire this.changed, if present        if (this.changed != null) this.changed(oldVal, newVal);        this.contents = newVal;    },        // ------------------------------------------------------------------------------------    // lineChanged / Synax Hiliting support    // ------------------------------------------------------------------------------------    //    // We want to detect any change made to the editable area so we can re-format the view.    // Change can be effected in several ways:    //   - keypress    //   - paste action using the browser "Edit" menu    //   - programmatic update (currently only via setContents())    //    // At the time of the change, the user may have an insertion cursor or a block of selected    // text.    //    // We want to format the newly added data, and potentially some data around the new data.    // To that end we want to:    //   - mark the location of the current insertion point, so we can restore it after making    //   changes    //   - determine the start and end index of the changed text    //   - expand the above indexes to fully envelop the start and end line of the changed    //   text.    //     - we want this because recolorization will happen on a line-by-line basis (for    //     performance reasons) except for some cases where we'll want to recolorize the    //     whole document    //    // In IE and FF we can insert arbitrary HTML at the insertion cursor.  This allows us to    // get the current location of the cursor.    //    // General issues    //---------------    // - In FF, we can't detect what was pasted unless we compare the original contents    // and the new contents - which is expensive.  In fact, if the user uses the Edit    // menu paste command, then we can't tell the the editable area even changed.  There's a    // DOM event called  "onsubtreemodified" that's part of the w3c spec that should at least    // tell us that the contents changed - but it doesn't work at all in current versions of FF    // (and this has been corroborated by postings on the web).    // - In FF, the contents of the editable area change asynchronously with the key event.  In    // other words you have to set a timeout to get the after-changed state of the editable area.    // - Detecting current selection/insertion point.  In IE and FF we can detect the current    // selection/insertion point by wrapping the selection contents in a DOM node (e.g. a span)    // and then scanning the contents for it.    // - In FF we lose the insertion cursor if there's no adjoining text.  Also, the cursor    // marker that we use to extract the cursor position blocks the user from using the right    // arrow on the keyboard to move to the next character beyond it.    //    // Approaches:    // -----------    // 1.  Wait for the user to stop typing for a bit and then reformat the entire editable    // area.  Performance is gated by the formatting algorithm, but this is very easy to    // implement and may be acceptable for some use cases.    // - benefits    //   - easy to implement    // - problems    //   - doesn't look as nice, because formatting is not realtime    //    // 2.  Determine the edited line by scanning backwards and forwards from the current    // insertion point looking for <BR>s.    // - benefits    //   - easier than maintaining line information in the editable area    // - problems    //   - scanning backwards for <BR>s potentially not cheap    //   - need to both scan backwards for <BR> (so we can select out the HTML to pass to the    //   formatter) and walk the DOM to the last <BR> so we can efficiently insert the results.    //    // 3.  Maintain line information in the editable area by inserting line spans into the    // contents provided to setContents().  Insert a span with a unique ID into the document at    // the current insertion point after a change and walk the    // DOM up from that node to find the current line for fast extraction.    // - benefits:    //   - very fast line extraction    //      - given a selection, can quickly determine what lines it spans.    //      - after formatting the line, we can replace it effieciently via innerHTML assignment    //      or equivalent.    //   - As long as line-based formatting is sufficient for most keystrokes, this approach    //   gives us an O(1) implementation.    //   - can get the contents of any line very quickly.  Given a line, can get its immediate    //   surrounding lines quickly.  Can get the line number quickly.    // - problems    //   - These spans must be maintained as the user hits Backspace, Enter and pastes    //   arbitrary content.    //     - this means fragmenting multiline pastes and those created by user hitting the    //     Enter key into separate lines and combining lines created by partial line pastes and    //     Backspace at beginning of line.    //       - In IE, copying a whole line out of the editable area also picks up its line span    //       delimiters, which means we can end up with a line inside a line situation.      //         - I think this can be fixed by defining a custom onbeforepaste handler on the    //         line spans and filtering the line spans out of the data retrieved from the    //         clipboard.    //       - In Moz, the <BR> inside the line span isn't picked up by the copy operation and    //       is replaced by the paste operation if the paste is at the end of the line.    //       Further, unlikes IE, the line span isn't placed inside the line that gets pasted    //       into - instead the pasted-into line is fragmented into two line spans by the    //       browser and the pasted line is added a peer in between those.    //     //     // line behaviors    // --------------    // - type character at beginning of line    //   - IE, FF: currentLine contains original chars + new char + selection marker + <br>    // - type character in the middle of a line     //   - IE, FF: as above    // - type character at end of a line    //   - IE, FF: as above    // - no special processing required for the above    //    // - hit enter at beginning of line    //   - IE, FF: current line contains <BR><cursor>origLineText<BR>    // - hit enter in the middle of a line    //   - IE, FF: current line contains origLineTextBeforeEnter<BR><cursor>origLineTextAfterEnter<BR>    // - hit enter at the end of a line    //   - IE, FF: current line contains origLineText<BR><cursor><BR>    // - split current line by <BR> count using regexes to extract new lines    //       // - hit backspace at beginning of line    //   - IE: <cursor> jumps to previous line, deleting the <BR> there.    //   - FF: previous line missing <BR>, currentLine has <cursor> at start    // - hit delete at end of line    //   - IE: current line now missing <BR> (basically as IE above)    //   - FF: as IE    // - hit backspace in middle of line    //   - IE, FF: as typing char in middle of line, except old char deleted    // - hit backspace at end of line    //   - IE, FF: as above    // - if current line is missing <BR>, combine with next, otherwise combine previous with current    //     // - paste external chars (not from a line span) with no BR in line:    //   - IE: as typing char, but selection goes to front of pasted text    //   - FF: as typing char    // - paste external chars (not from a line span) with BR in line:    //   - IE, FF: as above, plus a <BR> where there's a linebreak in pasted content    // - handled by above cases    //    // - paste chars from a line span with no BR in line:    //   - IE: if the copied selection touched the start of the line span, then behaves as FF,    //   except that the pasted line span appears as a child of the pasted-to line span, not a peer.    //   Otherwise behaves as paste of external chars    //     - filter out line spans from pasted content with onbeforepaste, onpaste on line spans,    //     then handled by above cases as external paste    //    //   - FF: pasted-to line is fragmented into two line spans by the insertion point.  pasted    //   text appears as its own line in between the two.  If pasted at end of a line, that    //   line's BR is moved out of that line's span as the nextSibling the newly created    //   line span.    //     - whenever pasting into a line, that line's <BR> is destroyed and either    //     moves outside the line span (if paste was at end of line) or into a new line    //     fragment (if there was text to the right of the insertion cursor before paste)    //     - a paste can be multiline, introducing potentially multiple whole lines, so can't    //     just look back for a missing <BR> until we hit a normal line (since some intervening    //     lines may actually be normal, because pasted wholesale from this edit area)    //     - SOLUTION:    //        - before paste:    //          - query total number of lines    //        - after paste:    //          - if <BR> is nextSibling outside currentLine (selection always at end of paste),    //          pull it into currentLine.    //        - now query total number of lines (after paste).  This is the number of lines we    //        have to walk back looking for missing <BR>s and combining.    //     // Actual approach used:    //----------------------    // #3, except don't combine lines in realtime.  Instead, provide a special change()    // notification that gives the user the pasted contents and the  pasted contents out to line    // breaks, and the line number.  The user can then format them and call a method to replace    // them and insert them at a given location.    //    // apply a SyntaxHiliter to the contents    setSyntaxHiliter : function (syntaxHiliter) {        if (syntaxHiliter == null) {            this.removeSyntaxHiliter;            return;        }        this.syntaxHiliter = syntaxHiliter;        this.countLines = true;        // apply syntax hiliting to the contents        var contents = this.getContents() || isc.emptyString;        this.setContents(contents);    },    removeSyntaxHiliter : function () {        // get the contents (do this before we delete this.syntaxHiliter, otherwise the        // contents will come with markup.        var contents = this.getContents() || isc.emptyString;        delete this.syntaxHiliter;        delete this.countLines;                // apply the contents, now without the markup        this.setContents(contents);    },    doLinesChanged : function (oldVal, newVal) {//        this.logWarn("doLinesChanged - newVal: " + newVal);        var startLineNum = this.getLastSelectionStartLine();                // initial setContents() only        if (startLineNum == null) return;         var startLine = this.getLine(startLineNum);//        this.logWarn("startLineNum: " + startLineNum);//        if (!startLine) this.logWarn("startLine is null");//        else this.logWarn("startLine: " + startLine.innerHTML);        var html = isc.emptyString;        var selectionId = this.markCurrentSelection();        if (isc.Browser.isIE) {            // startLine contains everything we need - in the event that lines from the editor            // got pasted back in, those lines appear as children of the current line and the            // line markers will just get stripped out by unescapeHTML()            if (!startLine) {                this.getLineContainer().innerHTML = isc.emptyString;                var line = this.createLine();                this.getLineContainer().appendChild(line);                var range = document.selection.createRange();                range.moveToElementText(line);                range.collapse();                range.select();                selectionId = this.markCurrentSelection();            

⌨️ 快捷键说明

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