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

  1. /*
  2.  * Copyright (C) 2007, 2008 Apple 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
  6.  * are met:
  7.  *
  8.  * 1.  Redistributions of source code must retain the above copyright
  9.  *     notice, this list of conditions and the following disclaimer.
  10.  * 2.  Redistributions in binary form must reproduce the above copyright
  11.  *     notice, this list of conditions and the following disclaimer in the
  12.  *     documentation and/or other materials provided with the distribution.
  13.  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
  14.  *     its contributors may be used to endorse or promote products derived
  15.  *     from this software without specific prior written permission.
  16.  *
  17.  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
  18.  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  19.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  20.  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
  21.  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  22.  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  23.  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  24.  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27.  */
  28.  
  29. WebInspector.Panel = function()
  30. {
  31.     WebInspector.View.call(this);
  32.  
  33.     this.element.addStyleClass("panel");
  34. }
  35.  
  36. WebInspector.Panel.prototype = {
  37.     get toolbarItem()
  38.     {
  39.         if (this._toolbarItem)
  40.             return this._toolbarItem;
  41.  
  42.         // Sample toolbar item as markup:
  43.         // <button class="toolbar-item resources toggleable">
  44.         // <div class="toolbar-icon"></div>
  45.         // <div class="toolbar-label">Resources</div>
  46.         // </button>
  47.  
  48.         this._toolbarItem = document.createElement("button");
  49.         this._toolbarItem.className = "toolbar-item toggleable";
  50.         this._toolbarItem.panel = this;
  51.  
  52.         if ("toolbarItemClass" in this)
  53.             this._toolbarItem.addStyleClass(this.toolbarItemClass);
  54.  
  55.         var iconElement = document.createElement("div");
  56.         iconElement.className = "toolbar-icon";
  57.         this._toolbarItem.appendChild(iconElement);
  58.  
  59.         if ("toolbarItemLabel" in this) {
  60.             var labelElement = document.createElement("div");
  61.             labelElement.className = "toolbar-label";
  62.             labelElement.textContent = this.toolbarItemLabel;
  63.             this._toolbarItem.appendChild(labelElement);
  64.         }
  65.  
  66.         return this._toolbarItem;
  67.     },
  68.  
  69.     show: function()
  70.     {
  71.         WebInspector.View.prototype.show.call(this);
  72.  
  73.         var statusBarItems = this.statusBarItems;
  74.         if (statusBarItems) {
  75.             this._statusBarItemContainer = document.createElement("div");
  76.             for (var i = 0; i < statusBarItems.length; ++i)
  77.                 this._statusBarItemContainer.appendChild(statusBarItems[i]);
  78.             document.getElementById("main-status-bar").appendChild(this._statusBarItemContainer);
  79.         }
  80.  
  81.         if ("_toolbarItem" in this)
  82.             this._toolbarItem.addStyleClass("toggled-on");
  83.  
  84.         WebInspector.currentFocusElement = this.defaultFocusedElement;
  85.  
  86.         this.updateSidebarWidth();
  87.         this._restoreScrollPositions();
  88.     },
  89.  
  90.     hide: function()
  91.     {
  92.         this._storeScrollPositions();
  93.         WebInspector.View.prototype.hide.call(this);
  94.  
  95.         if (this._statusBarItemContainer && this._statusBarItemContainer.parentNode)
  96.             this._statusBarItemContainer.parentNode.removeChild(this._statusBarItemContainer);
  97.         delete this._statusBarItemContainer;
  98.         if ("_toolbarItem" in this)
  99.             this._toolbarItem.removeStyleClass("toggled-on");
  100.     },
  101.  
  102.     get defaultFocusedElement()
  103.     {
  104.         return this.sidebarTreeElement || this.element;
  105.     },
  106.  
  107.     attach: function()
  108.     {
  109.         if (!this.element.parentNode)
  110.             document.getElementById("main-panels").appendChild(this.element);
  111.     },
  112.  
  113.     searchCanceled: function(startingNewSearch)
  114.     {
  115.         if (this._searchResults) {
  116.             for (var i = 0; i < this._searchResults.length; ++i) {
  117.                 var view = this._searchResults[i];
  118.                 if (view.searchCanceled)
  119.                     view.searchCanceled();
  120.                 delete view.currentQuery;
  121.             }
  122.         }
  123.  
  124.         WebInspector.updateSearchMatchesCount(0, this);
  125.  
  126.         if (this._currentSearchChunkIntervalIdentifier) {
  127.             clearInterval(this._currentSearchChunkIntervalIdentifier);
  128.             delete this._currentSearchChunkIntervalIdentifier;
  129.         }
  130.  
  131.         this._totalSearchMatches = 0;
  132.         this._currentSearchResultIndex = 0;
  133.         this._searchResults = [];
  134.     },
  135.  
  136.     performSearch: function(query)
  137.     {
  138.         // Call searchCanceled since it will reset everything we need before doing a new search.
  139.         this.searchCanceled(true);
  140.  
  141.         var searchableViews = this.searchableViews;
  142.         if (!searchableViews || !searchableViews.length)
  143.             return;
  144.  
  145.         var parentElement = this.viewsContainerElement;
  146.         var visibleView = this.visibleView;
  147.         var sortFuction = this.searchResultsSortFunction;
  148.  
  149.         var matchesCountUpdateTimeout = null;
  150.  
  151.         function updateMatchesCount()
  152.         {
  153.             WebInspector.updateSearchMatchesCount(this._totalSearchMatches, this);
  154.             matchesCountUpdateTimeout = null;
  155.         }
  156.  
  157.         function updateMatchesCountSoon()
  158.         {
  159.             if (matchesCountUpdateTimeout)
  160.                 return;
  161.             // Update the matches count every half-second so it doesn't feel twitchy.
  162.             matchesCountUpdateTimeout = setTimeout(updateMatchesCount.bind(this), 500);
  163.         }
  164.  
  165.         function finishedCallback(view, searchMatches)
  166.         {
  167.             if (!searchMatches)
  168.                 return;
  169.  
  170.             this._totalSearchMatches += searchMatches;
  171.             this._searchResults.push(view);
  172.  
  173.             if (sortFuction)
  174.                 this._searchResults.sort(sortFuction);
  175.  
  176.             if (this.searchMatchFound)
  177.                 this.searchMatchFound(view, searchMatches);
  178.  
  179.             updateMatchesCountSoon.call(this);
  180.  
  181.             if (view === visibleView)
  182.                 view.jumpToFirstSearchResult();
  183.         }
  184.  
  185.         var i = 0;
  186.         var panel = this;
  187.         var boundFinishedCallback = finishedCallback.bind(this);
  188.         var chunkIntervalIdentifier = null;
  189.  
  190.         // Split up the work into chunks so we don't block the
  191.         // UI thread while processing.
  192.  
  193.         function processChunk()
  194.         {
  195.             var view = searchableViews[i];
  196.  
  197.             if (++i >= searchableViews.length) {
  198.                 if (panel._currentSearchChunkIntervalIdentifier === chunkIntervalIdentifier)
  199.                     delete panel._currentSearchChunkIntervalIdentifier;
  200.                 clearInterval(chunkIntervalIdentifier);
  201.             }
  202.  
  203.             if (!view)
  204.                 return;
  205.  
  206.             if (view.element.parentNode !== parentElement && view.element.parentNode && parentElement)
  207.                 view.detach();
  208.  
  209.             view.currentQuery = query;
  210.             view.performSearch(query, boundFinishedCallback);
  211.         }
  212.  
  213.         processChunk();
  214.  
  215.         chunkIntervalIdentifier = setInterval(processChunk, 25);
  216.         this._currentSearchChunkIntervalIdentifier = chunkIntervalIdentifier;
  217.     },
  218.  
  219.     jumpToNextSearchResult: function()
  220.     {
  221.         if (!this.showView || !this._searchResults || !this._searchResults.length)
  222.             return;
  223.  
  224.         var showFirstResult = false;
  225.  
  226.         this._currentSearchResultIndex = this._searchResults.indexOf(this.visibleView);
  227.         if (this._currentSearchResultIndex === -1) {
  228.             this._currentSearchResultIndex = 0;
  229.             showFirstResult = true;
  230.         }
  231.  
  232.         var currentView = this._searchResults[this._currentSearchResultIndex];
  233.  
  234.         if (currentView.showingLastSearchResult()) {
  235.             if (this.searchIteratesOverViews()) {
  236.                 if (++this._currentSearchResultIndex >= this._searchResults.length)
  237.                     this._currentSearchResultIndex = 0;
  238.                 currentView = this._searchResults[this._currentSearchResultIndex];
  239.             }
  240.             showFirstResult = true;
  241.         }
  242.  
  243.         if (currentView !== this.visibleView) {
  244.             this.showView(currentView);
  245.             WebInspector.focusSearchField();
  246.         }
  247.  
  248.         if (showFirstResult)
  249.             currentView.jumpToFirstSearchResult();
  250.         else
  251.             currentView.jumpToNextSearchResult();
  252.     },
  253.  
  254.     jumpToPreviousSearchResult: function()
  255.     {
  256.         if (!this.showView || !this._searchResults || !this._searchResults.length)
  257.             return;
  258.  
  259.         var showLastResult = false;
  260.  
  261.         this._currentSearchResultIndex = this._searchResults.indexOf(this.visibleView);
  262.         if (this._currentSearchResultIndex === -1) {
  263.             this._currentSearchResultIndex = 0;
  264.             showLastResult = true;
  265.         }
  266.  
  267.         var currentView = this._searchResults[this._currentSearchResultIndex];
  268.  
  269.         if (currentView.showingFirstSearchResult()) {
  270.             if (this.searchIteratesOverViews()) {
  271.                 if (--this._currentSearchResultIndex < 0)
  272.                     this._currentSearchResultIndex = (this._searchResults.length - 1);
  273.                 currentView = this._searchResults[this._currentSearchResultIndex];
  274.             }
  275.             showLastResult = true;
  276.         }
  277.  
  278.         if (currentView !== this.visibleView) {
  279.             this.showView(currentView);
  280.             WebInspector.focusSearchField();
  281.         }
  282.  
  283.         if (showLastResult)
  284.             currentView.jumpToLastSearchResult();
  285.         else
  286.             currentView.jumpToPreviousSearchResult();
  287.     },
  288.  
  289.     createSidebar: function(parentElement, resizerParentElement)
  290.     {
  291.         if (this.hasSidebar)
  292.             return;
  293.  
  294.         if (!parentElement)
  295.             parentElement = this.element;
  296.  
  297.         if (!resizerParentElement)
  298.             resizerParentElement = parentElement;
  299.  
  300.         this.hasSidebar = true;
  301.  
  302.         this.sidebarElement = document.createElement("div");
  303.         this.sidebarElement.className = "sidebar";
  304.         parentElement.appendChild(this.sidebarElement);
  305.  
  306.         this.sidebarResizeElement = document.createElement("div");
  307.         this.sidebarResizeElement.className = "sidebar-resizer-vertical";
  308.         this.sidebarResizeElement.addEventListener("mousedown", this._startSidebarDragging.bind(this), false);
  309.         resizerParentElement.appendChild(this.sidebarResizeElement);
  310.  
  311.         this.sidebarTreeElement = document.createElement("ol");
  312.         this.sidebarTreeElement.className = "sidebar-tree";
  313.         this.sidebarElement.appendChild(this.sidebarTreeElement);
  314.  
  315.         this.sidebarTree = new TreeOutline(this.sidebarTreeElement);
  316.     },
  317.  
  318.     _startSidebarDragging: function(event)
  319.     {
  320.         WebInspector.elementDragStart(this.sidebarResizeElement, this._sidebarDragging.bind(this), this._endSidebarDragging.bind(this), event, "col-resize");
  321.     },
  322.  
  323.     _sidebarDragging: function(event)
  324.     {
  325.         this.updateSidebarWidth(event.pageX);
  326.  
  327.         event.preventDefault();
  328.     },
  329.  
  330.     _endSidebarDragging: function(event)
  331.     {
  332.         WebInspector.elementDragEnd(event);
  333.     },
  334.  
  335.     updateSidebarWidth: function(width)
  336.     {
  337.         if (!this.hasSidebar)
  338.             return;
  339.  
  340.         if (this.sidebarElement.offsetWidth <= 0) {
  341.             // The stylesheet hasn't loaded yet or the window is closed,
  342.             // so we can't calculate what is need. Return early.
  343.             return;
  344.         }
  345.  
  346.         if (!("_currentSidebarWidth" in this))
  347.             this._currentSidebarWidth = this.sidebarElement.offsetWidth;
  348.  
  349.         if (typeof width === "undefined")
  350.             width = this._currentSidebarWidth;
  351.  
  352.         width = Number.constrain(width, Preferences.minSidebarWidth, window.innerWidth / 2);
  353.  
  354.         this._currentSidebarWidth = width;
  355.         this.setSidebarWidth(width);
  356.  
  357.         this.updateMainViewWidth(width);
  358.     },
  359.  
  360.     setSidebarWidth: function(width)
  361.     {
  362.         this.sidebarElement.style.width = width + "px";
  363.         this.sidebarResizeElement.style.left = (width - 3) + "px";
  364.     },
  365.  
  366.     updateMainViewWidth: function(width)
  367.     {
  368.         // Should be implemented by ancestors.
  369.     },
  370.  
  371.     resize: function()
  372.     {
  373.         var visibleView = this.visibleView;
  374.         if (visibleView && "resize" in visibleView)
  375.             visibleView.resize();
  376.     },
  377.  
  378.     canShowSourceLine: function(url, line)
  379.     {
  380.         return false;
  381.     },
  382.  
  383.     showSourceLine: function(url, line)
  384.     {
  385.         return false;
  386.     },
  387.  
  388.     searchIteratesOverViews: function()
  389.     {
  390.         return false;
  391.     },
  392.  
  393.     elementsToRestoreScrollPositionsFor: function()
  394.     {
  395.         return [];
  396.     },
  397.  
  398.     _storeScrollPositions: function()
  399.     {
  400.         var elements = this.elementsToRestoreScrollPositionsFor();
  401.         for (var i = 0; i < elements.length; ++i) {
  402.             var container = elements[i];
  403.             container._scrollTop = container.scrollTop;
  404.         }
  405.     },
  406.  
  407.     _restoreScrollPositions: function()
  408.     {
  409.         var elements = this.elementsToRestoreScrollPositionsFor();
  410.         for (var i = 0; i < elements.length; ++i) {
  411.             var container = elements[i];
  412.             if (container._scrollTop)
  413.                 container.scrollTop = container._scrollTop;
  414.         }
  415.     }
  416. }
  417.  
  418. WebInspector.Panel.prototype.__proto__ = WebInspector.View.prototype;
  419.