📄 sourceframe.js
字号:
/* * Copyright (C) 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. * * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 * 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.SourceFrame = function(element, addBreakpointDelegate){ this.messages = []; this.breakpoints = []; this.addBreakpointDelegate = addBreakpointDelegate; this.element = element || document.createElement("iframe"); this.element.addStyleClass("source-view-frame"); this.element.setAttribute("viewsource", "true"); this.element.addEventListener("load", this._loaded.bind(this), false);}WebInspector.SourceFrame.prototype = { get executionLine() { return this._executionLine; }, set executionLine(x) { if (this._executionLine === x) return; var previousLine = this._executionLine; this._executionLine = x; this._updateExecutionLine(previousLine); }, get autoSizesToFitContentHeight() { return this._autoSizesToFitContentHeight; }, set autoSizesToFitContentHeight(x) { if (this._autoSizesToFitContentHeight === x) return; this._autoSizesToFitContentHeight = x; if (this._autoSizesToFitContentHeight) { this._windowResizeListener = this._windowResized.bind(this); window.addEventListener("resize", this._windowResizeListener, false); this.sizeToFitContentHeight(); } else { this.element.style.removeProperty("height"); if (this.element.contentDocument) this.element.contentDocument.body.removeStyleClass("webkit-height-sized-to-fit"); window.removeEventListener("resize", this._windowResizeListener, false); delete this._windowResizeListener; } }, sourceRow: function(lineNumber) { if (!lineNumber || !this.element.contentDocument) return; var table = this.element.contentDocument.getElementsByTagName("table")[0]; if (!table) return; var rows = table.rows; // Line numbers are a 1-based index, but the rows collection is 0-based. --lineNumber; return rows[lineNumber]; }, lineNumberForSourceRow: function(sourceRow) { // Line numbers are a 1-based index, but the rows collection is 0-based. var lineNumber = 0; while (sourceRow) { ++lineNumber; sourceRow = sourceRow.previousSibling; } return lineNumber; }, revealLine: function(lineNumber) { var row = this.sourceRow(lineNumber); if (row) row.scrollIntoViewIfNeeded(true); }, addBreakpoint: function(breakpoint) { this.breakpoints.push(breakpoint); breakpoint.addEventListener("enabled", this._breakpointEnableChanged, this); breakpoint.addEventListener("disabled", this._breakpointEnableChanged, this); this._addBreakpointToSource(breakpoint); }, removeBreakpoint: function(breakpoint) { this.breakpoints.remove(breakpoint); breakpoint.removeEventListener("enabled", null, this); breakpoint.removeEventListener("disabled", null, this); this._removeBreakpointFromSource(breakpoint); }, addMessage: function(msg) { // Don't add the message if there is no message or valid line or if the msg isn't an error or warning. if (!msg.message || msg.line <= 0 || !msg.isErrorOrWarning()) return; this.messages.push(msg); this._addMessageToSource(msg); }, clearMessages: function() { this.messages = []; if (!this.element.contentDocument) return; var bubbles = this.element.contentDocument.querySelectorAll(".webkit-html-message-bubble"); if (!bubbles) return; for (var i = 0; i < bubbles.length; ++i) { var bubble = bubbles[i]; bubble.parentNode.removeChild(bubble); } }, sizeToFitContentHeight: function() { if (this.element.contentDocument) { this.element.style.setProperty("height", this.element.contentDocument.body.offsetHeight + "px"); this.element.contentDocument.body.addStyleClass("webkit-height-sized-to-fit"); } }, _highlightLineEnds: function(event) { event.target.parentNode.removeStyleClass("webkit-highlighted-line"); }, highlightLine: function(lineNumber) { var sourceRow = this.sourceRow(lineNumber); if (!sourceRow) return; var line = sourceRow.getElementsByClassName('webkit-line-content')[0]; // Trick to reset the animation if the user clicks on the same link // Using a timeout to avoid coalesced style updates line.style.setProperty("-webkit-animation-name", "none"); setTimeout(function () { line.style.removeProperty("-webkit-animation-name"); sourceRow.addStyleClass("webkit-highlighted-line"); }, 0); }, _loaded: function() { WebInspector.addMainEventListeners(this.element.contentDocument); this.element.contentDocument.addEventListener("mousedown", this._documentMouseDown.bind(this), true); this.element.contentDocument.addEventListener("webkitAnimationEnd", this._highlightLineEnds.bind(this), false); var headElement = this.element.contentDocument.getElementsByTagName("head")[0]; if (!headElement) { headElement = this.element.contentDocument.createElement("head"); this.element.contentDocument.documentElement.insertBefore(headElement, this.element.contentDocument.documentElement.firstChild); } var styleElement = this.element.contentDocument.createElement("style"); headElement.appendChild(styleElement); // Add these style rules here since they are specific to the Inspector. They also behave oddly and not // all properties apply if added to view-source.css (becuase it is a user agent sheet.) var styleText = ".webkit-line-number { background-repeat: no-repeat; background-position: right 1px; }\n"; styleText += ".webkit-breakpoint .webkit-line-number { color: white; background-image: -webkit-canvas(breakpoint); }\n"; styleText += ".webkit-breakpoint-disabled .webkit-line-number { color: white; background-image: -webkit-canvas(breakpoint-disabled); }\n"; styleText += ".webkit-execution-line .webkit-line-number { color: transparent; background-image: -webkit-canvas(program-counter); }\n"; styleText += ".webkit-breakpoint.webkit-execution-line .webkit-line-number { color: transparent; background-image: -webkit-canvas(breakpoint-program-counter); }\n"; styleText += ".webkit-breakpoint-disabled.webkit-execution-line .webkit-line-number { color: transparent; background-image: -webkit-canvas(breakpoint-disabled-program-counter); }\n"; styleText += ".webkit-execution-line .webkit-line-content { background-color: rgb(171, 191, 254); outline: 1px solid rgb(64, 115, 244); }\n"; styleText += ".webkit-height-sized-to-fit { overflow-y: hidden }\n"; styleText += ".webkit-line-content { background-color: white; }\n"; styleText += "@-webkit-keyframes fadeout {from {background-color: rgb(255, 255, 120);} to { background-color: white;}}\n"; styleText += ".webkit-highlighted-line .webkit-line-content { background-color: rgb(255, 255, 120); -webkit-animation: 'fadeout' 2s 500ms}\n"; styleText += ".webkit-javascript-comment { color: rgb(0, 116, 0); }\n"; styleText += ".webkit-javascript-keyword { color: rgb(170, 13, 145); }\n"; styleText += ".webkit-javascript-number { color: rgb(28, 0, 207); }\n"; styleText += ".webkit-javascript-string, .webkit-javascript-regexp { color: rgb(196, 26, 22); }\n"; styleElement.textContent = styleText; this._needsProgramCounterImage = true; this._needsBreakpointImages = true; this.element.contentWindow.Element.prototype.addStyleClass = Element.prototype.addStyleClass; this.element.contentWindow.Element.prototype.removeStyleClass = Element.prototype.removeStyleClass; this.element.contentWindow.Element.prototype.hasStyleClass = Element.prototype.hasStyleClass; this.element.contentWindow.Node.prototype.enclosingNodeOrSelfWithNodeName = Node.prototype.enclosingNodeOrSelfWithNodeName; this._addExistingMessagesToSource(); this._addExistingBreakpointsToSource(); this._updateExecutionLine(); if (this.autoSizesToFitContentHeight) this.sizeToFitContentHeight(); }, _windowResized: function(event) { if (!this._autoSizesToFitContentHeight) return; this.sizeToFitContentHeight(); }, _documentMouseDown: function(event) { if (!event.target.hasStyleClass("webkit-line-number")) return; var sourceRow = event.target.enclosingNodeOrSelfWithNodeName("tr"); if (sourceRow._breakpointObject) sourceRow._breakpointObject.enabled = !sourceRow._breakpointObject.enabled; else if (this.addBreakpointDelegate) this.addBreakpointDelegate(this.lineNumberForSourceRow(sourceRow)); }, _breakpointEnableChanged: function(event) { var breakpoint = event.target; var sourceRow = this.sourceRow(breakpoint.line); if (!sourceRow) return; sourceRow.addStyleClass("webkit-breakpoint"); if (breakpoint.enabled) sourceRow.removeStyleClass("webkit-breakpoint-disabled"); else sourceRow.addStyleClass("webkit-breakpoint-disabled"); }, _updateExecutionLine: function(previousLine) { if (previousLine) { var sourceRow = this.sourceRow(previousLine); if (sourceRow) sourceRow.removeStyleClass("webkit-execution-line"); } if (!this._executionLine) return; this._drawProgramCounterImageIfNeeded(); var sourceRow = this.sourceRow(this._executionLine); if (sourceRow) sourceRow.addStyleClass("webkit-execution-line"); }, _addExistingBreakpointsToSource: function() { var length = this.breakpoints.length; for (var i = 0; i < length; ++i) this._addBreakpointToSource(this.breakpoints[i]); }, _addBreakpointToSource: function(breakpoint) { var sourceRow = this.sourceRow(breakpoint.line); if (!sourceRow) return; this._drawBreakpointImagesIfNeeded(); sourceRow._breakpointObject = breakpoint; sourceRow.addStyleClass("webkit-breakpoint"); if (!breakpoint.enabled) sourceRow.addStyleClass("webkit-breakpoint-disabled"); }, _removeBreakpointFromSource: function(breakpoint) { var sourceRow = this.sourceRow(breakpoint.line); if (!sourceRow) return; delete sourceRow._breakpointObject; sourceRow.removeStyleClass("webkit-breakpoint"); sourceRow.removeStyleClass("webkit-breakpoint-disabled"); }, _incrementMessageRepeatCount: function(msg, repeatDelta) { if (!msg._resourceMessageLineElement) return; if (!msg._resourceMessageRepeatCountElement) { var repeatedElement = document.createElement("span"); msg._resourceMessageLineElement.appendChild(repeatedElement); msg._resourceMessageRepeatCountElement = repeatedElement; } msg.repeatCount += repeatDelta; msg._resourceMessageRepeatCountElement.textContent = WebInspector.UIString(" (repeated %d times)", msg.repeatCount); }, _addExistingMessagesToSource: function() { var length = this.messages.length; for (var i = 0; i < length; ++i) this._addMessageToSource(this.messages[i]); }, _addMessageToSource: function(msg) { var row = this.sourceRow(msg.line); if (!row)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -