home *** CD-ROM | disk | FTP | other *** search
/ Computer Active Guide 2009 July / CAG7.ISO / Internetas / SafariSetup.exe / AppleApplicationSupport.msi / WebKit.resources_inspector_SourceFrame.js < prev    next >
Encoding:
Text File  |  2010-06-03  |  25.2 KB  |  705 lines

  1. /*
  2.  * Copyright (C) 2009 Google Inc. All rights reserved.
  3.  *
  4.  * Redistribution and use in source and binary forms, with or without
  5.  * modification, are permitted provided that the following conditions are
  6.  * met:
  7.  *
  8.  *     * Redistributions of source code must retain the above copyright
  9.  * notice, this list of conditions and the following disclaimer.
  10.  *     * Redistributions in binary form must reproduce the above
  11.  * copyright notice, this list of conditions and the following disclaimer
  12.  * in the documentation and/or other materials provided with the
  13.  * distribution.
  14.  *     * Neither the name of Google Inc. nor the names of its
  15.  * contributors may be used to endorse or promote products derived from
  16.  * this software without specific prior written permission.
  17.  *
  18.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  19.  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20.  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  21.  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  22.  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  23.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  24.  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  25.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  26.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  28.  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29.  */
  30.  
  31. WebInspector.SourceFrame = function(parentElement, addBreakpointDelegate, removeBreakpointDelegate, editDelegate)
  32. {
  33.     this._parentElement = parentElement;
  34.  
  35.     this._textModel = new WebInspector.TextEditorModel();
  36.     this._textModel.replaceTabsWithSpaces = true;
  37.  
  38.     this._messages = [];
  39.     this._rowMessages = {};
  40.     this._messageBubbles = {};
  41.     this.breakpoints = [];
  42.  
  43.     this._loaded = false;
  44.  
  45.     this._addBreakpointDelegate = addBreakpointDelegate;
  46.     this._removeBreakpointDelegate = removeBreakpointDelegate;
  47.     this._editDelegate = editDelegate;
  48.     this._popoverObjectGroup = "popover";
  49. }
  50.  
  51. WebInspector.SourceFrame.prototype = {
  52.  
  53.     set visible(visible)
  54.     {
  55.         this._visible = visible;
  56.         this._createViewerIfNeeded();
  57.         
  58.         if (!visible) {
  59.             this._hidePopup();
  60.             if (this._textViewer)
  61.                 this._textViewer.freeCachedElements();
  62.         }
  63.     },
  64.  
  65.     get executionLine()
  66.     {
  67.         return this._executionLine;
  68.     },
  69.  
  70.     set executionLine(x)
  71.     {
  72.         if (this._executionLine === x)
  73.             return;
  74.  
  75.         var previousLine = this._executionLine;
  76.         this._executionLine = x;
  77.  
  78.         if (this._textViewer)
  79.             this._updateExecutionLine(previousLine);
  80.     },
  81.  
  82.     revealLine: function(lineNumber)
  83.     {
  84.         if (this._textViewer)
  85.             this._textViewer.revealLine(lineNumber - 1, 0);
  86.         else
  87.             this._lineNumberToReveal = lineNumber;
  88.     },
  89.  
  90.     addBreakpoint: function(breakpoint)
  91.     {
  92.         this.breakpoints.push(breakpoint);
  93.         breakpoint.addEventListener("enabled", this._breakpointChanged, this);
  94.         breakpoint.addEventListener("disabled", this._breakpointChanged, this);
  95.         breakpoint.addEventListener("condition-changed", this._breakpointChanged, this);
  96.         if (this._textViewer)
  97.             this._addBreakpointToSource(breakpoint);
  98.     },
  99.  
  100.     removeBreakpoint: function(breakpoint)
  101.     {
  102.         this.breakpoints.remove(breakpoint);
  103.         breakpoint.removeEventListener("enabled", null, this);
  104.         breakpoint.removeEventListener("disabled", null, this);
  105.         breakpoint.removeEventListener("condition-changed", null, this);
  106.         if (this._textViewer)
  107.             this._removeBreakpointFromSource(breakpoint);
  108.     },
  109.  
  110.     addMessage: function(msg)
  111.     {
  112.         // Don't add the message if there is no message or valid line or if the msg isn't an error or warning.
  113.         if (!msg.message || msg.line <= 0 || !msg.isErrorOrWarning())
  114.             return;
  115.         this._messages.push(msg)
  116.         if (this._textViewer)
  117.             this._addMessageToSource(msg);
  118.     },
  119.  
  120.     clearMessages: function()
  121.     {
  122.         for (var line in this._messageBubbles) {
  123.             var bubble = this._messageBubbles[line];
  124.             bubble.parentNode.removeChild(bubble);
  125.         }
  126.  
  127.         this._messages = [];
  128.         this._rowMessages = {};
  129.         this._messageBubbles = {};
  130.         if (this._textViewer)
  131.             this._textViewer.resize();
  132.     },
  133.  
  134.     sizeToFitContentHeight: function()
  135.     {
  136.         if (this._textViewer)
  137.             this._textViewer.revalidateDecorationsAndPaint();
  138.     },
  139.  
  140.     setContent: function(mimeType, content, url)
  141.     {
  142.         this._loaded = true;
  143.         this._textModel.setText(null, content);
  144.         this._mimeType = mimeType;
  145.         this._url = url;
  146.         this._createViewerIfNeeded();
  147.     },
  148.  
  149.     updateContent: function(content)
  150.     {
  151.         this._textModel.setText(null, content);
  152.     },
  153.  
  154.     get textModel()
  155.     {
  156.         return this._textModel;
  157.     },
  158.  
  159.     highlightLine: function(line)
  160.     {
  161.         if (this._textViewer)
  162.             this._textViewer.highlightLine(line - 1);
  163.         else
  164.             this._lineToHighlight = line;
  165.     },
  166.  
  167.     _createViewerIfNeeded: function()
  168.     {
  169.         if (!this._visible || !this._loaded || this._textViewer)
  170.             return;
  171.  
  172.         this._textViewer = new WebInspector.TextViewer(this._textModel, WebInspector.platform, this._url);
  173.         var element = this._textViewer.element;
  174.         element.addEventListener("contextmenu", this._contextMenu.bind(this), true);
  175.         element.addEventListener("mousedown", this._mouseDown.bind(this), true);
  176.         element.addEventListener("mousemove", this._mouseMove.bind(this), true);
  177.         element.addEventListener("scroll", this._scroll.bind(this), true);
  178.         this._parentElement.appendChild(element);
  179.  
  180.         this._needsProgramCounterImage = true;
  181.         this._needsBreakpointImages = true;
  182.  
  183.         this._textViewer.beginUpdates();
  184.  
  185.         this._textViewer.mimeType = this._mimeType;
  186.         this._addExistingMessagesToSource();
  187.         this._addExistingBreakpointsToSource();
  188.         this._updateExecutionLine();
  189.         this._textViewer.resize();
  190.  
  191.         if (this._lineNumberToReveal) {
  192.             this.revealLine(this._lineNumberToReveal);
  193.             delete this._lineNumberToReveal;
  194.         }
  195.  
  196.         if (this._pendingMarkRange) {
  197.             var range = this._pendingMarkRange;
  198.             this.markAndRevealRange(range);
  199.             delete this._pendingMarkRange;
  200.         }
  201.  
  202.         if (this._lineToHighlight) {
  203.             this.highlightLine(this._lineToHighlight);
  204.             delete this._lineToHighlight;
  205.         }
  206.         this._textViewer.endUpdates();
  207.         if (this._editDelegate)
  208.             this._textViewer.editCallback = this._editDelegate;
  209.     },
  210.  
  211.     findSearchMatches: function(query)
  212.     {
  213.         var ranges = [];
  214.  
  215.         // First do case-insensitive search.
  216.         var regexObject = createSearchRegex(query);
  217.         this._collectRegexMatches(regexObject, ranges);
  218.  
  219.         // Then try regex search if user knows the / / hint.
  220.         try {
  221.             if (/^\/.*\/$/.test(query))
  222.                 this._collectRegexMatches(new RegExp(query.substring(1, query.length - 1)), ranges);
  223.         } catch (e) {
  224.             // Silent catch.
  225.         }
  226.         return ranges;
  227.     },
  228.  
  229.     _collectRegexMatches: function(regexObject, ranges)
  230.     {
  231.         for (var i = 0; i < this._textModel.linesCount; ++i) {
  232.             var line = this._textModel.line(i);
  233.             var offset = 0;
  234.             do {
  235.                 var match = regexObject.exec(line);
  236.                 if (match) {
  237.                     ranges.push(new WebInspector.TextRange(i, offset + match.index, i, offset + match.index + match[0].length));
  238.                     offset += match.index + 1;
  239.                     line = line.substring(match.index + 1);
  240.                 }
  241.             } while (match)
  242.         }
  243.         return ranges;
  244.     },
  245.  
  246.     markAndRevealRange: function(range)
  247.     {
  248.         if (this._textViewer)
  249.             this._textViewer.markAndRevealRange(range);
  250.         else
  251.             this._pendingMarkRange = range;
  252.     },
  253.  
  254.     clearMarkedRange: function()
  255.     {
  256.         if (this._textViewer) {
  257.             this._textViewer.markAndRevealRange(null);
  258.         } else
  259.             delete this._pendingMarkRange;
  260.     },
  261.  
  262.     _incrementMessageRepeatCount: function(msg, repeatDelta)
  263.     {
  264.         if (!msg._resourceMessageLineElement)
  265.             return;
  266.  
  267.         if (!msg._resourceMessageRepeatCountElement) {
  268.             var repeatedElement = document.createElement("span");
  269.             msg._resourceMessageLineElement.appendChild(repeatedElement);
  270.             msg._resourceMessageRepeatCountElement = repeatedElement;
  271.         }
  272.  
  273.         msg.repeatCount += repeatDelta;
  274.         msg._resourceMessageRepeatCountElement.textContent = WebInspector.UIString(" (repeated %d times)", msg.repeatCount);
  275.     },
  276.  
  277.     _breakpointChanged: function(event)
  278.     {
  279.         var breakpoint = event.target;
  280.         var lineNumber = breakpoint.line - 1;
  281.         if (lineNumber >= this._textModel.linesCount)
  282.             return;
  283.  
  284.         if (breakpoint.enabled)
  285.             this._textViewer.removeDecoration(lineNumber, "webkit-breakpoint-disabled");
  286.         else
  287.             this._textViewer.addDecoration(lineNumber, "webkit-breakpoint-disabled");
  288.  
  289.         if (breakpoint.condition)
  290.             this._textViewer.addDecoration(lineNumber, "webkit-breakpoint-conditional");
  291.         else
  292.             this._textViewer.removeDecoration(lineNumber, "webkit-breakpoint-conditional");
  293.     },
  294.  
  295.     _updateExecutionLine: function(previousLine)
  296.     {
  297.         if (previousLine) {
  298.             if (previousLine - 1 < this._textModel.linesCount)
  299.                 this._textViewer.removeDecoration(previousLine - 1, "webkit-execution-line");
  300.         }
  301.  
  302.         if (!this._executionLine)
  303.             return;
  304.  
  305.         if (this._executionLine < this._textModel.linesCount)
  306.             this._textViewer.addDecoration(this._executionLine - 1, "webkit-execution-line");
  307.     },
  308.  
  309.     _addExistingMessagesToSource: function()
  310.     {
  311.         var length = this._messages.length;
  312.         for (var i = 0; i < length; ++i)
  313.             this._addMessageToSource(this._messages[i]);
  314.     },
  315.  
  316.     _addMessageToSource: function(msg)
  317.     {
  318.         if (msg.line >= this._textModel.linesCount)
  319.             return;
  320.  
  321.         var messageBubbleElement = this._messageBubbles[msg.line];
  322.         if (!messageBubbleElement || messageBubbleElement.nodeType !== Node.ELEMENT_NODE || !messageBubbleElement.hasStyleClass("webkit-html-message-bubble")) {
  323.             messageBubbleElement = document.createElement("div");
  324.             messageBubbleElement.className = "webkit-html-message-bubble";
  325.             this._messageBubbles[msg.line] = messageBubbleElement;
  326.             this._textViewer.addDecoration(msg.line - 1, messageBubbleElement);
  327.         }
  328.  
  329.         var rowMessages = this._rowMessages[msg.line];
  330.         if (!rowMessages) {
  331.             rowMessages = [];
  332.             this._rowMessages[msg.line] = rowMessages;
  333.         }
  334.  
  335.         for (var i = 0; i < rowMessages.length; ++i) {
  336.             if (rowMessages[i].isEqual(msg, true)) {
  337.                 this._incrementMessageRepeatCount(rowMessages[i], msg.repeatDelta);
  338.                 return;
  339.             }
  340.         }
  341.  
  342.         rowMessages.push(msg);
  343.  
  344.         var imageURL;
  345.         switch (msg.level) {
  346.             case WebInspector.ConsoleMessage.MessageLevel.Error:
  347.                 messageBubbleElement.addStyleClass("webkit-html-error-message");
  348.                 imageURL = "Images/errorIcon.png";
  349.                 break;
  350.             case WebInspector.ConsoleMessage.MessageLevel.Warning:
  351.                 messageBubbleElement.addStyleClass("webkit-html-warning-message");
  352.                 imageURL = "Images/warningIcon.png";
  353.                 break;
  354.         }
  355.  
  356.         var messageLineElement = document.createElement("div");
  357.         messageLineElement.className = "webkit-html-message-line";
  358.         messageBubbleElement.appendChild(messageLineElement);
  359.  
  360.         // Create the image element in the Inspector's document so we can use relative image URLs.
  361.         var image = document.createElement("img");
  362.         image.src = imageURL;
  363.         image.className = "webkit-html-message-icon";
  364.         messageLineElement.appendChild(image);
  365.         messageLineElement.appendChild(document.createTextNode(msg.message));
  366.  
  367.         msg._resourceMessageLineElement = messageLineElement;
  368.     },
  369.  
  370.     _addExistingBreakpointsToSource: function()
  371.     {
  372.         for (var i = 0; i < this.breakpoints.length; ++i)
  373.             this._addBreakpointToSource(this.breakpoints[i]);
  374.     },
  375.  
  376.     _addBreakpointToSource: function(breakpoint)
  377.     {
  378.         var lineNumber = breakpoint.line - 1;
  379.         if (lineNumber >= this._textModel.linesCount)
  380.             return;
  381.  
  382.         this._textModel.setAttribute(lineNumber, "breakpoint", breakpoint);
  383.         breakpoint.sourceText = this._textModel.line(breakpoint.line - 1);
  384.  
  385.         this._textViewer.beginUpdates();
  386.         this._textViewer.addDecoration(lineNumber, "webkit-breakpoint");
  387.         if (!breakpoint.enabled)
  388.             this._textViewer.addDecoration(lineNumber, "webkit-breakpoint-disabled");
  389.         if (breakpoint.condition)
  390.             this._textViewer.addDecoration(lineNumber, "webkit-breakpoint-conditional");
  391.         this._textViewer.endUpdates();
  392.     },
  393.  
  394.     _removeBreakpointFromSource: function(breakpoint)
  395.     {
  396.         var lineNumber = breakpoint.line - 1;
  397.         this._textViewer.beginUpdates();
  398.         this._textModel.removeAttribute(lineNumber, "breakpoint");
  399.         this._textViewer.removeDecoration(lineNumber, "webkit-breakpoint");
  400.         this._textViewer.removeDecoration(lineNumber, "webkit-breakpoint-disabled");
  401.         this._textViewer.removeDecoration(lineNumber, "webkit-breakpoint-conditional");
  402.         this._textViewer.endUpdates();
  403.     },
  404.  
  405.     _contextMenu: function(event)
  406.     {
  407.         var target = event.target.enclosingNodeOrSelfWithClass("webkit-line-number");
  408.         if (!target)
  409.             return;
  410.         var row = target.parentElement;
  411.  
  412.         var lineNumber = row.lineNumber;
  413.         var contextMenu = new WebInspector.ContextMenu();
  414.  
  415.         var breakpoint = this._textModel.getAttribute(lineNumber, "breakpoint");
  416.         if (!breakpoint) {
  417.             // This row doesn't have a breakpoint: We want to show Add Breakpoint and Add and Edit Breakpoint.
  418.             contextMenu.appendItem(WebInspector.UIString("Add Breakpoint"), this._addBreakpointDelegate.bind(this, lineNumber + 1));
  419.  
  420.             function addConditionalBreakpoint() 
  421.             {
  422.                 this._addBreakpointDelegate(lineNumber + 1);
  423.                 var breakpoint = this._textModel.getAttribute(lineNumber, "breakpoint");
  424.                 if (breakpoint)
  425.                     this._editBreakpointCondition(breakpoint);
  426.             }
  427.  
  428.             contextMenu.appendItem(WebInspector.UIString("Add Conditional Breakpoint..."), addConditionalBreakpoint.bind(this));
  429.         } else {
  430.             // This row has a breakpoint, we want to show edit and remove breakpoint, and either disable or enable.
  431.             contextMenu.appendItem(WebInspector.UIString("Remove Breakpoint"), WebInspector.panels.scripts.removeBreakpoint.bind(WebInspector.panels.scripts, breakpoint));
  432.             contextMenu.appendItem(WebInspector.UIString("Edit Breakpoint..."), this._editBreakpointCondition.bind(this, breakpoint));
  433.             if (breakpoint.enabled)
  434.                 contextMenu.appendItem(WebInspector.UIString("Disable Breakpoint"), function() { breakpoint.enabled = false; });
  435.             else
  436.                 contextMenu.appendItem(WebInspector.UIString("Enable Breakpoint"), function() { breakpoint.enabled = true; });
  437.         }
  438.         contextMenu.show(event);
  439.     },
  440.  
  441.     _scroll: function(event)
  442.     {
  443.         this._hidePopup();
  444.     },
  445.  
  446.     _mouseDown: function(event)
  447.     {
  448.         this._resetHoverTimer();
  449.         this._hidePopup();
  450.         if (event.button != 0 || event.altKey || event.ctrlKey || event.metaKey)
  451.             return;
  452.         var target = event.target.enclosingNodeOrSelfWithClass("webkit-line-number");
  453.         if (!target)
  454.             return;
  455.         var row = target.parentElement;
  456.  
  457.         var lineNumber = row.lineNumber;
  458.  
  459.         var breakpoint = this._textModel.getAttribute(lineNumber, "breakpoint");
  460.         if (breakpoint) {
  461.             if (event.shiftKey)
  462.                 breakpoint.enabled = !breakpoint.enabled;
  463.             else
  464.                 this._removeBreakpointDelegate(breakpoint);
  465.         } else
  466.             this._addBreakpointDelegate(lineNumber + 1);
  467.         event.preventDefault();
  468.     },
  469.  
  470.     _mouseMove: function(event)
  471.     {
  472.         // Pretend that nothing has happened.
  473.         if (this._hoverElement === event.target || event.target.hasStyleClass("source-frame-eval-expression"))
  474.             return;
  475.  
  476.         this._resetHoverTimer();
  477.         // User has 500ms to reach the popup.
  478.         if (this._popup) {
  479.             var self = this;
  480.             function doHide()
  481.             {
  482.                 self._hidePopup();
  483.                 delete self._hidePopupTimer;
  484.             }
  485.             this._hidePopupTimer = setTimeout(doHide, 500);
  486.         }
  487.  
  488.         this._hoverElement = event.target;
  489.  
  490.         // Now that cleanup routines are set up above, leave this in case we are not on a break.
  491.         if (!WebInspector.panels.scripts || !WebInspector.panels.scripts.paused)
  492.             return;
  493.  
  494.         // We are interested in identifiers and "this" keyword.
  495.         if (this._hoverElement.hasStyleClass("webkit-javascript-keyword")) {
  496.             if (this._hoverElement.textContent !== "this")
  497.                 return;
  498.         } else if (!this._hoverElement.hasStyleClass("webkit-javascript-ident"))
  499.             return;
  500.  
  501.         const toolTipDelay = this._popup ? 600 : 1000;
  502.         this._hoverTimer = setTimeout(this._mouseHover.bind(this, this._hoverElement), toolTipDelay);
  503.     },
  504.  
  505.     _resetHoverTimer: function()
  506.     {
  507.         if (this._hoverTimer) {
  508.             clearTimeout(this._hoverTimer);
  509.             delete this._hoverTimer;
  510.         }
  511.     },
  512.  
  513.     _hidePopup: function()
  514.     {
  515.         if (!this._popup)
  516.             return;
  517.  
  518.         // Replace higlight element with its contents inplace.
  519.         var parentElement = this._popup.highlightElement.parentElement;
  520.         var child = this._popup.highlightElement.firstChild;
  521.         while (child) {
  522.             var nextSibling = child.nextSibling;
  523.             parentElement.insertBefore(child, this._popup.highlightElement);
  524.             child = nextSibling;
  525.         }
  526.         parentElement.removeChild(this._popup.highlightElement);
  527.  
  528.         this._popup.hide();
  529.         delete this._popup;
  530.         InspectorBackend.releaseWrapperObjectGroup(0, this._popoverObjectGroup);
  531.     },
  532.  
  533.     _mouseHover: function(element)
  534.     {
  535.         delete this._hoverTimer;
  536.  
  537.         if (!WebInspector.panels.scripts || !WebInspector.panels.scripts.paused)
  538.             return;
  539.  
  540.         var lineRow = element.enclosingNodeOrSelfWithNodeName("tr");
  541.         if (!lineRow)
  542.             return;
  543.  
  544.         // Collect tokens belonging to evaluated exression.
  545.         var tokens = [ element ];
  546.         var token = element.previousSibling;
  547.         while (token && (token.className === "webkit-javascript-ident" || token.className === "webkit-javascript-keyword" || token.textContent.trim() === ".")) {
  548.             tokens.push(token);
  549.             token = token.previousSibling;
  550.         }
  551.         tokens.reverse();
  552.  
  553.         // Wrap them with highlight element.
  554.         var parentElement = element.parentElement;
  555.         var nextElement = element.nextSibling;
  556.         var container = document.createElement("span");
  557.         for (var i = 0; i < tokens.length; ++i)
  558.             container.appendChild(tokens[i]);
  559.         parentElement.insertBefore(container, nextElement);
  560.         this._showPopup(container);
  561.     },
  562.  
  563.     _showPopup: function(element)
  564.     {
  565.         function killHidePopupTimer()
  566.         {
  567.             if (this._hidePopupTimer) {
  568.                 clearTimeout(this._hidePopupTimer);
  569.                 delete this._hidePopupTimer;
  570.  
  571.                 // We know that we reached the popup, but we might have moved over other elements.
  572.                 // Discard pending command.
  573.                 this._resetHoverTimer();
  574.             }
  575.         }
  576.  
  577.         function showObjectPopup(result)
  578.         {
  579.             if (!WebInspector.panels.scripts.paused)
  580.                 return;
  581.  
  582.             var popupContentElement = null;
  583.             if (result.type !== "object" && result.type !== "node" && result.type !== "array") {
  584.                 popupContentElement = document.createElement("span");
  585.                 popupContentElement.className = "monospace";
  586.                 popupContentElement.style.whiteSpace = "pre";
  587.                 popupContentElement.textContent = result.description;
  588.                 this._popup = new WebInspector.Popover(popupContentElement);
  589.                 this._popup.show(element);
  590.             } else {
  591.                 var popupContentElement = document.createElement("div");
  592.  
  593.                 var titleElement = document.createElement("div");
  594.                 titleElement.className = "source-frame-popover-title monospace";
  595.                 titleElement.textContent = result.description;
  596.                 popupContentElement.appendChild(titleElement);
  597.  
  598.                 var section = new WebInspector.ObjectPropertiesSection(result, "", null, false);
  599.                 section.expanded = true;
  600.                 section.element.addStyleClass("source-frame-popover-tree");
  601.                 section.headerElement.addStyleClass("hidden");
  602.                 popupContentElement.appendChild(section.element);
  603.  
  604.                 this._popup = new WebInspector.Popover(popupContentElement);
  605.                 const popupWidth = 300;
  606.                 const popupHeight = 250;
  607.                 this._popup.show(element, popupWidth, popupHeight);
  608.             }
  609.             this._popup.highlightElement = element;
  610.             this._popup.highlightElement.addStyleClass("source-frame-eval-expression");
  611.             popupContentElement.addEventListener("mousemove", killHidePopupTimer.bind(this), true);
  612.         }
  613.  
  614.         function evaluateCallback(result, exception)
  615.         {
  616.             if (exception)
  617.                 return;
  618.             if (!WebInspector.panels.scripts.paused)
  619.                 return;
  620.             showObjectPopup.call(this, result);
  621.         }
  622.         WebInspector.panels.scripts.evaluateInSelectedCallFrame(element.textContent, false, this._popoverObjectGroup, evaluateCallback.bind(this));
  623.     },
  624.  
  625.     _editBreakpointCondition: function(breakpoint)
  626.     {
  627.         this._showBreakpointConditionPopup(breakpoint.line);
  628.  
  629.         function committed(element, newText)
  630.         {
  631.             breakpoint.condition = newText;
  632.             dismissed.call(this);
  633.         }
  634.  
  635.         function dismissed()
  636.         {
  637.             if (this._conditionElement)
  638.                 this._textViewer.removeDecoration(breakpoint.line - 1, this._conditionElement);
  639.             delete this._conditionEditorElement;
  640.             delete this._conditionElement;
  641.         }
  642.  
  643.         var dismissedHandler = dismissed.bind(this);
  644.         this._conditionEditorElement.addEventListener("blur", dismissedHandler, false);
  645.  
  646.         WebInspector.startEditing(this._conditionEditorElement, committed.bind(this), dismissedHandler);
  647.         this._conditionEditorElement.value = breakpoint.condition;
  648.         this._conditionEditorElement.select();
  649.     },
  650.  
  651.     _showBreakpointConditionPopup: function(lineNumber)
  652.     {
  653.         this._conditionElement = this._createConditionElement(lineNumber);
  654.         this._textViewer.addDecoration(lineNumber - 1, this._conditionElement);
  655.     },
  656.  
  657.     _createConditionElement: function(lineNumber)
  658.     {
  659.         var conditionElement = document.createElement("div");
  660.         conditionElement.className = "source-frame-breakpoint-condition";
  661.  
  662.         var labelElement = document.createElement("label");
  663.         labelElement.className = "source-frame-breakpoint-message";
  664.         labelElement.htmlFor = "source-frame-breakpoint-condition";
  665.         labelElement.appendChild(document.createTextNode(WebInspector.UIString("The breakpoint on line %d will stop only if this expression is true:", lineNumber)));
  666.         conditionElement.appendChild(labelElement);
  667.  
  668.         var editorElement = document.createElement("input");
  669.         editorElement.id = "source-frame-breakpoint-condition";
  670.         editorElement.className = "monospace";
  671.         editorElement.type = "text"
  672.         conditionElement.appendChild(editorElement);
  673.         this._conditionEditorElement = editorElement;
  674.  
  675.         return conditionElement;
  676.     },
  677.  
  678.     _evalSelectionInCallFrame: function(event)
  679.     {
  680.         if (!WebInspector.panels.scripts || !WebInspector.panels.scripts.paused)
  681.             return;
  682.  
  683.         var selection = this.element.contentWindow.getSelection();
  684.         if (!selection.rangeCount)
  685.             return;
  686.  
  687.         var expression = selection.getRangeAt(0).toString().trim();
  688.         WebInspector.panels.scripts.evaluateInSelectedCallFrame(expression, false, "console", function(result, exception) {
  689.             WebInspector.showConsole();
  690.             var commandMessage = new WebInspector.ConsoleCommand(expression);
  691.             WebInspector.console.addMessage(commandMessage);
  692.             WebInspector.console.addMessage(new WebInspector.ConsoleCommandResult(result, exception, commandMessage));
  693.         });
  694.     },
  695.  
  696.     resize: function()
  697.     {
  698.         if (this._textViewer)
  699.             this._textViewer.resize();
  700.     }
  701. }
  702.  
  703.  
  704. WebInspector.SourceFrame.prototype.__proto__ = WebInspector.Object.prototype;
  705.