LCOV - code coverage report
Current view: top level - layout/inspector - inDOMUtils.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 599 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 50 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : #include "mozilla/ArrayUtils.h"
       7             : #include "mozilla/EventStates.h"
       8             : 
       9             : #include "inDOMUtils.h"
      10             : #include "inLayoutUtils.h"
      11             : 
      12             : #include "nsArray.h"
      13             : #include "nsAutoPtr.h"
      14             : #include "nsIServiceManager.h"
      15             : #include "nsString.h"
      16             : #include "nsIStyleSheetLinkingElement.h"
      17             : #include "nsIContentInlines.h"
      18             : #include "nsIDOMElement.h"
      19             : #include "nsIDocument.h"
      20             : #include "nsIPresShell.h"
      21             : #include "nsIDOMDocument.h"
      22             : #include "nsIDOMCharacterData.h"
      23             : #include "nsRuleNode.h"
      24             : #include "nsIStyleRule.h"
      25             : #include "mozilla/css/StyleRule.h"
      26             : #include "nsICSSStyleRuleDOMWrapper.h"
      27             : #include "nsIDOMWindow.h"
      28             : #include "nsXBLBinding.h"
      29             : #include "nsXBLPrototypeBinding.h"
      30             : #include "nsIMutableArray.h"
      31             : #include "nsBindingManager.h"
      32             : #include "ChildIterator.h"
      33             : #include "nsComputedDOMStyle.h"
      34             : #include "mozilla/EventStateManager.h"
      35             : #include "nsIAtom.h"
      36             : #include "nsRange.h"
      37             : #include "nsContentList.h"
      38             : #include "mozilla/StyleSheetInlines.h"
      39             : #include "mozilla/dom/Element.h"
      40             : #include "nsRuleWalker.h"
      41             : #include "nsCSSPseudoClasses.h"
      42             : #include "nsCSSRuleProcessor.h"
      43             : #include "mozilla/dom/CSSLexer.h"
      44             : #include "mozilla/dom/InspectorUtilsBinding.h"
      45             : #include "mozilla/dom/ToJSValue.h"
      46             : #include "nsCSSParser.h"
      47             : #include "nsCSSProps.h"
      48             : #include "nsCSSValue.h"
      49             : #include "nsColor.h"
      50             : #include "mozilla/StyleSetHandleInlines.h"
      51             : #include "nsStyleUtil.h"
      52             : #include "nsQueryObject.h"
      53             : #include "mozilla/ServoBindings.h"
      54             : #include "mozilla/ServoStyleRule.h"
      55             : #include "mozilla/ServoStyleRuleMap.h"
      56             : 
      57             : using namespace mozilla;
      58             : using namespace mozilla::css;
      59             : using namespace mozilla::dom;
      60             : 
      61             : ///////////////////////////////////////////////////////////////////////////////
      62             : 
      63           0 : inDOMUtils::inDOMUtils()
      64             : {
      65           0 : }
      66             : 
      67           0 : inDOMUtils::~inDOMUtils()
      68             : {
      69           0 : }
      70             : 
      71           0 : NS_IMPL_ISUPPORTS(inDOMUtils, inIDOMUtils)
      72             : 
      73             : ///////////////////////////////////////////////////////////////////////////////
      74             : // inIDOMUtils
      75             : 
      76             : NS_IMETHODIMP
      77           0 : inDOMUtils::GetAllStyleSheets(nsIDOMDocument *aDocument, uint32_t *aLength,
      78             :                               nsISupports ***aSheets)
      79             : {
      80           0 :   NS_ENSURE_ARG_POINTER(aDocument);
      81             : 
      82           0 :   nsTArray<RefPtr<StyleSheet>> sheets;
      83             : 
      84           0 :   nsCOMPtr<nsIDocument> document = do_QueryInterface(aDocument);
      85           0 :   MOZ_ASSERT(document);
      86             : 
      87             :   // Get the agent, then user and finally xbl sheets in the style set.
      88           0 :   nsIPresShell* presShell = document->GetShell();
      89             : 
      90           0 :   if (presShell) {
      91           0 :     StyleSetHandle styleSet = presShell->StyleSet();
      92           0 :     SheetType sheetType = SheetType::Agent;
      93           0 :     for (int32_t i = 0; i < styleSet->SheetCount(sheetType); i++) {
      94           0 :       sheets.AppendElement(styleSet->StyleSheetAt(sheetType, i));
      95             :     }
      96           0 :     sheetType = SheetType::User;
      97           0 :     for (int32_t i = 0; i < styleSet->SheetCount(sheetType); i++) {
      98           0 :       sheets.AppendElement(styleSet->StyleSheetAt(sheetType, i));
      99             :     }
     100             : 
     101           0 :     AutoTArray<StyleSheet*, 32> xblSheetArray;
     102           0 :     styleSet->AppendAllXBLStyleSheets(xblSheetArray);
     103             : 
     104             :     // The XBL stylesheet array will quite often be full of duplicates. Cope:
     105           0 :     nsTHashtable<nsPtrHashKey<StyleSheet>> sheetSet;
     106           0 :     for (StyleSheet* sheet : xblSheetArray) {
     107           0 :       if (!sheetSet.Contains(sheet)) {
     108           0 :         sheetSet.PutEntry(sheet);
     109           0 :         sheets.AppendElement(sheet);
     110             :       }
     111             :     }
     112             :   }
     113             : 
     114             :   // Get the document sheets.
     115           0 :   for (int32_t i = 0; i < document->GetNumberOfStyleSheets(); i++) {
     116           0 :     sheets.AppendElement(document->GetStyleSheetAt(i));
     117             :   }
     118             : 
     119           0 :   nsISupports** ret = static_cast<nsISupports**>(moz_xmalloc(sheets.Length() *
     120           0 :                                                  sizeof(nsISupports*)));
     121             : 
     122           0 :   for (size_t i = 0; i < sheets.Length(); i++) {
     123           0 :     NS_ADDREF(ret[i] = NS_ISUPPORTS_CAST(nsIDOMCSSStyleSheet*, sheets[i]));
     124             :   }
     125             : 
     126           0 :   *aLength = sheets.Length();
     127           0 :   *aSheets = ret;
     128             : 
     129           0 :   return NS_OK;
     130             : }
     131             : 
     132             : NS_IMETHODIMP
     133           0 : inDOMUtils::IsIgnorableWhitespace(nsIDOMCharacterData *aDataNode,
     134             :                                   bool *aReturn)
     135             : {
     136           0 :   NS_PRECONDITION(aReturn, "Must have an out parameter");
     137             : 
     138           0 :   NS_ENSURE_ARG_POINTER(aDataNode);
     139             : 
     140           0 :   *aReturn = false;
     141             : 
     142           0 :   nsCOMPtr<nsIContent> content = do_QueryInterface(aDataNode);
     143           0 :   NS_ASSERTION(content, "Does not implement nsIContent!");
     144             : 
     145           0 :   if (!content->TextIsOnlyWhitespace()) {
     146           0 :     return NS_OK;
     147             :   }
     148             : 
     149             :   // Okay.  We have only white space.  Let's check the white-space
     150             :   // property now and make sure that this isn't preformatted text...
     151           0 :   nsIFrame* frame = content->GetPrimaryFrame();
     152           0 :   if (frame) {
     153           0 :     const nsStyleText* text = frame->StyleText();
     154           0 :     *aReturn = !text->WhiteSpaceIsSignificant();
     155             :   }
     156             :   else {
     157             :     // empty inter-tag text node without frame, e.g., in between <table>\n<tr>
     158           0 :     *aReturn = true;
     159             :   }
     160             : 
     161           0 :   return NS_OK;
     162             : }
     163             : 
     164             : NS_IMETHODIMP
     165           0 : inDOMUtils::GetParentForNode(nsIDOMNode* aNode,
     166             :                              bool aShowingAnonymousContent,
     167             :                              nsIDOMNode** aParent)
     168             : {
     169           0 :   NS_ENSURE_ARG_POINTER(aNode);
     170             : 
     171             :   // First do the special cases -- document nodes and anonymous content
     172           0 :   nsCOMPtr<nsIDocument> doc(do_QueryInterface(aNode));
     173           0 :   nsCOMPtr<nsIDOMNode> parent;
     174             : 
     175           0 :   if (doc) {
     176           0 :     parent = inLayoutUtils::GetContainerFor(*doc);
     177           0 :   } else if (aShowingAnonymousContent) {
     178           0 :     nsCOMPtr<nsIContent> content = do_QueryInterface(aNode);
     179           0 :     if (content) {
     180           0 :       nsIContent* bparent = content->GetFlattenedTreeParent();
     181           0 :       parent = do_QueryInterface(bparent);
     182             :     }
     183             :   }
     184             : 
     185           0 :   if (!parent) {
     186             :     // Ok, just get the normal DOM parent node
     187           0 :     aNode->GetParentNode(getter_AddRefs(parent));
     188             :   }
     189             : 
     190           0 :   NS_IF_ADDREF(*aParent = parent);
     191           0 :   return NS_OK;
     192             : }
     193             : 
     194             : NS_IMETHODIMP
     195           0 : inDOMUtils::GetChildrenForNode(nsIDOMNode* aNode,
     196             :                                bool aShowingAnonymousContent,
     197             :                                nsIDOMNodeList** aChildren)
     198             : {
     199           0 :   NS_ENSURE_ARG_POINTER(aNode);
     200           0 :   NS_PRECONDITION(aChildren, "Must have an out parameter");
     201             : 
     202           0 :   nsCOMPtr<nsIDOMNodeList> kids;
     203             : 
     204           0 :   if (aShowingAnonymousContent) {
     205           0 :     nsCOMPtr<nsIContent> content = do_QueryInterface(aNode);
     206           0 :     if (content) {
     207           0 :       kids = content->GetChildren(nsIContent::eAllChildren);
     208             :     }
     209             :   }
     210             : 
     211           0 :   if (!kids) {
     212           0 :     aNode->GetChildNodes(getter_AddRefs(kids));
     213             :   }
     214             : 
     215           0 :   kids.forget(aChildren);
     216           0 :   return NS_OK;
     217             : }
     218             : 
     219             : NS_IMETHODIMP
     220           0 : inDOMUtils::GetCSSStyleRules(nsIDOMElement *aElement,
     221             :                              const nsAString& aPseudo,
     222             :                              nsIArrayExtensions **_retval)
     223             : {
     224           0 :   NS_ENSURE_ARG_POINTER(aElement);
     225             : 
     226           0 :   *_retval = nullptr;
     227             : 
     228           0 :   nsCOMPtr<nsIAtom> pseudoElt;
     229           0 :   if (!aPseudo.IsEmpty()) {
     230           0 :     pseudoElt = NS_Atomize(aPseudo);
     231             :   }
     232             : 
     233           0 :   nsCOMPtr<Element> element = do_QueryInterface(aElement);
     234           0 :   NS_ENSURE_STATE(element);
     235             :   RefPtr<nsStyleContext> styleContext =
     236           0 :     GetCleanStyleContextForElement(element, pseudoElt);
     237           0 :   if (!styleContext) {
     238             :     // This can fail for elements that are not in the document or
     239             :     // if the document they're in doesn't have a presshell.  Bail out.
     240           0 :     return NS_OK;
     241             :   }
     242             : 
     243             : 
     244           0 :   nsCOMPtr<nsIMutableArray> rules = nsArray::Create();
     245           0 :   if (auto gecko = styleContext->GetAsGecko()) {
     246           0 :     nsRuleNode* ruleNode = gecko->RuleNode();
     247           0 :     if (!ruleNode) {
     248           0 :       return NS_OK;
     249             :     }
     250             : 
     251           0 :     AutoTArray<nsRuleNode*, 16> ruleNodes;
     252           0 :     while (!ruleNode->IsRoot()) {
     253           0 :       ruleNodes.AppendElement(ruleNode);
     254           0 :       ruleNode = ruleNode->GetParent();
     255             :     }
     256             : 
     257           0 :     for (nsRuleNode* ruleNode : Reversed(ruleNodes)) {
     258           0 :       RefPtr<Declaration> decl = do_QueryObject(ruleNode->GetRule());
     259           0 :       if (decl) {
     260           0 :         css::Rule* owningRule = decl->GetOwningRule();
     261           0 :         if (owningRule) {
     262           0 :           rules->AppendElement(owningRule, /*weak =*/ false);
     263             :         }
     264             :       }
     265             :     }
     266             :   } else {
     267           0 :     nsIDocument* doc = element->GetOwnerDocument();
     268           0 :     nsIPresShell* shell = doc->GetShell();
     269           0 :     if (!shell) {
     270           0 :       return NS_OK;
     271             :     }
     272             : 
     273           0 :     ServoStyleContext* servo = styleContext->AsServo();
     274           0 :     nsTArray<const RawServoStyleRule*> rawRuleList;
     275           0 :     Servo_ComputedValues_GetStyleRuleList(servo->ComputedValues(),
     276           0 :                                           &rawRuleList);
     277             : 
     278           0 :     ServoStyleSet* styleSet = shell->StyleSet()->AsServo();
     279           0 :     ServoStyleRuleMap* map = styleSet->StyleRuleMap();
     280           0 :     map->EnsureTable();
     281             : 
     282             :     // Find matching rules in the table.
     283           0 :     for (const RawServoStyleRule* rawRule : Reversed(rawRuleList)) {
     284           0 :       if (ServoStyleRule* rule = map->Lookup(rawRule)) {
     285           0 :         rules->AppendElement(static_cast<css::Rule*>(rule), false);
     286             :       } else {
     287           0 :         MOZ_ASSERT_UNREACHABLE("We should be able to map a raw rule to a rule");
     288             :       }
     289             :     }
     290             :   }
     291             : 
     292           0 :   rules.forget(_retval);
     293             : 
     294           0 :   return NS_OK;
     295             : }
     296             : 
     297             : static already_AddRefed<BindingStyleRule>
     298           0 : GetRuleFromDOMRule(nsIDOMCSSStyleRule *aRule, ErrorResult& rv)
     299             : {
     300           0 :   nsCOMPtr<nsICSSStyleRuleDOMWrapper> rule = do_QueryInterface(aRule);
     301           0 :   if (!rule) {
     302           0 :     rv.Throw(NS_ERROR_INVALID_POINTER);
     303           0 :     return nullptr;
     304             :   }
     305             : 
     306           0 :   RefPtr<BindingStyleRule> cssrule;
     307           0 :   rv = rule->GetCSSStyleRule(getter_AddRefs(cssrule));
     308           0 :   if (rv.Failed()) {
     309           0 :     return nullptr;
     310             :   }
     311             : 
     312           0 :   if (!cssrule) {
     313           0 :     rv.Throw(NS_ERROR_FAILURE);
     314             :   }
     315           0 :   return cssrule.forget();
     316             : }
     317             : 
     318             : NS_IMETHODIMP
     319           0 : inDOMUtils::GetRuleLine(nsIDOMCSSRule* aRule, uint32_t* _retval)
     320             : {
     321           0 :   NS_ENSURE_ARG_POINTER(aRule);
     322             : 
     323           0 :   Rule* rule = aRule->GetCSSRule();
     324           0 :   if (!rule) {
     325           0 :     return NS_ERROR_FAILURE;
     326             :   }
     327             : 
     328           0 :   *_retval = rule->GetLineNumber();
     329           0 :   return NS_OK;
     330             : }
     331             : 
     332             : NS_IMETHODIMP
     333           0 : inDOMUtils::GetRuleColumn(nsIDOMCSSRule* aRule, uint32_t* _retval)
     334             : {
     335           0 :   NS_ENSURE_ARG_POINTER(aRule);
     336             : 
     337           0 :   Rule* rule = aRule->GetCSSRule();
     338           0 :   if (!rule) {
     339           0 :     return NS_ERROR_FAILURE;
     340             :   }
     341             : 
     342           0 :   *_retval = rule->GetColumnNumber();
     343           0 :   return NS_OK;
     344             : }
     345             : 
     346             : NS_IMETHODIMP
     347           0 : inDOMUtils::GetRelativeRuleLine(nsIDOMCSSRule* aRule, uint32_t* _retval)
     348             : {
     349           0 :   NS_ENSURE_ARG_POINTER(aRule);
     350             : 
     351           0 :   Rule* rule = aRule->GetCSSRule();
     352           0 :   if (!rule) {
     353           0 :     return NS_ERROR_FAILURE;
     354             :   }
     355             : 
     356           0 :   uint32_t lineNumber = rule->GetLineNumber();
     357           0 :   StyleSheet* sheet = rule->GetStyleSheet();
     358           0 :   if (sheet && lineNumber != 0) {
     359           0 :     nsINode* owningNode = sheet->GetOwnerNode();
     360           0 :     if (owningNode) {
     361             :       nsCOMPtr<nsIStyleSheetLinkingElement> link =
     362           0 :         do_QueryInterface(owningNode);
     363           0 :       if (link) {
     364           0 :         lineNumber -= link->GetLineNumber() - 1;
     365             :       }
     366             :     }
     367             :   }
     368             : 
     369           0 :   *_retval = lineNumber;
     370           0 :   return NS_OK;
     371             : }
     372             : 
     373             : NS_IMETHODIMP
     374           0 : inDOMUtils::GetCSSLexer(const nsAString& aText, JSContext* aCx,
     375             :                         JS::MutableHandleValue aResult)
     376             : {
     377           0 :   MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
     378           0 :   JS::Rooted<JSObject*> scope(aCx, JS::CurrentGlobalOrNull(aCx));
     379           0 :   nsAutoPtr<CSSLexer> lexer(new CSSLexer(aText));
     380           0 :   if (!WrapNewBindingNonWrapperCachedObject(aCx, scope, lexer, aResult)) {
     381           0 :     return NS_ERROR_FAILURE;
     382             :   }
     383           0 :   return NS_OK;
     384             : }
     385             : 
     386             : NS_IMETHODIMP
     387           0 : inDOMUtils::GetSelectorCount(nsIDOMCSSStyleRule* aRule, uint32_t *aCount)
     388             : {
     389           0 :   ErrorResult rv;
     390           0 :   RefPtr<BindingStyleRule> rule = GetRuleFromDOMRule(aRule, rv);
     391           0 :   if (rv.Failed()) {
     392           0 :     return rv.StealNSResult();
     393             :   }
     394             : 
     395           0 :   *aCount = rule->GetSelectorCount();
     396             : 
     397           0 :   return NS_OK;
     398             : }
     399             : 
     400             : NS_IMETHODIMP
     401           0 : inDOMUtils::GetSelectorText(nsIDOMCSSStyleRule* aRule,
     402             :                             uint32_t aSelectorIndex,
     403             :                             nsAString& aText)
     404             : {
     405           0 :   ErrorResult rv;
     406           0 :   RefPtr<BindingStyleRule> rule = GetRuleFromDOMRule(aRule, rv);
     407           0 :   MOZ_ASSERT(!rv.Failed(), "How could we get a selector but not a rule?");
     408             : 
     409           0 :   return rule->GetSelectorText(aSelectorIndex, aText);
     410             : }
     411             : 
     412             : NS_IMETHODIMP
     413           0 : inDOMUtils::GetSpecificity(nsIDOMCSSStyleRule* aRule,
     414             :                            uint32_t aSelectorIndex,
     415             :                            uint64_t* aSpecificity)
     416             : {
     417           0 :   ErrorResult rv;
     418           0 :   RefPtr<BindingStyleRule> rule = GetRuleFromDOMRule(aRule, rv);
     419           0 :   if (rv.Failed()) {
     420           0 :     return rv.StealNSResult();
     421             :   }
     422             : 
     423           0 :   return rule->GetSpecificity(aSelectorIndex, aSpecificity);
     424             : }
     425             : 
     426             : NS_IMETHODIMP
     427           0 : inDOMUtils::SelectorMatchesElement(nsIDOMElement* aElement,
     428             :                                    nsIDOMCSSStyleRule* aRule,
     429             :                                    uint32_t aSelectorIndex,
     430             :                                    const nsAString& aPseudo,
     431             :                                    bool* aMatches)
     432             : {
     433           0 :   nsCOMPtr<Element> element = do_QueryInterface(aElement);
     434           0 :   NS_ENSURE_ARG_POINTER(element);
     435             : 
     436           0 :   ErrorResult rv;
     437           0 :   RefPtr<BindingStyleRule> rule = GetRuleFromDOMRule(aRule, rv);
     438           0 :   if (rv.Failed()) {
     439           0 :     return rv.StealNSResult();
     440             :   }
     441             : 
     442           0 :   return rule->SelectorMatchesElement(element, aSelectorIndex, aPseudo,
     443           0 :                                       aMatches);
     444             : }
     445             : 
     446             : NS_IMETHODIMP
     447           0 : inDOMUtils::IsInheritedProperty(const nsAString &aPropertyName, bool *_retval)
     448             : {
     449             :   nsCSSPropertyID prop = nsCSSProps::
     450           0 :     LookupProperty(aPropertyName, CSSEnabledState::eIgnoreEnabledState);
     451           0 :   if (prop == eCSSProperty_UNKNOWN) {
     452           0 :     *_retval = false;
     453           0 :     return NS_OK;
     454             :   }
     455             : 
     456           0 :   if (prop == eCSSPropertyExtra_variable) {
     457           0 :     *_retval = true;
     458           0 :     return NS_OK;
     459             :   }
     460             : 
     461           0 :   if (nsCSSProps::IsShorthand(prop)) {
     462           0 :     prop = nsCSSProps::SubpropertyEntryFor(prop)[0];
     463             :   }
     464             : 
     465           0 :   nsStyleStructID sid = nsCSSProps::kSIDTable[prop];
     466           0 :   *_retval = !nsCachedStyleData::IsReset(sid);
     467           0 :   return NS_OK;
     468             : }
     469             : 
     470             : extern const char* const kCSSRawProperties[];
     471             : 
     472             : NS_IMETHODIMP
     473           0 : inDOMUtils::GetCSSPropertyNames(uint32_t aFlags, uint32_t* aCount,
     474             :                                 char16_t*** aProps)
     475             : {
     476             :   // maxCount is the largest number of properties we could have; our actual
     477             :   // number might be smaller because properties might be disabled.
     478             :   uint32_t maxCount;
     479           0 :   if (aFlags & EXCLUDE_SHORTHANDS) {
     480           0 :     maxCount = eCSSProperty_COUNT_no_shorthands;
     481             :   } else {
     482           0 :     maxCount = eCSSProperty_COUNT;
     483             :   }
     484             : 
     485           0 :   if (aFlags & INCLUDE_ALIASES) {
     486           0 :     maxCount += (eCSSProperty_COUNT_with_aliases - eCSSProperty_COUNT);
     487             :   }
     488             : 
     489             :   char16_t** props =
     490           0 :     static_cast<char16_t**>(moz_xmalloc(maxCount * sizeof(char16_t*)));
     491             : 
     492             : #define DO_PROP(_prop)                                                      \
     493             :   PR_BEGIN_MACRO                                                            \
     494             :     nsCSSPropertyID cssProp = nsCSSPropertyID(_prop);                           \
     495             :     if (nsCSSProps::IsEnabled(cssProp, CSSEnabledState::eForAllContent)) {  \
     496             :       props[propCount] =                                                    \
     497             :         ToNewUnicode(nsDependentCString(kCSSRawProperties[_prop]));         \
     498             :       ++propCount;                                                          \
     499             :     }                                                                       \
     500             :   PR_END_MACRO
     501             : 
     502             :   // prop is the property id we're considering; propCount is how many properties
     503             :   // we've put into props so far.
     504           0 :   uint32_t prop = 0, propCount = 0;
     505           0 :   for ( ; prop < eCSSProperty_COUNT_no_shorthands; ++prop) {
     506           0 :     if (nsCSSProps::PropertyParseType(nsCSSPropertyID(prop)) !=
     507             :         CSS_PROPERTY_PARSE_INACCESSIBLE) {
     508           0 :       DO_PROP(prop);
     509             :     }
     510             :   }
     511             : 
     512           0 :   if (!(aFlags & EXCLUDE_SHORTHANDS)) {
     513           0 :     for ( ; prop < eCSSProperty_COUNT; ++prop) {
     514             :       // Some shorthands are also aliases
     515           0 :       if ((aFlags & INCLUDE_ALIASES) ||
     516           0 :           !nsCSSProps::PropHasFlags(nsCSSPropertyID(prop),
     517             :                                     CSS_PROPERTY_IS_ALIAS)) {
     518           0 :         DO_PROP(prop);
     519             :       }
     520             :     }
     521             :   }
     522             : 
     523           0 :   if (aFlags & INCLUDE_ALIASES) {
     524           0 :     for (prop = eCSSProperty_COUNT; prop < eCSSProperty_COUNT_with_aliases; ++prop) {
     525           0 :       DO_PROP(prop);
     526             :     }
     527             :   }
     528             : 
     529             : #undef DO_PROP
     530             : 
     531           0 :   *aCount = propCount;
     532           0 :   *aProps = props;
     533             : 
     534           0 :   return NS_OK;
     535             : }
     536             : 
     537           0 : static void InsertNoDuplicates(nsTArray<nsString>& aArray,
     538             :                                const nsAString& aString)
     539             : {
     540           0 :   size_t i = aArray.IndexOfFirstElementGt(aString);
     541           0 :   if (i > 0 && aArray[i-1].Equals(aString)) {
     542           0 :     return;
     543             :   }
     544           0 :   aArray.InsertElementAt(i, aString);
     545             : }
     546             : 
     547           0 : static void GetKeywordsForProperty(const nsCSSPropertyID aProperty,
     548             :                                    nsTArray<nsString>& aArray)
     549             : {
     550           0 :   if (nsCSSProps::IsShorthand(aProperty)) {
     551             :     // Shorthand props have no keywords.
     552           0 :     return;
     553             :   }
     554             :   const nsCSSProps::KTableEntry* keywordTable =
     555           0 :     nsCSSProps::kKeywordTableTable[aProperty];
     556           0 :   if (keywordTable) {
     557           0 :     for (size_t i = 0; keywordTable[i].mKeyword != eCSSKeyword_UNKNOWN; ++i) {
     558           0 :       nsCSSKeyword word = keywordTable[i].mKeyword;
     559             : 
     560             :       // These are extra -moz values which are added while rebuilding
     561             :       // the properties db. These values are not relevant and are not
     562             :       // documented on MDN, so filter these out
     563           0 :       if (word != eCSSKeyword__moz_zoom_in && word != eCSSKeyword__moz_zoom_out &&
     564           0 :           word != eCSSKeyword__moz_grab && word != eCSSKeyword__moz_grabbing) {
     565             :           InsertNoDuplicates(aArray,
     566           0 :                   NS_ConvertASCIItoUTF16(nsCSSKeywords::GetStringValue(word)));
     567             :       }
     568             :     }
     569             :   }
     570             : }
     571             : 
     572           0 : static void GetColorsForProperty(const uint32_t aParserVariant,
     573             :                                  nsTArray<nsString>& aArray)
     574             : {
     575           0 :   if (aParserVariant & VARIANT_COLOR) {
     576             :     // GetKeywordsForProperty and GetOtherValuesForProperty assume aArray is sorted,
     577             :     // and if aArray is not empty here, then it's not going to be sorted coming out.
     578           0 :     MOZ_ASSERT(aArray.Length() == 0);
     579             :     size_t size;
     580           0 :     const char * const *allColorNames = NS_AllColorNames(&size);
     581           0 :     nsString* utf16Names = aArray.AppendElements(size);
     582           0 :     for (size_t i = 0; i < size; i++) {
     583           0 :       CopyASCIItoUTF16(allColorNames[i], utf16Names[i]);
     584             :     }
     585           0 :     InsertNoDuplicates(aArray, NS_LITERAL_STRING("currentColor"));
     586             :   }
     587           0 :   return;
     588             : }
     589             : 
     590           0 : static void GetOtherValuesForProperty(const uint32_t aParserVariant,
     591             :                                       nsTArray<nsString>& aArray)
     592             : {
     593           0 :   if (aParserVariant & VARIANT_AUTO) {
     594           0 :     InsertNoDuplicates(aArray, NS_LITERAL_STRING("auto"));
     595             :   }
     596           0 :   if (aParserVariant & VARIANT_NORMAL) {
     597           0 :     InsertNoDuplicates(aArray, NS_LITERAL_STRING("normal"));
     598             :   }
     599           0 :   if(aParserVariant & VARIANT_ALL) {
     600           0 :     InsertNoDuplicates(aArray, NS_LITERAL_STRING("all"));
     601             :   }
     602           0 :   if (aParserVariant & VARIANT_NONE) {
     603           0 :     InsertNoDuplicates(aArray, NS_LITERAL_STRING("none"));
     604             :   }
     605           0 :   if (aParserVariant & VARIANT_ELEMENT) {
     606           0 :     InsertNoDuplicates(aArray, NS_LITERAL_STRING("-moz-element"));
     607             :   }
     608           0 :   if (aParserVariant & VARIANT_IMAGE_RECT) {
     609           0 :     InsertNoDuplicates(aArray, NS_LITERAL_STRING("-moz-image-rect"));
     610             :   }
     611           0 :   if (aParserVariant & VARIANT_COLOR) {
     612           0 :     InsertNoDuplicates(aArray, NS_LITERAL_STRING("rgb"));
     613           0 :     InsertNoDuplicates(aArray, NS_LITERAL_STRING("hsl"));
     614           0 :     InsertNoDuplicates(aArray, NS_LITERAL_STRING("rgba"));
     615           0 :     InsertNoDuplicates(aArray, NS_LITERAL_STRING("hsla"));
     616             :   }
     617           0 :   if (aParserVariant & VARIANT_TIMING_FUNCTION) {
     618           0 :     InsertNoDuplicates(aArray, NS_LITERAL_STRING("cubic-bezier"));
     619           0 :     InsertNoDuplicates(aArray, NS_LITERAL_STRING("steps"));
     620             :   }
     621           0 :   if (aParserVariant & VARIANT_CALC) {
     622           0 :     InsertNoDuplicates(aArray, NS_LITERAL_STRING("calc"));
     623             :   }
     624           0 :   if (aParserVariant & VARIANT_URL) {
     625           0 :     InsertNoDuplicates(aArray, NS_LITERAL_STRING("url"));
     626             :   }
     627           0 :   if (aParserVariant & VARIANT_GRADIENT) {
     628           0 :     InsertNoDuplicates(aArray, NS_LITERAL_STRING("linear-gradient"));
     629           0 :     InsertNoDuplicates(aArray, NS_LITERAL_STRING("radial-gradient"));
     630           0 :     InsertNoDuplicates(aArray, NS_LITERAL_STRING("repeating-linear-gradient"));
     631           0 :     InsertNoDuplicates(aArray, NS_LITERAL_STRING("repeating-radial-gradient"));
     632           0 :     InsertNoDuplicates(aArray, NS_LITERAL_STRING("-moz-linear-gradient"));
     633           0 :     InsertNoDuplicates(aArray, NS_LITERAL_STRING("-moz-radial-gradient"));
     634           0 :     InsertNoDuplicates(aArray, NS_LITERAL_STRING("-moz-repeating-linear-gradient"));
     635           0 :     InsertNoDuplicates(aArray, NS_LITERAL_STRING("-moz-repeating-radial-gradient"));
     636             :   }
     637           0 : }
     638             : 
     639             : NS_IMETHODIMP
     640           0 : inDOMUtils::GetSubpropertiesForCSSProperty(const nsAString& aProperty,
     641             :                                            uint32_t* aLength,
     642             :                                            char16_t*** aValues)
     643             : {
     644             :   nsCSSPropertyID propertyID =
     645           0 :     nsCSSProps::LookupProperty(aProperty, CSSEnabledState::eForAllContent);
     646             : 
     647           0 :   if (propertyID == eCSSProperty_UNKNOWN) {
     648           0 :     return NS_ERROR_FAILURE;
     649             :   }
     650             : 
     651           0 :   if (propertyID == eCSSPropertyExtra_variable) {
     652           0 :     *aValues = static_cast<char16_t**>(moz_xmalloc(sizeof(char16_t*)));
     653           0 :     (*aValues)[0] = ToNewUnicode(aProperty);
     654           0 :     *aLength = 1;
     655           0 :     return NS_OK;
     656             :   }
     657             : 
     658           0 :   if (!nsCSSProps::IsShorthand(propertyID)) {
     659           0 :     *aValues = static_cast<char16_t**>(moz_xmalloc(sizeof(char16_t*)));
     660           0 :     (*aValues)[0] = ToNewUnicode(nsCSSProps::GetStringValue(propertyID));
     661           0 :     *aLength = 1;
     662           0 :     return NS_OK;
     663             :   }
     664             : 
     665             :   // Count up how many subproperties we have.
     666           0 :   size_t subpropCount = 0;
     667           0 :   for (const nsCSSPropertyID *props = nsCSSProps::SubpropertyEntryFor(propertyID);
     668           0 :        *props != eCSSProperty_UNKNOWN; ++props) {
     669           0 :     ++subpropCount;
     670             :   }
     671             : 
     672           0 :   *aValues =
     673           0 :     static_cast<char16_t**>(moz_xmalloc(subpropCount * sizeof(char16_t*)));
     674           0 :   *aLength = subpropCount;
     675           0 :   for (const nsCSSPropertyID *props = nsCSSProps::SubpropertyEntryFor(propertyID),
     676           0 :                            *props_start = props;
     677           0 :        *props != eCSSProperty_UNKNOWN; ++props) {
     678           0 :     (*aValues)[props-props_start] = ToNewUnicode(nsCSSProps::GetStringValue(*props));
     679             :   }
     680           0 :   return NS_OK;
     681             : }
     682             : 
     683             : NS_IMETHODIMP
     684           0 : inDOMUtils::CssPropertyIsShorthand(const nsAString& aProperty, bool *_retval)
     685             : {
     686             :   nsCSSPropertyID propertyID =
     687           0 :     nsCSSProps::LookupProperty(aProperty, CSSEnabledState::eForAllContent);
     688           0 :   if (propertyID == eCSSProperty_UNKNOWN) {
     689           0 :     return NS_ERROR_FAILURE;
     690             :   }
     691             : 
     692           0 :   if (propertyID == eCSSPropertyExtra_variable) {
     693           0 :     *_retval = false;
     694             :   } else {
     695           0 :     *_retval = nsCSSProps::IsShorthand(propertyID);
     696             :   }
     697           0 :   return NS_OK;
     698             : }
     699             : 
     700             : // A helper function that determines whether the given property
     701             : // supports the given type.
     702             : static bool
     703           0 : PropertySupportsVariant(nsCSSPropertyID aPropertyID, uint32_t aVariant)
     704             : {
     705           0 :   if (nsCSSProps::IsShorthand(aPropertyID)) {
     706             :     // We need a special case for border here, because while it resets
     707             :     // border-image, it can't actually parse an image.
     708           0 :     if (aPropertyID == eCSSProperty_border) {
     709           0 :       return (aVariant & (VARIANT_COLOR | VARIANT_LENGTH)) != 0;
     710             :     }
     711             : 
     712           0 :     for (const nsCSSPropertyID* props = nsCSSProps::SubpropertyEntryFor(aPropertyID);
     713           0 :          *props != eCSSProperty_UNKNOWN; ++props) {
     714           0 :       if (PropertySupportsVariant(*props, aVariant)) {
     715           0 :         return true;
     716             :       }
     717             :     }
     718           0 :     return false;
     719             :   }
     720             : 
     721             :   // Properties that are parsed by functions must have their
     722             :   // attributes hand-maintained here.
     723           0 :   if (nsCSSProps::PropHasFlags(aPropertyID, CSS_PROPERTY_VALUE_PARSER_FUNCTION) ||
     724           0 :       nsCSSProps::PropertyParseType(aPropertyID) == CSS_PROPERTY_PARSE_FUNCTION) {
     725             :     // These must all be special-cased.
     726             :     uint32_t supported;
     727           0 :     switch (aPropertyID) {
     728             :       case eCSSProperty_border_image_slice:
     729             :       case eCSSProperty_grid_template:
     730             :       case eCSSProperty_grid:
     731           0 :         supported = VARIANT_PN;
     732           0 :         break;
     733             : 
     734             :       case eCSSProperty_border_image_outset:
     735           0 :         supported = VARIANT_LN;
     736           0 :         break;
     737             : 
     738             :       case eCSSProperty_border_image_width:
     739             :       case eCSSProperty_stroke_dasharray:
     740           0 :         supported = VARIANT_LPN;
     741           0 :         break;
     742             : 
     743             :       case eCSSProperty_border_top_left_radius:
     744             :       case eCSSProperty_border_top_right_radius:
     745             :       case eCSSProperty_border_bottom_left_radius:
     746             :       case eCSSProperty_border_bottom_right_radius:
     747             :       case eCSSProperty_background_position:
     748             :       case eCSSProperty_background_position_x:
     749             :       case eCSSProperty_background_position_y:
     750             :       case eCSSProperty_background_size:
     751             : #ifdef MOZ_ENABLE_MASK_AS_SHORTHAND
     752             :       case eCSSProperty_mask_position:
     753             :       case eCSSProperty_mask_position_x:
     754             :       case eCSSProperty_mask_position_y:
     755             :       case eCSSProperty_mask_size:
     756             : #endif
     757             :       case eCSSProperty_grid_auto_columns:
     758             :       case eCSSProperty_grid_auto_rows:
     759             :       case eCSSProperty_grid_template_columns:
     760             :       case eCSSProperty_grid_template_rows:
     761             :       case eCSSProperty_object_position:
     762             :       case eCSSProperty_scroll_snap_coordinate:
     763             :       case eCSSProperty_scroll_snap_destination:
     764             :       case eCSSProperty_transform_origin:
     765             :       case eCSSProperty_perspective_origin:
     766             :       case eCSSProperty__moz_outline_radius_topleft:
     767             :       case eCSSProperty__moz_outline_radius_topright:
     768             :       case eCSSProperty__moz_outline_radius_bottomleft:
     769             :       case eCSSProperty__moz_outline_radius_bottomright:
     770             :       case eCSSProperty__moz_window_transform_origin:
     771           0 :         supported = VARIANT_LP;
     772           0 :         break;
     773             : 
     774             :       case eCSSProperty__moz_border_bottom_colors:
     775             :       case eCSSProperty__moz_border_left_colors:
     776             :       case eCSSProperty__moz_border_right_colors:
     777             :       case eCSSProperty__moz_border_top_colors:
     778           0 :         supported = VARIANT_COLOR;
     779           0 :         break;
     780             : 
     781             :       case eCSSProperty_text_shadow:
     782             :       case eCSSProperty_box_shadow:
     783           0 :         supported = VARIANT_LENGTH | VARIANT_COLOR;
     784           0 :         break;
     785             : 
     786             :       case eCSSProperty_border_spacing:
     787           0 :         supported = VARIANT_LENGTH;
     788           0 :         break;
     789             : 
     790             :       case eCSSProperty_content:
     791             :       case eCSSProperty_cursor:
     792             :       case eCSSProperty_clip_path:
     793             :       case eCSSProperty_shape_outside:
     794           0 :         supported = VARIANT_URL;
     795           0 :         break;
     796             : 
     797             :       case eCSSProperty_fill:
     798             :       case eCSSProperty_stroke:
     799           0 :         supported = VARIANT_COLOR | VARIANT_URL;
     800           0 :         break;
     801             : 
     802             :       case eCSSProperty_image_orientation:
     803           0 :         supported = VARIANT_ANGLE;
     804           0 :         break;
     805             : 
     806             :       case eCSSProperty_filter:
     807           0 :         supported = VARIANT_URL;
     808           0 :         break;
     809             : 
     810             :       case eCSSProperty_grid_column_start:
     811             :       case eCSSProperty_grid_column_end:
     812             :       case eCSSProperty_grid_row_start:
     813             :       case eCSSProperty_grid_row_end:
     814             :       case eCSSProperty_font_weight:
     815             :       case eCSSProperty_initial_letter:
     816           0 :         supported = VARIANT_NUMBER;
     817           0 :         break;
     818             : 
     819             :       default:
     820           0 :         supported = 0;
     821           0 :         break;
     822             :     }
     823             : 
     824           0 :     return (supported & aVariant) != 0;
     825             :   }
     826             : 
     827           0 :   return (nsCSSProps::ParserVariant(aPropertyID) & aVariant) != 0;
     828             : }
     829             : 
     830             : NS_IMETHODIMP
     831           0 : inDOMUtils::CssPropertySupportsType(const nsAString& aProperty, uint32_t aType,
     832             :                                     bool *_retval)
     833             : {
     834             :   nsCSSPropertyID propertyID =
     835           0 :     nsCSSProps::LookupProperty(aProperty, CSSEnabledState::eForAllContent);
     836           0 :   if (propertyID == eCSSProperty_UNKNOWN) {
     837           0 :     return NS_ERROR_FAILURE;
     838             :   }
     839             : 
     840           0 :   if (propertyID >= eCSSProperty_COUNT) {
     841           0 :     *_retval = false;
     842           0 :     return NS_OK;
     843             :   }
     844             : 
     845             :   uint32_t variant;
     846           0 :   switch (aType) {
     847             :   case TYPE_LENGTH:
     848           0 :     variant = VARIANT_LENGTH;
     849           0 :     break;
     850             :   case TYPE_PERCENTAGE:
     851           0 :     variant = VARIANT_PERCENT;
     852           0 :     break;
     853             :   case TYPE_COLOR:
     854           0 :     variant = VARIANT_COLOR;
     855           0 :     break;
     856             :   case TYPE_URL:
     857           0 :     variant = VARIANT_URL;
     858           0 :     break;
     859             :   case TYPE_ANGLE:
     860           0 :     variant = VARIANT_ANGLE;
     861           0 :     break;
     862             :   case TYPE_FREQUENCY:
     863           0 :     variant = VARIANT_FREQUENCY;
     864           0 :     break;
     865             :   case TYPE_TIME:
     866           0 :     variant = VARIANT_TIME;
     867           0 :     break;
     868             :   case TYPE_GRADIENT:
     869           0 :     variant = VARIANT_GRADIENT;
     870           0 :     break;
     871             :   case TYPE_TIMING_FUNCTION:
     872           0 :     variant = VARIANT_TIMING_FUNCTION;
     873           0 :     break;
     874             :   case TYPE_IMAGE_RECT:
     875           0 :     variant = VARIANT_IMAGE_RECT;
     876           0 :     break;
     877             :   case TYPE_NUMBER:
     878             :     // Include integers under "number"?
     879           0 :     variant = VARIANT_NUMBER | VARIANT_INTEGER;
     880           0 :     break;
     881             :   default:
     882             :     // Unknown type
     883           0 :     return NS_ERROR_NOT_AVAILABLE;
     884             :   }
     885             : 
     886           0 :   *_retval = PropertySupportsVariant(propertyID, variant);
     887           0 :   return NS_OK;
     888             : }
     889             : 
     890             : NS_IMETHODIMP
     891           0 : inDOMUtils::GetCSSValuesForProperty(const nsAString& aProperty,
     892             :                                     uint32_t* aLength,
     893             :                                     char16_t*** aValues)
     894             : {
     895             :   nsCSSPropertyID propertyID = nsCSSProps::
     896           0 :     LookupProperty(aProperty, CSSEnabledState::eForAllContent);
     897           0 :   if (propertyID == eCSSProperty_UNKNOWN) {
     898           0 :     return NS_ERROR_FAILURE;
     899             :   }
     900             : 
     901           0 :   nsTArray<nsString> array;
     902             :   // We start collecting the values, BUT colors need to go in first, because array
     903             :   // needs to stay sorted, and the colors are sorted, so we just append them.
     904           0 :   if (propertyID == eCSSPropertyExtra_variable) {
     905             :     // No other values we can report.
     906           0 :   } else if (!nsCSSProps::IsShorthand(propertyID)) {
     907             :     // Property is longhand.
     908           0 :     uint32_t propertyParserVariant = nsCSSProps::ParserVariant(propertyID);
     909             :     // Get colors first.
     910           0 :     GetColorsForProperty(propertyParserVariant, array);
     911           0 :     GetKeywordsForProperty(propertyID, array);
     912           0 :     GetOtherValuesForProperty(propertyParserVariant, array);
     913             :   } else {
     914             :     // Property is shorthand.
     915           0 :     CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(subproperty, propertyID,
     916             :                                          CSSEnabledState::eForAllContent) {
     917             :       // Get colors (once) first.
     918           0 :       uint32_t propertyParserVariant = nsCSSProps::ParserVariant(*subproperty);
     919           0 :       if (propertyParserVariant & VARIANT_COLOR) {
     920           0 :         GetColorsForProperty(propertyParserVariant, array);
     921           0 :         break;
     922             :       }
     923             :     }
     924           0 :     CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(subproperty, propertyID,
     925             :                                          CSSEnabledState::eForAllContent) {
     926           0 :       uint32_t propertyParserVariant = nsCSSProps::ParserVariant(*subproperty);
     927           0 :       GetKeywordsForProperty(*subproperty, array);
     928           0 :       GetOtherValuesForProperty(propertyParserVariant, array);
     929             :     }
     930             :   }
     931             :   // All CSS properties take initial, inherit and unset.
     932           0 :   InsertNoDuplicates(array, NS_LITERAL_STRING("initial"));
     933           0 :   InsertNoDuplicates(array, NS_LITERAL_STRING("inherit"));
     934           0 :   InsertNoDuplicates(array, NS_LITERAL_STRING("unset"));
     935             : 
     936           0 :   *aLength = array.Length();
     937             :   char16_t** ret =
     938           0 :     static_cast<char16_t**>(moz_xmalloc(*aLength * sizeof(char16_t*)));
     939           0 :   for (uint32_t i = 0; i < *aLength; ++i) {
     940           0 :     ret[i] = ToNewUnicode(array[i]);
     941             :   }
     942           0 :   *aValues = ret;
     943           0 :   return NS_OK;
     944             : }
     945             : 
     946             : NS_IMETHODIMP
     947           0 : inDOMUtils::ColorNameToRGB(const nsAString& aColorName, JSContext* aCx,
     948             :                            JS::MutableHandle<JS::Value> aValue)
     949             : {
     950             :   nscolor color;
     951           0 :   if (!NS_ColorNameToRGB(aColorName, &color)) {
     952           0 :     return NS_ERROR_INVALID_ARG;
     953             :   }
     954             : 
     955           0 :   InspectorRGBTriple triple;
     956           0 :   triple.mR = NS_GET_R(color);
     957           0 :   triple.mG = NS_GET_G(color);
     958           0 :   triple.mB = NS_GET_B(color);
     959             : 
     960           0 :   if (!ToJSValue(aCx, triple, aValue)) {
     961           0 :     return NS_ERROR_FAILURE;
     962             :   }
     963             : 
     964           0 :   return NS_OK;
     965             : }
     966             : 
     967             : NS_IMETHODIMP
     968           0 : inDOMUtils::RgbToColorName(uint8_t aR, uint8_t aG, uint8_t aB,
     969             :                            nsAString& aColorName)
     970             : {
     971           0 :   const char* color = NS_RGBToColorName(NS_RGB(aR, aG, aB));
     972           0 :   if (!color) {
     973           0 :     aColorName.Truncate();
     974           0 :     return NS_ERROR_INVALID_ARG;
     975             :   }
     976             : 
     977           0 :   aColorName.AssignASCII(color);
     978           0 :   return NS_OK;
     979             : }
     980             : 
     981             : NS_IMETHODIMP
     982           0 : inDOMUtils::ColorToRGBA(const nsAString& aColorString, JSContext* aCx,
     983             :                         JS::MutableHandle<JS::Value> aValue)
     984             : {
     985           0 :   nscolor color = 0;
     986           0 :   nsCSSParser cssParser;
     987           0 :   nsCSSValue cssValue;
     988             : 
     989             :   bool isColor = cssParser.ParseColorString(aColorString, nullptr, 0,
     990           0 :                                             cssValue, true);
     991             : 
     992           0 :   if (!isColor) {
     993           0 :     aValue.setNull();
     994           0 :     return NS_OK;
     995             :   }
     996             : 
     997           0 :   nsRuleNode::ComputeColor(cssValue, nullptr, nullptr, color);
     998             : 
     999           0 :   InspectorRGBATuple tuple;
    1000           0 :   tuple.mR = NS_GET_R(color);
    1001           0 :   tuple.mG = NS_GET_G(color);
    1002           0 :   tuple.mB = NS_GET_B(color);
    1003           0 :   tuple.mA = nsStyleUtil::ColorComponentToFloat(NS_GET_A(color));
    1004             : 
    1005           0 :   if (!ToJSValue(aCx, tuple, aValue)) {
    1006           0 :     return NS_ERROR_FAILURE;
    1007             :   }
    1008             : 
    1009           0 :   return NS_OK;
    1010             : }
    1011             : 
    1012             : NS_IMETHODIMP
    1013           0 : inDOMUtils::IsValidCSSColor(const nsAString& aColorString, bool *_retval)
    1014             : {
    1015           0 :   nsCSSParser cssParser;
    1016           0 :   nsCSSValue cssValue;
    1017           0 :   *_retval = cssParser.ParseColorString(aColorString, nullptr, 0, cssValue, true);
    1018           0 :   return NS_OK;
    1019             : }
    1020             : 
    1021             : NS_IMETHODIMP
    1022           0 : inDOMUtils::CssPropertyIsValid(const nsAString& aPropertyName,
    1023             :                                const nsAString& aPropertyValue,
    1024             :                                bool *_retval)
    1025             : {
    1026             :   nsCSSPropertyID propertyID = nsCSSProps::
    1027           0 :     LookupProperty(aPropertyName, CSSEnabledState::eIgnoreEnabledState);
    1028             : 
    1029           0 :   if (propertyID == eCSSProperty_UNKNOWN) {
    1030           0 :     *_retval = false;
    1031           0 :     return NS_OK;
    1032             :   }
    1033             : 
    1034           0 :   if (propertyID == eCSSPropertyExtra_variable) {
    1035           0 :     *_retval = true;
    1036           0 :     return NS_OK;
    1037             :   }
    1038             : 
    1039             :   // Get a parser, parse the property.
    1040           0 :   nsCSSParser parser;
    1041           0 :   *_retval = parser.IsValueValidForProperty(propertyID, aPropertyValue);
    1042             : 
    1043           0 :   return NS_OK;
    1044             : }
    1045             : 
    1046             : NS_IMETHODIMP
    1047           0 : inDOMUtils::GetBindingURLs(nsIDOMElement *aElement, nsIArray **_retval)
    1048             : {
    1049           0 :   NS_ENSURE_ARG_POINTER(aElement);
    1050             : 
    1051           0 :   *_retval = nullptr;
    1052             : 
    1053           0 :   nsCOMPtr<nsIMutableArray> urls = do_CreateInstance(NS_ARRAY_CONTRACTID);
    1054           0 :   if (!urls)
    1055           0 :     return NS_ERROR_FAILURE;
    1056             : 
    1057           0 :   nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
    1058           0 :   NS_ENSURE_ARG_POINTER(content);
    1059             : 
    1060           0 :   nsXBLBinding *binding = content->GetXBLBinding();
    1061             : 
    1062           0 :   while (binding) {
    1063           0 :     urls->AppendElement(binding->PrototypeBinding()->BindingURI(), false);
    1064           0 :     binding = binding->GetBaseBinding();
    1065             :   }
    1066             : 
    1067           0 :   urls.forget(_retval);
    1068           0 :   return NS_OK;
    1069             : }
    1070             : 
    1071             : NS_IMETHODIMP
    1072           0 : inDOMUtils::SetContentState(nsIDOMElement* aElement,
    1073             :                             EventStates::InternalType aState,
    1074             :                             bool* aRetVal)
    1075             : {
    1076           0 :   NS_ENSURE_ARG_POINTER(aElement);
    1077             : 
    1078             :   RefPtr<EventStateManager> esm =
    1079           0 :     inLayoutUtils::GetEventStateManagerFor(aElement);
    1080           0 :   NS_ENSURE_TRUE(esm, NS_ERROR_INVALID_ARG);
    1081             : 
    1082           0 :   nsCOMPtr<nsIContent> content;
    1083           0 :   content = do_QueryInterface(aElement);
    1084           0 :   NS_ENSURE_TRUE(content, NS_ERROR_INVALID_ARG);
    1085             : 
    1086           0 :   *aRetVal = esm->SetContentState(content, EventStates(aState));
    1087           0 :   return NS_OK;
    1088             : }
    1089             : 
    1090             : NS_IMETHODIMP
    1091           0 : inDOMUtils::RemoveContentState(nsIDOMElement* aElement,
    1092             :                                EventStates::InternalType aState,
    1093             :                                bool aClearActiveDocument,
    1094             :                                bool* aRetVal)
    1095             : {
    1096           0 :   NS_ENSURE_ARG_POINTER(aElement);
    1097             : 
    1098             :   RefPtr<EventStateManager> esm =
    1099           0 :     inLayoutUtils::GetEventStateManagerFor(aElement);
    1100           0 :   NS_ENSURE_TRUE(esm, NS_ERROR_INVALID_ARG);
    1101             : 
    1102           0 :   *aRetVal = esm->SetContentState(nullptr, EventStates(aState));
    1103             : 
    1104           0 :   if (aClearActiveDocument && EventStates(aState) == NS_EVENT_STATE_ACTIVE) {
    1105             :     EventStateManager* activeESM = static_cast<EventStateManager*>(
    1106           0 :       EventStateManager::GetActiveEventStateManager());
    1107           0 :     if (activeESM == esm) {
    1108           0 :       EventStateManager::ClearGlobalActiveContent(nullptr);
    1109             :     }
    1110             :   }
    1111             : 
    1112           0 :   return NS_OK;
    1113             : }
    1114             : 
    1115             : NS_IMETHODIMP
    1116           0 : inDOMUtils::GetContentState(nsIDOMElement* aElement,
    1117             :                             EventStates::InternalType* aState)
    1118             : {
    1119           0 :   *aState = 0;
    1120           0 :   nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
    1121           0 :   NS_ENSURE_ARG_POINTER(content);
    1122             : 
    1123             :   // NOTE: if this method is removed,
    1124             :   // please remove GetInternalValue from EventStates
    1125           0 :   *aState = content->AsElement()->State().GetInternalValue();
    1126           0 :   return NS_OK;
    1127             : }
    1128             : 
    1129             : /* static */ already_AddRefed<nsStyleContext>
    1130           0 : inDOMUtils::GetCleanStyleContextForElement(dom::Element* aElement,
    1131             :                                            nsIAtom* aPseudo)
    1132             : {
    1133           0 :   MOZ_ASSERT(aElement);
    1134             : 
    1135           0 :   nsIDocument* doc = aElement->GetComposedDoc();
    1136           0 :   if (!doc) {
    1137           0 :     return nullptr;
    1138             :   }
    1139             : 
    1140           0 :   nsIPresShell *presShell = doc->GetShell();
    1141           0 :   if (!presShell) {
    1142           0 :     return nullptr;
    1143             :   }
    1144             : 
    1145           0 :   nsPresContext *presContext = presShell->GetPresContext();
    1146           0 :   if (!presContext) {
    1147           0 :     return nullptr;
    1148             :   }
    1149             : 
    1150           0 :   presContext->EnsureSafeToHandOutCSSRules();
    1151             : 
    1152             :   RefPtr<nsStyleContext> styleContext =
    1153           0 :     nsComputedDOMStyle::GetStyleContext(aElement, aPseudo, presShell);
    1154           0 :   return styleContext.forget();
    1155             : }
    1156             : 
    1157             : NS_IMETHODIMP
    1158           0 : inDOMUtils::GetUsedFontFaces(nsIDOMRange* aRange,
    1159             :                              nsIDOMFontFaceList** aFontFaceList)
    1160             : {
    1161           0 :   return static_cast<nsRange*>(aRange)->GetUsedFontFaces(aFontFaceList);
    1162             : }
    1163             : 
    1164             : static EventStates
    1165           0 : GetStatesForPseudoClass(const nsAString& aStatePseudo)
    1166             : {
    1167             :   // An array of the states that are relevant for various pseudoclasses.
    1168             :   // XXXbz this duplicates code in nsCSSRuleProcessor
    1169             :   static const EventStates sPseudoClassStates[] = {
    1170             : #define CSS_PSEUDO_CLASS(_name, _value, _flags, _pref) \
    1171             :     EventStates(),
    1172             : #define CSS_STATE_PSEUDO_CLASS(_name, _value, _flags, _pref, _states) \
    1173             :     _states,
    1174             : #include "nsCSSPseudoClassList.h"
    1175             : #undef CSS_STATE_PSEUDO_CLASS
    1176             : #undef CSS_PSEUDO_CLASS
    1177             : 
    1178             :     // Add more entries for our fake values to make sure we can't
    1179             :     // index out of bounds into this array no matter what.
    1180             :     EventStates(),
    1181             :     EventStates()
    1182             :   };
    1183             :   static_assert(MOZ_ARRAY_LENGTH(sPseudoClassStates) ==
    1184             :                 static_cast<size_t>(CSSPseudoClassType::MAX),
    1185             :                 "Length of PseudoClassStates array is incorrect");
    1186             : 
    1187           0 :   nsCOMPtr<nsIAtom> atom = NS_Atomize(aStatePseudo);
    1188             :   CSSPseudoClassType type = nsCSSPseudoClasses::
    1189           0 :     GetPseudoType(atom, CSSEnabledState::eIgnoreEnabledState);
    1190             : 
    1191             :   // Ignore :any-link so we don't give the element simultaneous
    1192             :   // visited and unvisited style state
    1193           0 :   if (type == CSSPseudoClassType::anyLink ||
    1194             :       type == CSSPseudoClassType::mozAnyLink) {
    1195           0 :     return EventStates();
    1196             :   }
    1197             :   // Our array above is long enough that indexing into it with
    1198             :   // NotPseudo is ok.
    1199           0 :   return sPseudoClassStates[static_cast<CSSPseudoClassTypeBase>(type)];
    1200             : }
    1201             : 
    1202             : NS_IMETHODIMP
    1203           0 : inDOMUtils::GetCSSPseudoElementNames(uint32_t* aLength, char16_t*** aNames)
    1204             : {
    1205           0 :   nsTArray<nsIAtom*> array;
    1206             : 
    1207             :   const CSSPseudoElementTypeBase pseudoCount =
    1208           0 :     static_cast<CSSPseudoElementTypeBase>(CSSPseudoElementType::Count);
    1209           0 :   for (CSSPseudoElementTypeBase i = 0; i < pseudoCount; ++i) {
    1210           0 :     CSSPseudoElementType type = static_cast<CSSPseudoElementType>(i);
    1211           0 :     if (nsCSSPseudoElements::IsEnabled(type, CSSEnabledState::eForAllContent)) {
    1212           0 :       nsIAtom* atom = nsCSSPseudoElements::GetPseudoAtom(type);
    1213           0 :       array.AppendElement(atom);
    1214             :     }
    1215             :   }
    1216             : 
    1217           0 :   *aLength = array.Length();
    1218             :   char16_t** ret =
    1219           0 :     static_cast<char16_t**>(moz_xmalloc(*aLength * sizeof(char16_t*)));
    1220           0 :   for (uint32_t i = 0; i < *aLength; ++i) {
    1221           0 :     ret[i] = ToNewUnicode(nsDependentAtomString(array[i]));
    1222             :   }
    1223           0 :   *aNames = ret;
    1224           0 :   return NS_OK;
    1225             : }
    1226             : 
    1227             : NS_IMETHODIMP
    1228           0 : inDOMUtils::AddPseudoClassLock(nsIDOMElement *aElement,
    1229             :                                const nsAString &aPseudoClass,
    1230             :                                bool aEnabled,
    1231             :                                uint8_t aArgc)
    1232             : {
    1233           0 :   EventStates state = GetStatesForPseudoClass(aPseudoClass);
    1234           0 :   if (state.IsEmpty()) {
    1235           0 :     return NS_OK;
    1236             :   }
    1237             : 
    1238           0 :   nsCOMPtr<mozilla::dom::Element> element = do_QueryInterface(aElement);
    1239           0 :   NS_ENSURE_ARG_POINTER(element);
    1240             : 
    1241           0 :   element->LockStyleStates(state, aArgc > 0 ? aEnabled : true);
    1242             : 
    1243           0 :   return NS_OK;
    1244             : }
    1245             : 
    1246             : NS_IMETHODIMP
    1247           0 : inDOMUtils::RemovePseudoClassLock(nsIDOMElement *aElement,
    1248             :                                   const nsAString &aPseudoClass)
    1249             : {
    1250           0 :   EventStates state = GetStatesForPseudoClass(aPseudoClass);
    1251           0 :   if (state.IsEmpty()) {
    1252           0 :     return NS_OK;
    1253             :   }
    1254             : 
    1255           0 :   nsCOMPtr<mozilla::dom::Element> element = do_QueryInterface(aElement);
    1256           0 :   NS_ENSURE_ARG_POINTER(element);
    1257             : 
    1258           0 :   element->UnlockStyleStates(state);
    1259             : 
    1260           0 :   return NS_OK;
    1261             : }
    1262             : 
    1263             : NS_IMETHODIMP
    1264           0 : inDOMUtils::HasPseudoClassLock(nsIDOMElement *aElement,
    1265             :                                const nsAString &aPseudoClass,
    1266             :                                bool *_retval)
    1267             : {
    1268           0 :   EventStates state = GetStatesForPseudoClass(aPseudoClass);
    1269           0 :   if (state.IsEmpty()) {
    1270           0 :     *_retval = false;
    1271           0 :     return NS_OK;
    1272             :   }
    1273             : 
    1274           0 :   nsCOMPtr<mozilla::dom::Element> element = do_QueryInterface(aElement);
    1275           0 :   NS_ENSURE_ARG_POINTER(element);
    1276             : 
    1277           0 :   EventStates locks = element->LockedStyleStates().mLocks;
    1278             : 
    1279           0 :   *_retval = locks.HasAllStates(state);
    1280           0 :   return NS_OK;
    1281             : }
    1282             : 
    1283             : NS_IMETHODIMP
    1284           0 : inDOMUtils::ClearPseudoClassLocks(nsIDOMElement *aElement)
    1285             : {
    1286           0 :   nsCOMPtr<mozilla::dom::Element> element = do_QueryInterface(aElement);
    1287           0 :   NS_ENSURE_ARG_POINTER(element);
    1288             : 
    1289           0 :   element->ClearStyleStateLocks();
    1290             : 
    1291           0 :   return NS_OK;
    1292             : }
    1293             : 
    1294             : NS_IMETHODIMP
    1295           0 : inDOMUtils::ParseStyleSheet(nsIDOMCSSStyleSheet *aSheet,
    1296             :                             const nsAString& aInput)
    1297             : {
    1298           0 :   RefPtr<CSSStyleSheet> geckoSheet = do_QueryObject(aSheet);
    1299           0 :   if (geckoSheet) {
    1300           0 :     NS_ENSURE_ARG_POINTER(geckoSheet);
    1301           0 :     return geckoSheet->ReparseSheet(aInput);
    1302             :   }
    1303             : 
    1304           0 :   RefPtr<ServoStyleSheet> servoSheet = do_QueryObject(aSheet);
    1305           0 :   if (servoSheet) {
    1306           0 :     NS_ENSURE_ARG_POINTER(servoSheet);
    1307           0 :     return servoSheet->ReparseSheet(aInput);
    1308             :   }
    1309             : 
    1310           0 :   return NS_ERROR_INVALID_POINTER;
    1311             : }
    1312             : 
    1313             : NS_IMETHODIMP
    1314           0 : inDOMUtils::ScrollElementIntoView(nsIDOMElement *aElement)
    1315             : {
    1316           0 :   nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
    1317           0 :   NS_ENSURE_ARG_POINTER(content);
    1318             : 
    1319           0 :   nsIPresShell* presShell = content->OwnerDoc()->GetShell();
    1320           0 :   if (!presShell) {
    1321           0 :     return NS_OK;
    1322             :   }
    1323             : 
    1324           0 :   presShell->ScrollContentIntoView(content,
    1325             :                                    nsIPresShell::ScrollAxis(),
    1326             :                                    nsIPresShell::ScrollAxis(),
    1327           0 :                                    nsIPresShell::SCROLL_OVERFLOW_HIDDEN);
    1328             : 
    1329           0 :   return NS_OK;
    1330             : }

Generated by: LCOV version 1.13