/* * 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.HierarchicalPathComponent = class HierarchicalPathComponent extends WebInspector.Object { constructor(displayName, styleClassNames, representedObject, textOnly, showSelectorArrows) { super(); console.assert(displayName); console.assert(styleClassNames); this._representedObject = representedObject || null; this._element = document.createElement("div"); this._element.className = "hierarchical-path-component"; if (!Array.isArray(styleClassNames)) styleClassNames = [styleClassNames]; this._element.classList.add(...styleClassNames); if (!textOnly) { this._iconElement = document.createElement("img"); this._iconElement.className = "icon"; this._element.appendChild(this._iconElement); } else this._element.classList.add("text-only"); this._titleElement = document.createElement("div"); this._titleElement.className = "title"; this._element.appendChild(this._titleElement); this._titleContentElement = document.createElement("div"); this._titleContentElement.className = "content"; this._titleElement.appendChild(this._titleContentElement); this._separatorElement = document.createElement("div"); this._separatorElement.className = "separator"; this._element.appendChild(this._separatorElement); this._selectElement = document.createElement("select"); this._selectElement.addEventListener("mouseover", this._selectElementMouseOver.bind(this)); this._selectElement.addEventListener("mouseout", this._selectElementMouseOut.bind(this)); this._selectElement.addEventListener("mousedown", this._selectElementMouseDown.bind(this)); this._selectElement.addEventListener("mouseup", this._selectElementMouseUp.bind(this)); this._selectElement.addEventListener("change", this._selectElementSelectionChanged.bind(this)); this._element.appendChild(this._selectElement); this._previousSibling = null; this._nextSibling = null; this._truncatedDisplayNameLength = 0; this._collapsed = false; this._hidden = false; this._selectorArrows = false; this.displayName = displayName; this.selectorArrows = showSelectorArrows; } // Public get selectedPathComponent() { let selectedOption = this._selectElement[this._selectElement.selectedIndex]; if (!selectedOption && this._selectElement.options.length === 1) selectedOption = this._selectElement.options[0]; return selectedOption && selectedOption._pathComponent || null; } get element() { return this._element; } get representedObject() { return this._representedObject; } get displayName() { return this._displayName; } set displayName(newDisplayName) { console.assert(newDisplayName); if (newDisplayName === this._displayName) return; this._displayName = newDisplayName; this._updateElementTitleAndText(); } get truncatedDisplayNameLength() { return this._truncatedDisplayNameLength; } set truncatedDisplayNameLength(truncatedDisplayNameLength) { truncatedDisplayNameLength = truncatedDisplayNameLength || 0; if (truncatedDisplayNameLength === this._truncatedDisplayNameLength) return; this._truncatedDisplayNameLength = truncatedDisplayNameLength; this._updateElementTitleAndText(); } get minimumWidth() { if (this._collapsed) return WebInspector.HierarchicalPathComponent.MinimumWidthCollapsed; if (this._selectorArrows) return WebInspector.HierarchicalPathComponent.MinimumWidth + WebInspector.HierarchicalPathComponent.SelectorArrowsWidth; return WebInspector.HierarchicalPathComponent.MinimumWidth; } get forcedWidth() { let maxWidth = this._element.style.getProperty("width"); if (typeof maxWidth === "string") return parseInt(maxWidth); return null; } set forcedWidth(width) { if (typeof width === "number") { let minimumWidthForOneCharacterTruncatedTitle = WebInspector.HierarchicalPathComponent.MinimumWidthForOneCharacterTruncatedTitle; if (this.selectorArrows) minimumWidthForOneCharacterTruncatedTitle += WebInspector.HierarchicalPathComponent.SelectorArrowsWidth; // If the width is less than the minimum width required to show a single character and ellipsis, then // just collapse down to the bare minimum to show only the icon. if (width < minimumWidthForOneCharacterTruncatedTitle) width = 0; // Ensure the width does not go less than 1px. If the width is 0 the layout gets funky. There is a min-width // in the CSS too, so as long the width is less than min-width we get the desired effect of only showing the icon. this._element.style.setProperty("width", Math.max(1, width) + "px"); } else this._element.style.removeProperty("width"); } get hidden() { return this._hidden; } set hidden(flag) { if (this._hidden === flag) return; this._hidden = flag; this._element.classList.toggle("hidden", this._hidden); } get collapsed() { return this._collapsed; } set collapsed(flag) { if (this._collapsed === flag) return; this._collapsed = flag; this._element.classList.toggle("collapsed", this._collapsed); } get selectorArrows() { return this._selectorArrows; } set selectorArrows(flag) { if (this._selectorArrows === flag) return; this._selectorArrows = flag; if (this._selectorArrows) { this._selectorArrowsElement = document.createElement("img"); this._selectorArrowsElement.className = "selector-arrows"; this._element.insertBefore(this._selectorArrowsElement, this._separatorElement); } else if (this._selectorArrowsElement) { this._selectorArrowsElement.remove(); this._selectorArrowsElement = null; } this._element.classList.toggle("show-selector-arrows", !!this._selectorArrows); } get previousSibling() { return this._previousSibling; } set previousSibling(newSlibling) { this._previousSibling = newSlibling || null; } get nextSibling() { return this._nextSibling; } set nextSibling(newSlibling) { this._nextSibling = newSlibling || null; } // Private _updateElementTitleAndText() { let truncatedDisplayName = this._displayName; if (this._truncatedDisplayNameLength && truncatedDisplayName.length > this._truncatedDisplayNameLength) truncatedDisplayName = truncatedDisplayName.substring(0, this._truncatedDisplayNameLength) + ellipsis; this._element.title = this._displayName; this._titleContentElement.textContent = truncatedDisplayName; } _updateSelectElement() { this._selectElement.removeChildren(); function createOption(component) { let optionElement = document.createElement("option"); let maxPopupMenuLength = 130; //