Web Inspector: Move the Popover code out of the Breakpoint model object
authormattbaker@apple.com <mattbaker@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 31 Aug 2015 22:39:30 +0000 (22:39 +0000)
committermattbaker@apple.com <mattbaker@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 31 Aug 2015 22:39:30 +0000 (22:39 +0000)
https://bugs.webkit.org/show_bug.cgi?id=127328

Reviewed by Timothy Hatcher.

* UserInterface/Controllers/BreakpointPopoverController.js: Added.
(WebInspector.BreakpointPopoverController):
(WebInspector.BreakpointPopoverController.prototype.appendContextMenuItems.editBreakpoint):
(WebInspector.BreakpointPopoverController.prototype.appendContextMenuItems.removeBreakpoint):
(WebInspector.BreakpointPopoverController.prototype.appendContextMenuItems.toggleBreakpoint):
(WebInspector.BreakpointPopoverController.prototype.appendContextMenuItems.toggleAutoContinue):
(WebInspector.BreakpointPopoverController.prototype.appendContextMenuItems.revealOriginalSourceCodeLocation):
(WebInspector.BreakpointPopoverController.prototype.appendContextMenuItems):
(WebInspector.BreakpointPopoverController.prototype.showEditBreakpointPopover):
(WebInspector.BreakpointPopoverController.prototype._createPopoverContent):
(WebInspector.BreakpointPopoverController.prototype._popoverToggleEnabledCheckboxChanged):
(WebInspector.BreakpointPopoverController.prototype._popoverConditionInputChanged):
(WebInspector.BreakpointPopoverController.prototype._popoverToggleAutoContinueCheckboxChanged):
(WebInspector.BreakpointPopoverController.prototype._popoverConditionInputKeyDown):
(WebInspector.BreakpointPopoverController.prototype._popoverActionsCreateAddActionButton):
(WebInspector.BreakpointPopoverController.prototype._popoverActionsAddActionButtonClicked):
(WebInspector.BreakpointPopoverController.prototype._popoverActionsInsertBreakpointActionView):
(WebInspector.BreakpointPopoverController.prototype.breakpointActionViewAppendActionView):
(WebInspector.BreakpointPopoverController.prototype.breakpointActionViewRemoveActionView):
(WebInspector.BreakpointPopoverController.prototype.breakpointActionViewResized):
(WebInspector.BreakpointPopoverController.prototype.willDismissPopover):
(WebInspector.BreakpointPopoverController.prototype.didDismissPopover):
Added controller class to encapsulate view logic previously located in WebInspector.Breakpoint.

* UserInterface/Main.html:
Added and updated file paths.

* UserInterface/Models/Breakpoint.js:
(WebInspector.Breakpoint.prototype.appendContextMenuItems.editBreakpoint): Deleted.
(WebInspector.Breakpoint.prototype.appendContextMenuItems.removeBreakpoint): Deleted.
(WebInspector.Breakpoint.prototype.appendContextMenuItems.toggleBreakpoint): Deleted.
(WebInspector.Breakpoint.prototype.appendContextMenuItems.toggleAutoContinue): Deleted.
(WebInspector.Breakpoint.prototype.appendContextMenuItems.revealOriginalSourceCodeLocation): Deleted.
(WebInspector.Breakpoint.prototype.appendContextMenuItems): Deleted.
(WebInspector.Breakpoint.prototype._popoverToggleEnabledCheckboxChanged): Deleted.
(WebInspector.Breakpoint.prototype._popoverConditionInputChanged): Deleted.
(WebInspector.Breakpoint.prototype._popoverToggleAutoContinueCheckboxChanged): Deleted.
(WebInspector.Breakpoint.prototype._popoverConditionInputKeyDown): Deleted.
(WebInspector.Breakpoint.prototype._editBreakpointPopoverContentElement): Deleted.
(WebInspector.Breakpoint.prototype._popoverActionsCreateAddActionButton): Deleted.
(WebInspector.Breakpoint.prototype._popoverActionsAddActionButtonClicked): Deleted.
(WebInspector.Breakpoint.prototype._popoverActionsInsertBreakpointActionView): Deleted.
(WebInspector.Breakpoint.prototype.breakpointActionViewAppendActionView): Deleted.
(WebInspector.Breakpoint.prototype.breakpointActionViewRemoveActionView): Deleted.
(WebInspector.Breakpoint.prototype.breakpointActionViewResized): Deleted.
(WebInspector.Breakpoint.prototype.willDismissPopover): Deleted.
(WebInspector.Breakpoint.prototype.didDismissPopover): Deleted.
(WebInspector.Breakpoint.prototype._showEditBreakpointPopover): Deleted.
Removed view logic.

