diff options
Diffstat (limited to 'WebCore/inspector/front-end/SourceFrame.js')
-rw-r--r-- | WebCore/inspector/front-end/SourceFrame.js | 2301 |
1 files changed, 372 insertions, 1929 deletions
diff --git a/WebCore/inspector/front-end/SourceFrame.js b/WebCore/inspector/front-end/SourceFrame.js index b5cf4c0..1e1bd0c 100644 --- a/WebCore/inspector/front-end/SourceFrame.js +++ b/WebCore/inspector/front-end/SourceFrame.js @@ -1,45 +1,58 @@ /* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. - * Copyright (C) 2009 Joseph Pecoraro + * Copyright (C) 2009 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: - * 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. + * modification, are permitted provided that the following conditions are + * met: * - * 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 + * * 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. */ -WebInspector.SourceFrame = function(element, addBreakpointDelegate) +WebInspector.SourceFrame = function(parentElement, addBreakpointDelegate) { - this.messages = []; + this._parentElement = parentElement; + + this._textModel = new WebInspector.TextEditorModel(); + + this._messages = []; + this._rowMessages = {}; + this._messageBubbles = {}; this.breakpoints = []; this._shortcuts = {}; - this.addBreakpointDelegate = addBreakpointDelegate; - - this.element = element || document.createElement("iframe"); - this.element.addStyleClass("source-view-frame"); - this.element.setAttribute("viewsource", "true"); + this._loaded = false; - this.element.addEventListener("load", this._loaded.bind(this), false); + this._addBreakpointDelegate = addBreakpointDelegate; } WebInspector.SourceFrame.prototype = { + + set visible(visible) + { + this._visible = visible; + this._createEditorIfNeeded(); + }, + get executionLine() { return this._executionLine; @@ -49,84 +62,25 @@ WebInspector.SourceFrame.prototype = { { 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; + if (this._editor) + this._editor.repaintAll(); }, revealLine: function(lineNumber) { - if (!this._isContentLoaded()) { + if (this._editor) + this._editor.reveal(lineNumber - 1, 0); + else this._lineNumberToReveal = lineNumber; - return; - } - - 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); + breakpoint.addEventListener("enabled", this._breakpointChanged, this); + breakpoint.addEventListener("disabled", this._breakpointChanged, this); + breakpoint.addEventListener("condition-changed", this._breakpointChanged, this); this._addBreakpointToSource(breakpoint); }, @@ -135,6 +89,7 @@ WebInspector.SourceFrame.prototype = { this.breakpoints.remove(breakpoint); breakpoint.removeEventListener("enabled", null, this); breakpoint.removeEventListener("disabled", null, this); + breakpoint.removeEventListener("condition-changed", null, this); this._removeBreakpointFromSource(breakpoint); }, @@ -143,368 +98,135 @@ WebInspector.SourceFrame.prototype = { // 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); + this._messages.push(msg) + if (this._editor) + 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]; + for (var line in this._messageBubbles) { + var bubble = this._messageBubbles[line]; bubble.parentNode.removeChild(bubble); } + + this._messages = []; + this._rowMessages = {}; + this._messageBubbles = {}; + if (this._editor) + this._editor.revalidateDecorationsAndPaint(); }, 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"); - } + if (this._editor) + this._editor.revalidateDecorationsAndPaint(); }, - _highlightLineEnds: function(event) + setContent: function(mimeType, content) { - event.target.parentNode.removeStyleClass("webkit-highlighted-line"); + this._loaded = true; + this._textModel.setText(null, content); + this._mimeType = mimeType; + this._createEditorIfNeeded(); }, - highlightLine: function(lineNumber) + _createEditorIfNeeded: function() { - if (!this._isContentLoaded()) { - this._lineNumberToHighlight = lineNumber; + if (!this._visible || !this._loaded || this._editor) return; - } - 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); - }, + var editorConstructor = Preferences.useCanvasBasedEditor ? WebInspector.TextEditor : WebInspector.NativeTextViewer; + this._editor = new editorConstructor(this._textModel, WebInspector.platform); + this._editor.lineNumberDecorator = new WebInspector.BreakpointLineNumberDecorator(this, this._editor.textModel); + this._editor.lineDecorator = new WebInspector.ExecutionLineDecorator(this); + this._editor.readOnly = true; + this._element = this._editor.element; + this._element.addEventListener("keydown", this._keyDown.bind(this), true); + this._parentElement.appendChild(this._element); - _loaded: function() - { - WebInspector.addMainEventListeners(this.element.contentDocument); - this.element.contentDocument.addEventListener("contextmenu", this._documentContextMenu.bind(this), true); - this.element.contentDocument.addEventListener("mousedown", this._documentMouseDown.bind(this), true); - this.element.contentDocument.addEventListener("keydown", this._documentKeyDown.bind(this), true); - this.element.contentDocument.addEventListener("keyup", WebInspector.documentKeyUp.bind(WebInspector), true); - this.element.contentDocument.addEventListener("webkitAnimationEnd", this._highlightLineEnds.bind(this), false); - - // Register 'eval' shortcut. - var platformSpecificModifier = WebInspector.isMac() ? WebInspector.KeyboardShortcut.Modifiers.Meta : WebInspector.KeyboardShortcut.Modifiers.Ctrl; - var shortcut = WebInspector.KeyboardShortcut.makeKey(69 /* 'E' */, platformSpecificModifier | WebInspector.KeyboardShortcut.Modifiers.Shift); - this._shortcuts[shortcut] = this._evalSelectionInCallFrame.bind(this); - - var headElement = this.element.contentDocument.head; - if (!headElement) { - headElement = this.element.contentDocument.createElement("head"); - this.element.contentDocument.documentElement.insertBefore(headElement, this.element.contentDocument.documentElement.firstChild); - } - - var linkElement = this.element.contentDocument.createElement("link"); - linkElement.type = "text/css"; - linkElement.rel = "stylesheet"; - linkElement.href = "inspectorSyntaxHighlight.css"; - headElement.appendChild(linkElement); - - 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 (because it is a user agent sheet.) - var styleText = ".webkit-line-number { background-repeat: no-repeat; background-position: right 1px; }\n"; - styleText += ".webkit-execution-line .webkit-line-number { color: transparent; background-image: -webkit-canvas(program-counter); }\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-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-breakpoint.webkit-breakpoint-conditional .webkit-line-number { color: white; background-image: -webkit-canvas(breakpoint-conditional); }\n"; - styleText += ".webkit-breakpoint-disabled.webkit-breakpoint-conditional .webkit-line-number { color: white; background-image: -webkit-canvas(breakpoint-disabled-conditional); }\n"; - styleText += ".webkit-breakpoint.webkit-breakpoint-conditional.webkit-execution-line .webkit-line-number { color: transparent; background-image: -webkit-canvas(breakpoint-conditional-program-counter); }\n"; - styleText += ".webkit-breakpoint-disabled.webkit-breakpoint-conditional.webkit-execution-line .webkit-line-number { color: transparent; background-image: -webkit-canvas(breakpoint-disabled-conditional-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"; - - // TODO: Move these styles into inspector.css once https://bugs.webkit.org/show_bug.cgi?id=28913 is fixed and popup moved into the top frame. - styleText += ".popup-content { position: absolute; z-index: 10000; padding: 4px; background-color: rgb(203, 226, 255); -webkit-border-radius: 7px; border: 2px solid rgb(169, 172, 203); }"; - styleText += ".popup-glasspane { position: absolute; top: 0; left: 0; height: 100%; width: 100%; opacity: 0; z-index: 9900; }"; - styleText += ".popup-message { background-color: transparent; font-family: Lucida Grande, sans-serif; font-weight: normal; font-size: 11px; text-align: left; text-shadow: none; color: rgb(85, 85, 85); cursor: default; margin: 0 0 2px 0; }"; - styleText += ".popup-content.breakpoint-condition { width: 90%; }"; - styleText += ".popup-content input#bp-condition { font-family: monospace; margin: 0; border: 1px inset rgb(190, 190, 190) !important; width: 100%; box-shadow: none !important; outline: none !important; -webkit-user-modify: read-write; }"; - // This class is already in inspector.css - styleText += ".hidden { display: none !important; }"; - - 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.removeChildren = Element.prototype.removeChildren; - this.element.contentWindow.Element.prototype.positionAt = Element.prototype.positionAt; - this.element.contentWindow.Element.prototype.removeMatchingStyleClasses = Element.prototype.removeMatchingStyleClasses; - this.element.contentWindow.Element.prototype.hasStyleClass = Element.prototype.hasStyleClass; - this.element.contentWindow.Element.prototype.pageOffsetRelativeToWindow = Element.prototype.pageOffsetRelativeToWindow; - this.element.contentWindow.Element.prototype.__defineGetter__("totalOffsetLeft", Element.prototype.__lookupGetter__("totalOffsetLeft")); - this.element.contentWindow.Element.prototype.__defineGetter__("totalOffsetTop", Element.prototype.__lookupGetter__("totalOffsetTop")); - this.element.contentWindow.Node.prototype.enclosingNodeOrSelfWithNodeName = Node.prototype.enclosingNodeOrSelfWithNodeName; - this.element.contentWindow.Node.prototype.enclosingNodeOrSelfWithNodeNameInArray = Node.prototype.enclosingNodeOrSelfWithNodeNameInArray; + this._editor.mimeType = this._mimeType; this._addExistingMessagesToSource(); this._addExistingBreakpointsToSource(); - this._updateExecutionLine(); + + this._editor.setCoalescingUpdate(true); + this._editor.resize(); + this._editor.revalidateDecorationsAndPaint(); + if (this._executionLine) this.revealLine(this._executionLine); - if (this.autoSizesToFitContentHeight) - this.sizeToFitContentHeight(); - if (this._lineNumberToReveal) { this.revealLine(this._lineNumberToReveal); delete this._lineNumberToReveal; } - if (this._lineNumberToHighlight) { - this.highlightLine(this._lineNumberToHighlight); - delete this._lineNumberToHighlight; + if (this._pendingSelectionRange) { + var range = this._pendingSelectionRange; + this._editor.setSelection(range.startLine, range.startColumn, range.endLine, range.endColumn); + delete this._pendingSelectionRange; } - - this.dispatchEventToListeners("content loaded"); - }, - - _isContentLoaded: function() { - var doc = this.element.contentDocument; - return doc && doc.getElementsByTagName("table")[0]; - }, - - _windowResized: function(event) - { - if (!this._autoSizesToFitContentHeight) - return; - this.sizeToFitContentHeight(); - }, - - _documentContextMenu: function(event) - { - if (!event.target.hasStyleClass("webkit-line-number")) - return; - var sourceRow = event.target.enclosingNodeOrSelfWithNodeName("tr"); - if (!sourceRow._breakpointObject && this.addBreakpointDelegate) - this.addBreakpointDelegate(this.lineNumberForSourceRow(sourceRow)); - - var breakpoint = sourceRow._breakpointObject; - if (!breakpoint) - return; - - this._editBreakpointCondition(event.target, sourceRow, breakpoint); - event.preventDefault(); - }, - - _documentMouseDown: function(event) - { - if (!event.target.hasStyleClass("webkit-line-number")) - return; - if (event.button != 0 || event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) - return; - var sourceRow = event.target.enclosingNodeOrSelfWithNodeName("tr"); - if (sourceRow._breakpointObject && sourceRow._breakpointObject.enabled) - sourceRow._breakpointObject.enabled = false; - else if (sourceRow._breakpointObject) - WebInspector.panels.scripts.removeBreakpoint(sourceRow._breakpointObject); - else if (this.addBreakpointDelegate) - this.addBreakpointDelegate(this.lineNumberForSourceRow(sourceRow)); - - event.preventDefault(); + this._editor.setCoalescingUpdate(false); }, - _editBreakpointCondition: function(eventTarget, sourceRow, breakpoint) + findSearchMatches: function(query) { - // TODO: Migrate the popup to the top-level document and remove the blur listener from conditionElement once https://bugs.webkit.org/show_bug.cgi?id=28913 is fixed. - var popupDocument = this.element.contentDocument; - this._showBreakpointConditionPopup(eventTarget, breakpoint.line, popupDocument); + var ranges = []; - function committed(element, newText) - { - breakpoint.condition = newText; - if (breakpoint.condition) - sourceRow.addStyleClass("webkit-breakpoint-conditional"); - else - sourceRow.removeStyleClass("webkit-breakpoint-conditional"); - dismissed.call(this); + // First do case-insensitive search. + var regex = ""; + for (var i = 0; i < query.length; ++i) { + var char = query.charAt(i); + if (char === "]") + char = "\\]"; + regex += "[" + char + "]"; } - - function dismissed() - { - this._popup.hide(); - delete this._conditionEditorElement; + var regexObject = new RegExp(regex, "i"); + this._collectRegexMatches(regexObject, ranges); + + // Then try regex search if user knows the / / hint. + try { + if (/^\/.*\/$/.test(query)) + this._collectRegexMatches(new RegExp(query.substring(1, query.length - 1)), ranges); + } catch (e) { + // Silent catch. } - - var dismissedHandler = dismissed.bind(this); - this._conditionEditorElement.addEventListener("blur", dismissedHandler, false); - - WebInspector.startEditing(this._conditionEditorElement, committed.bind(this), dismissedHandler); - this._conditionEditorElement.value = breakpoint.condition; - this._conditionEditorElement.select(); + return ranges; }, - _showBreakpointConditionPopup: function(clickedElement, lineNumber, popupDocument) + _collectRegexMatches: function(regexObject, ranges) { - var popupContentElement = this._createPopupElement(lineNumber, popupDocument); - var lineElement = clickedElement.enclosingNodeOrSelfWithNodeName("td").nextSibling; - if (this._popup) { - this._popup.hide(); - this._popup.element = popupContentElement; - } else { - this._popup = new WebInspector.Popup(popupContentElement); - this._popup.autoHide = true; - } - this._popup.anchor = lineElement; - this._popup.show(); - }, - - _createPopupElement: function(lineNumber, popupDocument) - { - var popupContentElement = popupDocument.createElement("div"); - popupContentElement.className = "popup-content breakpoint-condition"; - - var labelElement = document.createElement("label"); - labelElement.className = "popup-message"; - labelElement.htmlFor = "bp-condition"; - labelElement.appendChild(document.createTextNode(WebInspector.UIString("The breakpoint on line %d will stop only if this expression is true:", lineNumber))); - popupContentElement.appendChild(labelElement); - - var editorElement = document.createElement("input"); - editorElement.id = "bp-condition"; - editorElement.type = "text" - popupContentElement.appendChild(editorElement); - this._conditionEditorElement = editorElement; - - return popupContentElement; - }, - - _documentKeyDown: function(event) - { - var shortcut = WebInspector.KeyboardShortcut.makeKeyFromEvent(event); - var handler = this._shortcuts[shortcut]; - if (handler) { - handler(event); - event.preventDefault(); - } else { - WebInspector.documentKeyDown(event); + for (var i = 0; i < this._textModel.linesCount; ++i) { + var line = this._textModel.line(i); + var offset = 0; + do { + var match = regexObject.exec(line); + if (match) { + ranges.push(new WebInspector.TextRange(i, offset + match.index, i, offset + match.index + match[0].length)); + offset += match.index + 1; + line = line.substring(match.index + 1); + } + } while (match) } + return ranges; }, - _evalSelectionInCallFrame: function(event) - { - if (!WebInspector.panels.scripts || !WebInspector.panels.scripts.paused) - return; - - var selection = this.element.contentWindow.getSelection(); - if (!selection.rangeCount) - return; - - var expression = selection.getRangeAt(0).toString().trimWhitespace(); - WebInspector.panels.scripts.evaluateInSelectedCallFrame(expression, false, "console", function(result, exception) { - WebInspector.showConsole(); - var commandMessage = new WebInspector.ConsoleCommand(expression); - WebInspector.console.addMessage(commandMessage); - WebInspector.console.addMessage(new WebInspector.ConsoleCommandResult(result, exception, commandMessage)); - }); - }, - - _breakpointEnableChanged: function(event) + setSelection: function(range) { - 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"); + if (this._editor) + this._editor.setSelection(range.startLine, range.startColumn, range.endLine, range.endColumn); else - sourceRow.addStyleClass("webkit-breakpoint-disabled"); + this._pendingSelectionRange = range; }, - _updateExecutionLine: function(previousLine) + clearSelection: function() { - 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; - - breakpoint.sourceText = sourceRow.getElementsByClassName('webkit-line-content')[0].textContent; - - this._drawBreakpointImagesIfNeeded(); - - sourceRow._breakpointObject = breakpoint; - - sourceRow.addStyleClass("webkit-breakpoint"); - if (!breakpoint.enabled) - sourceRow.addStyleClass("webkit-breakpoint-disabled"); - if (breakpoint.condition) - sourceRow.addStyleClass("webkit-breakpoint-conditional"); - }, - - _removeBreakpointFromSource: function(breakpoint) - { - var sourceRow = this.sourceRow(breakpoint.line); - if (!sourceRow) - return; - - delete sourceRow._breakpointObject; - - sourceRow.removeStyleClass("webkit-breakpoint"); - sourceRow.removeStyleClass("webkit-breakpoint-disabled"); - sourceRow.removeStyleClass("webkit-breakpoint-conditional"); + if (this._editor) { + var range = this._editor.selection; + this._editor.setSelection(range.endLine, range.endColumn, range.endLine, range.endColumn); + } else + delete this._pendingSelectionRange; }, _incrementMessageRepeatCount: function(msg, repeatDelta) @@ -524,39 +246,39 @@ WebInspector.SourceFrame.prototype = { _addExistingMessagesToSource: function() { - var length = this.messages.length; + var length = this._messages.length; for (var i = 0; i < length; ++i) - this._addMessageToSource(this.messages[i]); + this._addMessageToSource(this._messages[i]); }, _addMessageToSource: function(msg) { - var row = this.sourceRow(msg.line); - if (!row) - return; - - var cell = row.cells[1]; - if (!cell) + if (msg.line >= this._textModel.linesCount) return; - var messageBubbleElement = cell.lastChild; + var messageBubbleElement = this._messageBubbles[msg.line]; if (!messageBubbleElement || messageBubbleElement.nodeType !== Node.ELEMENT_NODE || !messageBubbleElement.hasStyleClass("webkit-html-message-bubble")) { - messageBubbleElement = this.element.contentDocument.createElement("div"); + messageBubbleElement = document.createElement("div"); messageBubbleElement.className = "webkit-html-message-bubble"; - cell.appendChild(messageBubbleElement); + this._messageBubbles[msg.line] = messageBubbleElement; + this._editor.setDivDecoration(msg.line - 1, messageBubbleElement); } - if (!row.messages) - row.messages = []; + var rowMessages = this._rowMessages[msg.line]; + if (!rowMessages) { + rowMessages = []; + this._rowMessages[msg.line] = rowMessages; + } - for (var i = 0; i < row.messages.length; ++i) { - if (row.messages[i].isEqual(msg, true)) { - this._incrementMessageRepeatCount(row.messages[i], msg.repeatDelta); + for (var i = 0; i < rowMessages.length; ++i) { + if (rowMessages[i].isEqual(msg, true)) { + this._incrementMessageRepeatCount(rowMessages[i], msg.repeatDelta); + this._editor.revalidateDecorationsAndPaint(); return; } } - row.messages.push(msg); + rowMessages.push(msg); var imageURL; switch (msg.level) { @@ -570,7 +292,7 @@ WebInspector.SourceFrame.prototype = { break; } - var messageLineElement = this.element.contentDocument.createElement("div"); + var messageLineElement = document.createElement("div"); messageLineElement.className = "webkit-html-message-line"; messageBubbleElement.appendChild(messageLineElement); @@ -578,1580 +300,301 @@ WebInspector.SourceFrame.prototype = { var image = document.createElement("img"); image.src = imageURL; image.className = "webkit-html-message-icon"; - - // Adopt the image element since it wasn't created in element's contentDocument. - image = this.element.contentDocument.adoptNode(image); messageLineElement.appendChild(image); - messageLineElement.appendChild(this.element.contentDocument.createTextNode(msg.message)); + messageLineElement.appendChild(document.createTextNode(msg.message)); msg._resourceMessageLineElement = messageLineElement; + + this._editor.revalidateDecorationsAndPaint(); }, - _drawProgramCounterInContext: function(ctx, glow) + _addExistingBreakpointsToSource: function() { - if (glow) - ctx.save(); - - ctx.beginPath(); - ctx.moveTo(17, 2); - ctx.lineTo(19, 2); - ctx.lineTo(19, 0); - ctx.lineTo(21, 0); - ctx.lineTo(26, 5.5); - ctx.lineTo(21, 11); - ctx.lineTo(19, 11); - ctx.lineTo(19, 9); - ctx.lineTo(17, 9); - ctx.closePath(); - ctx.fillStyle = "rgb(142, 5, 4)"; - - if (glow) { - ctx.shadowBlur = 4; - ctx.shadowColor = "rgb(255, 255, 255)"; - ctx.shadowOffsetX = -1; - ctx.shadowOffsetY = 0; - } - - ctx.fill(); - ctx.fill(); // Fill twice to get a good shadow and darker anti-aliased pixels. - - if (glow) - ctx.restore(); + var length = this.breakpoints.length; + for (var i = 0; i < length; ++i) + this._addBreakpointToSource(this.breakpoints[i]); }, - _drawProgramCounterImageIfNeeded: function() + _addBreakpointToSource: function(breakpoint) { - if (!this._needsProgramCounterImage || !this.element.contentDocument) - return; - - var ctx = this.element.contentDocument.getCSSCanvasContext("2d", "program-counter", 26, 11); - ctx.clearRect(0, 0, 26, 11); - this._drawProgramCounterInContext(ctx, true); + this._textModel.setAttribute(breakpoint.line - 1, "breakpoint", breakpoint); + breakpoint.sourceText = this._textModel.line(breakpoint.line - 1); + this._editor.paintLineNumbers(); + }, - delete this._needsProgramCounterImage; + _removeBreakpointFromSource: function(breakpoint) + { + this._textModel.removeAttribute(breakpoint.line - 1, "breakpoint"); + this._editor.paintLineNumbers(); }, - _drawBreakpointImagesIfNeeded: function(conditional) + _contextMenu: function(lineNumber, event) { - if (!this._needsBreakpointImages || !this.element.contentDocument) + if (!this._addBreakpointDelegate) return; - function drawBreakpoint(ctx, disabled, conditional) - { - ctx.beginPath(); - ctx.moveTo(0, 2); - ctx.lineTo(2, 0); - ctx.lineTo(21, 0); - ctx.lineTo(26, 5.5); - ctx.lineTo(21, 11); - ctx.lineTo(2, 11); - ctx.lineTo(0, 9); - ctx.closePath(); - ctx.fillStyle = conditional ? "rgb(217, 142, 1)" : "rgb(1, 142, 217)"; - ctx.strokeStyle = conditional ? "rgb(205, 103, 0)" : "rgb(0, 103, 205)"; - ctx.lineWidth = 3; - ctx.fill(); - ctx.save(); - ctx.clip(); - ctx.stroke(); - ctx.restore(); + var contextMenu = new WebInspector.ContextMenu(); - if (!disabled) - return; + var breakpoint = this._textModel.getAttribute(lineNumber, "breakpoint"); + if (!breakpoint) { + // This row doesn't have a breakpoint: We want to show Add Breakpoint and Add and Edit Breakpoint. + contextMenu.appendItem(WebInspector.UIString("Add Breakpoint"), this._addBreakpointDelegate.bind(this, lineNumber + 1)); - ctx.save(); - ctx.globalCompositeOperation = "destination-out"; - ctx.fillStyle = "rgba(0, 0, 0, 0.5)"; - ctx.fillRect(0, 0, 26, 11); - ctx.restore(); - } + function addConditionalBreakpoint() + { + this._addBreakpointDelegate(lineNumber + 1); + var breakpoint = this._textModel.getAttribute(lineNumber, "breakpoint"); + if (breakpoint) + this._editBreakpointCondition(breakpoint); + } + contextMenu.appendItem(WebInspector.UIString("Add Conditional Breakpoint..."), addConditionalBreakpoint.bind(this)); + } else { + // This row has a breakpoint, we want to show edit and remove breakpoint, and either disable or enable. + contextMenu.appendItem(WebInspector.UIString("Remove Breakpoint"), WebInspector.panels.scripts.removeBreakpoint.bind(WebInspector.panels.scripts, breakpoint)); + contextMenu.appendItem(WebInspector.UIString("Edit Breakpoint..."), this._editBreakpointCondition.bind(this, breakpoint)); + if (breakpoint.enabled) + contextMenu.appendItem(WebInspector.UIString("Disable Breakpoint"), function() { breakpoint.enabled = false; }); + else + contextMenu.appendItem(WebInspector.UIString("Enable Breakpoint"), function() { breakpoint.enabled = true; }); + } + contextMenu.show(event); + }, - // Unconditional breakpoints. + _toggleBreakpoint: function(lineNumber, event) + { + if (event.button != 0 || event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) + return; + var breakpoint = this._textModel.getAttribute(lineNumber, "breakpoint"); + if (breakpoint) + WebInspector.panels.scripts.removeBreakpoint(breakpoint); + else if (this._addBreakpointDelegate) + this._addBreakpointDelegate(lineNumber + 1); + event.preventDefault(); + }, - var ctx = this.element.contentDocument.getCSSCanvasContext("2d", "breakpoint", 26, 11); - ctx.clearRect(0, 0, 26, 11); - drawBreakpoint(ctx); + _editBreakpointCondition: function(breakpoint) + { + this._showBreakpointConditionPopup(breakpoint.line); - var ctx = this.element.contentDocument.getCSSCanvasContext("2d", "breakpoint-program-counter", 26, 11); - ctx.clearRect(0, 0, 26, 11); - drawBreakpoint(ctx); - ctx.clearRect(20, 0, 6, 11); - this._drawProgramCounterInContext(ctx, true); + function committed(element, newText) + { + breakpoint.condition = newText; + this._editor.paintLineNumbers(); + dismissed.call(this); + } - var ctx = this.element.contentDocument.getCSSCanvasContext("2d", "breakpoint-disabled", 26, 11); - ctx.clearRect(0, 0, 26, 11); - drawBreakpoint(ctx, true); + function dismissed() + { + this._editor.setDivDecoration(breakpoint.line - 1, null); + delete this._conditionEditorElement; + } - var ctx = this.element.contentDocument.getCSSCanvasContext("2d", "breakpoint-disabled-program-counter", 26, 11); - ctx.clearRect(0, 0, 26, 11); - drawBreakpoint(ctx, true); - ctx.clearRect(20, 0, 6, 11); - this._drawProgramCounterInContext(ctx, true); + var dismissedHandler = dismissed.bind(this); + this._conditionEditorElement.addEventListener("blur", dismissedHandler, false); + WebInspector.startEditing(this._conditionEditorElement, committed.bind(this), dismissedHandler); + this._conditionEditorElement.value = breakpoint.condition; + this._conditionEditorElement.select(); + }, - // Conditional breakpoints. + _showBreakpointConditionPopup: function(lineNumber) + { + var conditionElement = this._createConditionElement(lineNumber); + this._editor.setDivDecoration(lineNumber - 1, conditionElement); + }, - var ctx = this.element.contentDocument.getCSSCanvasContext("2d", "breakpoint-conditional", 26, 11); - ctx.clearRect(0, 0, 26, 11); - drawBreakpoint(ctx, false, true); + _createConditionElement: function(lineNumber) + { + var conditionElement = document.createElement("div"); + conditionElement.className = "source-breakpoint-condition"; - var ctx = this.element.contentDocument.getCSSCanvasContext("2d", "breakpoint-conditional-program-counter", 26, 11); - ctx.clearRect(0, 0, 26, 11); - drawBreakpoint(ctx, false, true); - ctx.clearRect(20, 0, 6, 11); - this._drawProgramCounterInContext(ctx, true); + var labelElement = document.createElement("label"); + labelElement.className = "source-breakpoint-message"; + labelElement.htmlFor = "source-breakpoint-condition"; + labelElement.appendChild(document.createTextNode(WebInspector.UIString("The breakpoint on line %d will stop only if this expression is true:", lineNumber))); + conditionElement.appendChild(labelElement); - var ctx = this.element.contentDocument.getCSSCanvasContext("2d", "breakpoint-disabled-conditional", 26, 11); - ctx.clearRect(0, 0, 26, 11); - drawBreakpoint(ctx, true, true); + var editorElement = document.createElement("input"); + editorElement.id = "source-breakpoint-condition"; + editorElement.className = "monospace"; + editorElement.type = "text" + conditionElement.appendChild(editorElement); + this._conditionEditorElement = editorElement; - var ctx = this.element.contentDocument.getCSSCanvasContext("2d", "breakpoint-disabled-conditional-program-counter", 26, 11); - ctx.clearRect(0, 0, 26, 11); - drawBreakpoint(ctx, true, true); - ctx.clearRect(20, 0, 6, 11); - this._drawProgramCounterInContext(ctx, true); + return conditionElement; + }, - delete this._needsBreakpointImages; + _keyDown: function(event) + { + var shortcut = WebInspector.KeyboardShortcut.makeKeyFromEvent(event); + var handler = this._shortcuts[shortcut]; + if (handler) { + handler(event); + event.preventDefault(); + } else { + WebInspector.documentKeyDown(event); + } }, - syntaxHighlightJavascript: function() + _evalSelectionInCallFrame: function(event) { - var table = this.element.contentDocument.getElementsByTagName("table")[0]; - if (!table) + if (!WebInspector.panels.scripts || !WebInspector.panels.scripts.paused) + return; + + var selection = this.element.contentWindow.getSelection(); + if (!selection.rangeCount) return; - var jsSyntaxHighlighter = new WebInspector.JavaScriptSourceSyntaxHighlighter(table, this); - jsSyntaxHighlighter.process(); + var expression = selection.getRangeAt(0).toString().trimWhitespace(); + WebInspector.panels.scripts.evaluateInSelectedCallFrame(expression, false, "console", function(result, exception) { + WebInspector.showConsole(); + var commandMessage = new WebInspector.ConsoleCommand(expression); + WebInspector.console.addMessage(commandMessage); + WebInspector.console.addMessage(new WebInspector.ConsoleCommandResult(result, exception, commandMessage)); + }); }, - syntaxHighlightCSS: function() + _breakpointChanged: function(event) { - var table = this.element.contentDocument.getElementsByTagName("table")[0]; - if (!table) - return; + this._editor.paintLineNumbers(); + }, - var cssSyntaxHighlighter = new WebInspector.CSSSourceSyntaxHighlighter(table, this); - cssSyntaxHighlighter.process(); + resize: function() + { + if (this._editor) + this._editor.resize(); } } WebInspector.SourceFrame.prototype.__proto__ = WebInspector.Object.prototype; -WebInspector.SourceSyntaxHighlighter = function(table, sourceFrame) +WebInspector.BreakpointLineNumberDecorator = function(sourceFrame, textModel) { - this.table = table; - this.sourceFrame = sourceFrame; + this._sourceFrame = sourceFrame; + this._textModel = textModel; } -WebInspector.SourceSyntaxHighlighter.prototype = { - createSpan: function(content, className) - { - var span = document.createElement("span"); - span.className = className; - span.appendChild(document.createTextNode(content)); - return span; - }, - - process: function() +WebInspector.BreakpointLineNumberDecorator.prototype = { + decorate: function(lineNumber, ctx, x, y, width, height, lineHeight) { - // Split up the work into chunks so we don't block the - // UI thread while processing. - - var rows = this.table.rows; - var rowsLength = rows.length; - const tokensPerChunk = 100; - const lineLengthLimit = 20000; - - var boundProcessChunk = processChunk.bind(this); - var processChunkInterval = setInterval(boundProcessChunk, 25); - boundProcessChunk(); - - function processChunk() - { - for (var i = 0; i < tokensPerChunk; i++) { - if (this.cursor >= this.lineCode.length) - moveToNextLine.call(this); - if (this.lineIndex >= rowsLength) { - this.sourceFrame.dispatchEventToListeners("syntax highlighting complete"); - return; - } - if (this.cursor > lineLengthLimit) { - var codeFragment = this.lineCode.substring(this.cursor); - this.nonToken += codeFragment; - this.cursor += codeFragment.length; - } + var breakpoint = this._textModel.getAttribute(lineNumber, "breakpoint"); + var isExecutionLine = lineNumber + 1 === this._sourceFrame._executionLine; + if (breakpoint || isExecutionLine) { + ctx.save(); + ctx.translate(x + 4, y + 2); + var breakpointWidth = width - 6; + var breakpointHeight = lineHeight - 4; + + if (breakpoint) + this._paintBreakpoint(ctx, breakpointWidth, breakpointHeight, breakpoint); + + if (isExecutionLine) + this._paintProgramCounter(ctx, breakpointWidth, breakpointHeight, false); - this.lex(); - } + ctx.restore(); } - - function moveToNextLine() - { - this.appendNonToken(); - - var row = rows[this.lineIndex]; - var line = row ? row.cells[1] : null; - if (line && this.newLine) { - line.removeChildren(); - - if (this.messageBubble) - this.newLine.appendChild(this.messageBubble); - - line.parentNode.insertBefore(this.newLine, line); - line.parentNode.removeChild(line); - - this.newLine = null; - } - this.lineIndex++; - if (this.lineIndex >= rowsLength && processChunkInterval) { - clearInterval(processChunkInterval); - this.sourceFrame.dispatchEventToListeners("syntax highlighting complete"); - return; - } - row = rows[this.lineIndex]; - line = row ? row.cells[1] : null; - - this.messageBubble = null; - if (line.lastChild && line.lastChild.nodeType === Node.ELEMENT_NODE && line.lastChild.hasStyleClass("webkit-html-message-bubble")) { - this.messageBubble = line.lastChild; - line.removeChild(this.messageBubble); - } - this.lineCode = line.textContent; - this.newLine = line.cloneNode(false); - this.cursor = 0; - if (!line) - moveToNextLine(); - } - }, - - lex: function() - { - var token = null; - var codeFragment = this.lineCode.substring(this.cursor); - - for (var i = 0; i < this.rules.length; i++) { - var rule = this.rules[i]; - var ruleContinueStateCondition = typeof rule.continueStateCondition === "undefined" ? this.ContinueState.None : rule.continueStateCondition; - if (this.continueState === ruleContinueStateCondition) { - if (typeof rule.lexStateCondition !== "undefined" && this.lexState !== rule.lexStateCondition) - continue; - var match = rule.pattern.exec(codeFragment); - if (match) { - token = match[0]; - if (token) { - if (!rule.dontAppendNonToken) - this.appendNonToken(); - return rule.action.call(this, token); - } - } - } - } - this.nonToken += codeFragment[0]; - this.cursor++; - }, - - appendNonToken: function () - { - if (this.nonToken.length > 0) { - this.newLine.appendChild(document.createTextNode(this.nonToken)); - this.nonToken = ""; + if (isExecutionLine) { + // Override default behavior. + return true; } + + ctx.fillStyle = breakpoint ? "rgb(255,255,255)" : "rgb(155,155,155)"; + return false; }, - - syntaxHighlightNode: function(node) + + _paintBreakpoint: function(ctx, width, height, breakpoint) { - this.lineCode = node.textContent; - node.removeChildren(); - this.newLine = node; - this.cursor = 0; - while (true) { - if (this.cursor >= this.lineCode.length) { - var codeFragment = this.lineCode.substring(this.cursor); - this.nonToken += codeFragment; - this.cursor += codeFragment.length; - this.appendNonToken(); - this.newLine = null; - return; - } + ctx.beginPath(); + ctx.moveTo(0, 2); + ctx.lineTo(2, 0); + ctx.lineTo(width - 5, 0); + ctx.lineTo(width, height / 2); + ctx.lineTo(width - 5, height); + ctx.lineTo(2, height); + ctx.lineTo(0, height - 2); + ctx.closePath(); + ctx.fillStyle = breakpoint.condition ? "rgb(217, 142, 1)" : "rgb(1, 142, 217)"; + ctx.strokeStyle = breakpoint.condition ? "rgb(205, 103, 0)" : "rgb(0, 103, 205)"; + ctx.lineWidth = 3; + ctx.fill(); - this.lex(); + ctx.save(); + ctx.clip(); + ctx.stroke(); + ctx.restore(); + + if (!breakpoint.enabled) { + ctx.save(); + ctx.globalCompositeOperation = "destination-out"; + ctx.fillStyle = "rgba(0, 0, 0, 0.5)"; + ctx.fillRect(0, 0, width, height); + ctx.restore(); } - } -} + }, -WebInspector.CSSSourceSyntaxHighlighter = function(table, sourceFrame) { - WebInspector.SourceSyntaxHighlighter.call(this, table, sourceFrame); - - this.LexState = { - Initial: 1, - DeclarationProperty: 2, - DeclarationValue: 3, - AtMedia: 4, - AtRule: 5, - AtKeyframes: 6 - }; - this.ContinueState = { - None: 0, - Comment: 1 - }; - - this.nonToken = ""; - this.cursor = 0; - this.lineIndex = -1; - this.lineCode = ""; - this.newLine = null; - this.lexState = this.LexState.Initial; - this.continueState = this.ContinueState.None; - - const urlPattern = /^url\(\s*(?:(?:"(?:[^\\\"]|(?:\\[\da-f]{1,6}\s?|\.))*"|'(?:[^\\\']|(?:\\[\da-f]{1,6}\s?|\.))*')|(?:[!#$%&*-~\w]|(?:\\[\da-f]{1,6}\s?|\.))*)\s*\)/i; - const stringPattern = /^(?:"(?:[^\\\"]|(?:\\[\da-f]{1,6}\s?|\.))*"|'(?:[^\\\']|(?:\\[\da-f]{1,6}\s?|\.))*')/i; - const identPattern = /^-?(?:\w|(?:\\[\da-f]{1,6}\s?|\.))(?:[-\w]|(?:\\[\da-f]{1,6}\s?|\.))*/i; - const startBlockPattern = /^{/i; - const endBlockPattern = /^}/i; - this.rules = [{ - pattern: /^\/\*[^\*]*\*+([^\/*][^*]*\*+)*\//i, - action: commentAction - }, { - pattern: /^(?:\/\*(?:[^\*]|\*[^\/])*)/i, - action: commentStartAction - }, { - pattern: /^(?:(?:[^\*]|\*[^\/])*\*+\/)/i, - action: commentEndAction, - continueStateCondition: this.ContinueState.Comment - }, { - pattern: /^.*/i, - action: commentMiddleAction, - continueStateCondition: this.ContinueState.Comment - }, { - pattern: /^(?:(?:-?(?:\w|(?:\\[\da-f]{1,6}\s?|\.))(?:[-\w]|(?:\\[\da-f]{1,6}\s?|\.))*|\*)(?:#-?(?:\w|(?:\\[\da-f]{1,6}\s?|\.))(?:[-\w]|(?:\\[\da-f]{1,6}\s?|\.))*|\.-?(?:\w|(?:\\[\da-f]{1,6}\s?|\.))(?:[-\w]|(?:\\[\da-f]{1,6}\s?|\.))*|\[\s*-?(?:\w|(?:\\[\da-f]{1,6}\s?|\.))(?:[-\w]|(?:\\[\da-f]{1,6}\s?|\.))*\s*(?:(?:=|~=|\|=)\s*(?:-?(?:\w|(?:\\[\da-f]{1,6}\s?|\.))(?:[-\w]|(?:\\[\da-f]{1,6}\s?|\.))*|(?:"(?:[^\\\"]|(?:\\[\da-f]{1,6}\s?|\.))*"|'(?:[^\\\']|(?:\\[\da-f]{1,6}\s?|\.))*'))\s*)?\]|:(?:-?(?:\w|(?:\\[\da-f]{1,6}\s?|\.))(?:[-\w]|(?:\\[\da-f]{1,6}\s?|\.))*|-?(?:\w|(?:\\[\da-f]{1,6}\s?|\.))(?:[-\w]|(?:\\[\da-f]{1,6}\s?|\.))*\(\s*(?:-?(?:\w|(?:\\[\da-f]{1,6}\s?|\.))(?:[-\w]|(?:\\[\da-f]{1,6}\s?|\.))*\s*)?\)))*|(?:#-?(?:\w|(?:\\[\da-f]{1,6}\s?|\.))(?:[-\w]|(?:\\[\da-f]{1,6}\s?|\.))*|\.-?(?:\w|(?:\\[\da-f]{1,6}\s?|\.))(?:[-\w]|(?:\\[\da-f]{1,6}\s?|\.))*|\[\s*-?(?:\w|(?:\\[\da-f]{1,6}\s?|\.))(?:[-\w]|(?:\\[\da-f]{1,6}\s?|\.))*\s*(?:(?:=|~=|\|=)\s*(?:-?(?:\w|(?:\\[\da-f]{1,6}\s?|\.))(?:[-\w]|(?:\\[\da-f]{1,6}\s?|\.))*|(?:"(?:[^\\\"]|(?:\\[\da-f]{1,6}\s?|\.))*"|'(?:[^\\\']|(?:\\[\da-f]{1,6}\s?|\.))*'))\s*)?\]|:(?:-?(?:\w|(?:\\[\da-f]{1,6}\s?|\.))(?:[-\w]|(?:\\[\da-f]{1,6}\s?|\.))*|-?(?:\w|(?:\\[\da-f]{1,6}\s?|\.))(?:[-\w]|(?:\\[\da-f]{1,6}\s?|\.))*\(\s*(?:-?(?:\w|(?:\\[\da-f]{1,6}\s?|\.))(?:[-\w]|(?:\\[\da-f]{1,6}\s?|\.))*\s*)?\)))+)/i, - action: selectorAction, - lexStateCondition: this.LexState.Initial - }, { - pattern: startBlockPattern, - action: startRulesetBlockAction, - lexStateCondition: this.LexState.Initial, - dontAppendNonToken: true - }, { - pattern: identPattern, - action: propertyAction, - lexStateCondition: this.LexState.DeclarationProperty, - dontAppendNonToken: true - }, { - pattern: /^:/i, - action: declarationColonAction, - lexStateCondition: this.LexState.DeclarationProperty, - dontAppendNonToken: true - }, { - pattern: /^(?:#(?:[\da-f]{6}|[\da-f]{3})|rgba\(\s*(?:\d+|\d*\.\d+)%?\s*,\s*(?:\d+|\d*\.\d+)%?\s*,\s*(?:\d+|\d*\.\d+)%?\s*,\s*(?:\d+|\d*\.\d+)%?\s*\)|hsla\(\s*(?:\d+|\d*\.\d+)%?\s*,\s*(?:\d+|\d*\.\d+)%?\s*,\s*(?:\d+|\d*\.\d+)%?\s*,\s*(?:\d+|\d*\.\d+)%?\s*\)|rgb\(\s*(?:\d+|\d*\.\d+)%?\s*,\s*(?:\d+|\d*\.\d+)%?\s*,\s*(?:\d+|\d*\.\d+)%?\s*\)|hsl\(\s*(?:\d+|\d*\.\d+)%?\s*,\s*(?:\d+|\d*\.\d+)%?\s*,\s*(?:\d+|\d*\.\d+)%?\s*\))/i, - action: colorAction, - lexStateCondition: this.LexState.DeclarationValue - }, { - pattern: /^(?:-?(?:\d+|\d*\.\d+)(?:em|rem|__qem|ex|px|cm|mm|in|pt|pc|deg|rad|grad|turn|ms|s|Hz|kHz|%)?)/i, - action: numvalueAction, - lexStateCondition: this.LexState.DeclarationValue - }, { - pattern: urlPattern, - action: urlAction, - lexStateCondition: this.LexState.DeclarationValue - }, { - pattern: stringPattern, - action: stringAction, - lexStateCondition: this.LexState.DeclarationValue - }, { - pattern: /^!\s*important/i, - action: importantAction, - lexStateCondition: this.LexState.DeclarationValue - }, { - pattern: identPattern, - action: valueIdentAction, - lexStateCondition: this.LexState.DeclarationValue, - dontAppendNonToken: true - }, { - pattern: /^;/i, - action: declarationSemicolonAction, - lexStateCondition: this.LexState.DeclarationValue, - dontAppendNonToken: true - }, { - pattern: endBlockPattern, - action: endRulesetBlockAction, - lexStateCondition: this.LexState.DeclarationProperty, - dontAppendNonToken: true - }, { - pattern: endBlockPattern, - action: endRulesetBlockAction, - lexStateCondition: this.LexState.DeclarationValue, - dontAppendNonToken: true - }, { - pattern: /^@media/i, - action: atMediaAction, - lexStateCondition: this.LexState.Initial - }, { - pattern: startBlockPattern, - action: startAtMediaBlockAction, - lexStateCondition: this.LexState.AtMedia, - dontAppendNonToken: true - }, { - pattern: /^@-webkit-keyframes/i, - action: atKeyframesAction, - lexStateCondition: this.LexState.Initial - }, { - pattern: startBlockPattern, - action: startAtMediaBlockAction, - lexStateCondition: this.LexState.AtKeyframes, - dontAppendNonToken: true - }, { - pattern: /^@-?(?:\w|(?:\\[\da-f]{1,6}\s?|\.))(?:[-\w]|(?:\\[\da-f]{1,6}\s?|\.))*/i, - action: atRuleAction, - lexStateCondition: this.LexState.Initial - }, { - pattern: /^;/i, - action: endAtRuleAction, - lexStateCondition: this.LexState.AtRule - }, { - pattern: urlPattern, - action: urlAction, - lexStateCondition: this.LexState.AtRule - }, { - pattern: stringPattern, - action: stringAction, - lexStateCondition: this.LexState.AtRule - }, { - pattern: stringPattern, - action: stringAction, - lexStateCondition: this.LexState.AtKeyframes - }, { - pattern: identPattern, - action: atRuleIdentAction, - lexStateCondition: this.LexState.AtRule, - dontAppendNonToken: true - }, { - pattern: identPattern, - action: atRuleIdentAction, - lexStateCondition: this.LexState.AtMedia, - dontAppendNonToken: true - }, { - pattern: startBlockPattern, - action: startAtRuleBlockAction, - lexStateCondition: this.LexState.AtRule, - dontAppendNonToken: true - }]; - - function commentAction(token) + _paintProgramCounter: function(ctx, width, height) { - this.cursor += token.length; - this.newLine.appendChild(this.createSpan(token, "webkit-css-comment")); - } - - function commentStartAction(token) - { - this.cursor += token.length; - this.newLine.appendChild(this.createSpan(token, "webkit-css-comment")); - this.continueState = this.ContinueState.Comment; - } - - function commentEndAction(token) - { - this.cursor += token.length; - this.newLine.appendChild(this.createSpan(token, "webkit-css-comment")); - this.continueState = this.ContinueState.None; - } + ctx.save(); - function commentMiddleAction(token) - { - this.cursor += token.length; - this.newLine.appendChild(this.createSpan(token, "webkit-css-comment")); - } - - function selectorAction(token) - { - this.cursor += token.length; - this.newLine.appendChild(this.createSpan(token, "webkit-css-selector")); - } - - function startRulesetBlockAction(token) - { - this.cursor += token.length; - this.nonToken += token; - this.lexState = this.LexState.DeclarationProperty; - } - - function endRulesetBlockAction(token) - { - this.cursor += token.length; - this.nonToken += token; - this.lexState = this.LexState.Initial; - } - - const propertyKeywords = { - "background": true, - "background-attachment": true, - "background-clip": true, - "background-color": true, - "background-image": true, - "background-origin": true, - "background-position": true, - "background-position-x": true, - "background-position-y": true, - "background-repeat": true, - "background-repeat-x": true, - "background-repeat-y": true, - "background-size": true, - "border": true, - "border-bottom": true, - "border-bottom-color": true, - "border-bottom-left-radius": true, - "border-bottom-right-radius": true, - "border-bottom-style": true, - "border-bottom-width": true, - "border-collapse": true, - "border-color": true, - "border-left": true, - "border-left-color": true, - "border-left-style": true, - "border-left-width": true, - "border-radius": true, - "border-right": true, - "border-right-color": true, - "border-right-style": true, - "border-right-width": true, - "border-spacing": true, - "border-style": true, - "border-top": true, - "border-top-color": true, - "border-top-left-radius": true, - "border-top-right-radius": true, - "border-top-style": true, - "border-top-width": true, - "border-width": true, - "bottom": true, - "caption-side": true, - "clear": true, - "clip": true, - "color": true, - "content": true, - "counter-increment": true, - "counter-reset": true, - "cursor": true, - "direction": true, - "display": true, - "empty-cells": true, - "float": true, - "font": true, - "font-family": true, - "font-size": true, - "font-stretch": true, - "font-style": true, - "font-variant": true, - "font-weight": true, - "height": true, - "left": true, - "letter-spacing": true, - "line-height": true, - "list-style": true, - "list-style-image": true, - "list-style-position": true, - "list-style-type": true, - "margin": true, - "margin-bottom": true, - "margin-left": true, - "margin-right": true, - "margin-top": true, - "max-height": true, - "max-width": true, - "min-height": true, - "min-width": true, - "opacity": true, - "orphans": true, - "outline": true, - "outline-color": true, - "outline-offset": true, - "outline-style": true, - "outline-width": true, - "overflow": true, - "overflow-x": true, - "overflow-y": true, - "padding": true, - "padding-bottom": true, - "padding-left": true, - "padding-right": true, - "padding-top": true, - "page": true, - "page-break-after": true, - "page-break-before": true, - "page-break-inside": true, - "pointer-events": true, - "position": true, - "quotes": true, - "resize": true, - "right": true, - "size": true, - "src": true, - "table-layout": true, - "text-align": true, - "text-decoration": true, - "text-indent": true, - "text-line-through": true, - "text-line-through-color": true, - "text-line-through-mode": true, - "text-line-through-style": true, - "text-line-through-width": true, - "text-overflow": true, - "text-overline": true, - "text-overline-color": true, - "text-overline-mode": true, - "text-overline-style": true, - "text-overline-width": true, - "text-rendering": true, - "text-shadow": true, - "text-transform": true, - "text-underline": true, - "text-underline-color": true, - "text-underline-mode": true, - "text-underline-style": true, - "text-underline-width": true, - "top": true, - "unicode-bidi": true, - "unicode-range": true, - "vertical-align": true, - "visibility": true, - "white-space": true, - "widows": true, - "width": true, - "word-break": true, - "word-spacing": true, - "word-wrap": true, - "z-index": true, - "zoom": true, - "-webkit-animation": true, - "-webkit-animation-delay": true, - "-webkit-animation-direction": true, - "-webkit-animation-duration": true, - "-webkit-animation-iteration-count": true, - "-webkit-animation-name": true, - "-webkit-animation-play-state": true, - "-webkit-animation-timing-function": true, - "-webkit-appearance": true, - "-webkit-backface-visibility": true, - "-webkit-background-clip": true, - "-webkit-background-composite": true, - "-webkit-background-origin": true, - "-webkit-background-size": true, - "-webkit-binding": true, - "-webkit-border-fit": true, - "-webkit-border-horizontal-spacing": true, - "-webkit-border-image": true, - "-webkit-border-radius": true, - "-webkit-border-vertical-spacing": true, - "-webkit-box-align": true, - "-webkit-box-direction": true, - "-webkit-box-flex": true, - "-webkit-box-flex-group": true, - "-webkit-box-lines": true, - "-webkit-box-ordinal-group": true, - "-webkit-box-orient": true, - "-webkit-box-pack": true, - "-webkit-box-reflect": true, - "-webkit-box-shadow": true, - "-webkit-box-sizing": true, - "-webkit-column-break-after": true, - "-webkit-column-break-before": true, - "-webkit-column-break-inside": true, - "-webkit-column-count": true, - "-webkit-column-gap": true, - "-webkit-column-rule": true, - "-webkit-column-rule-color": true, - "-webkit-column-rule-style": true, - "-webkit-column-rule-width": true, - "-webkit-column-width": true, - "-webkit-columns": true, - "-webkit-font-size-delta": true, - "-webkit-font-smoothing": true, - "-webkit-highlight": true, - "-webkit-line-break": true, - "-webkit-line-clamp": true, - "-webkit-margin-bottom-collapse": true, - "-webkit-margin-collapse": true, - "-webkit-margin-start": true, - "-webkit-margin-top-collapse": true, - "-webkit-marquee": true, - "-webkit-marquee-direction": true, - "-webkit-marquee-increment": true, - "-webkit-marquee-repetition": true, - "-webkit-marquee-speed": true, - "-webkit-marquee-style": true, - "-webkit-mask": true, - "-webkit-mask-attachment": true, - "-webkit-mask-box-image": true, - "-webkit-mask-clip": true, - "-webkit-mask-composite": true, - "-webkit-mask-image": true, - "-webkit-mask-origin": true, - "-webkit-mask-position": true, - "-webkit-mask-position-x": true, - "-webkit-mask-position-y": true, - "-webkit-mask-repeat": true, - "-webkit-mask-repeat-x": true, - "-webkit-mask-repeat-y": true, - "-webkit-mask-size": true, - "-webkit-match-nearest-mail-blockquote-color": true, - "-webkit-nbsp-mode": true, - "-webkit-padding-start": true, - "-webkit-perspective": true, - "-webkit-perspective-origin": true, - "-webkit-perspective-origin-x": true, - "-webkit-perspective-origin-y": true, - "-webkit-rtl-ordering": true, - "-webkit-text-decorations-in-effect": true, - "-webkit-text-fill-color": true, - "-webkit-text-security": true, - "-webkit-text-size-adjust": true, - "-webkit-text-stroke": true, - "-webkit-text-stroke-color": true, - "-webkit-text-stroke-width": true, - "-webkit-transform": true, - "-webkit-transform-origin": true, - "-webkit-transform-origin-x": true, - "-webkit-transform-origin-y": true, - "-webkit-transform-origin-z": true, - "-webkit-transform-style": true, - "-webkit-transition": true, - "-webkit-transition-delay": true, - "-webkit-transition-duration": true, - "-webkit-transition-property": true, - "-webkit-transition-timing-function": true, - "-webkit-user-drag": true, - "-webkit-user-modify": true, - "-webkit-user-select": true, - "-webkit-variable-declaration-block": true - }; - function propertyAction(token) - { - this.cursor += token.length; - if (token in propertyKeywords) { - this.appendNonToken.call(this); - this.newLine.appendChild(this.createSpan(token, "webkit-css-property")); - } else - this.nonToken += token; - } - - function declarationColonAction(token) - { - this.cursor += token.length; - this.nonToken += token; - this.lexState = this.LexState.DeclarationValue; - } + ctx.beginPath(); + ctx.moveTo(width - 9, 2); + ctx.lineTo(width - 7, 2); + ctx.lineTo(width - 7, 0); + ctx.lineTo(width - 5, 0); + ctx.lineTo(width, height / 2); + ctx.lineTo(width - 5, height); + ctx.lineTo(width - 7, height); + ctx.lineTo(width - 7, height - 2); + ctx.lineTo(width - 9, height - 2); + ctx.closePath(); + ctx.fillStyle = "rgb(142, 5, 4)"; - const valueKeywords = { - "inherit": true, - "initial": true, - "none": true, - "hidden": true, - "inset": true, - "groove": true, - "ridge": true, - "outset": true, - "dotted": true, - "dashed": true, - "solid": true, - "double": true, - "caption": true, - "icon": true, - "menu": true, - "message-box": true, - "small-caption": true, - "-webkit-mini-control": true, - "-webkit-small-control": true, - "-webkit-control": true, - "status-bar": true, - "italic": true, - "oblique": true, - "all": true, - "small-caps": true, - "normal": true, - "bold": true, - "bolder": true, - "lighter": true, - "xx-small": true, - "x-small": true, - "small": true, - "medium": true, - "large": true, - "x-large": true, - "xx-large": true, - "-webkit-xxx-large": true, - "smaller": true, - "larger": true, - "wider": true, - "narrower": true, - "ultra-condensed": true, - "extra-condensed": true, - "condensed": true, - "semi-condensed": true, - "semi-expanded": true, - "expanded": true, - "extra-expanded": true, - "ultra-expanded": true, - "serif": true, - "sans-serif": true, - "cursive": true, - "fantasy": true, - "monospace": true, - "-webkit-body": true, - "aqua": true, - "black": true, - "blue": true, - "fuchsia": true, - "gray": true, - "green": true, - "lime": true, - "maroon": true, - "navy": true, - "olive": true, - "orange": true, - "purple": true, - "red": true, - "silver": true, - "teal": true, - "white": true, - "yellow": true, - "transparent": true, - "-webkit-link": true, - "-webkit-activelink": true, - "activeborder": true, - "activecaption": true, - "appworkspace": true, - "background": true, - "buttonface": true, - "buttonhighlight": true, - "buttonshadow": true, - "buttontext": true, - "captiontext": true, - "graytext": true, - "highlight": true, - "highlighttext": true, - "inactiveborder": true, - "inactivecaption": true, - "inactivecaptiontext": true, - "infobackground": true, - "infotext": true, - "match": true, - "menutext": true, - "scrollbar": true, - "threeddarkshadow": true, - "threedface": true, - "threedhighlight": true, - "threedlightshadow": true, - "threedshadow": true, - "window": true, - "windowframe": true, - "windowtext": true, - "-webkit-focus-ring-color": true, - "currentcolor": true, - "grey": true, - "-webkit-text": true, - "repeat": true, - "repeat-x": true, - "repeat-y": true, - "no-repeat": true, - "clear": true, - "copy": true, - "source-over": true, - "source-in": true, - "source-out": true, - "source-atop": true, - "destination-over": true, - "destination-in": true, - "destination-out": true, - "destination-atop": true, - "xor": true, - "plus-darker": true, - "plus-lighter": true, - "baseline": true, - "middle": true, - "sub": true, - "super": true, - "text-top": true, - "text-bottom": true, - "top": true, - "bottom": true, - "-webkit-baseline-middle": true, - "-webkit-auto": true, - "left": true, - "right": true, - "center": true, - "justify": true, - "-webkit-left": true, - "-webkit-right": true, - "-webkit-center": true, - "outside": true, - "inside": true, - "disc": true, - "circle": true, - "square": true, - "decimal": true, - "decimal-leading-zero": true, - "lower-roman": true, - "upper-roman": true, - "lower-greek": true, - "lower-alpha": true, - "lower-latin": true, - "upper-alpha": true, - "upper-latin": true, - "hebrew": true, - "armenian": true, - "georgian": true, - "cjk-ideographic": true, - "hiragana": true, - "katakana": true, - "hiragana-iroha": true, - "katakana-iroha": true, - "inline": true, - "block": true, - "list-item": true, - "run-in": true, - "compact": true, - "inline-block": true, - "table": true, - "inline-table": true, - "table-row-group": true, - "table-header-group": true, - "table-footer-group": true, - "table-row": true, - "table-column-group": true, - "table-column": true, - "table-cell": true, - "table-caption": true, - "-webkit-box": true, - "-webkit-inline-box": true, - "-wap-marquee": true, - "auto": true, - "crosshair": true, - "default": true, - "pointer": true, - "move": true, - "vertical-text": true, - "cell": true, - "context-menu": true, - "alias": true, - "progress": true, - "no-drop": true, - "not-allowed": true, - "-webkit-zoom-in": true, - "-webkit-zoom-out": true, - "e-resize": true, - "ne-resize": true, - "nw-resize": true, - "n-resize": true, - "se-resize": true, - "sw-resize": true, - "s-resize": true, - "w-resize": true, - "ew-resize": true, - "ns-resize": true, - "nesw-resize": true, - "nwse-resize": true, - "col-resize": true, - "row-resize": true, - "text": true, - "wait": true, - "help": true, - "all-scroll": true, - "-webkit-grab": true, - "-webkit-grabbing": true, - "ltr": true, - "rtl": true, - "capitalize": true, - "uppercase": true, - "lowercase": true, - "visible": true, - "collapse": true, - "above": true, - "absolute": true, - "always": true, - "avoid": true, - "below": true, - "bidi-override": true, - "blink": true, - "both": true, - "close-quote": true, - "crop": true, - "cross": true, - "embed": true, - "fixed": true, - "hand": true, - "hide": true, - "higher": true, - "invert": true, - "landscape": true, - "level": true, - "line-through": true, - "local": true, - "loud": true, - "lower": true, - "-webkit-marquee": true, - "mix": true, - "no-close-quote": true, - "no-open-quote": true, - "nowrap": true, - "open-quote": true, - "overlay": true, - "overline": true, - "portrait": true, - "pre": true, - "pre-line": true, - "pre-wrap": true, - "relative": true, - "scroll": true, - "separate": true, - "show": true, - "static": true, - "thick": true, - "thin": true, - "underline": true, - "-webkit-nowrap": true, - "stretch": true, - "start": true, - "end": true, - "reverse": true, - "horizontal": true, - "vertical": true, - "inline-axis": true, - "block-axis": true, - "single": true, - "multiple": true, - "forwards": true, - "backwards": true, - "ahead": true, - "up": true, - "down": true, - "slow": true, - "fast": true, - "infinite": true, - "slide": true, - "alternate": true, - "read-only": true, - "read-write": true, - "read-write-plaintext-only": true, - "element": true, - "ignore": true, - "intrinsic": true, - "min-intrinsic": true, - "clip": true, - "ellipsis": true, - "discard": true, - "dot-dash": true, - "dot-dot-dash": true, - "wave": true, - "continuous": true, - "skip-white-space": true, - "break-all": true, - "break-word": true, - "space": true, - "after-white-space": true, - "checkbox": true, - "radio": true, - "push-button": true, - "square-button": true, - "button": true, - "button-bevel": true, - "default-button": true, - "list-button": true, - "listbox": true, - "listitem": true, - "media-fullscreen-button": true, - "media-mute-button": true, - "media-play-button": true, - "media-seek-back-button": true, - "media-seek-forward-button": true, - "media-rewind-button": true, - "media-return-to-realtime-button": true, - "media-slider": true, - "media-sliderthumb": true, - "media-volume-slider-container": true, - "media-volume-slider": true, - "media-volume-sliderthumb": true, - "media-controls-background": true, - "media-current-time-display": true, - "media-time-remaining-display": true, - "menulist": true, - "menulist-button": true, - "menulist-text": true, - "menulist-textfield": true, - "slider-horizontal": true, - "slider-vertical": true, - "sliderthumb-horizontal": true, - "sliderthumb-vertical": true, - "caret": true, - "searchfield": true, - "searchfield-decoration": true, - "searchfield-results-decoration": true, - "searchfield-results-button": true, - "searchfield-cancel-button": true, - "textfield": true, - "textarea": true, - "caps-lock-indicator": true, - "round": true, - "border": true, - "border-box": true, - "content": true, - "content-box": true, - "padding": true, - "padding-box": true, - "contain": true, - "cover": true, - "logical": true, - "visual": true, - "lines": true, - "running": true, - "paused": true, - "flat": true, - "preserve-3d": true, - "ease": true, - "linear": true, - "ease-in": true, - "ease-out": true, - "ease-in-out": true, - "document": true, - "reset": true, - "visiblePainted": true, - "visibleFill": true, - "visibleStroke": true, - "painted": true, - "fill": true, - "stroke": true, - "antialiased": true, - "subpixel-antialiased": true, - "optimizeSpeed": true, - "optimizeLegibility": true, - "geometricPrecision": true - }; - function valueIdentAction(token) { - this.cursor += token.length; - if (token in valueKeywords) { - this.appendNonToken.call(this); - this.newLine.appendChild(this.createSpan(token, "webkit-css-keyword")); - } else - this.nonToken += token; - } + ctx.shadowBlur = 4; + ctx.shadowColor = "rgb(255, 255, 255)"; + ctx.shadowOffsetX = -1; + ctx.shadowOffsetY = 0; - function numvalueAction(token) - { - this.cursor += token.length; - this.newLine.appendChild(this.createSpan(token, "webkit-css-number")); - } - - function declarationSemicolonAction(token) - { - this.cursor += token.length; - this.nonToken += token; - this.lexState = this.LexState.DeclarationProperty; - } - - function urlAction(token) - { - this.cursor += token.length; - this.newLine.appendChild(this.createSpan(token, "webkit-css-url")); - } - - function stringAction(token) - { - this.cursor += token.length; - this.newLine.appendChild(this.createSpan(token, "webkit-css-string")); - } - - function colorAction(token) - { - this.cursor += token.length; - this.newLine.appendChild(this.createSpan(token, "webkit-css-color")); - } - - function importantAction(token) - { - this.cursor += token.length; - this.newLine.appendChild(this.createSpan(token, "webkit-css-important")); - } - - function atMediaAction(token) - { - this.cursor += token.length; - this.newLine.appendChild(this.createSpan(token, "webkit-css-at-rule")); - this.lexState = this.LexState.AtMedia; - } - - function startAtMediaBlockAction(token) - { - this.cursor += token.length; - this.nonToken += token; - this.lexState = this.LexState.Initial; - } - - function atKeyframesAction(token) - { - this.cursor += token.length; - this.newLine.appendChild(this.createSpan(token, "webkit-css-at-rule")); - this.lexState = this.LexState.AtKeyframes; - } - - function startAtKeyframesBlockAction(token) - { - this.cursor += token.length; - this.nonToken += token; - this.lexState = this.LexState.Initial; - } - - function atRuleAction(token) { - this.cursor += token.length; - this.newLine.appendChild(this.createSpan(token, "webkit-css-at-rule")); - this.lexState = this.LexState.AtRule; - } - - function endAtRuleAction(token) { - this.cursor += token.length; - this.nonToken += token; - this.lexState = this.LexState.Initial; - } - - function startAtRuleBlockAction(token) - { - this.cursor += token.length; - this.nonToken += token; - this.lexState = this.LexState.DeclarationProperty; - } - - const mediaTypes = ["all", "aural", "braille", "embossed", "handheld", "print", "projection", "screen", "tty", "tv"]; - function atRuleIdentAction(token) { - this.cursor += token.length; - if (mediaTypes.indexOf(token) === -1) - this.nonToken += token; - else { - this.appendNonToken.call(this); - this.newLine.appendChild(this.createSpan(token, "webkit-css-keyword")); - } - } -} + ctx.fill(); + ctx.fill(); // Fill twice to get a good shadow and darker anti-aliased pixels. -WebInspector.CSSSourceSyntaxHighlighter.prototype.__proto__ = WebInspector.SourceSyntaxHighlighter.prototype; - -WebInspector.JavaScriptSourceSyntaxHighlighter = function(table, sourceFrame) { - WebInspector.SourceSyntaxHighlighter.call(this, table, sourceFrame); - - this.LexState = { - Initial: 1, - DivisionAllowed: 2, - }; - this.ContinueState = { - None: 0, - Comment: 1, - SingleQuoteString: 2, - DoubleQuoteString: 3, - RegExp: 4 - }; - - this.nonToken = ""; - this.cursor = 0; - this.lineIndex = -1; - this.lineCode = ""; - this.newLine = null; - this.lexState = this.LexState.Initial; - this.continueState = this.ContinueState.None; - - this.rules = [{ - pattern: /^(?:\/\/.*)/, - action: singleLineCommentAction - }, { - pattern: /^(?:\/\*(?:[^\*]|\*[^\/])*\*+\/)/, - action: multiLineSingleLineCommentAction - }, { - pattern: /^(?:\/\*(?:[^\*]|\*[^\/])*)/, - action: multiLineCommentStartAction - }, { - pattern: /^(?:(?:[^\*]|\*[^\/])*\*+\/)/, - action: multiLineCommentEndAction, - continueStateCondition: this.ContinueState.Comment - }, { - pattern: /^.*/, - action: multiLineCommentMiddleAction, - continueStateCondition: this.ContinueState.Comment - }, { - pattern: /^(?:(?:0|[1-9]\d*)\.\d+?(?:[eE](?:\d+|\+\d+|-\d+))?|\.\d+(?:[eE](?:\d+|\+\d+|-\d+))?|(?:0|[1-9]\d*)(?:[eE](?:\d+|\+\d+|-\d+))?|0x[0-9a-fA-F]+|0X[0-9a-fA-F]+)/, - action: numericLiteralAction - }, { - pattern: /^(?:"(?:[^"\\]|\\(?:['"\bfnrtv]|[^'"\bfnrtv0-9xu]|0|x[0-9a-fA-F][0-9a-fA-F]|(?:u[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])))*"|'(?:[^'\\]|\\(?:['"\bfnrtv]|[^'"\bfnrtv0-9xu]|0|x[0-9a-fA-F][0-9a-fA-F]|(?:u[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])))*')/, - action: stringLiteralAction - }, { - pattern: /^(?:'(?:[^'\\]|\\(?:['"\bfnrtv]|[^'"\bfnrtv0-9xu]|0|x[0-9a-fA-F][0-9a-fA-F]|(?:u[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])))*)\\$/, - action: singleQuoteStringStartAction - }, { - pattern: /^(?:(?:[^'\\]|\\(?:['"\bfnrtv]|[^'"\bfnrtv0-9xu]|0|x[0-9a-fA-F][0-9a-fA-F]|(?:u[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])))*')/, - action: singleQuoteStringEndAction, - continueStateCondition: this.ContinueState.SingleQuoteString - }, { - pattern: /^(?:(?:[^'\\]|\\(?:['"\bfnrtv]|[^'"\bfnrtv0-9xu]|0|x[0-9a-fA-F][0-9a-fA-F]|(?:u[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])))*)\\$/, - action: singleQuoteStringMiddleAction, - continueStateCondition: this.ContinueState.SingleQuoteString - }, { - pattern: /^(?:"(?:[^"\\]|\\(?:['"\bfnrtv]|[^'"\bfnrtv0-9xu]|0|x[0-9a-fA-F][0-9a-fA-F]|(?:u[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])))*)\\$/, - action: doubleQuoteStringStartAction - }, { - pattern: /^(?:(?:[^"\\]|\\(?:['"\bfnrtv]|[^'"\bfnrtv0-9xu]|0|x[0-9a-fA-F][0-9a-fA-F]|(?:u[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])))*")/, - action: doubleQuoteStringEndAction, - continueStateCondition: this.ContinueState.DoubleQuoteString - }, { - pattern: /^(?:(?:[^"\\]|\\(?:['"\bfnrtv]|[^'"\bfnrtv0-9xu]|0|x[0-9a-fA-F][0-9a-fA-F]|(?:u[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])))*)\\$/, - action: doubleQuoteStringMiddleAction, - continueStateCondition: this.ContinueState.DoubleQuoteString - }, { - pattern: /^(?:(?:[a-zA-Z]|[$_]|\\(?:u[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]))(?:(?:[a-zA-Z]|[$_]|\\(?:u[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]))|[0-9])*)/, - action: identOrKeywordAction - }, { - pattern: /^\)/, - action: rightParenAction, - dontAppendNonToken: true - }, { - pattern: /^(?:<=|>=|===|==|!=|!==|\+\+|\-\-|<<|>>|>>>|&&|\|\||\+=|\-=|\*=|%=|<<=|>>=|>>>=|&=|\|=|^=|[{}\(\[\]\.;,<>\+\-\*%&\|\^!~\?:=])/, - action: punctuatorAction, - dontAppendNonToken: true - }, { - pattern: /^(?:\/=?)/, - action: divPunctuatorAction, - lexStateCondition: this.LexState.DivisionAllowed, - dontAppendNonToken: true - }, { - pattern: /^(?:\/(?:(?:\\.)|[^\\*\/])(?:(?:\\.)|[^\\/])*\/(?:(?:[a-zA-Z]|[$_]|\\(?:u[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]))|[0-9])*)/, - action: regExpLiteralAction - }, { - pattern: /^(?:\/(?:(?:\\.)|[^\\*\/])(?:(?:\\.)|[^\\/])*)\\$/, - action: regExpStartAction - }, { - pattern: /^(?:(?:(?:\\.)|[^\\/])*\/(?:(?:[a-zA-Z]|[$_]|\\(?:u[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]))|[0-9])*)/, - action: regExpEndAction, - continueStateCondition: this.ContinueState.RegExp - }, { - pattern: /^(?:(?:(?:\\.)|[^\\/])*)\\$/, - action: regExpMiddleAction, - continueStateCondition: this.ContinueState.RegExp - }]; - - function singleLineCommentAction(token) - { - this.cursor += token.length; - this.newLine.appendChild(this.createSpan(token, "webkit-javascript-comment")); - } - - function multiLineSingleLineCommentAction(token) - { - this.cursor += token.length; - this.newLine.appendChild(this.createSpan(token, "webkit-javascript-comment")); - } - - function multiLineCommentStartAction(token) - { - this.cursor += token.length; - this.newLine.appendChild(this.createSpan(token, "webkit-javascript-comment")); - this.continueState = this.ContinueState.Comment; - } - - function multiLineCommentEndAction(token) - { - this.cursor += token.length; - this.newLine.appendChild(this.createSpan(token, "webkit-javascript-comment")); - this.continueState = this.ContinueState.None; - } - - function multiLineCommentMiddleAction(token) - { - this.cursor += token.length; - this.newLine.appendChild(this.createSpan(token, "webkit-javascript-comment")); - } - - function numericLiteralAction(token) - { - this.cursor += token.length; - this.newLine.appendChild(this.createSpan(token, "webkit-javascript-number")); - this.lexState = this.LexState.DivisionAllowed; - } - - function stringLiteralAction(token) - { - this.cursor += token.length; - this.newLine.appendChild(this.createSpan(token, "webkit-javascript-string")); - this.lexState = this.LexState.Initial; - } - - function singleQuoteStringStartAction(token) - { - this.cursor += token.length; - this.newLine.appendChild(this.createSpan(token, "webkit-javascript-string")); - this.continueState = this.ContinueState.SingleQuoteString; - } - - function singleQuoteStringEndAction(token) - { - this.cursor += token.length; - this.newLine.appendChild(this.createSpan(token, "webkit-javascript-string")); - this.continueState = this.ContinueState.None; - } - - function singleQuoteStringMiddleAction(token) - { - this.cursor += token.length; - this.newLine.appendChild(this.createSpan(token, "webkit-javascript-string")); - } - - function doubleQuoteStringStartAction(token) - { - this.cursor += token.length; - this.newLine.appendChild(this.createSpan(token, "webkit-javascript-string")); - this.continueState = this.ContinueState.DoubleQuoteString; - } - - function doubleQuoteStringEndAction(token) - { - this.cursor += token.length; - this.newLine.appendChild(this.createSpan(token, "webkit-javascript-string")); - this.continueState = this.ContinueState.None; - } - - function doubleQuoteStringMiddleAction(token) - { - this.cursor += token.length; - this.newLine.appendChild(this.createSpan(token, "webkit-javascript-string")); - } - - function regExpLiteralAction(token) - { - this.cursor += token.length; - this.newLine.appendChild(this.createSpan(token, "webkit-javascript-regexp")); - this.lexState = this.LexState.Initial; - } + ctx.restore(); + }, - function regExpStartAction(token) + mouseDown: function(lineNumber, e) { - this.cursor += token.length; - this.newLine.appendChild(this.createSpan(token, "webkit-javascript-regexp")); - this.continueState = this.ContinueState.RegExp; - } + this._sourceFrame._toggleBreakpoint(lineNumber, e); + return true; + }, - function regExpEndAction(token) + contextMenu: function(lineNumber, e) { - this.cursor += token.length; - this.newLine.appendChild(this.createSpan(token, "webkit-javascript-regexp")); - this.continueState = this.ContinueState.None; + this._sourceFrame._contextMenu(lineNumber, e); + return true; } +} - function regExpMiddleAction(token) - { - this.cursor += token.length; - this.newLine.appendChild(this.createSpan(token, "webkit-javascript-regexp")); - } - - const keywords = { - "null": true, - "true": true, - "false": true, - "break": true, - "case": true, - "catch": true, - "const": true, - "default": true, - "finally": true, - "for": true, - "instanceof": true, - "new": true, - "var": true, - "continue": true, - "function": true, - "return": true, - "void": true, - "delete": true, - "if": true, - "this": true, - "do": true, - "while": true, - "else": true, - "in": true, - "switch": true, - "throw": true, - "try": true, - "typeof": true, - "debugger": true, - "class": true, - "enum": true, - "export": true, - "extends": true, - "import": true, - "super": true, - "get": true, - "set": true - }; - function identOrKeywordAction(token) +WebInspector.ExecutionLineDecorator = function(sourceFrame) +{ + this._sourceFrame = sourceFrame; +} + +WebInspector.ExecutionLineDecorator.prototype = { + decorate: function(lineNumber, ctx, x, y, width, height, lineHeight) { - this.cursor += token.length; - - if (token in keywords) { - this.newLine.appendChild(this.createSpan(token, "webkit-javascript-keyword")); - this.lexState = this.LexState.Initial; - } else { - var identElement = this.createSpan(token, "webkit-javascript-ident"); - identElement.addEventListener("mouseover", showDatatip, false); - this.newLine.appendChild(identElement); - this.lexState = this.LexState.DivisionAllowed; - } - } - - function showDatatip(event) { - if (!WebInspector.panels.scripts || !WebInspector.panels.scripts.paused) + if (this._sourceFrame._executionLine !== lineNumber + 1) return; + ctx.save(); + ctx.fillStyle = "rgb(171, 191, 254)"; + ctx.fillRect(x, y, width, height); + + ctx.beginPath(); + ctx.rect(x - 1, y, width + 2, height); + ctx.clip(); + ctx.strokeStyle = "rgb(64, 115, 244)"; + ctx.stroke(); - var node = event.target; - var parts = [node.textContent]; - while (node.previousSibling && node.previousSibling.textContent === ".") { - node = node.previousSibling.previousSibling; - if (!node || !node.hasStyleClass("webkit-javascript-ident")) - break; - parts.unshift(node.textContent); - } - - var expression = parts.join("."); - - WebInspector.panels.scripts.evaluateInSelectedCallFrame(expression, false, "console", callback); - function callback(result, exception) - { - if (exception) - return; - event.target.setAttribute("title", result.description); - event.target.addEventListener("mouseout", onmouseout, false); - - function onmouseout(event) - { - event.target.removeAttribute("title"); - event.target.removeEventListener("mouseout", onmouseout, false); - } - } - } - - function divPunctuatorAction(token) - { - this.cursor += token.length; - this.nonToken += token; - this.lexState = this.LexState.Initial; - } - - function rightParenAction(token) - { - this.cursor += token.length; - this.nonToken += token; - this.lexState = this.LexState.DivisionAllowed; - } - - function punctuatorAction(token) - { - this.cursor += token.length; - this.nonToken += token; - this.lexState = this.LexState.Initial; + ctx.restore(); } } - -WebInspector.JavaScriptSourceSyntaxHighlighter.prototype.__proto__ = WebInspector.SourceSyntaxHighlighter.prototype; |