diff options
Diffstat (limited to 'Source/WebInspectorUI/UserInterface/NavigationBar.js')
-rw-r--r-- | Source/WebInspectorUI/UserInterface/NavigationBar.js | 451 |
1 files changed, 0 insertions, 451 deletions
diff --git a/Source/WebInspectorUI/UserInterface/NavigationBar.js b/Source/WebInspectorUI/UserInterface/NavigationBar.js deleted file mode 100644 index c12a7e521..000000000 --- a/Source/WebInspectorUI/UserInterface/NavigationBar.js +++ /dev/null @@ -1,451 +0,0 @@ -/* - * Copyright (C) 2013 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.NavigationBar = function(element, navigationItems, role, label) { - WebInspector.Object.call(this); - - this._element = element || document.createElement("div"); - this._element.classList.add(this.constructor.StyleClassName || WebInspector.NavigationBar.StyleClassName); - this._element.tabIndex = 0; - - if (role) - this._element.setAttribute("role", role); - if (label) - this._element.setAttribute("aria-label", label); - - this._element.addEventListener("focus", this._focus.bind(this), false); - this._element.addEventListener("blur", this._blur.bind(this), false); - this._element.addEventListener("keydown", this._keyDown.bind(this), false); - this._element.addEventListener("mousedown", this._mouseDown.bind(this), false); - - document.addEventListener("load", this.updateLayout.bind(this), false); - - this._styleElement = document.createElement("style"); - - this._navigationItems = []; - - if (navigationItems) { - for (var i = 0; i < navigationItems.length; ++i) - this.addNavigationItem(navigationItems[i]); - } - - document.head.appendChild(this._styleElement); -}; - -WebInspector.Object.addConstructorFunctions(WebInspector.NavigationBar); - -WebInspector.NavigationBar.StyleClassName = "navigation-bar"; -WebInspector.NavigationBar.CollapsedStyleClassName = "collapsed"; - -WebInspector.NavigationBar.Event = { - NavigationItemSelected: "navigation-bar-navigation-item-selected" -}; - -WebInspector.NavigationBar.prototype = { - constructor: WebInspector.NavigationBar, - - // Public - - addNavigationItem: function(navigationItem, parentElement) - { - return this.insertNavigationItem(navigationItem, this._navigationItems.length, parentElement); - }, - - insertNavigationItem: function(navigationItem, index, parentElement) - { - console.assert(navigationItem instanceof WebInspector.NavigationItem); - if (!(navigationItem instanceof WebInspector.NavigationItem)) - return; - - if (navigationItem.parentNavigationBar) - navigationItem.parentNavigationBar.removeNavigationItem(navigationItem); - - navigationItem._parentNavigationBar = this; - - console.assert(index >= 0 && index <= this._navigationItems.length); - index = Math.max(0, Math.min(index, this._navigationItems.length)); - - this._navigationItems.splice(index, 0, navigationItem); - - if (!parentElement) - parentElement = this._element; - - var nextSibling = this._navigationItems[index + 1]; - var nextSiblingElement = nextSibling ? nextSibling.element : null; - if (nextSiblingElement && nextSiblingElement.parentNode !== parentElement) - nextSiblingElement = null; - - parentElement.insertBefore(navigationItem.element, nextSiblingElement); - - this._minimumWidthNeedsRecalculation = true; - this._needsStyleUpdated = true; - - this.updateLayoutSoon(); - - return navigationItem; - }, - - removeNavigationItem: function(navigationItemOrIdentifierOrIndex, index) - { - var navigationItem = this._findNavigationItem(navigationItemOrIdentifierOrIndex); - if (!navigationItem) - return; - - navigationItem._parentNavigationBar = null; - - if (this._selectedNavigationItem === navigationItem) - this.selectedNavigationItem = null; - - this._navigationItems.remove(navigationItem); - navigationItem.element.remove(); - - this._minimumWidthNeedsRecalculation = true; - this._needsStyleUpdated = true; - - this.updateLayoutSoon(); - - return navigationItem; - }, - - updateLayoutSoon: function() - { - if (this._updateLayoutTimeout) - return; - - this._needsLayout = true; - - function update() - { - delete this._updateLayoutTimeout; - - if (this._needsLayout || this._needsStyleUpdated) - this.updateLayout(); - } - - this._updateLayoutTimeout = setTimeout(update.bind(this), 0); - }, - - updateLayout: function() - { - if (this._updateLayoutTimeout) { - clearTimeout(this._updateLayoutTimeout); - delete this._updateLayoutTimeout; - } - - if (this._needsStyleUpdated) - this._updateStyle(); - - this._needsLayout = false; - - if (typeof this.customUpdateLayout === "function") { - this.customUpdateLayout(); - return; - } - - // Remove the collapsed style class to test if the items can fit at full width. - this._element.classList.remove(WebInspector.NavigationBar.CollapsedStyleClassName); - - // Tell each navigation item to update to full width if needed. - for (var i = 0; i < this._navigationItems.length; ++i) - this._navigationItems[i].updateLayout(true); - - var totalItemWidth = 0; - for (var i = 0; i < this._navigationItems.length; ++i) { - // Skip flexible space items since they can take up no space at the minimum width. - if (this._navigationItems[i] instanceof WebInspector.FlexibleSpaceNavigationItem) - continue; - - totalItemWidth += this._navigationItems[i].element.offsetWidth; - } - - var barWidth = this._element.offsetWidth; - - // Add the collapsed class back if the items are wider than the bar. - if (totalItemWidth > barWidth) - this._element.classList.add(WebInspector.NavigationBar.CollapsedStyleClassName); - - // Give each navigation item the opportunity to collapse further. - for (var i = 0; i < this._navigationItems.length; ++i) - this._navigationItems[i].updateLayout(); - }, - - get selectedNavigationItem() - { - return this._selectedNavigationItem || null; - }, - - set selectedNavigationItem(navigationItemOrIdentifierOrIndex) - { - var navigationItem = this._findNavigationItem(navigationItemOrIdentifierOrIndex); - - // Only radio navigation items can be selected. - if (!(navigationItem instanceof WebInspector.RadioButtonNavigationItem)) - navigationItem = null; - - if (this._selectedNavigationItem === navigationItem) - return; - - if (this._selectedNavigationItem) - this._selectedNavigationItem.selected = false; - - this._selectedNavigationItem = navigationItem || null; - - if (this._selectedNavigationItem) - this._selectedNavigationItem.selected = true; - - // When the mouse is down don't dispatch the selected event, it will be dispatched on mouse up. - // This prevents sending the event while the user is scrubbing the bar. - if (!this._mouseIsDown) - this.dispatchEventToListeners(WebInspector.NavigationBar.Event.NavigationItemSelected); - }, - - get navigationItems() - { - return this._navigationItems; - }, - - get element() - { - return this._element; - }, - - get minimumWidth() - { - if (typeof this._minimumWidth === "undefined" || this._minimumWidthNeedsRecalculation) { - this._minimumWidth = this._calculateMinimumWidth(); - delete this._minimumWidthNeedsRecalculation; - } - - return this._minimumWidth; - }, - - get sizesToFit() - { - // Can be overriden by subclasses. - return false; - }, - - // Private - - _findNavigationItem: function(navigationItemOrIdentifierOrIndex) - { - var navigationItem = null; - - if (navigationItemOrIdentifierOrIndex instanceof WebInspector.NavigationItem) { - if (this._navigationItems.contains(navigationItemOrIdentifierOrIndex)) - navigationItem = navigationItemOrIdentifierOrIndex; - } else if (typeof navigationItemOrIdentifierOrIndex === "number") { - navigationItem = this._navigationItems[navigationItemOrIdentifierOrIndex]; - } else if (typeof navigationItemOrIdentifierOrIndex === "string") { - for (var i = 0; i < this._navigationItems.length; ++i) { - if (this._navigationItems[i].identifier === navigationItemOrIdentifierOrIndex) { - navigationItem = this._navigationItems[i]; - break; - } - } - } - - return navigationItem; - }, - - _mouseDown: function(event) - { - // Only handle left mouse clicks. - if (event.button !== 0) - return; - - // Remove the tabIndex so clicking the navigation bar does not give it focus. - // Only keep the tabIndex if already focused from keyboard navigation. This matches Xcode. - if (!this._focused) - this._element.removeAttribute("tabindex"); - - var itemElement = event.target.enclosingNodeOrSelfWithClass(WebInspector.RadioButtonNavigationItem.StyleClassName); - if (!itemElement || !itemElement.navigationItem) - return; - - this._previousSelectedNavigationItem = this.selectedNavigationItem; - this.selectedNavigationItem = itemElement.navigationItem; - - this._mouseIsDown = true; - - this._mouseMovedEventListener = this._mouseMoved.bind(this); - this._mouseUpEventListener = this._mouseUp.bind(this); - - // Register these listeners on the document so we can track the mouse if it leaves the resizer. - document.addEventListener("mousemove", this._mouseMovedEventListener, false); - document.addEventListener("mouseup", this._mouseUpEventListener, false); - - event.preventDefault(); - event.stopPropagation(); - }, - - _mouseMoved: function(event) - { - console.assert(event.button === 0); - console.assert(this._mouseIsDown); - if (!this._mouseIsDown) - return; - - event.preventDefault(); - event.stopPropagation(); - - var itemElement = event.target.enclosingNodeOrSelfWithClass(WebInspector.RadioButtonNavigationItem.StyleClassName); - if (!itemElement || !itemElement.navigationItem) { - // Find the element that is at the X position of the mouse, even when the mouse is no longer - // vertically in the navigation bar. - var element = document.elementFromPoint(event.pageX, this._element.totalOffsetTop); - if (!element) - return; - - itemElement = element.enclosingNodeOrSelfWithClass(WebInspector.RadioButtonNavigationItem.StyleClassName); - if (!itemElement || !itemElement.navigationItem) - return; - } - - if (this.selectedNavigationItem) - this.selectedNavigationItem.active = false; - - this.selectedNavigationItem = itemElement.navigationItem; - - this.selectedNavigationItem.active = true; - }, - - _mouseUp: function(event) - { - console.assert(event.button === 0); - console.assert(this._mouseIsDown); - if (!this._mouseIsDown) - return; - - if (this.selectedNavigationItem) - this.selectedNavigationItem.active = false; - - this._mouseIsDown = false; - - document.removeEventListener("mousemove", this._mouseMovedEventListener, false); - document.removeEventListener("mouseup", this._mouseUpEventListener, false); - - delete this._mouseMovedEventListener; - delete this._mouseUpEventListener; - - // Restore the tabIndex so the navigation bar can be in the keyboard tab loop. - this._element.tabIndex = 0; - - // Dispatch the selected event here since the selectedNavigationItem setter surpresses it - // while the mouse is down to prevent sending it while scrubbing the bar. - if (this._previousSelectedNavigationItem !== this.selectedNavigationItem) - this.dispatchEventToListeners(WebInspector.NavigationBar.Event.NavigationItemSelected); - - delete this._previousSelectedNavigationItem; - - event.preventDefault(); - event.stopPropagation(); - }, - - _keyDown: function(event) - { - if (!this._focused) - return; - - if (event.keyIdentifier !== "Left" && event.keyIdentifier !== "Right") - return; - - event.preventDefault(); - event.stopPropagation(); - - var selectedNavigationItemIndex = this._navigationItems.indexOf(this._selectedNavigationItem); - - if (event.keyIdentifier === "Left") { - if (selectedNavigationItemIndex === -1) - selectedNavigationItemIndex = this._navigationItems.length; - - do { - selectedNavigationItemIndex = Math.max(0, selectedNavigationItemIndex - 1); - } while (selectedNavigationItemIndex && !(this._navigationItems[selectedNavigationItemIndex] instanceof WebInspector.RadioButtonNavigationItem)); - } else if (event.keyIdentifier === "Right") { - do { - selectedNavigationItemIndex = Math.min(selectedNavigationItemIndex + 1, this._navigationItems.length - 1); - } while (selectedNavigationItemIndex < this._navigationItems.length - 1 && !(this._navigationItems[selectedNavigationItemIndex] instanceof WebInspector.RadioButtonNavigationItem)); - } - - if (!(this._navigationItems[selectedNavigationItemIndex] instanceof WebInspector.RadioButtonNavigationItem)) - return; - - this.selectedNavigationItem = this._navigationItems[selectedNavigationItemIndex]; - }, - - _focus: function(event) - { - this._focused = true; - }, - - _blur: function(event) - { - this._focused = false; - }, - - _updateStyle: function() - { - this._needsStyleUpdated = false; - - var parentSelector = "." + (this.constructor.StyleClassName || WebInspector.NavigationBar.StyleClassName); - - var styleText = ""; - for (var i = 0; i < this._navigationItems.length; ++i) { - if (!this._navigationItems[i].generateStyleText) - continue; - if (styleText) - styleText += "\n"; - styleText += this._navigationItems[i].generateStyleText(parentSelector); - } - - this._styleElement.textContent = styleText; - }, - - _calculateMinimumWidth: function() - { - var wasCollapsed = this._element.classList.contains(WebInspector.NavigationBar.CollapsedStyleClassName); - - // Add the collapsed style class to calculate the width of the items when they are collapsed. - if (!wasCollapsed) - this._element.classList.add(WebInspector.NavigationBar.CollapsedStyleClassName); - - var totalItemWidth = 0; - for (var i = 0; i < this._navigationItems.length; ++i) { - // Skip flexible space items since they can take up no space at the minimum width. - if (this._navigationItems[i] instanceof WebInspector.FlexibleSpaceNavigationItem) - continue; - totalItemWidth += this._navigationItems[i].element.offsetWidth; - } - - // Remove the collapsed style class if we were not collapsed before. - if (!wasCollapsed) - this._element.classList.remove(WebInspector.NavigationBar.CollapsedStyleClassName); - - return totalItemWidth; - } -}; - -WebInspector.NavigationBar.prototype.__proto__ = WebInspector.Object.prototype; |