* UserInterface/Views/BreakpointPopoverController.css: Renamed from Source/WebInspectorUI/UserInterface/Views/Breakpoint.css.
(.popover .edit-breakpoint-popover-content):
(.popover .edit-breakpoint-popover-content.wide):
(.popover .edit-breakpoint-popover-content > label.toggle):
(.popover .edit-breakpoint-popover-content > table):
(.popover .edit-breakpoint-popover-content > table > tr > th):
(.popover .edit-breakpoint-popover-content > table > tr > td):
(#edit-breakpoint-popover-condition):
(#edit-breakpoint-popoover-auto-continue):

* UserInterface/Views/SourceCodeTextEditor.js:
(WebInspector.SourceCodeTextEditor):
Creates a BreakpointPopoverController instance. The lifetime of the 'Edit Breakpoint' view is internal to the
controller, and can't be initiated outside of a context menu item click.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@189189 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebInspectorUI/ChangeLog
Source/WebInspectorUI/UserInterface/Controllers/BreakpointPopoverController.js [new file with mode: 0644]
Source/WebInspectorUI/UserInterface/Main.html
Source/WebInspectorUI/UserInterface/Models/Breakpoint.js
Source/WebInspectorUI/UserInterface/Views/BreakpointPopoverController.css [moved from Source/WebInspectorUI/UserInterface/Views/Breakpoint.css with 97% similarity]
Source/WebInspectorUI/UserInterface/Views/SourceCodeTextEditor.js

index 0459036..4303bfc 100644 (file)
@@ -1,5 +1,77 @@
 2015-08-31  Matt Baker  <mattbaker@apple.com>
 
+        Web Inspector: Move the Popover code out of the Breakpoint model object
+        https://bugs.webkit.org/show_bug.cgi?id=127328
+
+        Reviewed by Timothy Hatcher.
+
+        * UserInterface/Controllers/BreakpointPopoverController.js: Added.
+        (WebInspector.BreakpointPopoverController):
+        (WebInspector.BreakpointPopoverController.prototype.appendContextMenuItems.editBreakpoint):
+        (WebInspector.BreakpointPopoverController.prototype.appendContextMenuItems.removeBreakpoint):
+        (WebInspector.BreakpointPopoverController.prototype.appendContextMenuItems.toggleBreakpoint):
+        (WebInspector.BreakpointPopoverController.prototype.appendContextMenuItems.toggleAutoContinue):
+        (WebInspector.BreakpointPopoverController.prototype.appendContextMenuItems.revealOriginalSourceCodeLocation):
+        (WebInspector.BreakpointPopoverController.prototype.appendContextMenuItems):
+        (WebInspector.BreakpointPopoverController.prototype.showEditBreakpointPopover):
+        (WebInspector.BreakpointPopoverController.prototype._createPopoverContent):
+        (WebInspector.BreakpointPopoverController.prototype._popoverToggleEnabledCheckboxChanged):
+        (WebInspector.BreakpointPopoverController.prototype._popoverConditionInputChanged):
+        (WebInspector.BreakpointPopoverController.prototype._popoverToggleAutoContinueCheckboxChanged):
+        (WebInspector.BreakpointPopoverController.prototype._popoverConditionInputKeyDown):
+        (WebInspector.BreakpointPopoverController.prototype._popoverActionsCreateAddActionButton):
+        (WebInspector.BreakpointPopoverController.prototype._popoverActionsAddActionButtonClicked):
+        (WebInspector.BreakpointPopoverController.prototype._popoverActionsInsertBreakpointActionView):
+        (WebInspector.BreakpointPopoverController.prototype.breakpointActionViewAppendActionView):
+        (WebInspector.BreakpointPopoverController.prototype.breakpointActionViewRemoveActionView):
+        (WebInspector.BreakpointPopoverController.prototype.breakpointActionViewResized):
+        (WebInspector.BreakpointPopoverController.prototype.willDismissPopover):
+        (WebInspector.BreakpointPopoverController.prototype.didDismissPopover):
+        Added controller class to encapsulate view logic previously located in WebInspector.Breakpoint.
+
+        * UserInterface/Main.html:
+        Added and updated file paths.
+
+        * UserInterface/Models/Breakpoint.js:
+        (WebInspector.Breakpoint.prototype.appendContextMenuItems.editBreakpoint): Deleted.
+        (WebInspector.Breakpoint.prototype.appendContextMenuItems.removeBreakpoint): Deleted.
+        (WebInspector.Breakpoint.prototype.appendContextMenuItems.toggleBreakpoint): Deleted.
+        (WebInspector.Breakpoint.prototype.appendContextMenuItems.toggleAutoContinue): Deleted.
+        (WebInspector.Breakpoint.prototype.appendContextMenuItems.revealOriginalSourceCodeLocation): Deleted.
+        (WebInspector.Breakpoint.prototype.appendContextMenuItems): Deleted.
+        (WebInspector.Breakpoint.prototype._popoverToggleEnabledCheckboxChanged): Deleted.
+        (WebInspector.Breakpoint.prototype._popoverConditionInputChanged): Deleted.
+        (WebInspector.Breakpoint.prototype._popoverToggleAutoContinueCheckboxChanged): Deleted.
+        (WebInspector.Breakpoint.prototype._popoverConditionInputKeyDown): Deleted.
+        (WebInspector.Breakpoint.prototype._editBreakpointPopoverContentElement): Deleted.
+        (WebInspector.Breakpoint.prototype._popoverActionsCreateAddActionButton): Deleted.
+        (WebInspector.Breakpoint.prototype._popoverActionsAddActionButtonClicked): Deleted.
+        (WebInspector.Breakpoint.prototype._popoverActionsInsertBreakpointActionView): Deleted.
+        (WebInspector.Breakpoint.prototype.breakpointActionViewAppendActionView): Deleted.
+        (WebInspector.Breakpoint.prototype.breakpointActionViewRemoveActionView): Deleted.
+        (WebInspector.Breakpoint.prototype.breakpointActionViewResized): Deleted.
+        (WebInspector.Breakpoint.prototype.willDismissPopover): Deleted.
+        (WebInspector.Breakpoint.prototype.didDismissPopover): Deleted.
+        (WebInspector.Breakpoint.prototype._showEditBreakpointPopover): Deleted.
+        Removed view logic.
+
+        * UserInterface/Views/BreakpointPopoverController.css: Renamed from Source/WebInspectorUI/UserInterface/Views/Breakpoint.css.
+        (.popover .edit-breakpoint-popover-content):
+        (.popover .edit-breakpoint-popover-content.wide):
+        (.popover .edit-breakpoint-popover-content > label.toggle):
+        (.popover .edit-breakpoint-popover-content > table):
+        (.popover .edit-breakpoint-popover-content > table > tr > th):
+        (.popover .edit-breakpoint-popover-content > table > tr > td):
+        (#edit-breakpoint-popover-condition):
+        (#edit-breakpoint-popoover-auto-continue):
+
+        * UserInterface/Views/SourceCodeTextEditor.js:
+        (WebInspector.SourceCodeTextEditor):
+        Creates a BreakpointPopoverController instance. The lifetime of the 'Edit Breakpoint' view is internal to the
+        controller, and can't be initiated outside of a context menu item click.
+
+2015-08-31  Matt Baker  <mattbaker@apple.com>
+
         Web Inspector: Rendering Frame tasks making up < 1% of the selection don't appear in the pie chart
         https://bugs.webkit.org/show_bug.cgi?id=148549
 
diff --git a/Source/WebInspectorUI/UserInterface/Controllers/BreakpointPopoverController.js b/Source/WebInspectorUI/UserInterface/Controllers/BreakpointPopoverController.js
new file mode 100644 (file)
index 0000000..e3b8f7f
--- /dev/null
@@ -0,0 +1,305 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.BreakpointPopoverController = class BreakpointPopoverController extends WebInspector.Object
+{
+    constructor()
+    {
+        super();
+
+        this._breakpoint = null;
+        this._popover = null;
+        this._popoverContentElement = null;
+        this._keyboardShortcutEsc = new WebInspector.KeyboardShortcut(null, WebInspector.KeyboardShortcut.Key.Escape);
+        this._keyboardShortcutEnter = new WebInspector.KeyboardShortcut(null, WebInspector.KeyboardShortcut.Key.Enter);
+    }
+
+    // Public
+
+    appendContextMenuItems(contextMenu, breakpoint, breakpointDisplayElement)
+    {
+        console.assert(document.body.contains(breakpointDisplayElement), "Breakpoint popover display element must be in the DOM.");
+
+        function editBreakpoint()
+        {
+            console.assert(!this._popover, "Breakpoint popover already exists.");
+            if (this._popover)
+                return;
+
+            this._createPopoverContent(breakpoint);
+            this._popover = new WebInspector.Popover(this);
+            this._popover.content = this._popoverContentElement;
+
+            let bounds = WebInspector.Rect.rectFromClientRect(breakpointDisplayElement.getBoundingClientRect());
+            bounds.origin.x -= 1; // Move the anchor left one pixel so it looks more centered.
+            this._popover.present(bounds.pad(2), [WebInspector.RectEdge.MAX_Y]);
+
+            document.getElementById(WebInspector.BreakpointPopoverController.PopoverConditionInputId).select();
+        }
+
+        function removeBreakpoint()
+        {
+            WebInspector.debuggerManager.removeBreakpoint(breakpoint);
+        }
+
+        function toggleBreakpoint()
+        {
+            breakpoint.disabled = !breakpoint.disabled;
+        }
+
+        function toggleAutoContinue()
+        {
+            breakpoint.autoContinue = !breakpoint.autoContinue;
+        }
+
+        function revealOriginalSourceCodeLocation()
+        {
+            WebInspector.showOriginalOrFormattedSourceCodeLocation(breakpoint.sourceCodeLocation);
+        }
+
+        if (WebInspector.debuggerManager.isBreakpointEditable(breakpoint))
+            contextMenu.appendItem(WebInspector.UIString("Edit Breakpoint…"), editBreakpoint.bind(this));
+
+        if (breakpoint.autoContinue && !breakpoint.disabled) {
+            contextMenu.appendItem(WebInspector.UIString("Disable Breakpoint"), toggleBreakpoint.bind(this));
+            contextMenu.appendItem(WebInspector.UIString("Cancel Automatic Continue"), toggleAutoContinue.bind(this));
+        } else if (!breakpoint.disabled)
+            contextMenu.appendItem(WebInspector.UIString("Disable Breakpoint"), toggleBreakpoint.bind(this));
+        else
+            contextMenu.appendItem(WebInspector.UIString("Enable Breakpoint"), toggleBreakpoint.bind(this));
+
+        if (!breakpoint.autoContinue && !breakpoint.disabled && breakpoint.actions.length)
+            contextMenu.appendItem(WebInspector.UIString("Set to Automatically Continue"), toggleAutoContinue.bind(this));
+
+        if (WebInspector.debuggerManager.isBreakpointRemovable(breakpoint)) {
+            contextMenu.appendSeparator();
+            contextMenu.appendItem(WebInspector.UIString("Delete Breakpoint"), removeBreakpoint.bind(this));
+        }
+
+        if (breakpoint._sourceCodeLocation.hasMappedLocation()) {
+            contextMenu.appendSeparator();
+            contextMenu.appendItem(WebInspector.UIString("Reveal in Original Resource"), revealOriginalSourceCodeLocation.bind(this));
+        }
+    }
+
+    // Private
+
+    _createPopoverContent(breakpoint)
+    {
+        console.assert(!this._popoverContentElement, "Popover content element already exists.");
+        if (this._popoverContentElement)
+            return;
+
+        this._breakpoint = breakpoint;
+        this._popoverContentElement = document.createElement("div");
+        this._popoverContentElement.className = "edit-breakpoint-popover-content";
+
+        let checkboxElement = document.createElement("input");
+        checkboxElement.type = "checkbox";
+        checkboxElement.checked = !this._breakpoint.disabled;
+        checkboxElement.addEventListener("change", this._popoverToggleEnabledCheckboxChanged.bind(this));
+
+        let checkboxLabel = document.createElement("label");
+        checkboxLabel.className = "toggle";
+        checkboxLabel.appendChild(checkboxElement);
+        checkboxLabel.append(this._breakpoint.sourceCodeLocation.displayLocationString());
+
+        let table = document.createElement("table");
+
+        let conditionRow = table.appendChild(document.createElement("tr"));
+        let conditionHeader = conditionRow.appendChild(document.createElement("th"));
+        let conditionData = conditionRow.appendChild(document.createElement("td"));
+        let conditionLabel = conditionHeader.appendChild(document.createElement("label"));
+        let conditionInput = conditionData.appendChild(document.createElement("input"));
+        conditionInput.id = WebInspector.BreakpointPopoverController.PopoverConditionInputId;
+        conditionInput.value = this._breakpoint.condition || "";
+        conditionInput.spellcheck = false;
+        conditionInput.addEventListener("change", this._popoverConditionInputChanged.bind(this));
+        conditionInput.addEventListener("keydown", this._popoverConditionInputKeyDown.bind(this));
+        conditionInput.placeholder = WebInspector.UIString("Conditional expression");
+        conditionLabel.setAttribute("for", conditionInput.id);
+        conditionLabel.textContent = WebInspector.UIString("Condition");
+
+        // COMPATIBILITY (iOS 7): Debugger.setBreakpoint did not support options.
+        if (DebuggerAgent.setBreakpoint.supports("options")) {
+            let actionRow = table.appendChild(document.createElement("tr"));
+            let actionHeader = actionRow.appendChild(document.createElement("th"));
+            let actionData = this._actionsContainer = actionRow.appendChild(document.createElement("td"));
+            let actionLabel = actionHeader.appendChild(document.createElement("label"));
+            actionLabel.textContent = WebInspector.UIString("Action");
+
+            if (!this._breakpoint.actions.length)
+                this._popoverActionsCreateAddActionButton();
+            else {
+                this._popoverContentElement.classList.add(WebInspector.BreakpointPopoverController.WidePopoverClassName);
+                for (let i = 0; i < this._breakpoint.actions.length; ++i) {
+                    let breakpointActionView = new WebInspector.BreakpointActionView(this._breakpoint.actions[i], this, true);
+                    this._popoverActionsInsertBreakpointActionView(breakpointActionView, i);
+                }
+            }
+
+            let optionsRow = this._popoverOptionsRowElement = table.appendChild(document.createElement("tr"));
+            if (!this._breakpoint.actions.length)
+                optionsRow.classList.add(WebInspector.BreakpointPopoverController.HiddenStyleClassName);
+            let optionsHeader = optionsRow.appendChild(document.createElement("th"));
+            let optionsData = optionsRow.appendChild(document.createElement("td"));
+            let optionsLabel = optionsHeader.appendChild(document.createElement("label"));
+            let optionsCheckbox = this._popoverOptionsCheckboxElement = optionsData.appendChild(document.createElement("input"));
+            let optionsCheckboxLabel = optionsData.appendChild(document.createElement("label"));
+            optionsCheckbox.id = "edit-breakpoint-popoover-auto-continue";
+            optionsCheckbox.type = "checkbox";
+            optionsCheckbox.checked = this._breakpoint.autoContinue;
+            optionsCheckbox.addEventListener("change", this._popoverToggleAutoContinueCheckboxChanged.bind(this));
+            optionsLabel.textContent = WebInspector.UIString("Options");
+            optionsCheckboxLabel.setAttribute("for", optionsCheckbox.id);
+            optionsCheckboxLabel.textContent = WebInspector.UIString("Automatically continue after evaluating");
+        }
+
+        this._popoverContentElement.appendChild(checkboxLabel);
+        this._popoverContentElement.appendChild(table);
+    }
+
+    _popoverToggleEnabledCheckboxChanged(event)
+    {
+        this._breakpoint.disabled = !event.target.checked;
+    }
+
+    _popoverConditionInputChanged(event)
+    {
+        this._breakpoint.condition = event.target.value;
+    }
+
+    _popoverToggleAutoContinueCheckboxChanged(event)
+    {
+        this._breakpoint.autoContinue = event.target.checked;
+    }
+
+    _popoverConditionInputKeyDown(event)
+    {
+        if (this._keyboardShortcutEsc.matchesEvent(event) || this._keyboardShortcutEnter.matchesEvent(event)) {
+            this._popover.dismiss();
+            event.stopPropagation();
+            event.preventDefault();
+        }
+    }
+
+    _popoverActionsCreateAddActionButton()
+    {
+        this._popoverContentElement.classList.remove(WebInspector.BreakpointPopoverController.WidePopoverClassName);
+        this._actionsContainer.removeChildren();
+
+        let addActionButton = this._actionsContainer.appendChild(document.createElement("button"));
+        addActionButton.textContent = WebInspector.UIString("Add Action");
+        addActionButton.addEventListener("click", this._popoverActionsAddActionButtonClicked.bind(this));
+    }
+
+    _popoverActionsAddActionButtonClicked(event)
+    {
+        this._popoverContentElement.classList.add(WebInspector.BreakpointPopoverController.WidePopoverClassName);
+        this._actionsContainer.removeChildren();
+
+        let newAction = this._breakpoint.createAction(WebInspector.Breakpoint.DefaultBreakpointActionType);
+        let newBreakpointActionView = new WebInspector.BreakpointActionView(newAction, this);
+        this._popoverActionsInsertBreakpointActionView(newBreakpointActionView, -1);
+        this._popoverOptionsRowElement.classList.remove(WebInspector.BreakpointPopoverController.HiddenStyleClassName);
+        this._popover.update();
+    }
+
+    _popoverActionsInsertBreakpointActionView(breakpointActionView, index)
+    {
+        if (index === -1)
+            this._actionsContainer.appendChild(breakpointActionView.element);
+        else {
+            let nextElement = this._actionsContainer.children[index + 1] || null;
+            this._actionsContainer.insertBefore(breakpointActionView.element, nextElement);
+        }
+    }
+
+    breakpointActionViewAppendActionView(breakpointActionView, newAction)
+    {
+        let newBreakpointActionView = new WebInspector.BreakpointActionView(newAction, this);
+
+        let index = 0;
+        let children = this._actionsContainer.children;
+        for (let i = 0; children.length; ++i) {
+            if (children[i] === breakpointActionView.element) {
+                index = i;
+                break;
+            }
+        }
+
+        this._popoverActionsInsertBreakpointActionView(newBreakpointActionView, index);
+        this._popoverOptionsRowElement.classList.remove(WebInspector.BreakpointPopoverController.HiddenStyleClassName);
+
+        this._popover.update();
+    }
+
+    breakpointActionViewRemoveActionView(breakpointActionView)
+    {
+        breakpointActionView.element.remove();
+
+        if (!this._actionsContainer.children.length) {
+            this._popoverActionsCreateAddActionButton();
+            this._popoverOptionsRowElement.classList.add(WebInspector.BreakpointPopoverController.HiddenStyleClassName);
+            this._popoverOptionsCheckboxElement.checked = false;
+        }
+
+        this._popover.update();
+    }
+
+    breakpointActionViewResized(breakpointActionView)
+    {
+        this._popover.update();
+    }
+
+    willDismissPopover(popover)
+    {
+        console.assert(this._popover === popover);
+        this._popoverContentElement = null;
+        this._popoverOptionsRowElement = null;
+        this._popoverOptionsCheckboxElement = null;
+        this._actionsContainer = null;
+        this._popover = null;
+    }
+
+    didDismissPopover(popover)
+    {
+        // Remove Evaluate and Probe actions that have no data.
+        let emptyActions = this._breakpoint.actions.filter(function(action) {
+            if (action.type !== WebInspector.BreakpointAction.Type.Evaluate && action.type !== WebInspector.BreakpointAction.Type.Probe)
+                return false;
+            return !(action.data && action.data.trim());
+        });
+
+        for (let action of emptyActions)
+            this._breakpoint.removeAction(action);
+
+        this._breakpoint = null;
+    }
+};
+
+WebInspector.BreakpointPopoverController.WidePopoverClassName = "wide";
+WebInspector.BreakpointPopoverController.PopoverConditionInputId = "edit-breakpoint-popover-condition";
+WebInspector.BreakpointPopoverController.HiddenStyleClassName = "hidden";
index 0b0dc00..b0b4b59 100644 (file)
@@ -34,8 +34,8 @@
     <link rel="stylesheet" href="Views/ApplicationCacheIcons.css">
     <link rel="stylesheet" href="Views/BezierEditor.css">
     <link rel="stylesheet" href="Views/BoxModelDetailsSectionRow.css">
-    <link rel="stylesheet" href="Views/Breakpoint.css">
     <link rel="stylesheet" href="Views/BreakpointActionView.css">
+    <link rel="stylesheet" href="Views/BreakpointPopoverController.css">
     <link rel="stylesheet" href="Views/BreakpointTreeElement.css">
     <link rel="stylesheet" href="Views/ButtonNavigationItem.css">
     <link rel="stylesheet" href="Views/ButtonToolbarItem.css">
     <script src="Controllers/ApplicationCacheManager.js"></script>
     <script src="Controllers/BasicBlockAnnotator.js"></script>
     <script src="Controllers/BranchManager.js"></script>
+    <script src="Controllers/BreakpointPopoverController.js"></script>
     <script src="Controllers/CSSStyleManager.js"></script>
     <script src="Controllers/CodeMirrorColorEditingController.js"></script>
     <script src="Controllers/CodeMirrorCompletionController.js"></script>
index 0cdf3e4..d518f71 100644 (file)
@@ -213,62 +213,6 @@ WebInspector.Breakpoint = class Breakpoint extends WebInspector.Object
         this.disabled = true;
     }
 
-    appendContextMenuItems(contextMenu, breakpointDisplayElement)
-    {
-        console.assert(document.body.contains(breakpointDisplayElement), "breakpoint popover display element must be in the DOM");
-
-        var boundingClientRect = breakpointDisplayElement.getBoundingClientRect();
-
-        function editBreakpoint()
-        {
-            this._showEditBreakpointPopover(boundingClientRect);
-        }
-
-        function removeBreakpoint()
-        {
-            WebInspector.debuggerManager.removeBreakpoint(this);
-        }
-
-        function toggleBreakpoint()
-        {
-            this.disabled = !this.disabled;
-        }
-
-        function toggleAutoContinue()
-        {
-            this.autoContinue = !this.autoContinue;
-        }
-
-        function revealOriginalSourceCodeLocation()
-        {
-            WebInspector.showOriginalOrFormattedSourceCodeLocation(this._sourceCodeLocation);
-        }
-
-        if (WebInspector.debuggerManager.isBreakpointEditable(this))
-            contextMenu.appendItem(WebInspector.UIString("Edit Breakpoint…"), editBreakpoint.bind(this));
-
-        if (this.autoContinue && !this.disabled) {
-            contextMenu.appendItem(WebInspector.UIString("Disable Breakpoint"), toggleBreakpoint.bind(this));
-            contextMenu.appendItem(WebInspector.UIString("Cancel Automatic Continue"), toggleAutoContinue.bind(this));
-        } else if (!this.disabled)
-            contextMenu.appendItem(WebInspector.UIString("Disable Breakpoint"), toggleBreakpoint.bind(this));
-        else
-            contextMenu.appendItem(WebInspector.UIString("Enable Breakpoint"), toggleBreakpoint.bind(this));
-
-        if (!this.autoContinue && !this.disabled && this.actions.length)
-            contextMenu.appendItem(WebInspector.UIString("Set to Automatically Continue"), toggleAutoContinue.bind(this));
-
-        if (WebInspector.debuggerManager.isBreakpointRemovable(this)) {
-            contextMenu.appendSeparator();
-            contextMenu.appendItem(WebInspector.UIString("Delete Breakpoint"), removeBreakpoint.bind(this));
-        }
-
-        if (this._sourceCodeLocation.hasMappedLocation()) {
-            contextMenu.appendSeparator();
-            contextMenu.appendItem(WebInspector.UIString("Reveal in Original Resource"), revealOriginalSourceCodeLocation.bind(this));
-        }
-    }
-
     createAction(type, precedingAction, data)
     {
         var newAction = new WebInspector.BreakpointAction(this, type, data || null);
@@ -359,211 +303,6 @@ WebInspector.Breakpoint = class Breakpoint extends WebInspector.Object
         return actions;
     }
 
-    _popoverToggleEnabledCheckboxChanged(event)
-    {
-        this.disabled = !event.target.checked;
-    }
-
-    _popoverConditionInputChanged(event)
-    {
-        this.condition = event.target.value;
-    }
-
-    _popoverToggleAutoContinueCheckboxChanged(event)
-    {
-        this.autoContinue = event.target.checked;
-    }
-
-    _popoverConditionInputKeyDown(event)
-    {
-        if (this._keyboardShortcutEsc.matchesEvent(event) || this._keyboardShortcutEnter.matchesEvent(event)) {
-            this._popover.dismiss();
-            event.stopPropagation();
-            event.preventDefault();
-        }
-    }
-
-    _editBreakpointPopoverContentElement()
-    {
-        var content = this._popoverContentElement = document.createElement("div");
-        content.className = WebInspector.Breakpoint.PopoverClassName;
-
-        var checkboxElement = document.createElement("input");
-        checkboxElement.type = "checkbox";
-        checkboxElement.checked = !this._disabled;
-        checkboxElement.addEventListener("change", this._popoverToggleEnabledCheckboxChanged.bind(this));
-
-        var checkboxLabel = document.createElement("label");
-        checkboxLabel.className = "toggle";
-        checkboxLabel.appendChild(checkboxElement);
-        checkboxLabel.append(this._sourceCodeLocation.displayLocationString());
-
-        var table = document.createElement("table");
-
-        var conditionRow = table.appendChild(document.createElement("tr"));
-        var conditionHeader = conditionRow.appendChild(document.createElement("th"));
-        var conditionData = conditionRow.appendChild(document.createElement("td"));
-        var conditionLabel = conditionHeader.appendChild(document.createElement("label"));
-        var conditionInput = conditionData.appendChild(document.createElement("input"));
-        conditionInput.id = WebInspector.Breakpoint.PopoverConditionInputId;
-        conditionInput.value = this._condition || "";
-        conditionInput.spellcheck = false;
-        conditionInput.addEventListener("change", this._popoverConditionInputChanged.bind(this));
-        conditionInput.addEventListener("keydown", this._popoverConditionInputKeyDown.bind(this));
-        conditionInput.placeholder = WebInspector.UIString("Conditional expression");
-        conditionLabel.setAttribute("for", conditionInput.id);
-        conditionLabel.textContent = WebInspector.UIString("Condition");
-
-        // COMPATIBILITY (iOS 7): Debugger.setBreakpoint did not support options.
-        if (DebuggerAgent.setBreakpoint.supports("options")) {
-            var actionRow = table.appendChild(document.createElement("tr"));
-            var actionHeader = actionRow.appendChild(document.createElement("th"));
-            var actionData = this._actionsContainer = actionRow.appendChild(document.createElement("td"));
-            var actionLabel = actionHeader.appendChild(document.createElement("label"));
-            actionLabel.textContent = WebInspector.UIString("Action");
-
-            if (!this._actions.length)
-                this._popoverActionsCreateAddActionButton();
-            else {
-                this._popoverContentElement.classList.add(WebInspector.Breakpoint.WidePopoverClassName);
-                for (var i = 0; i < this._actions.length; ++i) {
-                    var breakpointActionView = new WebInspector.BreakpointActionView(this._actions[i], this, true);
-                    this._popoverActionsInsertBreakpointActionView(breakpointActionView, i);
-                }
-            }
-
-            var optionsRow = this._popoverOptionsRowElement = table.appendChild(document.createElement("tr"));
-            if (!this._actions.length)
-                optionsRow.classList.add(WebInspector.Breakpoint.HiddenStyleClassName);
-            var optionsHeader = optionsRow.appendChild(document.createElement("th"));
-            var optionsData = optionsRow.appendChild(document.createElement("td"));
-            var optionsLabel = optionsHeader.appendChild(document.createElement("label"));
-            var optionsCheckbox = this._popoverOptionsCheckboxElement = optionsData.appendChild(document.createElement("input"));
-            var optionsCheckboxLabel = optionsData.appendChild(document.createElement("label"));
-            optionsCheckbox.id = WebInspector.Breakpoint.PopoverOptionsAutoContinueInputId;
-            optionsCheckbox.type = "checkbox";
-            optionsCheckbox.checked = this._autoContinue;
-            optionsCheckbox.addEventListener("change", this._popoverToggleAutoContinueCheckboxChanged.bind(this));
-            optionsLabel.textContent = WebInspector.UIString("Options");
-            optionsCheckboxLabel.setAttribute("for", optionsCheckbox.id);
-            optionsCheckboxLabel.textContent = WebInspector.UIString("Automatically continue after evaluating");
-        }
-
-        content.appendChild(checkboxLabel);
-        content.appendChild(table);
-
-        return content;
-    }
-
-    _popoverActionsCreateAddActionButton()
-    {
-        this._popoverContentElement.classList.remove(WebInspector.Breakpoint.WidePopoverClassName);
-        this._actionsContainer.removeChildren();
-
-        var addActionButton = this._actionsContainer.appendChild(document.createElement("button"));
-        addActionButton.textContent = WebInspector.UIString("Add Action");
-        addActionButton.addEventListener("click", this._popoverActionsAddActionButtonClicked.bind(this));
-    }
-
-    _popoverActionsAddActionButtonClicked(event)
-    {
-        this._popoverContentElement.classList.add(WebInspector.Breakpoint.WidePopoverClassName);
-        this._actionsContainer.removeChildren();
-
-        var newAction = this.createAction(WebInspector.Breakpoint.DefaultBreakpointActionType);
-        var newBreakpointActionView = new WebInspector.BreakpointActionView(newAction, this);
-        this._popoverActionsInsertBreakpointActionView(newBreakpointActionView, -1);
-        this._popoverOptionsRowElement.classList.remove(WebInspector.Breakpoint.HiddenStyleClassName);
-        this._popover.update();
-    }
-
-    _popoverActionsInsertBreakpointActionView(breakpointActionView, index)
-    {
-        if (index === -1)
-            this._actionsContainer.appendChild(breakpointActionView.element);
-        else {
-            var nextElement = this._actionsContainer.children[index + 1] || null;
-            this._actionsContainer.insertBefore(breakpointActionView.element, nextElement);
-        }
-    }
-
-    breakpointActionViewAppendActionView(breakpointActionView, newAction)
-    {
-        var newBreakpointActionView = new WebInspector.BreakpointActionView(newAction, this);
-
-        var index = 0;
-        var children = this._actionsContainer.children;
-        for (var i = 0; children.length; ++i) {
-            if (children[i] === breakpointActionView.element) {
-                index = i;
-                break;
-            }
-        }
-
-        this._popoverActionsInsertBreakpointActionView(newBreakpointActionView, index);
-        this._popoverOptionsRowElement.classList.remove(WebInspector.Breakpoint.HiddenStyleClassName);
-
-        this._popover.update();
-    }
-
-    breakpointActionViewRemoveActionView(breakpointActionView)
-    {
-        breakpointActionView.element.remove();
-
-        if (!this._actionsContainer.children.length) {
-            this._popoverActionsCreateAddActionButton();
-            this._popoverOptionsRowElement.classList.add(WebInspector.Breakpoint.HiddenStyleClassName);
-            this._popoverOptionsCheckboxElement.checked = false;
-        }
-
-        this._popover.update();
-    }
-
-    breakpointActionViewResized(breakpointActionView)
-    {
-        this._popover.update();
-    }
-
-    willDismissPopover(popover)
-    {
-        console.assert(this._popover === popover);
-        delete this._popoverContentElement;
-        delete this._popoverOptionsRowElement;
-        delete this._popoverOptionsCheckboxElement;
-        delete this._actionsContainer;
-        delete this._popover;
-    }
-
-    didDismissPopover(popover)
-    {
-        // Remove Evaluate and Probe actions that have no data.
-        var emptyActions = this._actions.filter(function(action) {
-            if (action.type !== WebInspector.BreakpointAction.Type.Evaluate && action.type !== WebInspector.BreakpointAction.Type.Probe)
-                return false;
-            return !(action.data && action.data.trim());
-        });
-
-        for (var action of emptyActions)
-            this.removeAction(action);
-    }
-
-    _showEditBreakpointPopover(boundingClientRect)
-    {
-        var bounds = WebInspector.Rect.rectFromClientRect(boundingClientRect);
-        bounds.origin.x -= 1; // Move the anchor left one pixel so it looks more centered.
-
-        this._popover = this._popover || new WebInspector.Popover(this);
-        this._popover.content = this._editBreakpointPopoverContentElement();
-        this._popover.present(bounds.pad(2), [WebInspector.RectEdge.MAX_Y]);
-
-        if (!this._keyboardShortcutEsc) {
-            this._keyboardShortcutEsc = new WebInspector.KeyboardShortcut(null, WebInspector.KeyboardShortcut.Key.Escape);
-            this._keyboardShortcutEnter = new WebInspector.KeyboardShortcut(null, WebInspector.KeyboardShortcut.Key.Enter);
-        }
-
-        document.getElementById(WebInspector.Breakpoint.PopoverConditionInputId).select();
-    }
-
     _sourceCodeLocationLocationChanged(event)
     {
         this.dispatchEventToListeners(WebInspector.Breakpoint.Event.LocationDidChange, event.data);
@@ -575,12 +314,6 @@ WebInspector.Breakpoint = class Breakpoint extends WebInspector.Object
     }
 };
 
-WebInspector.Breakpoint.PopoverClassName = "edit-breakpoint-popover-content";
-WebInspector.Breakpoint.WidePopoverClassName = "wide";
-WebInspector.Breakpoint.PopoverConditionInputId = "edit-breakpoint-popover-condition";
-WebInspector.Breakpoint.PopoverOptionsAutoContinueInputId = "edit-breakpoint-popoover-auto-continue";
-WebInspector.Breakpoint.HiddenStyleClassName = "hidden";
-
 WebInspector.Breakpoint.DefaultBreakpointActionType = WebInspector.BreakpointAction.Type.Log;
 
 WebInspector.Breakpoint.TypeIdentifier = "breakpoint";
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
index cf4dd92..3cc784a 100644 (file)
@@ -47,6 +47,8 @@ WebInspector.SourceCodeTextEditor = class SourceCodeTextEditor extends WebInspec
 
         this._isProbablyMinified = false;
 
+        this._breakpointPopoverController = new WebInspector.BreakpointPopoverController;
+
         // FIXME: Currently this just jumps between resources and related source map resources. It doesn't "jump to symbol" yet.
         this._updateTokenTrackingControllerState();
 
@@ -1023,9 +1025,7 @@ WebInspector.SourceCodeTextEditor = class SourceCodeTextEditor extends WebInspec
 
         // Single breakpoint.
         if (breakpoints.length === 1) {
-            var breakpoint = breakpoints[0];
-
-            breakpoint.appendContextMenuItems(contextMenu, event.target);
+            this._breakpointPopoverController.appendContextMenuItems(contextMenu, breakpoints[0], event.target);
 
             if (!WebInspector.isShowingDebuggerTab()) {
                 contextMenu.appendSeparator();