text: /*
   * 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.
   */
  
  // FIXME: CSSManager lacks advanced multi-target support. (Stylesheets per-target)
  
  WI.CSSManager = class CSSManager extends WI.Object
  {
      constructor()
      {
          super();
  
          WI.Frame.addEventListener(WI.Frame.Event.MainResourceDidChange, this._mainResourceDidChange, this);
          WI.Frame.addEventListener(WI.Frame.Event.ResourceWasAdded, this._resourceAdded, this);
          WI.Resource.addEventListener(WI.SourceCode.Event.ContentDidChange, this._resourceContentDidChange, this);
          WI.Resource.addEventListener(WI.Resource.Event.TypeDidChange, this._resourceTypeDidChange, this);
  
          WI.DOMNode.addEventListener(WI.DOMNode.Event.AttributeModified, this._nodeAttributesDidChange, this);
          WI.DOMNode.addEventListener(WI.DOMNode.Event.AttributeRemoved, this._nodeAttributesDidChange, this);
          WI.DOMNode.addEventListener(WI.DOMNode.Event.EnabledPseudoClassesChanged, this._nodePseudoClassesDidChange, this);
  
          this._colorFormatSetting = new WI.Setting("default-color-format", WI.Color.Format.Original);
  
          this._styleSheetIdentifierMap = new Map;
          this._styleSheetFrameURLMap = new Map;
          this._nodeStylesMap = {};
          this._modifiedStyles = new Map;
          this._defaultAppearance = null;
          this._forcedAppearance = null;
  
          // COMPATIBILITY (iOS 9): Legacy backends did not send stylesheet
          // added/removed events and must be fetched manually.
          this._fetchedInitialStyleSheets = InspectorBackend.domains.CSS.hasEvent("styleSheetAdded");
      }
  
      // Target
  
      initializeTarget(target)
      {
          if (target.CSSAgent)
              target.CSSAgent.enable();
      }
  
      // Static
  
      static protocolStyleSheetOriginToEnum(origin)
      {
          switch (origin) {
          case CSSAgent.StyleSheetOrigin.Regular:
              return WI.CSSStyleSheet.Type.Author;
          case CSSAgent.StyleSheetOrigin.User:
              return WI.CSSStyleSheet.Type.User;
          case CSSAgent.StyleSheetOrigin.UserAgent:
              return WI.CSSStyleSheet.Type.UserAgent;
          case CSSAgent.StyleSheetOrigin.Inspector:
              return WI.CSSStyleSheet.Type.Inspector;
          default:
              console.assert(false, "Unknown CSS.StyleSheetOrigin", origin);
              return CSSAgent.StyleSheetOrigin.Regular;
          }
      }
  
      static protocolMediaSourceToEnum(source)
      {
          switch (source) {
          case CSSAgent.CSSMediaSource.MediaRule:
              return WI.CSSMedia.Type.MediaRule;
          case CSSAgent.CSSMediaSource.ImportRule:
              return WI.CSSMedia.Type.ImportRule;
          case CSSAgent.CSSMediaSource.LinkedSheet:
              return WI.CSSMedia.Type.LinkedStyleSheet;
          case CSSAgent.CSSMediaSource.InlineSheet:
              return WI.CSSMedia.Type.InlineStyleSheet;
          default:
              console.assert(false, "Unknown CSS.CSSMediaSource", source);
              return WI.CSSMedia.Type.MediaRule;
          }
      }
  
      static displayNameForPseudoId(pseudoId)
      {
          // Compatibility (iOS 12.2): CSS.PseudoId did not exist.
          if (!InspectorBackend.domains.CSS.PseudoId) {
              switch (pseudoId) {
              case 1: // PseudoId.FirstLine
                  return WI.unlocalizedString("::first-line");
              case 2: // PseudoId.FirstLetter
                  return WI.unlocalizedString("::first-letter");
              case 3: // PseudoId.Marker
                  return WI.unlocalizedString("::marker");
              case 4: // PseudoId.Before
                  return WI.unlocalizedString("::before");
              case 5: // PseudoId.After
                  return WI.unlocalizedString("::after");
              case 6: // PseudoId.Selection
                  return WI.unlocalizedString("::selection");
              case 7: // PseudoId.Scrollbar
                  return WI.unlocalizedString("::scrollbar");
              case 8: // PseudoId.ScrollbarThumb
                  return WI.unlocalizedString("::scrollbar-thumb");
              case 9: // PseudoId.ScrollbarButton
                  return WI.unlocalizedString("::scrollbar-button");
              case 10: // PseudoId.ScrollbarTrack
                  return WI.unlocalizedString("::scrollbar-track");
              case 11: // PseudoId.ScrollbarTrackPiece
                  return WI.unlocalizedString("::scrollbar-track-piece");
              case 12: // PseudoId.ScrollbarCorner
                  return WI.unlocalizedString("::scrollbar-corner");
              case 13: // PseudoId.Resizer
                  return WI.unlocalizedString("::resizer");
  
              default:
                  console.error("Unknown pseudo id", pseudoId);
                  return "";
              }
          }
  
          switch (pseudoId) {
          case InspectorBackend.domains.CSS.PseudoId.FirstLine:
              return WI.unlocalizedString("::first-line");
          case InspectorBackend.domains.CSS.PseudoId.FirstLetter:
              return WI.unlocalizedString("::first-letter");
          case InspectorBackend.domains.CSS.PseudoId.Marker:
              return WI.unlocalizedString("::marker");
          case InspectorBackend.domains.CSS.PseudoId.Before:
              return WI.unlocalizedString("::before");
          case InspectorBackend.domains.CSS.PseudoId.After:
              return WI.unlocalizedString("::after");
          case InspectorBackend.domains.CSS.PseudoId.Selection:
              return WI.unlocalizedString("::selection");
          case InspectorBackend.domains.CSS.PseudoId.Scrollbar:
              return WI.unlocalizedString("::scrollbar");
          case InspectorBackend.domains.CSS.PseudoId.ScrollbarThumb:
              return WI.unlocalizedString("::scrollbar-thumb");
          case InspectorBackend.domains.CSS.PseudoId.ScrollbarButton:
              return WI.unlocalizedString("::scrollbar-button");
          case InspectorBackend.domains.CSS.PseudoId.ScrollbarTrack:
              return WI.unlocalizedString("::scrollbar-track");
          case InspectorBackend.domains.CSS.PseudoId.ScrollbarTrackPiece:
              return WI.unlocalizedString("::scrollbar-track-piece");
          case InspectorBackend.domains.CSS.PseudoId.ScrollbarCorner:
              return WI.unlocalizedString("::scrollbar-corner");
          case InspectorBackend.domains.CSS.PseudoId.Resizer:
              return WI.unlocalizedString("::resizer");
  
          default:
              console.error("Unknown pseudo id", pseudoId);
              return "";
          }
      }
  
      // Public
  
      get preferredColorFormat()
      {
          return this._colorFormatSetting.value;
      }
  
      get styleSheets()
      {
          return Array.from(this._styleSheetIdentifierMap.values());
      }
  
      get defaultAppearance()
      {
          return this._defaultAppearance;
      }
  
      get forcedAppearance()
      {
          return this._forcedAppearance;
      }
  
      set forcedAppearance(name)
      {
          if (!this.canForceAppearance())
              return;
  
          let protocolName = "";
  
          switch (name) {
          case WI.CSSManager.Appearance.Light:
              protocolName = PageAgent.Appearance.Light;
              break;
  
          case WI.CSSManager.Appearance.Dark:
              protocolName = PageAgent.Appearance.Dark;
              break;
  
          case null:
          case undefined:
          case "":
              protocolName = "";
              break;
  
          default:
              // Abort for unknown values.
              return;
          }
  
          this._forcedAppearance = name || null;
  
          PageAgent.setForcedAppearance(protocolName).then(() => {
              this.mediaQueryResultChanged();
              this.dispatchEventToListeners(WI.CSSManager.Event.ForcedAppearanceDidChange, {appearance: this._forcedAppearance});
          });
      }
  
      canForceAppearance()
      {
          return window.PageAgent && !!PageAgent.setForcedAppearance && this._defaultAppearance;
      }
  
      canForcePseudoClasses()
      {
          return window.CSSAgent && !!CSSAgent.forcePseudoState;
      }
  
      propertyNameHasOtherVendorPrefix(name)
      {
          if (!name || name.length < 4 || name.charAt(0) !== "-")
              return false;
  
          var match = name.match(/^(?:-moz-|-ms-|-o-|-epub-)/);
          if (!match)
              return false;
  
          return true;
      }
  
      propertyValueHasOtherVendorKeyword(value)
      {
          var match = value.match(/(?:-moz-|-ms-|-o-|-epub-)[-\w]+/);
          if (!match)
              return false;
  
          return true;
      }
  
      canonicalNameForPropertyName(name)
      {
          if (!name || name.length < 8 || name.charAt(0) !== "-")
              return name;
  
          var match = name.match(/^(?:-webkit-|-khtml-|-apple-)(.+)/);
          if (!match)
              return name;
  
          return match[1];
      }
  
      fetchStyleSheetsIfNeeded()
      {
          if (this._fetchedInitialStyleSheets)
              return;
  
          this._fetchInfoForAllStyleSheets(function() {});
      }
  
      styleSheetForIdentifier(id)
      {
          let styleSheet = this._styleSheetIdentifierMap.get(id);
          if (styleSheet)
              return styleSheet;
  
          styleSheet = new WI.CSSStyleSheet(id);
          this._styleSheetIdentifierMap.set(id, styleSheet);
          return styleSheet;
      }
  
      stylesForNode(node)
      {
          if (node.id in this._nodeStylesMap)
              return this._nodeStylesMap[node.id];
  
          var styles = new WI.DOMNodeStyles(node);
          this._nodeStylesMap[node.id] = styles;
          return styles;
      }
  
      inspectorStyleSheetsForFrame(frame)
      {
          return this.styleSheets.filter((styleSheet) => styleSheet.isInspectorStyleSheet() && styleSheet.parentFrame === frame);
      }
  
      preferredInspectorStyleSheetForFrame(frame, callback, doNotCreateIfMissing)
      {
          var inspectorStyleSheets = this.inspectorStyleSheetsForFrame(frame);
          for (let styleSheet of inspectorStyleSheets) {
              if (styleSheet[WI.CSSManager.PreferredInspectorStyleSheetSymbol]) {
                  callback(styleSheet);
                  return;
              }
          }
  
          if (doNotCreateIfMissing)
              return;
  
          if (CSSAgent.createStyleSheet) {
              CSSAgent.createStyleSheet(frame.id, function(error, styleSheetId) {
                  const url = null;
                  let styleSheet = WI.cssManager.styleSheetForIdentifier(styleSheetId);
                  styleSheet.updateInfo(url, frame, styleSheet.origin, styleSheet.isInlineStyleTag(), styleSheet.startLineNumber, styleSheet.startColumnNumber);
                  styleSheet[WI.CSSManager.PreferredInspectorStyleSheetSymbol] = true;
                  callback(styleSheet);
              });
              return;
          }
  
          // COMPATIBILITY (iOS 9): CSS.createStyleSheet did not exist.
          // Legacy backends can only create the Inspector StyleSheet through CSS.addRule.
          // Exploit that to create the Inspector StyleSheet for the document.body node in
          // this frame, then get the StyleSheet for the new rule.
  
          let expression = appendWebInspectorSourceURL("document");
          let contextId = frame.pageExecutionContext.id;
          RuntimeAgent.evaluate.invoke({expression, objectGroup: "", includeCommandLineAPI: false, doNotPauseOnExceptionsAndMuteConsole: true, contextId, returnByValue: false, generatePreview: false}, documentAvailable);
  
          function documentAvailable(error, documentRemoteObjectPayload)
          {
              if (error) {
                  callback(null);
                  return;
              }
  
              let remoteObject = WI.RemoteObject.fromPayload(documentRemoteObjectPayload);
              remoteObject.pushNodeToFrontend(documentNodeAvailable.bind(null, remoteObject));
          }
  
          function documentNodeAvailable(remoteObject, documentNodeId)
          {
              remoteObject.release();
  
              if (!documentNodeId) {
                  callback(null);
                  return;
              }
  
              DOMAgent.querySelector(documentNodeId, "body", bodyNodeAvailable);
          }
  
          function bodyNodeAvailable(error, bodyNodeId)
          {
              if (error) {
                  console.error(error);
                  callback(null);
                  return;
              }
  
              let selector = ""; // Intentionally empty.
              CSSAgent.addRule(bodyNodeId, selector, cssRuleAvailable);
          }
  
          function cssRuleAvailable(error, payload)
          {
              if (error || !payload.ruleId) {
                  callback(null);
                  return;
              }
  
              let styleSheetId = payload.ruleId.styleSheetId;
              let styleSheet = WI.cssManager.styleSheetForIdentifier(styleSheetId);
              if (!styleSheet) {
                  callback(null);
                  return;
              }
  
              styleSheet[WI.CSSManager.PreferredInspectorStyleSheetSymbol] = true;
  
              console.assert(styleSheet.isInspectorStyleSheet());
              console.assert(styleSheet.parentFrame === frame);
  
              callback(styleSheet);
          }
      }
  
      mediaTypeChanged()
      {
          // Act the same as if media queries changed.
          this.mediaQueryResultChanged();
      }
  
      defaultAppearanceDidChange(protocolName)
      {
          // Called from WI.PageObserver.
  
          let appearance = null;
  
          switch (protocolName) {
          case PageAgent.Appearance.Light:
              appearance = WI.CSSManager.Appearance.Light;
              break;
  
          case PageAgent.Appearance.Dark:
              appearance = WI.CSSManager.Appearance.Dark;
              break;
  
          default:
              console.error("Unknown default appearance name:", protocolName);
              break;
          }
  
          this._defaultAppearance = appearance;
  
          this.mediaQueryResultChanged();
  
          this.dispatchEventToListeners(WI.CSSManager.Event.DefaultAppearanceDidChange, {appearance});
      }
  
      get modifiedStyles()
      {
          return Array.from(this._modifiedStyles.values());
      }
  
      addModifiedStyle(style)
      {
          this._modifiedStyles.set(style.stringId, style);
      }
  
      getModifiedStyle(style)
      {
          return this._modifiedStyles.get(style.stringId);
      }
  
      removeModifiedStyle(style)
      {
          this._modifiedStyles.delete(style.stringId);
      }
  
      // Protected
  
      mediaQueryResultChanged()
      {
          // Called from WI.CSSObserver.
  
          for (var key in this._nodeStylesMap)
              this._nodeStylesMap[key].mediaQueryResultDidChange();
      }
  
      styleSheetChanged(styleSheetIdentifier)
      {
          // Called from WI.CSSObserver.
          var styleSheet = this.styleSheetForIdentifier(styleSheetIdentifier);
          console.assert(styleSheet);
  
          // Do not observe inline styles
          if (styleSheet.isInlineStyleAttributeStyleSheet())
              return;
  
          styleSheet.noteContentDidChange();
          this._updateResourceContent(styleSheet);
      }
  
      styleSheetAdded(styleSheetInfo)
      {
          console.assert(!this._styleSheetIdentifierMap.has(styleSheetInfo.styleSheetId), "Attempted to add a CSSStyleSheet but identifier was already in use");
          let styleSheet = this.styleSheetForIdentifier(styleSheetInfo.styleSheetId);
          let parentFrame = WI.networkManager.frameForIdentifier(styleSheetInfo.frameId);
          let origin = WI.CSSManager.protocolStyleSheetOriginToEnum(styleSheetInfo.origin);
          styleSheet.updateInfo(styleSheetInfo.sourceURL, parentFrame, origin, styleSheetInfo.isInline, styleSheetInfo.startLine, styleSheetInfo.startColumn);
  
          this.dispatchEventToListeners(WI.CSSManager.Event.StyleSheetAdded, {styleSheet});
      }
  
      styleSheetRemoved(styleSheetIdentifier)
      {
          let styleSheet = this._styleSheetIdentifierMap.get(styleSheetIdentifier);
          console.assert(styleSheet, "Attempted to remove a CSSStyleSheet that was not tracked");
          if (!styleSheet)
              return;
  
          this._styleSheetIdentifierMap.delete(styleSheetIdentifier);
  
          this.dispatchEventToListeners(WI.CSSManager.Event.StyleSheetRemoved, {styleSheet});
      }
  
      // Private
  
      _nodePseudoClassesDidChange(event)
      {
          var node = event.target;
  
          for (var key in this._nodeStylesMap) {
              var nodeStyles = this._nodeStylesMap[key];
              if (nodeStyles.node !== node && !nodeStyles.node.isDescendant(node))
                  continue;
              nodeStyles.pseudoClassesDidChange(node);
          }
      }
  
      _nodeAttributesDidChange(event)
      {
          var node = event.target;
  
          for (var key in this._nodeStylesMap) {
              var nodeStyles = this._nodeStylesMap[key];
              if (nodeStyles.node !== node && !nodeStyles.node.isDescendant(node))
                  continue;
              nodeStyles.attributeDidChange(node, event.data.name);
          }
      }
  
      _mainResourceDidChange(event)
      {
          console.assert(event.target instanceof WI.Frame);
  
          if (!event.target.isMainFrame())
              return;
  
          // Clear our maps when the main frame navigates.
  
          this._fetchedInitialStyleSheets = InspectorBackend.domains.CSS.hasEvent("styleSheetAdded");
          this._styleSheetIdentifierMap.clear();
          this._styleSheetFrameURLMap.clear();
          this._modifiedStyles.clear();
  
          this._nodeStylesMap = {};
      }
  
      _resourceAdded(event)
      {
          console.assert(event.target instanceof WI.Frame);
  
          var resource = event.data.resource;
          console.assert(resource);
  
          if (resource.type !== WI.Resource.Type.Stylesheet)
              return;
  
          this._clearStyleSheetsForResource(resource);
      }
  
      _resourceTypeDidChange(event)
      {
          console.assert(event.target instanceof WI.Resource);
  
          var resource = event.target;
          if (resource.type !== WI.Resource.Type.Stylesheet)
              return;
  
          this._clearStyleSheetsForResource(resource);
      }
  
      _clearStyleSheetsForResource(resource)
      {
          // Clear known stylesheets for this URL and frame. This will cause the stylesheets to
          // be updated next time _fetchInfoForAllStyleSheets is called.
          this._styleSheetIdentifierMap.delete(this._frameURLMapKey(resource.parentFrame, resource.url));
      }
  
      _frameURLMapKey(frame, url)
      {
          return frame.id + ":" + url;
      }
  
      _lookupStyleSheetForResource(resource, callback)
      {
          this._lookupStyleSheet(resource.parentFrame, resource.url, callback);
      }
  
      _lookupStyleSheet(frame, url, callback)
      {
          console.assert(frame instanceof WI.Frame);
  
          let key = this._frameURLMapKey(frame, url);
  
          function styleSheetsFetched()
          {
              callback(this._styleSheetFrameURLMap.get(key) || null);
          }
  
          let styleSheet = this._styleSheetFrameURLMap.get(key) || null;
          if (styleSheet)
              callback(styleSheet);
          else
              this._fetchInfoForAllStyleSheets(styleSheetsFetched.bind(this));
      }
  
      _fetchInfoForAllStyleSheets(callback)
      {
          console.assert(typeof callback === "function");
  
          function processStyleSheets(error, styleSheets)
          {
              this._styleSheetFrameURLMap.clear();
  
              if (error) {
                  callback();
                  return;
              }
  
              for (let styleSheetInfo of styleSheets) {
                  let parentFrame = WI.networkManager.frameForIdentifier(styleSheetInfo.frameId);
                  let origin = WI.CSSManager.protocolStyleSheetOriginToEnum(styleSheetInfo.origin);
  
                  // COMPATIBILITY (iOS 9): The info did not have 'isInline', 'startLine', and 'startColumn', so make false and 0 in these cases.
                  let isInline = styleSheetInfo.isInline || false;
                  let startLine = styleSheetInfo.startLine || 0;
                  let startColumn = styleSheetInfo.startColumn || 0;
  
                  let styleSheet = this.styleSheetForIdentifier(styleSheetInfo.styleSheetId);
                  styleSheet.updateInfo(styleSheetInfo.sourceURL, parentFrame, origin, isInline, startLine, startColumn);
  
                  let key = this._frameURLMapKey(parentFrame, styleSheetInfo.sourceURL);
                  this._styleSheetFrameURLMap.set(key, styleSheet);
              }
  
              callback();
          }
  
          CSSAgent.getAllStyleSheets(processStyleSheets.bind(this));
      }
  
      _resourceContentDidChange(event)
      {
          var resource = event.target;
          if (resource === this._ignoreResourceContentDidChangeEventForResource)
              return;
  
          // Ignore if it isn't a CSS stylesheet.
          if (resource.type !== WI.Resource.Type.Stylesheet || resource.syntheticMIMEType !== "text/css")
              return;
  
          function applyStyleSheetChanges()
          {
              function styleSheetFound(styleSheet)
              {
                  resource.__pendingChangeTimeout.cancel();
  
                  console.assert(styleSheet);
                  if (!styleSheet)
                      return;
  
                  // To prevent updating a TextEditor's content while the user is typing in it we want to
                  // ignore the next _updateResourceContent call.
                  resource.__ignoreNextUpdateResourceContent = true;
  
                  WI.branchManager.currentBranch.revisionForRepresentedObject(styleSheet).content = resource.content;
              }
  
              this._lookupStyleSheetForResource(resource, styleSheetFound.bind(this));
          }
  
          if (!resource.__pendingChangeTimeout)
              resource.__pendingChangeTimeout = new Throttler(applyStyleSheetChanges.bind(this), 100);
          resource.__pendingChangeTimeout.fire();
      }
  
      _updateResourceContent(styleSheet)
      {
          console.assert(styleSheet);
  
          function fetchedStyleSheetContent(parameters)
          {
              styleSheet.__pendingChangeTimeout.cancel();
  
              let representedObject = parameters.sourceCode;
  
              console.assert(representedObject.url);
              if (!representedObject.url)
                  return;
  
              if (!styleSheet.isInspectorStyleSheet()) {
                  representedObject = representedObject.parentFrame.resourceForURL(representedObject.url);
                  if (!representedObject)
                      return;
  
                  // Only try to update stylesheet resources. Other resources, like documents, can contain
                  // multiple stylesheets and we don't have the source ranges to update those.
                  if (representedObject.type !== WI.Resource.Type.Stylesheet)
                      return;
              }
  
              if (representedObject.__ignoreNextUpdateResourceContent) {
                  representedObject.__ignoreNextUpdateResourceContent = false;
                  return;
              }
  
              this._ignoreResourceContentDidChangeEventForResource = representedObject;
  
              let revision = WI.branchManager.currentBranch.revisionForRepresentedObject(representedObject);
              if (styleSheet.isInspectorStyleSheet()) {
                  revision.content = representedObject.content;
                  styleSheet.dispatchEventToListeners(WI.SourceCode.Event.ContentDidChange);
              } else
                  revision.content = parameters.content;
  
              this._ignoreResourceContentDidChangeEventForResource = null;
          }
  
          function styleSheetReady()
          {
              styleSheet.requestContent().then(fetchedStyleSheetContent.bind(this));
          }
  
          function applyStyleSheetChanges()
          {
              if (styleSheet.url)
                  styleSheetReady.call(this);
              else
                  this._fetchInfoForAllStyleSheets(styleSheetReady.bind(this));
          }
  
          if (!styleSheet.__pendingChangeTimeout)
              styleSheet.__pendingChangeTimeout = new Throttler(applyStyleSheetChanges.bind(this), 100);
          styleSheet.__pendingChangeTimeout.fire();
      }
  };
  
  WI.CSSManager.Event = {
      StyleSheetAdded: "css-manager-style-sheet-added",
      StyleSheetRemoved: "css-manager-style-sheet-removed",
      DefaultAppearanceDidChange: "css-manager-default-appearance-did-change",
      ForcedAppearanceDidChange: "css-manager-forced-appearance-did-change",
  };
  
  WI.CSSManager.Appearance = {
      Light: Symbol("light"),
      Dark: Symbol("dark"),
  };
  
  WI.CSSManager.PseudoElementNames = ["before", "after"];
  WI.CSSManager.ForceablePseudoClasses = ["active", "focus", "hover", "visited"];
  WI.CSSManager.PreferredInspectorStyleSheetSymbol = Symbol("css-manager-preferred-inspector-stylesheet");
  