📄 console.js
字号:
/* * Copyright (C) 2007, 2008 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. * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 APPLE 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 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.Console = function(){ this.messages = []; WebInspector.View.call(this, document.getElementById("console")); this.messagesElement = document.getElementById("console-messages"); this.messagesElement.addEventListener("selectstart", this._messagesSelectStart.bind(this), false); this.messagesElement.addEventListener("click", this._messagesClicked.bind(this), true); this.promptElement = document.getElementById("console-prompt"); this.promptElement.handleKeyEvent = this._promptKeyDown.bind(this); this.prompt = new WebInspector.TextPrompt(this.promptElement, this.completions.bind(this), " .=:[({;"); this.toggleButton = document.getElementById("console-status-bar-item"); this.toggleButton.title = WebInspector.UIString("Show console."); this.toggleButton.addEventListener("click", this._toggleButtonClicked.bind(this), false); this.clearButton = document.getElementById("clear-console-status-bar-item"); this.clearButton.title = WebInspector.UIString("Clear console log."); this.clearButton.addEventListener("click", this._clearButtonClicked.bind(this), false); this.topGroup = new WebInspector.ConsoleGroup(null, 0); this.messagesElement.insertBefore(this.topGroup.element, this.promptElement); this.groupLevel = 0; this.currentGroup = this.topGroup; document.getElementById("main-status-bar").addEventListener("mousedown", this._startStatusBarDragging.bind(this), true);}WebInspector.Console.prototype = { show: function() { if (this._animating || this.visible) return; WebInspector.View.prototype.show.call(this); this._animating = true; this.toggleButton.addStyleClass("toggled-on"); this.toggleButton.title = WebInspector.UIString("Hide console."); document.body.addStyleClass("console-visible"); var anchoredItems = document.getElementById("anchored-status-bar-items"); var animations = [ {element: document.getElementById("main"), end: {bottom: this.element.offsetHeight}}, {element: document.getElementById("main-status-bar"), start: {"padding-left": anchoredItems.offsetWidth - 1}, end: {"padding-left": 0}}, {element: document.getElementById("other-console-status-bar-items"), start: {opacity: 0}, end: {opacity: 1}} ]; var consoleStatusBar = document.getElementById("console-status-bar"); consoleStatusBar.insertBefore(anchoredItems, consoleStatusBar.firstChild); function animationFinished() { if ("updateStatusBarItems" in WebInspector.currentPanel) WebInspector.currentPanel.updateStatusBarItems(); WebInspector.currentFocusElement = this.promptElement; delete this._animating; } WebInspector.animateStyle(animations, window.event && window.event.shiftKey ? 2000 : 250, animationFinished.bind(this)); if (!this.prompt.isCaretInsidePrompt()) this.prompt.moveCaretToEndOfPrompt(); }, hide: function() { if (this._animating || !this.visible) return; WebInspector.View.prototype.hide.call(this); this._animating = true; this.toggleButton.removeStyleClass("toggled-on"); this.toggleButton.title = WebInspector.UIString("Show console."); if (this.element === WebInspector.currentFocusElement || this.element.isAncestor(WebInspector.currentFocusElement)) WebInspector.currentFocusElement = WebInspector.previousFocusElement; var anchoredItems = document.getElementById("anchored-status-bar-items"); // Temporally set properties and classes to mimic the post-animation values so panels // like Elements in their updateStatusBarItems call will size things to fit the final location. document.getElementById("main-status-bar").style.setProperty("padding-left", (anchoredItems.offsetWidth - 1) + "px"); document.body.removeStyleClass("console-visible"); if ("updateStatusBarItems" in WebInspector.currentPanel) WebInspector.currentPanel.updateStatusBarItems(); document.body.addStyleClass("console-visible"); var animations = [ {element: document.getElementById("main"), end: {bottom: 0}}, {element: document.getElementById("main-status-bar"), start: {"padding-left": 0}, end: {"padding-left": anchoredItems.offsetWidth - 1}}, {element: document.getElementById("other-console-status-bar-items"), start: {opacity: 1}, end: {opacity: 0}} ]; function animationFinished() { var mainStatusBar = document.getElementById("main-status-bar"); mainStatusBar.insertBefore(anchoredItems, mainStatusBar.firstChild); mainStatusBar.style.removeProperty("padding-left"); document.body.removeStyleClass("console-visible"); delete this._animating; } WebInspector.animateStyle(animations, window.event && window.event.shiftKey ? 2000 : 250, animationFinished.bind(this)); }, addMessage: function(msg) { if (msg instanceof WebInspector.ConsoleMessage && !(msg instanceof WebInspector.ConsoleCommandResult)) { msg.totalRepeatCount = msg.repeatCount; msg.repeatDelta = msg.repeatCount; var messageRepeated = false; if (msg.isEqual && msg.isEqual(this.previousMessage)) { // Because sometimes we get a large number of repeated messages and sometimes // we get them one at a time, we need to know the difference between how many // repeats we used to have and how many we have now. msg.repeatDelta -= this.previousMessage.totalRepeatCount; if (!isNaN(this.repeatCountBeforeCommand)) msg.repeatCount -= this.repeatCountBeforeCommand; if (!this.commandSincePreviousMessage) { // Recreate the previous message element to reset the repeat count. var messagesElement = this.currentGroup.messagesElement; messagesElement.removeChild(messagesElement.lastChild); messagesElement.appendChild(msg.toMessageElement()); messageRepeated = true; } } else delete this.repeatCountBeforeCommand; // Increment the error or warning count switch (msg.level) { case WebInspector.ConsoleMessage.MessageLevel.Warning: WebInspector.warnings += msg.repeatDelta; break; case WebInspector.ConsoleMessage.MessageLevel.Error: WebInspector.errors += msg.repeatDelta; break; } // Add message to the resource panel if (msg.url in WebInspector.resourceURLMap) { msg.resource = WebInspector.resourceURLMap[msg.url]; if (WebInspector.panels.resources) WebInspector.panels.resources.addMessageToResource(msg.resource, msg); } this.commandSincePreviousMessage = false; this.previousMessage = msg; if (messageRepeated) return; } else if (msg instanceof WebInspector.ConsoleCommand) { if (this.previousMessage) { this.commandSincePreviousMessage = true; this.repeatCountBeforeCommand = this.previousMessage.totalRepeatCount; } } this.messages.push(msg); if (msg.level === WebInspector.ConsoleMessage.MessageLevel.EndGroup) { if (this.groupLevel < 1) return; this.groupLevel--; this.currentGroup = this.currentGroup.parentGroup; } else { if (msg.level === WebInspector.ConsoleMessage.MessageLevel.StartGroup) { this.groupLevel++; var group = new WebInspector.ConsoleGroup(this.currentGroup, this.groupLevel); this.currentGroup.messagesElement.appendChild(group.element); this.currentGroup = group; } this.currentGroup.addMessage(msg); } this.promptElement.scrollIntoView(false); }, clearMessages: function(clearInspectorController) { if (clearInspectorController) InspectorController.clearMessages(); if (WebInspector.panels.resources) WebInspector.panels.resources.clearMessages(); this.messages = []; this.groupLevel = 0; this.currentGroup = this.topGroup; this.topGroup.messagesElement.removeChildren(); WebInspector.errors = 0; WebInspector.warnings = 0; delete this.commandSincePreviousMessage; delete this.repeatCountBeforeCommand; delete this.previousMessage; }, completions: function(wordRange, bestMatchOnly) { // Pass less stop characters to rangeOfWord so the range will be a more complete expression. const expressionStopCharacters = " =:{;"; var expressionRange = wordRange.startContainer.rangeOfWord(wordRange.startOffset, expressionStopCharacters, this.promptElement, "backward"); var expressionString = expressionRange.toString(); var lastIndex = expressionString.length - 1; var dotNotation = (expressionString[lastIndex] === "."); var bracketNotation = (expressionString[lastIndex] === "["); if (dotNotation || bracketNotation) expressionString = expressionString.substr(0, lastIndex); var prefix = wordRange.toString(); if (!expressionString && !prefix) return; var result; if (expressionString) { try { result = this._evalInInspectedWindow(expressionString); } catch(e) { // Do nothing, the prefix will be considered a window property. } } else { // There is no expressionString, so the completion should happen against global properties. // Or if the debugger is paused, against properties in scope of the selected call frame. if (WebInspector.panels.scripts && WebInspector.panels.scripts.paused) result = WebInspector.panels.scripts.variablesInScopeForSelectedCallFrame(); else result = InspectorController.inspectedWindow(); } if (bracketNotation) { if (prefix.length && prefix[0] === "'") var quoteUsed = "'"; else var quoteUsed = "\""; } var results = []; var properties = Object.sortedProperties(result); for (var i = 0; i < properties.length; ++i) { var property = properties[i]; if (dotNotation && !/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(property)) continue; if (bracketNotation) { if (!/^[0-9]+$/.test(property)) property = quoteUsed + property.escapeCharacters(quoteUsed + "\\") + quoteUsed; property += "]"; } if (property.length < prefix.length) continue; if (property.indexOf(prefix) !== 0) continue; results.push(property); if (bestMatchOnly) break; } return results; }, _toggleButtonClicked: function() {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -