diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebInspectorUI/UserInterface/Views/ConsolePrompt.js | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WebInspectorUI/UserInterface/Views/ConsolePrompt.js')
-rw-r--r-- | Source/WebInspectorUI/UserInterface/Views/ConsolePrompt.js | 330 |
1 files changed, 330 insertions, 0 deletions
diff --git a/Source/WebInspectorUI/UserInterface/Views/ConsolePrompt.js b/Source/WebInspectorUI/UserInterface/Views/ConsolePrompt.js new file mode 100644 index 000000000..43179793e --- /dev/null +++ b/Source/WebInspectorUI/UserInterface/Views/ConsolePrompt.js @@ -0,0 +1,330 @@ +/* + * Copyright (C) 2013, 2015 Apple 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: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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. + */ + +WebInspector.ConsolePrompt = class ConsolePrompt extends WebInspector.View +{ + constructor(delegate, mimeType) + { + super(); + + mimeType = parseMIMEType(mimeType).type; + + this.element.classList.add("console-prompt", WebInspector.SyntaxHighlightedStyleClassName); + + this._delegate = delegate || null; + + this._codeMirror = WebInspector.CodeMirrorEditor.create(this.element, { + lineWrapping: true, + mode: {name: mimeType, globalVars: true}, + indentWithTabs: true, + indentUnit: 4, + matchBrackets: true + }); + + var keyMap = { + "Up": this._handlePreviousKey.bind(this), + "Down": this._handleNextKey.bind(this), + "Ctrl-P": this._handlePreviousKey.bind(this), + "Ctrl-N": this._handleNextKey.bind(this), + "Enter": this._handleEnterKey.bind(this), + "Cmd-Enter": this._handleCommandEnterKey.bind(this), + "Tab": this._handleTabKey.bind(this), + "Esc": this._handleEscapeKey.bind(this) + }; + + this._codeMirror.addKeyMap(keyMap); + + this._completionController = new WebInspector.CodeMirrorCompletionController(this._codeMirror, this); + this._completionController.addExtendedCompletionProvider("javascript", WebInspector.javaScriptRuntimeCompletionProvider); + + this._history = [{}]; + this._historyIndex = 0; + } + + // Public + + get delegate() + { + return this._delegate; + } + + set delegate(delegate) + { + this._delegate = delegate || null; + } + + set escapeKeyHandlerWhenEmpty(handler) + { + this._escapeKeyHandlerWhenEmpty = handler; + } + + get text() + { + return this._codeMirror.getValue(); + } + + set text(text) + { + this._codeMirror.setValue(text || ""); + this._codeMirror.clearHistory(); + this._codeMirror.markClean(); + } + + get history() + { + this._history[this._historyIndex] = this._historyEntryForCurrentText(); + return this._history; + } + + set history(history) + { + this._history = history instanceof Array ? history.slice(0, WebInspector.ConsolePrompt.MaximumHistorySize) : [{}]; + this._historyIndex = 0; + this._restoreHistoryEntry(0); + } + + get focused() + { + return this._codeMirror.getWrapperElement().classList.contains("CodeMirror-focused"); + } + + focus() + { + this._codeMirror.focus(); + } + + shown() + { + this._codeMirror.refresh(); + } + + updateCompletions(completions, implicitSuffix) + { + this._completionController.updateCompletions(completions, implicitSuffix); + } + + pushHistoryItem(text) + { + this._commitHistoryEntry({text}); + } + + // Protected + + completionControllerCompletionsNeeded(completionController, prefix, defaultCompletions, base, suffix, forced) + { + if (this.delegate && typeof this.delegate.consolePromptCompletionsNeeded === "function") + this.delegate.consolePromptCompletionsNeeded(this, defaultCompletions, base, prefix, suffix, forced); + else + this._completionController.updateCompletions(defaultCompletions); + } + + completionControllerShouldAllowEscapeCompletion(completionController) + { + // Only allow escape to complete if there is text in the prompt. Otherwise allow it to pass through + // so escape to toggle the quick console still works. + return !!this.text; + } + + layout() + { + this._codeMirror.refresh(); + } + + // Private + + _handleTabKey(codeMirror) + { + var cursor = codeMirror.getCursor(); + var line = codeMirror.getLine(cursor.line); + + if (!line.trim().length) + return CodeMirror.Pass; + + var firstNonSpace = line.search(/[^\s]/); + + if (cursor.ch <= firstNonSpace) + return CodeMirror.Pass; + + this._completionController.completeAtCurrentPositionIfNeeded().then(function(result) { + if (result === WebInspector.CodeMirrorCompletionController.UpdatePromise.NoCompletionsFound) + InspectorFrontendHost.beep(); + }); + } + + _handleEscapeKey(codeMirror) + { + if (this.text) + return CodeMirror.Pass; + + if (!this._escapeKeyHandlerWhenEmpty) + return CodeMirror.Pass; + + this._escapeKeyHandlerWhenEmpty(); + } + + _handlePreviousKey(codeMirror) + { + if (this._codeMirror.somethingSelected()) + return CodeMirror.Pass; + + // Pass unless we are on the first line. + if (this._codeMirror.getCursor().line) + return CodeMirror.Pass; + + var historyEntry = this._history[this._historyIndex + 1]; + if (!historyEntry) + return CodeMirror.Pass; + + this._rememberCurrentTextInHistory(); + + ++this._historyIndex; + + this._restoreHistoryEntry(this._historyIndex); + } + + _handleNextKey(codeMirror) + { + if (this._codeMirror.somethingSelected()) + return CodeMirror.Pass; + + // Pass unless we are on the last line. + if (this._codeMirror.getCursor().line !== this._codeMirror.lastLine()) + return CodeMirror.Pass; + + var historyEntry = this._history[this._historyIndex - 1]; + if (!historyEntry) + return CodeMirror.Pass; + + this._rememberCurrentTextInHistory(); + + --this._historyIndex; + + this._restoreHistoryEntry(this._historyIndex); + } + + _handleEnterKey(codeMirror, forceCommit, keepCurrentText) + { + var currentText = this.text; + + // Always do nothing when there is just whitespace. + if (!currentText.trim()) + return; + + var cursor = this._codeMirror.getCursor(); + var lastLine = this._codeMirror.lastLine(); + var lastLineLength = this._codeMirror.getLine(lastLine).length; + var cursorIsAtLastPosition = positionsEqual(cursor, {line: lastLine, ch: lastLineLength}); + + function positionsEqual(a, b) + { + console.assert(a); + console.assert(b); + return a.line === b.line && a.ch === b.ch; + } + + function commitTextOrInsertNewLine(commit) + { + if (!commit) { + // Only insert a new line if the previous cursor and the current cursor are in the same position. + if (positionsEqual(cursor, this._codeMirror.getCursor())) + CodeMirror.commands.newlineAndIndent(this._codeMirror); + return; + } + + this._commitHistoryEntry(this._historyEntryForCurrentText()); + + if (!keepCurrentText) { + this._codeMirror.setValue(""); + this._codeMirror.clearHistory(); + } + + if (this.delegate && typeof this.delegate.consolePromptHistoryDidChange === "function") + this.delegate.consolePromptHistoryDidChange(this); + + if (this.delegate && typeof this.delegate.consolePromptTextCommitted === "function") + this.delegate.consolePromptTextCommitted(this, currentText); + } + + if (!forceCommit && this.delegate && typeof this.delegate.consolePromptShouldCommitText === "function") { + this.delegate.consolePromptShouldCommitText(this, currentText, cursorIsAtLastPosition, commitTextOrInsertNewLine.bind(this)); + return; + } + + commitTextOrInsertNewLine.call(this, true); + } + + _commitHistoryEntry(historyEntry) + { + // Replace the previous entry if it does not have text or if the text is the same. + if (this._history[1] && (!this._history[1].text || this._history[1].text === historyEntry.text)) { + this._history[1] = historyEntry; + this._history[0] = {}; + } else { + // Replace the first history entry and push a new empty one. + this._history[0] = historyEntry; + this._history.unshift({}); + + // Trim the history length if needed. + if (this._history.length > WebInspector.ConsolePrompt.MaximumHistorySize) + this._history = this._history.slice(0, WebInspector.ConsolePrompt.MaximumHistorySize); + } + + this._historyIndex = 0; + } + + _handleCommandEnterKey(codeMirror) + { + this._handleEnterKey(codeMirror, true, true); + } + + _restoreHistoryEntry(index) + { + var historyEntry = this._history[index]; + + this._codeMirror.setValue(historyEntry.text || ""); + + if (historyEntry.undoHistory) + this._codeMirror.setHistory(historyEntry.undoHistory); + else + this._codeMirror.clearHistory(); + + this._codeMirror.setCursor(historyEntry.cursor || {line: 0}); + } + + _historyEntryForCurrentText() + { + return {text: this.text, undoHistory: this._codeMirror.getHistory(), cursor: this._codeMirror.getCursor()}; + } + + _rememberCurrentTextInHistory() + { + this._history[this._historyIndex] = this._historyEntryForCurrentText(); + + if (this.delegate && typeof this.delegate.consolePromptHistoryDidChange === "function") + this.delegate.consolePromptHistoryDidChange(this); + } +}; + +WebInspector.ConsolePrompt.MaximumHistorySize = 30; |