text: // Copyright (c) 2014 The Chromium Authors. All rights reserved.
  // Use of this source code is governed by a BSD-style license that can be
  // found in the LICENSE file.
  
  /**
   * @constructor
   * @extends {WebInspector.SidebarPane}
   * @param {string} title
   */
  WebInspector.ElementsSidebarPane = function(title)
  {
      WebInspector.SidebarPane.call(this, title);
      this._node = null;
      this._updateController = new WebInspector.ElementsSidebarPane._UpdateController(this, this.doUpdate.bind(this));
      WebInspector.context.addFlavorChangeListener(WebInspector.DOMNode, this._nodeChanged, this);
  }
  
  WebInspector.ElementsSidebarPane.prototype = {
      /**
       * @return {?WebInspector.DOMNode}
       */
      node: function()
      {
          return this._node;
      },
  
      /**
       * @return {?WebInspector.CSSStyleModel}
       */
      cssModel: function()
      {
          return this._cssModel && this._cssModel.isEnabled() ? this._cssModel : null;
      },
  
      /**
       * @param {!WebInspector.Event} event
       */
      _nodeChanged: function(event)
      {
          this.setNode(/** @type {?WebInspector.DOMNode} */ (event.data));
      },
  
      /**
       * @param {?WebInspector.DOMNode} node
       */
      setNode: function(node)
      {
          this._node = node;
          this._updateTarget(node ? node.target() : null);
          this.update();
      },
  
      /**
       * @protected
       * @return {!Promise.<?>}
       */
      doUpdate: function()
      {
          return Promise.resolve();
      },
  
      update: function()
      {
          this._updateController.update();
      },
  
      wasShown: function()
      {
          WebInspector.SidebarPane.prototype.wasShown.call(this);
          this._updateController.viewWasShown();
      },
  
      /**
       * @param {?WebInspector.Target} target
       */
      _updateTarget: function(target)
      {
          if (this._target === target)
              return;
          if (this._targetEvents) {
              WebInspector.EventTarget.removeEventListeners(this._targetEvents);
              this._targetEvents = null;
          }
          this._target = target;
  
          var domModel = null;
          var resourceTreeModel = null;
          if (target) {
              this._cssModel = WebInspector.CSSStyleModel.fromTarget(target);
              domModel = WebInspector.DOMModel.fromTarget(target);
              resourceTreeModel = target.resourceTreeModel;
          }
  
          if (this._cssModel && domModel && resourceTreeModel) {
              this._targetEvents = [
                  this._cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleSheetAdded, this.onCSSModelChanged, this),
                  this._cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleSheetRemoved, this.onCSSModelChanged, this),
                  this._cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleSheetChanged, this.onCSSModelChanged, this),
                  this._cssModel.addEventListener(WebInspector.CSSStyleModel.Events.MediaQueryResultChanged, this.onCSSModelChanged, this),
                  this._cssModel.addEventListener(WebInspector.CSSStyleModel.Events.PseudoStateForced, this.onCSSModelChanged, this),
                  this._cssModel.addEventListener(WebInspector.CSSStyleModel.Events.ModelWasEnabled, this.onCSSModelChanged, this),
                  domModel.addEventListener(WebInspector.DOMModel.Events.DOMMutated, this._domModelChanged, this),
                  resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameResized, this._onFrameResized, this),
              ];
          }
      },
  
      /**
       * @param {!WebInspector.Event} event
       */
      _onFrameResized: function(event)
      {
          /**
           * @this {WebInspector.ElementsSidebarPane}
           */
          function refreshContents()
          {
              this.onFrameResizedThrottled();
              delete this._frameResizedTimer;
          }
  
          if (this._frameResizedTimer)
              clearTimeout(this._frameResizedTimer);
  
          this._frameResizedTimer = setTimeout(refreshContents.bind(this), 100);
      },
  
      /**
       * @param {!WebInspector.Event} event
       */
      _domModelChanged: function(event)
      {
          var node = /** @type {!WebInspector.DOMNode} */ (event.data);
          this.onDOMModelChanged(node)
      },
  
      /**
       * @param {!WebInspector.DOMNode} node
       */
      onDOMModelChanged: function(node) { },
  
      onCSSModelChanged: function() { },
  
      onFrameResizedThrottled: function() { },
  
      __proto__: WebInspector.SidebarPane.prototype
  }
  
  /**
   * @constructor
   * @param {!WebInspector.Widget} view
   * @param {function():!Promise.<?>} doUpdate
   */
  WebInspector.ElementsSidebarPane._UpdateController = function(view, doUpdate)
  {
      this._view = view;
      this._updateThrottler = new WebInspector.Throttler(100);
      this._updateWhenVisible = false;
      this._doUpdate = doUpdate;
  }
  
  WebInspector.ElementsSidebarPane._UpdateController.prototype = {
      update: function()
      {
          this._updateWhenVisible = !this._view.isShowing();
          if (this._updateWhenVisible)
              return;
          this._updateThrottler.schedule(innerUpdate.bind(this));
  
          /**
           * @this {WebInspector.ElementsSidebarPane._UpdateController}
           * @return {!Promise.<?>}
           */
          function innerUpdate()
          {
              return this._view.isShowing() ? this._doUpdate.call(null) : Promise.resolve();
          }
      },
  
      viewWasShown: function()
      {
          if (this._updateWhenVisible)
              this.update();
      }
  }
  