diff options
Diffstat (limited to 'chromium/third_party/WebKit/Source/devtools/front_end/CodeMirrorTextEditor.js')
-rw-r--r-- | chromium/third_party/WebKit/Source/devtools/front_end/CodeMirrorTextEditor.js | 1572 |
1 files changed, 0 insertions, 1572 deletions
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/CodeMirrorTextEditor.js b/chromium/third_party/WebKit/Source/devtools/front_end/CodeMirrorTextEditor.js deleted file mode 100644 index 1cec6fdb1b8..00000000000 --- a/chromium/third_party/WebKit/Source/devtools/front_end/CodeMirrorTextEditor.js +++ /dev/null @@ -1,1572 +0,0 @@ -/* - * Copyright (C) 2012 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -importScript("cm/codemirror.js"); -importScript("cm/css.js"); -importScript("cm/javascript.js"); -importScript("cm/xml.js"); -importScript("cm/htmlmixed.js"); - -importScript("cm/matchbrackets.js"); -importScript("cm/closebrackets.js"); -importScript("cm/markselection.js"); -importScript("cm/comment.js"); -importScript("cm/overlay.js"); - -importScript("cm/htmlembedded.js"); -importScript("cm/clike.js"); -importScript("cm/coffeescript.js"); -importScript("cm/php.js"); -importScript("cm/python.js"); -importScript("cm/shell.js"); -importScript("CodeMirrorUtils.js"); - -/** - * @constructor - * @extends {WebInspector.View} - * @implements {WebInspector.TextEditor} - * @param {?string} url - * @param {!WebInspector.TextEditorDelegate} delegate - */ -WebInspector.CodeMirrorTextEditor = function(url, delegate) -{ - WebInspector.View.call(this); - this._delegate = delegate; - this._url = url; - - this.registerRequiredCSS("cm/codemirror.css"); - this.registerRequiredCSS("cm/cmdevtools.css"); - - this._codeMirror = window.CodeMirror(this.element, { - lineNumbers: true, - gutters: ["CodeMirror-linenumbers"], - matchBrackets: true, - smartIndent: false, - styleSelectedText: true, - electricChars: false, - }); - this._codeMirror._codeMirrorTextEditor = this; - - CodeMirror.keyMap["devtools-common"] = { - "Left": "goCharLeft", - "Right": "goCharRight", - "Up": "goLineUp", - "Down": "goLineDown", - "End": "goLineEnd", - "Home": "goLineStartSmart", - "PageUp": "goPageUp", - "PageDown": "goPageDown", - "Delete": "delCharAfter", - "Backspace": "delCharBefore", - "Tab": "defaultTab", - "Shift-Tab": "indentLess", - "Enter": "smartNewlineAndIndent", - "Ctrl-Space": "autocomplete" - }; - - CodeMirror.keyMap["devtools-pc"] = { - "Ctrl-A": "selectAll", - "Ctrl-Z": "undoAndReveal", - "Shift-Ctrl-Z": "redoAndReveal", - "Ctrl-Y": "redo", - "Ctrl-Home": "goDocStart", - "Ctrl-Up": "goDocStart", - "Ctrl-End": "goDocEnd", - "Ctrl-Down": "goDocEnd", - "Ctrl-Left": "goGroupLeft", - "Ctrl-Right": "goGroupRight", - "Alt-Left": "goLineStart", - "Alt-Right": "goLineEnd", - "Ctrl-Backspace": "delGroupBefore", - "Ctrl-Delete": "delGroupAfter", - "Ctrl-/": "toggleComment", - fallthrough: "devtools-common" - }; - - CodeMirror.keyMap["devtools-mac"] = { - "Cmd-A" : "selectAll", - "Cmd-Z" : "undoAndReveal", - "Shift-Cmd-Z": "redoAndReveal", - "Cmd-Up": "goDocStart", - "Cmd-Down": "goDocEnd", - "Alt-Left": "goGroupLeft", - "Alt-Right": "goGroupRight", - "Cmd-Left": "goLineStartSmart", - "Cmd-Right": "goLineEnd", - "Alt-Backspace": "delGroupBefore", - "Alt-Delete": "delGroupAfter", - "Cmd-/": "toggleComment", - fallthrough: "devtools-common" - }; - - WebInspector.settings.textEditorIndent.addChangeListener(this._updateEditorIndentation, this); - this._updateEditorIndentation(); - WebInspector.settings.showWhitespacesInEditor.addChangeListener(this._updateCodeMirrorMode, this); - WebInspector.settings.textEditorBracketMatching.addChangeListener(this._enableBracketMatchingIfNeeded, this); - this._enableBracketMatchingIfNeeded(); - - this._codeMirror.setOption("keyMap", WebInspector.isMac() ? "devtools-mac" : "devtools-pc"); - this._codeMirror.setOption("flattenSpans", false); - - this._codeMirror.setOption("maxHighlightLength", WebInspector.CodeMirrorTextEditor.maxHighlightLength); - this._codeMirror.setOption("mode", null); - this._codeMirror.setOption("crudeMeasuringFrom", 1000); - - this._shouldClearHistory = true; - this._lineSeparator = "\n"; - - this._tokenHighlighter = new WebInspector.CodeMirrorTextEditor.TokenHighlighter(this._codeMirror); - this._blockIndentController = new WebInspector.CodeMirrorTextEditor.BlockIndentController(this._codeMirror); - this._fixWordMovement = new WebInspector.CodeMirrorTextEditor.FixWordMovement(this._codeMirror); - this._autocompleteController = new WebInspector.CodeMirrorTextEditor.AutocompleteController(this, this._codeMirror); - - this._codeMirror.on("change", this._change.bind(this)); - this._codeMirror.on("beforeChange", this._beforeChange.bind(this)); - this._codeMirror.on("gutterClick", this._gutterClick.bind(this)); - this._codeMirror.on("cursorActivity", this._cursorActivity.bind(this)); - this._codeMirror.on("scroll", this._scroll.bind(this)); - this._codeMirror.on("focus", this._focus.bind(this)); - this._codeMirror.on("blur", this._blur.bind(this)); - this.element.addEventListener("contextmenu", this._contextMenu.bind(this), false); - - this.element.classList.add("fill"); - this.element.style.overflow = "hidden"; - this.element.firstChild.classList.add("source-code"); - this.element.firstChild.classList.add("fill"); - this._elementToWidget = new Map(); - this._nestedUpdatesCounter = 0; - - this.element.addEventListener("focus", this._handleElementFocus.bind(this), false); - this.element.addEventListener("keydown", this._handleKeyDown.bind(this), true); - this.element.tabIndex = 0; - - this._setupSelectionColor(); - this._setupWhitespaceHighlight(); -} - -WebInspector.CodeMirrorTextEditor.maxHighlightLength = 1000; - -WebInspector.CodeMirrorTextEditor.autocompleteCommand = function(codeMirror) -{ - codeMirror._codeMirrorTextEditor._autocompleteController.autocomplete(); -} -CodeMirror.commands.autocomplete = WebInspector.CodeMirrorTextEditor.autocompleteCommand; - -CodeMirror.commands.smartNewlineAndIndent = function(codeMirror) -{ - codeMirror.operation(innerSmartNewlineAndIndent.bind(this, codeMirror)); - - function countIndent(line) - { - for(var i = 0; i < line.length; ++i) { - if (!WebInspector.TextUtils.isSpaceChar(line[i])) - return i; - } - return line.length; - } - - function innerSmartNewlineAndIndent(codeMirror) - { - var cur = codeMirror.getCursor("start"); - var line = codeMirror.getLine(cur.line); - var indent = cur.line > 0 ? countIndent(line) : 0; - if (cur.ch <= indent) { - codeMirror.replaceSelection("\n" + line.substring(0, cur.ch), "end", "+input"); - codeMirror.setSelection(new CodeMirror.Pos(cur.line + 1, cur.ch)); - } else - codeMirror.execCommand("newlineAndIndent"); - } -} - -CodeMirror.commands.undoAndReveal = function(codemirror) -{ - var scrollInfo = codemirror.getScrollInfo(); - codemirror.execCommand("undo"); - var cursor = codemirror.getCursor("start"); - codemirror._codeMirrorTextEditor._innerRevealLine(cursor.line, scrollInfo); -} - -CodeMirror.commands.redoAndReveal = function(codemirror) -{ - var scrollInfo = codemirror.getScrollInfo(); - codemirror.execCommand("redo"); - var cursor = codemirror.getCursor("start"); - codemirror._codeMirrorTextEditor._innerRevealLine(cursor.line, scrollInfo); -} - -WebInspector.CodeMirrorTextEditor.LongLineModeLineLengthThreshold = 2000; -WebInspector.CodeMirrorTextEditor.MaximumNumberOfWhitespacesPerSingleSpan = 16; - -WebInspector.CodeMirrorTextEditor.prototype = { - _enableBracketMatchingIfNeeded: function() - { - this._codeMirror.setOption("autoCloseBrackets", WebInspector.settings.textEditorBracketMatching.get() ? { explode: false } : false); - }, - - wasShown: function() - { - this._codeMirror.refresh(); - }, - - _guessIndentationLevel: function() - { - var tabRegex = /^\t+/; - var tabLines = 0; - var indents = {}; - function processLine(lineHandle) - { - var text = lineHandle.text; - if (text.length === 0 || !WebInspector.TextUtils.isSpaceChar(text[0])) - return; - if (tabRegex.test(text)) { - ++tabLines; - return; - } - var i = 0; - while (i < text.length && WebInspector.TextUtils.isSpaceChar(text[i])) - ++i; - if (i % 2 !== 0) - return; - indents[i] = 1 + (indents[i] || 0); - } - this._codeMirror.eachLine(processLine); - - var onePercentFilterThreshold = this.linesCount / 100; - if (tabLines && tabLines > onePercentFilterThreshold) - return "\t"; - var minimumIndent = Infinity; - for (var i in indents) { - if (indents[i] < onePercentFilterThreshold) - continue; - var indent = parseInt(i, 10); - if (minimumIndent > indent) - minimumIndent = indent; - } - if (minimumIndent === Infinity) - return WebInspector.TextUtils.Indent.FourSpaces; - return new Array(minimumIndent + 1).join(" "); - }, - - _updateEditorIndentation: function() - { - var extraKeys = {}; - var indent = WebInspector.settings.textEditorIndent.get(); - if (WebInspector.settings.textEditorAutoDetectIndent.get()) - indent = this._guessIndentationLevel(); - if (indent === WebInspector.TextUtils.Indent.TabCharacter) { - this._codeMirror.setOption("indentWithTabs", true); - this._codeMirror.setOption("indentUnit", 4); - } else { - this._codeMirror.setOption("indentWithTabs", false); - this._codeMirror.setOption("indentUnit", indent.length); - extraKeys.Tab = function(codeMirror) - { - if (codeMirror.somethingSelected()) - return CodeMirror.Pass; - var pos = codeMirror.getCursor("head"); - codeMirror.replaceRange(indent.substring(pos.ch % indent.length), codeMirror.getCursor()); - } - } - this._codeMirror.setOption("extraKeys", extraKeys); - this._indentationLevel = indent; - }, - - /** - * @return {string} - */ - indent: function() - { - return this._indentationLevel; - }, - - /** - * @param {!RegExp} regex - * @param {?WebInspector.TextRange} range - */ - highlightSearchResults: function(regex, range) - { - /** - * @this {WebInspector.CodeMirrorTextEditor} - */ - function innerHighlightRegex() - { - if (range) { - this.revealLine(range.startLine); - if (range.endColumn > WebInspector.CodeMirrorTextEditor.maxHighlightLength) - this.setSelection(range); - else - this.setSelection(WebInspector.TextRange.createFromLocation(range.startLine, range.startColumn)); - } else { - // Collapse selection to end on search start so that we jump to next occurence on the first enter press. - this.setSelection(this.selection().collapseToEnd()); - } - this._tokenHighlighter.highlightSearchResults(regex, range); - } - this._codeMirror.operation(innerHighlightRegex.bind(this)); - }, - - cancelSearchResultsHighlight: function() - { - this._codeMirror.operation(this._tokenHighlighter.highlightSelectedTokens.bind(this._tokenHighlighter)); - }, - - undo: function() - { - this._codeMirror.undo(); - }, - - redo: function() - { - this._codeMirror.redo(); - }, - - _setupSelectionColor: function() - { - if (WebInspector.CodeMirrorTextEditor._selectionStyleInjected) - return; - WebInspector.CodeMirrorTextEditor._selectionStyleInjected = true; - var backgroundColor = WebInspector.getSelectionBackgroundColor(); - var backgroundColorRule = backgroundColor ? ".CodeMirror .CodeMirror-selected { background-color: " + backgroundColor + ";}" : ""; - var foregroundColor = WebInspector.getSelectionForegroundColor(); - var foregroundColorRule = foregroundColor ? ".CodeMirror .CodeMirror-selectedtext:not(.CodeMirror-persist-highlight) { color: " + foregroundColor + "!important;}" : ""; - if (!foregroundColorRule && !backgroundColorRule) - return; - - var style = document.createElement("style"); - style.textContent = backgroundColorRule + foregroundColorRule; - document.head.appendChild(style); - }, - - _setupWhitespaceHighlight: function() - { - if (WebInspector.CodeMirrorTextEditor._whitespaceStyleInjected || !WebInspector.settings.showWhitespacesInEditor.get()) - return; - WebInspector.CodeMirrorTextEditor._whitespaceStyleInjected = true; - const classBase = ".show-whitespaces .CodeMirror .cm-whitespace-"; - const spaceChar = "ยท"; - var spaceChars = ""; - var rules = ""; - for (var i = 1; i <= WebInspector.CodeMirrorTextEditor.MaximumNumberOfWhitespacesPerSingleSpan; ++i) { - spaceChars += spaceChar; - var rule = classBase + i + "::before { content: '" + spaceChars + "';}\n"; - rules += rule; - } - var style = document.createElement("style"); - style.textContent = rules; - document.head.appendChild(style); - }, - - _handleKeyDown: function(e) - { - if (this._autocompleteController.keyDown(e)) - e.consume(true); - }, - - _shouldProcessWordForAutocompletion: function(word) - { - return word.length && (word[0] < '0' || word[0] > '9'); - }, - - /** - * @param {string} text - */ - _addTextToCompletionDictionary: function(text) - { - var words = WebInspector.TextUtils.textToWords(text); - for(var i = 0; i < words.length; ++i) { - if (this._shouldProcessWordForAutocompletion(words[i])) - this._dictionary.addWord(words[i]); - } - }, - - /** - * @param {string} text - */ - _removeTextFromCompletionDictionary: function(text) - { - var words = WebInspector.TextUtils.textToWords(text); - for(var i = 0; i < words.length; ++i) { - if (this._shouldProcessWordForAutocompletion(words[i])) - this._dictionary.removeWord(words[i]); - } - }, - - /** - * @param {?WebInspector.CompletionDictionary} dictionary - */ - setCompletionDictionary: function(dictionary) - { - if (!dictionary) { - delete this._dictionary; - return; - } - this._dictionary = dictionary; - this._addTextToCompletionDictionary(this.text()); - }, - - /** - * @param {number} lineNumber - * @param {number} column - * @return {?{x: number, y: number, height: number}} - */ - cursorPositionToCoordinates: function(lineNumber, column) - { - if (lineNumber >= this._codeMirror.lineCount() || lineNumber < 0 || column < 0 || column > this._codeMirror.getLine(lineNumber).length) - return null; - - var metrics = this._codeMirror.cursorCoords(new CodeMirror.Pos(lineNumber, column)); - - return { - x: metrics.left, - y: metrics.top, - height: metrics.bottom - metrics.top - }; - }, - - /** - * @param {number} x - * @param {number} y - * @return {?WebInspector.TextRange} - */ - coordinatesToCursorPosition: function(x, y) - { - var element = document.elementFromPoint(x, y); - if (!element || !element.isSelfOrDescendant(this._codeMirror.getWrapperElement())) - return null; - var gutterBox = this._codeMirror.getGutterElement().boxInWindow(); - if (x >= gutterBox.x && x <= gutterBox.x + gutterBox.width && - y >= gutterBox.y && y <= gutterBox.y + gutterBox.height) - return null; - var coords = this._codeMirror.coordsChar({left: x, top: y}); - return this._toRange(coords, coords); - }, - - /** - * @param {number} lineNumber - * @param {number} column - * @return {?{startColumn: number, endColumn: number, type: string}} - */ - tokenAtTextPosition: function(lineNumber, column) - { - if (lineNumber < 0 || lineNumber >= this._codeMirror.lineCount()) - return null; - var token = this._codeMirror.getTokenAt(new CodeMirror.Pos(lineNumber, (column || 0) + 1)); - if (!token || !token.type) - return null; - var convertedType = WebInspector.CodeMirrorUtils.convertTokenType(token.type); - if (!convertedType) - return null; - return { - startColumn: token.start, - endColumn: token.end - 1, - type: convertedType - }; - }, - - /** - * @param {!WebInspector.TextRange} textRange - * @return {string} - */ - copyRange: function(textRange) - { - var pos = this._toPos(textRange.normalize()); - return this._codeMirror.getRange(pos.start, pos.end); - }, - - /** - * @return {boolean} - */ - isClean: function() - { - return this._codeMirror.isClean(); - }, - - markClean: function() - { - this._codeMirror.markClean(); - }, - - _hasLongLines: function() - { - function lineIterator(lineHandle) - { - if (lineHandle.text.length > WebInspector.CodeMirrorTextEditor.LongLineModeLineLengthThreshold) - hasLongLines = true; - return hasLongLines; - } - var hasLongLines = false; - this._codeMirror.eachLine(lineIterator); - return hasLongLines; - }, - - /** - * @param {string} mimeType - * @return {string} - */ - _whitespaceOverlayMode: function(mimeType) - { - var modeName = CodeMirror.mimeModes[mimeType] ? (CodeMirror.mimeModes[mimeType].name || CodeMirror.mimeModes[mimeType]) : CodeMirror.mimeModes["text/plain"]; - modeName += "+whitespaces"; - if (CodeMirror.modes[modeName]) - return modeName; - - function modeConstructor(config, parserConfig) - { - function nextToken(stream) - { - if (stream.peek() === " ") { - var spaces = 0; - while (spaces < WebInspector.CodeMirrorTextEditor.MaximumNumberOfWhitespacesPerSingleSpan && stream.peek() === " ") { - ++spaces; - stream.next(); - } - return "whitespace whitespace-" + spaces; - } - while (!stream.eol() && stream.peek() !== " ") - stream.next(); - return null; - } - var whitespaceMode = { - token: nextToken - }; - return CodeMirror.overlayMode(CodeMirror.getMode(config, mimeType), whitespaceMode, false); - } - CodeMirror.defineMode(modeName, modeConstructor); - return modeName; - }, - - _enableLongLinesMode: function() - { - this._codeMirror.setOption("styleSelectedText", false); - this._longLinesMode = true; - }, - - _disableLongLinesMode: function() - { - this._codeMirror.setOption("styleSelectedText", true); - this._longLinesMode = false; - }, - - _updateCodeMirrorMode: function() - { - var showWhitespaces = WebInspector.settings.showWhitespacesInEditor.get(); - this.element.enableStyleClass("show-whitespaces", showWhitespaces); - this._codeMirror.setOption("mode", showWhitespaces ? this._whitespaceOverlayMode(this._mimeType) : this._mimeType); - }, - - /** - * @param {string} mimeType - */ - setMimeType: function(mimeType) - { - this._mimeType = mimeType; - if (this._hasLongLines()) - this._enableLongLinesMode(); - else - this._disableLongLinesMode(); - this._updateCodeMirrorMode(); - }, - - /** - * @param {boolean} readOnly - */ - setReadOnly: function(readOnly) - { - this.element.enableStyleClass("CodeMirror-readonly", readOnly) - this._codeMirror.setOption("readOnly", readOnly); - }, - - /** - * @return {boolean} - */ - readOnly: function() - { - return !!this._codeMirror.getOption("readOnly"); - }, - - /** - * @param {!Object} highlightDescriptor - */ - removeHighlight: function(highlightDescriptor) - { - highlightDescriptor.clear(); - }, - - /** - * @param {!WebInspector.TextRange} range - * @param {string} cssClass - * @return {!Object} - */ - highlightRange: function(range, cssClass) - { - cssClass = "CodeMirror-persist-highlight " + cssClass; - var pos = this._toPos(range); - ++pos.end.ch; - return this._codeMirror.markText(pos.start, pos.end, { - className: cssClass, - startStyle: cssClass + "-start", - endStyle: cssClass + "-end" - }); - }, - - /** - * @return {!Element} - */ - defaultFocusedElement: function() - { - return this.element; - }, - - focus: function() - { - this._codeMirror.focus(); - }, - - _handleElementFocus: function() - { - this._codeMirror.focus(); - }, - - beginUpdates: function() - { - ++this._nestedUpdatesCounter; - }, - - endUpdates: function() - { - if (!--this._nestedUpdatesCounter) - this._codeMirror.refresh(); - }, - - /** - * @param {number} lineNumber - */ - revealLine: function(lineNumber) - { - this._innerRevealLine(lineNumber, this._codeMirror.getScrollInfo()); - }, - - /** - * @param {number} lineNumber - * @param {!{left: number, top: number, width: number, height: number, clientWidth: number, clientHeight: number}} scrollInfo - */ - _innerRevealLine: function(lineNumber, scrollInfo) - { - var topLine = this._codeMirror.lineAtHeight(scrollInfo.top, "local"); - var bottomLine = this._codeMirror.lineAtHeight(scrollInfo.top + scrollInfo.clientHeight, "local"); - var linesPerScreen = bottomLine - topLine + 1; - if (lineNumber < topLine) { - var topLineToReveal = Math.max(lineNumber - (linesPerScreen / 2) + 1, 0) | 0; - this._codeMirror.scrollIntoView(new CodeMirror.Pos(topLineToReveal, 0)); - } else if (lineNumber > bottomLine) { - var bottomLineToReveal = Math.min(lineNumber + (linesPerScreen / 2) - 1, this.linesCount - 1) | 0; - this._codeMirror.scrollIntoView(new CodeMirror.Pos(bottomLineToReveal, 0)); - } - }, - - _gutterClick: function(instance, lineNumber, gutter, event) - { - this.dispatchEventToListeners(WebInspector.TextEditor.Events.GutterClick, { lineNumber: lineNumber, event: event }); - }, - - _contextMenu: function(event) - { - var contextMenu = new WebInspector.ContextMenu(event); - var target = event.target.enclosingNodeOrSelfWithClass("CodeMirror-gutter-elt"); - if (target) - this._delegate.populateLineGutterContextMenu(contextMenu, parseInt(target.textContent, 10) - 1); - else - this._delegate.populateTextAreaContextMenu(contextMenu, 0); - contextMenu.show(); - }, - - /** - * @param {number} lineNumber - * @param {boolean} disabled - * @param {boolean} conditional - */ - addBreakpoint: function(lineNumber, disabled, conditional) - { - if (lineNumber < 0 || lineNumber >= this._codeMirror.lineCount()) - return; - var className = "cm-breakpoint" + (conditional ? " cm-breakpoint-conditional" : "") + (disabled ? " cm-breakpoint-disabled" : ""); - this._codeMirror.addLineClass(lineNumber, "wrap", className); - }, - - /** - * @param {number} lineNumber - */ - removeBreakpoint: function(lineNumber) - { - if (lineNumber < 0 || lineNumber >= this._codeMirror.lineCount()) - return; - var wrapClasses = this._codeMirror.getLineHandle(lineNumber).wrapClass; - if (!wrapClasses) - return; - var classes = wrapClasses.split(" "); - for(var i = 0; i < classes.length; ++i) { - if (classes[i].startsWith("cm-breakpoint")) - this._codeMirror.removeLineClass(lineNumber, "wrap", classes[i]); - } - }, - - /** - * @param {number} lineNumber - */ - setExecutionLine: function(lineNumber) - { - this._executionLine = this._codeMirror.getLineHandle(lineNumber); - this._codeMirror.addLineClass(this._executionLine, "wrap", "cm-execution-line"); - }, - - clearExecutionLine: function() - { - if (this._executionLine) - this._codeMirror.removeLineClass(this._executionLine, "wrap", "cm-execution-line"); - delete this._executionLine; - }, - - /** - * @param {number} lineNumber - * @param {!Element} element - */ - addDecoration: function(lineNumber, element) - { - var widget = this._codeMirror.addLineWidget(lineNumber, element); - this._elementToWidget.put(element, widget); - }, - - /** - * @param {number} lineNumber - * @param {!Element} element - */ - removeDecoration: function(lineNumber, element) - { - var widget = this._elementToWidget.remove(element); - if (widget) - this._codeMirror.removeLineWidget(widget); - }, - - /** - * @param {number} lineNumber - * @param {number=} columnNumber - */ - highlightPosition: function(lineNumber, columnNumber) - { - if (lineNumber < 0) - return; - lineNumber = Math.min(lineNumber, this._codeMirror.lineCount() - 1); - if (typeof columnNumber !== "number" || columnNumber < 0 || columnNumber > this._codeMirror.getLine(lineNumber).length) - columnNumber = 0; - - this.clearPositionHighlight(); - this._highlightedLine = this._codeMirror.getLineHandle(lineNumber); - if (!this._highlightedLine) - return; - this.revealLine(lineNumber); - this._codeMirror.addLineClass(this._highlightedLine, null, "cm-highlight"); - this._clearHighlightTimeout = setTimeout(this.clearPositionHighlight.bind(this), 2000); - if (!this.readOnly()) - this._codeMirror.setSelection(new CodeMirror.Pos(lineNumber, columnNumber)); - }, - - clearPositionHighlight: function() - { - if (this._clearHighlightTimeout) - clearTimeout(this._clearHighlightTimeout); - delete this._clearHighlightTimeout; - - if (this._highlightedLine) - this._codeMirror.removeLineClass(this._highlightedLine, null, "cm-highlight"); - delete this._highlightedLine; - }, - - /** - * @return {!Array.<!Element>} - */ - elementsToRestoreScrollPositionsFor: function() - { - return []; - }, - - /** - * @param {!WebInspector.TextEditor} textEditor - */ - inheritScrollPositions: function(textEditor) - { - }, - - /** - * @param {number} width - * @param {number} height - */ - _updatePaddingBottom: function(width, height) - { - var scrollInfo = this._codeMirror.getScrollInfo(); - var newPaddingBottom; - var linesElement = this.element.firstChild.querySelector(".CodeMirror-lines"); - var lineCount = this._codeMirror.lineCount(); - if (lineCount <= 1) - newPaddingBottom = 0; - else - newPaddingBottom = Math.max(scrollInfo.clientHeight - this._codeMirror.getLineHandle(this._codeMirror.lastLine()).height, 0); - newPaddingBottom += "px"; - linesElement.style.paddingBottom = newPaddingBottom; - this._codeMirror.setSize(width, height); - }, - - _resizeEditor: function() - { - var parentElement = this.element.parentElement; - if (!parentElement || !this.isShowing()) - return; - var scrollInfo = this._codeMirror.getScrollInfo(); - var width = parentElement.offsetWidth; - var height = parentElement.offsetHeight; - this._codeMirror.setSize(width, height); - this._updatePaddingBottom(width, height); - this._codeMirror.scrollTo(scrollInfo.left, scrollInfo.top); - }, - - onResize: function() - { - this._resizeEditor(); - }, - - /** - * @param {!WebInspector.TextRange} range - * @param {string} text - * @return {!WebInspector.TextRange} - */ - editRange: function(range, text) - { - var pos = this._toPos(range); - this._codeMirror.replaceRange(text, pos.start, pos.end); - var newRange = this._toRange(pos.start, this._codeMirror.posFromIndex(this._codeMirror.indexFromPos(pos.start) + text.length)); - this._delegate.onTextChanged(range, newRange); - if (WebInspector.settings.textEditorAutoDetectIndent.get()) - this._updateEditorIndentation(); - return newRange; - }, - - /** - * @param {number} lineNumber - * @param {number} column - * @param {boolean=} prefixOnly - * @return {?WebInspector.TextRange} - */ - _wordRangeForCursorPosition: function(lineNumber, column, prefixOnly) - { - var line = this.line(lineNumber); - if (column === 0 || !WebInspector.TextUtils.isWordChar(line.charAt(column - 1))) - return null; - var wordStart = column - 1; - while(wordStart > 0 && WebInspector.TextUtils.isWordChar(line.charAt(wordStart - 1))) - --wordStart; - if (prefixOnly) - return new WebInspector.TextRange(lineNumber, wordStart, lineNumber, column); - var wordEnd = column; - while(wordEnd < line.length && WebInspector.TextUtils.isWordChar(line.charAt(wordEnd))) - ++wordEnd; - return new WebInspector.TextRange(lineNumber, wordStart, lineNumber, wordEnd); - }, - - _beforeChange: function(codeMirror, changeObject) - { - if (!this._dictionary) - return; - this._updatedLines = this._updatedLines || {}; - for(var i = changeObject.from.line; i <= changeObject.to.line; ++i) - this._updatedLines[i] = this.line(i); - }, - - /** - * @param {!CodeMirror} codeMirror - * @param {!{origin: string, text: !Array.<string>, removed: !Array.<string>}} changeObject - */ - _change: function(codeMirror, changeObject) - { - // We do not show "scroll beyond end of file" span for one line documents, so we need to check if "document has one line" changed. - var hasOneLine = this._codeMirror.lineCount() === 1; - if (hasOneLine !== this._hasOneLine) - this._resizeEditor(); - this._hasOneLine = hasOneLine; - var widgets = this._elementToWidget.values(); - for (var i = 0; i < widgets.length; ++i) - this._codeMirror.removeLineWidget(widgets[i]); - this._elementToWidget.clear(); - - if (this._updatedLines) { - for(var lineNumber in this._updatedLines) - this._removeTextFromCompletionDictionary(this._updatedLines[lineNumber]); - delete this._updatedLines; - } - - var linesToUpdate = {}; - var singleCharInput = false; - do { - var oldRange = this._toRange(changeObject.from, changeObject.to); - var newRange = oldRange.clone(); - var linesAdded = changeObject.text.length; - singleCharInput = (changeObject.origin === "+input" && changeObject.text.length === 1 && changeObject.text[0].length === 1) || - (changeObject.origin === "+delete" && changeObject.removed.length === 1 && changeObject.removed[0].length === 1); - if (linesAdded === 0) { - newRange.endLine = newRange.startLine; - newRange.endColumn = newRange.startColumn; - } else if (linesAdded === 1) { - newRange.endLine = newRange.startLine; - newRange.endColumn = newRange.startColumn + changeObject.text[0].length; - } else { - newRange.endLine = newRange.startLine + linesAdded - 1; - newRange.endColumn = changeObject.text[linesAdded - 1].length; - } - - if (!this._muteTextChangedEvent) - this._delegate.onTextChanged(oldRange, newRange); - - for(var i = newRange.startLine; i <= newRange.endLine; ++i) { - linesToUpdate[i] = true; - } - if (this._dictionary) { - for(var i = newRange.startLine; i <= newRange.endLine; ++i) - linesToUpdate[i] = this.line(i); - } - } while (changeObject = changeObject.next); - if (this._dictionary) { - for(var lineNumber in linesToUpdate) - this._addTextToCompletionDictionary(linesToUpdate[lineNumber]); - } - if (singleCharInput) - this._autocompleteController.autocomplete(); - }, - - _cursorActivity: function() - { - var start = this._codeMirror.getCursor("anchor"); - var end = this._codeMirror.getCursor("head"); - this._delegate.selectionChanged(this._toRange(start, end)); - if (!this._tokenHighlighter.highlightedRegex()) - this._codeMirror.operation(this._tokenHighlighter.highlightSelectedTokens.bind(this._tokenHighlighter)); - }, - - _scroll: function() - { - if (this._scrollTimer) - clearTimeout(this._scrollTimer); - var topmostLineNumber = this._codeMirror.lineAtHeight(this._codeMirror.getScrollInfo().top, "local"); - this._scrollTimer = setTimeout(this._delegate.scrollChanged.bind(this._delegate, topmostLineNumber), 100); - }, - - _focus: function() - { - this._delegate.editorFocused(); - }, - - _blur: function() - { - this._autocompleteController.finishAutocomplete(); - }, - - /** - * @param {number} lineNumber - */ - scrollToLine: function(lineNumber) - { - var pos = new CodeMirror.Pos(lineNumber, 0); - var coords = this._codeMirror.charCoords(pos, "local"); - this._codeMirror.scrollTo(0, coords.top); - }, - - /** - * @return {number} - */ - firstVisibleLine: function() - { - return this._codeMirror.lineAtHeight(this._codeMirror.getScrollInfo().top, "local"); - }, - - /** - * @return {number} - */ - lastVisibleLine: function() - { - var scrollInfo = this._codeMirror.getScrollInfo(); - return this._codeMirror.lineAtHeight(scrollInfo.top + scrollInfo.clientHeight, "local"); - }, - - /** - * @return {!WebInspector.TextRange} - */ - selection: function() - { - var start = this._codeMirror.getCursor("anchor"); - var end = this._codeMirror.getCursor("head"); - - return this._toRange(start, end); - }, - - /** - * @return {?WebInspector.TextRange} - */ - lastSelection: function() - { - return this._lastSelection; - }, - - /** - * @param {!WebInspector.TextRange} textRange - */ - setSelection: function(textRange) - { - this._lastSelection = textRange; - var pos = this._toPos(textRange); - this._codeMirror.setSelection(pos.start, pos.end); - }, - - /** - * @param {string} text - */ - _detectLineSeparator: function(text) - { - this._lineSeparator = text.indexOf("\r\n") >= 0 ? "\r\n" : "\n"; - }, - - /** - * @param {string} text - */ - setText: function(text) - { - this._muteTextChangedEvent = true; - this._codeMirror.setValue(text); - this._updateEditorIndentation(); - if (this._shouldClearHistory) { - this._codeMirror.clearHistory(); - this._shouldClearHistory = false; - } - this._detectLineSeparator(text); - delete this._muteTextChangedEvent; - }, - - /** - * @return {string} - */ - text: function() - { - return this._codeMirror.getValue().replace(/\n/g, this._lineSeparator); - }, - - /** - * @return {!WebInspector.TextRange} - */ - range: function() - { - var lineCount = this.linesCount; - var lastLine = this._codeMirror.getLine(lineCount - 1); - return this._toRange(new CodeMirror.Pos(0, 0), new CodeMirror.Pos(lineCount - 1, lastLine.length)); - }, - - /** - * @param {number} lineNumber - * @return {string} - */ - line: function(lineNumber) - { - return this._codeMirror.getLine(lineNumber); - }, - - /** - * @return {number} - */ - get linesCount() - { - return this._codeMirror.lineCount(); - }, - - /** - * @param {number} line - * @param {string} name - * @param {?Object} value - */ - setAttribute: function(line, name, value) - { - if (line < 0 || line >= this._codeMirror.lineCount()) - return; - var handle = this._codeMirror.getLineHandle(line); - if (handle.attributes === undefined) handle.attributes = {}; - handle.attributes[name] = value; - }, - - /** - * @param {number} line - * @param {string} name - * @return {?Object} value - */ - getAttribute: function(line, name) - { - if (line < 0 || line >= this._codeMirror.lineCount()) - return null; - var handle = this._codeMirror.getLineHandle(line); - return handle.attributes && handle.attributes[name] !== undefined ? handle.attributes[name] : null; - }, - - /** - * @param {number} line - * @param {string} name - */ - removeAttribute: function(line, name) - { - if (line < 0 || line >= this._codeMirror.lineCount()) - return; - var handle = this._codeMirror.getLineHandle(line); - if (handle && handle.attributes) - delete handle.attributes[name]; - }, - - /** - * @param {!WebInspector.TextRange} range - * @return {!{start: !CodeMirror.Pos, end: !CodeMirror.Pos}} - */ - _toPos: function(range) - { - return { - start: new CodeMirror.Pos(range.startLine, range.startColumn), - end: new CodeMirror.Pos(range.endLine, range.endColumn) - } - }, - - _toRange: function(start, end) - { - return new WebInspector.TextRange(start.line, start.ch, end.line, end.ch); - }, - - __proto__: WebInspector.View.prototype -} - -/** - * @constructor - * @param {!CodeMirror} codeMirror - */ -WebInspector.CodeMirrorTextEditor.TokenHighlighter = function(codeMirror) -{ - this._codeMirror = codeMirror; -} - -WebInspector.CodeMirrorTextEditor.TokenHighlighter.prototype = { - /** - * @param {!RegExp} regex - * @param {?WebInspector.TextRange} range - */ - highlightSearchResults: function(regex, range) - { - var oldRegex = this._highlightRegex; - this._highlightRegex = regex; - this._highlightRange = range; - if (this._searchResultMarker) { - this._searchResultMarker.clear(); - delete this._searchResultMarker; - } - if (this._highlightDescriptor && this._highlightDescriptor.selectionStart) - this._codeMirror.removeLineClass(this._highlightDescriptor.selectionStart.line, "wrap", "cm-line-with-selection"); - var selectionStart = this._highlightRange ? new CodeMirror.Pos(this._highlightRange.startLine, this._highlightRange.startColumn) : null; - if (selectionStart) - this._codeMirror.addLineClass(selectionStart.line, "wrap", "cm-line-with-selection"); - if (this._highlightRegex === oldRegex) { - // Do not re-add overlay mode if regex did not change for better performance. - if (this._highlightDescriptor) - this._highlightDescriptor.selectionStart = selectionStart; - } else { - this._removeHighlight(); - this._setHighlighter(this._searchHighlighter.bind(this, this._highlightRegex), selectionStart); - } - if (this._highlightRange) { - var pos = WebInspector.CodeMirrorTextEditor.prototype._toPos(this._highlightRange); - this._searchResultMarker = this._codeMirror.markText(pos.start, pos.end, {className: "cm-column-with-selection"}); - } - }, - - highlightedRegex: function() - { - return this._highlightRegex; - }, - - highlightSelectedTokens: function() - { - delete this._highlightRegex; - delete this._highlightRange; - - if (this._highlightDescriptor && this._highlightDescriptor.selectionStart) - this._codeMirror.removeLineClass(this._highlightDescriptor.selectionStart.line, "wrap", "cm-line-with-selection"); - this._removeHighlight(); - var selectionStart = this._codeMirror.getCursor("start"); - var selectionEnd = this._codeMirror.getCursor("end"); - if (selectionStart.line !== selectionEnd.line) - return; - if (selectionStart.ch === selectionEnd.ch) - return; - - var selectedText = this._codeMirror.getSelection(); - if (this._isWord(selectedText, selectionStart.line, selectionStart.ch, selectionEnd.ch)) { - if (selectionStart) - this._codeMirror.addLineClass(selectionStart.line, "wrap", "cm-line-with-selection") - this._setHighlighter(this._tokenHighlighter.bind(this, selectedText, selectionStart), selectionStart); - } - }, - - /** - * @param {string} selectedText - * @param {number} lineNumber - * @param {number} startColumn - * @param {number} endColumn - */ - _isWord: function(selectedText, lineNumber, startColumn, endColumn) - { - var line = this._codeMirror.getLine(lineNumber); - var leftBound = startColumn === 0 || !WebInspector.TextUtils.isWordChar(line.charAt(startColumn - 1)); - var rightBound = endColumn === line.length || !WebInspector.TextUtils.isWordChar(line.charAt(endColumn)); - return leftBound && rightBound && WebInspector.TextUtils.isWord(selectedText); - }, - - _removeHighlight: function() - { - if (this._highlightDescriptor) { - this._codeMirror.removeOverlay(this._highlightDescriptor.overlay); - delete this._highlightDescriptor; - } - }, - - /** - * @param {!RegExp} regex - * @param {!CodeMirror.StringStream} stream - */ - _searchHighlighter: function(regex, stream) - { - if (stream.column() === 0) - delete this._searchMatchLength; - if (this._searchMatchLength) { - if (this._searchMatchLength > 1) { - for (var i = 0; i < this._searchMatchLength - 2; ++i) - stream.next(); - this._searchMatchLength = 1; - return "search-highlight"; - } else { - stream.next(); - delete this._searchMatchLength; - return "search-highlight search-highlight-end"; - } - } - var match = stream.match(regex, false); - if (match) { - stream.next(); - var matchLength = match[0].length; - if (matchLength === 1) - return "search-highlight search-highlight-full"; - this._searchMatchLength = matchLength; - return "search-highlight search-highlight-start"; - } - - while (!stream.match(regex, false) && stream.next()) {}; - }, - - /** - * @param {string} token - * @param {!CodeMirror.Pos} selectionStart - * @param {!CodeMirror.StringStream} stream - */ - _tokenHighlighter: function(token, selectionStart, stream) - { - var tokenFirstChar = token.charAt(0); - if (stream.match(token) && (stream.eol() || !WebInspector.TextUtils.isWordChar(stream.peek()))) - return stream.column() === selectionStart.ch ? "token-highlight column-with-selection" : "token-highlight"; - - var eatenChar; - do { - eatenChar = stream.next(); - } while (eatenChar && (WebInspector.TextUtils.isWordChar(eatenChar) || stream.peek() !== tokenFirstChar)); - }, - - /** - * @param {function(!CodeMirror.StringStream)} highlighter - */ - _setHighlighter: function(highlighter, selectionStart) - { - var overlayMode = { - token: highlighter - }; - this._codeMirror.addOverlay(overlayMode); - this._highlightDescriptor = { - overlay: overlayMode, - selectionStart: selectionStart - }; - } -} - -/** - * @constructor - * @param {!CodeMirror} codeMirror - */ -WebInspector.CodeMirrorTextEditor.BlockIndentController = function(codeMirror) -{ - codeMirror.addKeyMap(this); -} - -WebInspector.CodeMirrorTextEditor.BlockIndentController.prototype = { - name: "blockIndentKeymap", - - Enter: function(codeMirror) - { - if (codeMirror.somethingSelected()) - return CodeMirror.Pass; - var cursor = codeMirror.getCursor(); - if (cursor.ch === 0) - return CodeMirror.Pass; - var line = codeMirror.getLine(cursor.line); - if (line.substr(cursor.ch - 1, 2) === "{}") { - codeMirror.execCommand("newlineAndIndent"); - codeMirror.setCursor(cursor); - codeMirror.execCommand("newlineAndIndent"); - codeMirror.execCommand("indentMore"); - } else if (line.substr(cursor.ch - 1, 1) === "{") { - codeMirror.execCommand("newlineAndIndent"); - codeMirror.execCommand("indentMore"); - } else - return CodeMirror.Pass; - }, - - "'}'": function(codeMirror) - { - var cursor = codeMirror.getCursor(); - var line = codeMirror.getLine(cursor.line); - for(var i = 0 ; i < line.length; ++i) - if (!WebInspector.TextUtils.isSpaceChar(line.charAt(i))) - return CodeMirror.Pass; - - codeMirror.replaceRange("}", cursor); - var matchingBracket = codeMirror.findMatchingBracket(); - if (!matchingBracket || !matchingBracket.match) - return; - - line = codeMirror.getLine(matchingBracket.to.line); - var desiredIndentation = 0; - while (desiredIndentation < line.length && WebInspector.TextUtils.isSpaceChar(line.charAt(desiredIndentation))) - ++desiredIndentation; - - codeMirror.replaceRange(line.substr(0, desiredIndentation) + "}", new CodeMirror.Pos(cursor.line, 0), new CodeMirror.Pos(cursor.line, cursor.ch + 1)); - } -} - -/** - * @constructor - * @param {!CodeMirror} codeMirror - */ -WebInspector.CodeMirrorTextEditor.FixWordMovement = function(codeMirror) -{ - function moveLeft(shift, codeMirror) - { - var cursor = codeMirror.getCursor("head"); - if (cursor.ch !== 0 || cursor.line === 0) - return CodeMirror.Pass; - codeMirror.setExtending(shift); - codeMirror.execCommand("goLineUp"); - codeMirror.execCommand("goLineEnd") - codeMirror.setExtending(false); - } - function moveRight(shift, codeMirror) - { - var cursor = codeMirror.getCursor("head"); - var line = codeMirror.getLine(cursor.line); - if (cursor.ch !== line.length || cursor.line + 1 === codeMirror.lineCount()) - return CodeMirror.Pass; - codeMirror.setExtending(shift); - codeMirror.execCommand("goLineDown"); - codeMirror.execCommand("goLineStart"); - codeMirror.setExtending(false); - } - function delWordBack(codeMirror) - { - if (codeMirror.somethingSelected()) - return CodeMirror.Pass; - var cursor = codeMirror.getCursor("head"); - if (cursor.ch === 0) - codeMirror.execCommand("delCharBefore"); - else - return CodeMirror.Pass; - } - - var modifierKey = WebInspector.isMac() ? "Alt" : "Ctrl"; - var leftKey = modifierKey + "-Left"; - var rightKey = modifierKey + "-Right"; - var keyMap = {}; - keyMap[leftKey] = moveLeft.bind(this, false); - keyMap[rightKey] = moveRight.bind(this, false); - keyMap["Shift-" + leftKey] = moveLeft.bind(this, true); - keyMap["Shift-" + rightKey] = moveRight.bind(this, true); - keyMap[modifierKey + "-Backspace"] = delWordBack.bind(this); - codeMirror.addKeyMap(keyMap); -} - -/** - * @constructor - * @implements {WebInspector.SuggestBoxDelegate} - * @param {!WebInspector.CodeMirrorTextEditor} textEditor - * @param {!CodeMirror} codeMirror - */ -WebInspector.CodeMirrorTextEditor.AutocompleteController = function(textEditor, codeMirror) -{ - this._textEditor = textEditor; - this._codeMirror = codeMirror; - this._codeMirror.on("scroll", this._onScroll.bind(this)); - this._codeMirror.on("cursorActivity", this._onCursorActivity.bind(this)); -} - -WebInspector.CodeMirrorTextEditor.AutocompleteController.prototype = { - autocomplete: function() - { - var dictionary = this._textEditor._dictionary; - if (!dictionary || this._codeMirror.somethingSelected()) { - this.finishAutocomplete(); - return; - } - - var cursor = this._codeMirror.getCursor(); - var substituteRange = this._textEditor._wordRangeForCursorPosition(cursor.line, cursor.ch, false); - if (!substituteRange || substituteRange.startColumn === cursor.ch) { - this.finishAutocomplete(); - return; - } - var prefixRange = substituteRange.clone(); - prefixRange.endColumn = cursor.ch; - - var substituteWord = this._textEditor.copyRange(substituteRange); - var hasPrefixInDictionary = dictionary.hasWord(substituteWord); - if (hasPrefixInDictionary) - dictionary.removeWord(substituteWord); - var wordsWithPrefix = dictionary.wordsWithPrefix(this._textEditor.copyRange(prefixRange)); - if (hasPrefixInDictionary) - dictionary.addWord(substituteWord); - - function sortSuggestions(a, b) - { - return dictionary.wordCount(b) - dictionary.wordCount(a) || a.length - b.length; - } - - wordsWithPrefix.sort(sortSuggestions); - - if (!this._suggestBox) { - this._suggestBox = new WebInspector.SuggestBox(this, this._textEditor.element, "generic-suggest", 6); - this._anchorBox = this._anchorBoxForPosition(cursor.line, cursor.ch); - } - this._suggestBox.updateSuggestions(this._anchorBox, wordsWithPrefix, 0, true, this._textEditor.copyRange(prefixRange)); - this._prefixRange = prefixRange; - if (!this._suggestBox.visible()) - this.finishAutocomplete(); - }, - - finishAutocomplete: function() - { - if (!this._suggestBox) - return; - this._suggestBox.hide(); - this._suggestBox = null; - this._prefixRange = null; - this._anchorBox = null; - }, - - /** - * @param {?Event} e - */ - keyDown: function(e) - { - if (!this._suggestBox) - return false; - if (e.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code) { - this.finishAutocomplete(); - return true; - } - if (e.keyCode === WebInspector.KeyboardShortcut.Keys.Tab.code) { - this._suggestBox.acceptSuggestion(); - this.finishAutocomplete(); - return true; - } - return this._suggestBox.keyPressed(e); - }, - - /** - * @param {string} suggestion - * @param {boolean=} isIntermediateSuggestion - */ - applySuggestion: function(suggestion, isIntermediateSuggestion) - { - this._currentSuggestion = suggestion; - }, - - acceptSuggestion: function() - { - if (this._prefixRange.endColumn - this._prefixRange.startColumn !== this._currentSuggestion.length) { - var pos = this._textEditor._toPos(this._prefixRange); - this._codeMirror.replaceRange(this._currentSuggestion, pos.start, pos.end, "+autocomplete"); - } - }, - - _onScroll: function() - { - if (!this._suggestBox) - return; - var cursor = this._codeMirror.getCursor(); - var scrollInfo = this._codeMirror.getScrollInfo(); - var topmostLineNumber = this._codeMirror.lineAtHeight(scrollInfo.top, "local"); - var bottomLine = this._codeMirror.lineAtHeight(scrollInfo.top + scrollInfo.clientHeight, "local"); - if (cursor.line < topmostLineNumber || cursor.line > bottomLine) - this.finishAutocomplete(); - else { - this._anchorBox = this._anchorBoxForPosition(cursor.line, cursor.ch); - this._suggestBox.setPosition(this._anchorBox); - } - }, - - _onCursorActivity: function() - { - if (!this._suggestBox) - return; - var cursor = this._codeMirror.getCursor(); - if (cursor.line !== this._prefixRange.startLine || cursor.ch > this._prefixRange.endColumn || cursor.ch < this._prefixRange.startColumn) - this.finishAutocomplete(); - }, - - /** - * @param {number} line - * @param {number} column - * @return {?AnchorBox} - */ - _anchorBoxForPosition: function(line, column) - { - var metrics = this._textEditor.cursorPositionToCoordinates(line, column); - return metrics ? new AnchorBox(metrics.x, metrics.y, 0, metrics.height) : null; - }, -} |