Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/layout/inspector/InspectorUtils.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#include "mozilla/ArrayUtils.h"
8
#include "mozilla/EventStates.h"
9
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 "nsIDocument.h"
19
#include "nsIPresShell.h"
20
#include "nsIDOMWindow.h"
21
#include "nsXBLBinding.h"
22
#include "nsXBLPrototypeBinding.h"
23
#include "nsIMutableArray.h"
24
#include "nsBindingManager.h"
25
#include "ChildIterator.h"
26
#include "nsComputedDOMStyle.h"
27
#include "mozilla/EventStateManager.h"
28
#include "nsAtom.h"
29
#include "nsRange.h"
30
#include "mozilla/StyleSheetInlines.h"
31
#include "mozilla/dom/CharacterData.h"
32
#include "mozilla/dom/Element.h"
33
#include "mozilla/dom/CSSStyleRule.h"
34
#include "mozilla/dom/InspectorUtilsBinding.h"
35
#include "mozilla/dom/ToJSValue.h"
36
#include "nsCSSProps.h"
37
#include "nsCSSValue.h"
38
#include "nsColor.h"
39
#include "mozilla/ServoStyleSet.h"
40
#include "nsStyleUtil.h"
41
#include "nsQueryObject.h"
42
#include "mozilla/ServoBindings.h"
43
#include "mozilla/ServoStyleRuleMap.h"
44
#include "mozilla/ServoCSSParser.h"
45
#include "mozilla/dom/InspectorUtils.h"
46
#include "mozilla/dom/InspectorFontFace.h"
47
48
using namespace mozilla;
49
using namespace mozilla::css;
50
using namespace mozilla::dom;
51
52
namespace mozilla {
53
namespace dom {
54
55
/* static */ void
56
InspectorUtils::GetAllStyleSheets(GlobalObject& aGlobalObject,
57
                                  nsIDocument& aDocument,
58
                                  bool aDocumentOnly,
59
                                  nsTArray<RefPtr<StyleSheet>>& aResult)
60
0
{
61
0
  // Get the agent, then user and finally xbl sheets in the style set.
62
0
  nsIPresShell* presShell = aDocument.GetShell();
63
0
64
0
  if (presShell) {
65
0
    ServoStyleSet* styleSet = presShell->StyleSet();
66
0
67
0
    if (!aDocumentOnly) {
68
0
      SheetType sheetType = SheetType::Agent;
69
0
      for (int32_t i = 0; i < styleSet->SheetCount(sheetType); i++) {
70
0
        aResult.AppendElement(styleSet->StyleSheetAt(sheetType, i));
71
0
      }
72
0
      sheetType = SheetType::User;
73
0
      for (int32_t i = 0; i < styleSet->SheetCount(sheetType); i++) {
74
0
        aResult.AppendElement(styleSet->StyleSheetAt(sheetType, i));
75
0
      }
76
0
    }
77
0
78
0
    AutoTArray<StyleSheet*, 32> xblSheetArray;
79
0
    styleSet->AppendAllNonDocumentAuthorSheets(xblSheetArray);
80
0
81
0
    // The XBL stylesheet array will quite often be full of duplicates. Cope:
82
0
    //
83
0
    // FIXME(emilio, bug 1454467): I think this is not true since bug 1452525.
84
0
    nsTHashtable<nsPtrHashKey<StyleSheet>> sheetSet;
85
0
    for (StyleSheet* sheet : xblSheetArray) {
86
0
      if (!sheetSet.Contains(sheet)) {
87
0
        sheetSet.PutEntry(sheet);
88
0
        aResult.AppendElement(sheet);
89
0
      }
90
0
    }
91
0
  }
92
0
93
0
  // Get the document sheets.
94
0
  for (size_t i = 0; i < aDocument.SheetCount(); i++) {
95
0
    aResult.AppendElement(aDocument.SheetAt(i));
96
0
  }
97
0
}
98
99
bool
100
InspectorUtils::IsIgnorableWhitespace(CharacterData& aDataNode)
101
0
{
102
0
  if (!aDataNode.TextIsOnlyWhitespace()) {
103
0
    return false;
104
0
  }
105
0
106
0
  // Okay.  We have only white space.  Let's check the white-space
107
0
  // property now and make sure that this isn't preformatted text...
108
0
  if (nsIFrame* frame = aDataNode.GetPrimaryFrame()) {
109
0
    return !frame->StyleText()->WhiteSpaceIsSignificant();
110
0
  }
111
0
112
0
  // empty inter-tag text node without frame, e.g., in between <table>\n<tr>
113
0
  return true;
114
0
}
115
116
/* static */ nsINode*
117
InspectorUtils::GetParentForNode(nsINode& aNode,
118
                                 bool aShowingAnonymousContent)
119
0
{
120
0
  // First do the special cases -- document nodes and anonymous content
121
0
  nsINode* parent = nullptr;
122
0
123
0
  if (aNode.IsDocument()) {
124
0
    parent = inLayoutUtils::GetContainerFor(*aNode.AsDocument());
125
0
  } else if (aShowingAnonymousContent) {
126
0
    if (aNode.IsContent()) {
127
0
      parent = aNode.AsContent()->GetFlattenedTreeParent();
128
0
    }
129
0
  }
130
0
131
0
  if (!parent) {
132
0
    // Ok, just get the normal DOM parent node
133
0
    return aNode.GetParentNode();
134
0
  }
135
0
136
0
  return parent;
137
0
}
138
139
/* static */ already_AddRefed<nsINodeList>
140
InspectorUtils::GetChildrenForNode(nsINode& aNode,
141
                                   bool aShowingAnonymousContent)
142
0
{
143
0
  nsCOMPtr<nsINodeList> kids;
144
0
145
0
  if (aShowingAnonymousContent) {
146
0
    if (aNode.IsContent()) {
147
0
      kids = aNode.AsContent()->GetChildren(nsIContent::eAllChildren);
148
0
    }
149
0
  }
150
0
151
0
  if (!kids) {
152
0
    kids = aNode.ChildNodes();
153
0
  }
154
0
155
0
  return kids.forget();
156
0
}
157
158
/* static */ void
159
InspectorUtils::GetCSSStyleRules(GlobalObject& aGlobalObject,
160
                                 Element& aElement,
161
                                 const nsAString& aPseudo,
162
                                 nsTArray<RefPtr<css::Rule>>& aResult)
163
0
{
164
0
  RefPtr<nsAtom> pseudoElt;
165
0
  if (!aPseudo.IsEmpty()) {
166
0
    pseudoElt = NS_Atomize(aPseudo);
167
0
  }
168
0
169
0
  RefPtr<ComputedStyle> computedStyle =
170
0
    GetCleanComputedStyleForElement(&aElement, pseudoElt);
171
0
  if (!computedStyle) {
172
0
    // This can fail for elements that are not in the document or
173
0
    // if the document they're in doesn't have a presshell.  Bail out.
174
0
    return;
175
0
  }
176
0
177
0
178
0
  nsIDocument* doc = aElement.OwnerDoc();
179
0
  nsIPresShell* shell = doc->GetShell();
180
0
  if (!shell) {
181
0
    return;
182
0
  }
183
0
184
0
  nsTArray<const RawServoStyleRule*> rawRuleList;
185
0
  Servo_ComputedValues_GetStyleRuleList(computedStyle, &rawRuleList);
186
0
187
0
  AutoTArray<ServoStyleRuleMap*, 1> maps;
188
0
  {
189
0
    ServoStyleSet* styleSet = shell->StyleSet();
190
0
    ServoStyleRuleMap* map = styleSet->StyleRuleMap();
191
0
    maps.AppendElement(map);
192
0
  }
193
0
194
0
  // Collect style rule maps for bindings.
195
0
  for (nsIContent* bindingContent = &aElement; bindingContent;
196
0
       bindingContent = bindingContent->GetBindingParent()) {
197
0
    for (nsXBLBinding* binding = bindingContent->GetXBLBinding();
198
0
         binding; binding = binding->GetBaseBinding()) {
199
0
      if (auto* map = binding->PrototypeBinding()->GetServoStyleRuleMap()) {
200
0
        maps.AppendElement(map);
201
0
      }
202
0
    }
203
0
    // Note that we intentionally don't cut off here, unlike when we
204
0
    // do styling, because even if style rules from parent binding
205
0
    // do not apply to the element directly in those cases, their
206
0
    // rules may still show up in the list we get above due to the
207
0
    // inheritance in cascading.
208
0
  }
209
0
210
0
  // Now shadow DOM stuff...
211
0
  if (auto* shadow = aElement.GetShadowRoot()) {
212
0
    maps.AppendElement(&shadow->ServoStyleRuleMap());
213
0
  }
214
0
215
0
  for (auto* shadow = aElement.GetContainingShadow();
216
0
       shadow;
217
0
       shadow = shadow->Host()->GetContainingShadow()) {
218
0
    maps.AppendElement(&shadow->ServoStyleRuleMap());
219
0
  }
220
0
221
0
  // Find matching rules in the table.
222
0
  for (const RawServoStyleRule* rawRule : Reversed(rawRuleList)) {
223
0
    CSSStyleRule* rule = nullptr;
224
0
    for (ServoStyleRuleMap* map : maps) {
225
0
      rule = map->Lookup(rawRule);
226
0
      if (rule) {
227
0
        break;
228
0
      }
229
0
    }
230
0
    if (rule) {
231
0
      aResult.AppendElement(rule);
232
0
    } else {
233
#ifdef DEBUG
234
      nsAutoCString str;
235
      fprintf(stderr, "%s\n", str.get());
236
      Servo_StyleRule_Debug(rawRule, &str);
237
      MOZ_CRASH_UNSAFE_PRINTF(
238
        "We should be able to map a raw rule to a rule: %s\n",
239
        str.get()
240
      );
241
#endif
242
    }
243
0
  }
244
0
}
245
246
/* static */ uint32_t
247
InspectorUtils::GetRuleLine(GlobalObject& aGlobal, css::Rule& aRule)
248
0
{
249
0
  return aRule.GetLineNumber();
250
0
}
251
252
/* static */ uint32_t
253
InspectorUtils::GetRuleColumn(GlobalObject& aGlobal, css::Rule& aRule)
254
0
{
255
0
  return aRule.GetColumnNumber();
256
0
}
257
258
/* static */ uint32_t
259
InspectorUtils::GetRelativeRuleLine(GlobalObject& aGlobal, css::Rule& aRule)
260
0
{
261
0
  uint32_t lineNumber = aRule.GetLineNumber();
262
0
263
0
  // If aRule was parsed along with its stylesheet, then it will
264
0
  // have an absolute lineNumber that we need to remap to its
265
0
  // containing node. But if aRule was added via CSSOM after parsing,
266
0
  // then it has a sort-of relative line number already:
267
0
  // Gecko gives all rules a 0 lineNumber.
268
0
  // Servo gives the first line of a rule a 0 lineNumber, and then
269
0
  //   counts up from there.
270
0
271
0
  // The Servo behavior is arguably more correct, but harder to
272
0
  // interpret for purposes of deciding whether a lineNumber is
273
0
  // relative or absolute.
274
0
275
0
  // Since most of the time, inserted rules are single line and
276
0
  // therefore have 0 lineNumbers in both Gecko and Servo, we use
277
0
  // that to detect that a lineNumber is already relative.
278
0
279
0
  // There is one ugly edge case that we avoid: if an inserted rule
280
0
  // is multi-line, then Servo will give it 0+ lineNumbers. If we
281
0
  // do relative number mapping on those line numbers, we could get
282
0
  // negative underflow. So we check for underflow and instead report
283
0
  // a 0 lineNumber.
284
0
  StyleSheet* sheet = aRule.GetStyleSheet();
285
0
  if (sheet && lineNumber != 0) {
286
0
    nsINode* owningNode = sheet->GetOwnerNode();
287
0
    if (owningNode) {
288
0
      nsCOMPtr<nsIStyleSheetLinkingElement> link =
289
0
        do_QueryInterface(owningNode);
290
0
      if (link) {
291
0
        // Check for underflow, which is one indication that we're
292
0
        // trying to remap an already relative lineNumber.
293
0
        uint32_t linkLineIndex0 = link->GetLineNumber() - 1;
294
0
        if (linkLineIndex0 > lineNumber ) {
295
0
          lineNumber = 0;
296
0
        } else {
297
0
          lineNumber -= linkLineIndex0;
298
0
        }
299
0
      }
300
0
    }
301
0
  }
302
0
303
0
  return lineNumber;
304
0
}
305
306
/* static */ bool
307
InspectorUtils::HasRulesModifiedByCSSOM(GlobalObject& aGlobal, StyleSheet& aSheet)
308
0
{
309
0
  return aSheet.HasModifiedRules();
310
0
}
311
312
/* static */ uint32_t
313
InspectorUtils::GetSelectorCount(GlobalObject& aGlobal,
314
                                 BindingStyleRule& aRule)
315
0
{
316
0
  return aRule.GetSelectorCount();
317
0
}
318
319
/* static */ void
320
InspectorUtils::GetSelectorText(GlobalObject& aGlobal,
321
                                BindingStyleRule& aRule,
322
                                uint32_t aSelectorIndex,
323
                                nsString& aText,
324
                                ErrorResult& aRv)
325
0
{
326
0
  aRv = aRule.GetSelectorText(aSelectorIndex, aText);
327
0
}
328
329
/* static */ uint64_t
330
InspectorUtils::GetSpecificity(GlobalObject& aGlobal,
331
                               BindingStyleRule& aRule,
332
                               uint32_t aSelectorIndex,
333
                               ErrorResult& aRv)
334
0
{
335
0
  uint64_t s;
336
0
  aRv = aRule.GetSpecificity(aSelectorIndex, &s);
337
0
  return s;
338
0
}
339
340
/* static */ bool
341
InspectorUtils::SelectorMatchesElement(GlobalObject& aGlobalObject,
342
                                       Element& aElement,
343
                                       BindingStyleRule& aRule,
344
                                       uint32_t aSelectorIndex,
345
                                       const nsAString& aPseudo,
346
                                       ErrorResult& aRv)
347
0
{
348
0
  bool result = false;
349
0
  aRv = aRule.SelectorMatchesElement(&aElement, aSelectorIndex, aPseudo,
350
0
                                     &result);
351
0
  return result;
352
0
}
353
354
/* static */ bool
355
InspectorUtils::IsInheritedProperty(GlobalObject& aGlobalObject,
356
                                    const nsAString& aPropertyName)
357
0
{
358
0
  NS_ConvertUTF16toUTF8 propName(aPropertyName);
359
0
  return Servo_Property_IsInherited(&propName);
360
0
}
361
362
/* static */ void
363
InspectorUtils::GetCSSPropertyNames(GlobalObject& aGlobalObject,
364
                                    const PropertyNamesOptions& aOptions,
365
                                    nsTArray<nsString>& aResult)
366
0
{
367
0
  CSSEnabledState enabledState = aOptions.mIncludeExperimentals
368
0
    ? CSSEnabledState::eIgnoreEnabledState
369
0
    : CSSEnabledState::eForAllContent;
370
0
371
0
  auto appendProperty = [enabledState, &aResult](uint32_t prop) {
372
0
    nsCSSPropertyID cssProp = nsCSSPropertyID(prop);
373
0
    if (nsCSSProps::IsEnabled(cssProp, enabledState)) {
374
0
      aResult.AppendElement(NS_ConvertASCIItoUTF16(
375
0
        nsCSSProps::GetStringValue(cssProp)));
376
0
    }
377
0
  };
378
0
379
0
  uint32_t prop = 0;
380
0
  for ( ; prop < eCSSProperty_COUNT_no_shorthands; ++prop) {
381
0
    if (!nsCSSProps::PropHasFlags(nsCSSPropertyID(prop),
382
0
                                  CSSPropFlags::Inaccessible)) {
383
0
      appendProperty(prop);
384
0
    }
385
0
  }
386
0
387
0
  if (aOptions.mIncludeShorthands) {
388
0
    for ( ; prop < eCSSProperty_COUNT; ++prop) {
389
0
      appendProperty(prop);
390
0
    }
391
0
  }
392
0
393
0
  if (aOptions.mIncludeAliases) {
394
0
    for (prop = eCSSProperty_COUNT; prop < eCSSProperty_COUNT_with_aliases; ++prop) {
395
0
      appendProperty(prop);
396
0
    }
397
0
  }
398
0
}
399
400
/* static */ void
401
InspectorUtils::GetCSSPropertyPrefs(GlobalObject& aGlobalObject,
402
                                    nsTArray<PropertyPref>& aResult)
403
0
{
404
0
  for (const auto* src = nsCSSProps::kPropertyPrefTable;
405
0
       src->mPropID != eCSSProperty_UNKNOWN; src++) {
406
0
    PropertyPref& dest = *aResult.AppendElement();
407
0
    dest.mName.Assign(NS_ConvertASCIItoUTF16(nsCSSProps::GetStringValue(src->mPropID)));
408
0
    dest.mPref.AssignASCII(src->mPref);
409
0
  }
410
0
}
411
412
/* static */ void
413
InspectorUtils::GetSubpropertiesForCSSProperty(GlobalObject& aGlobal,
414
                                               const nsAString& aProperty,
415
                                               nsTArray<nsString>& aResult,
416
                                               ErrorResult& aRv)
417
0
{
418
0
  nsCSSPropertyID propertyID = nsCSSProps::LookupProperty(aProperty);
419
0
420
0
  if (propertyID == eCSSProperty_UNKNOWN) {
421
0
    aRv.Throw(NS_ERROR_FAILURE);
422
0
    return;
423
0
  }
424
0
425
0
  if (propertyID == eCSSPropertyExtra_variable) {
426
0
    aResult.AppendElement(aProperty);
427
0
    return;
428
0
  }
429
0
430
0
  if (!nsCSSProps::IsShorthand(propertyID)) {
431
0
    nsString* name = aResult.AppendElement();
432
0
    CopyASCIItoUTF16(nsCSSProps::GetStringValue(propertyID), *name);
433
0
    return;
434
0
  }
435
0
436
0
  for (const nsCSSPropertyID* props = nsCSSProps::SubpropertyEntryFor(propertyID);
437
0
       *props != eCSSProperty_UNKNOWN; ++props) {
438
0
    nsString* name = aResult.AppendElement();
439
0
    CopyASCIItoUTF16(nsCSSProps::GetStringValue(*props), *name);
440
0
  }
441
0
}
442
443
/* static */ bool
444
InspectorUtils::CssPropertyIsShorthand(GlobalObject& aGlobalObject,
445
                                       const nsAString& aProperty,
446
                                       ErrorResult& aRv)
447
0
{
448
0
  NS_ConvertUTF16toUTF8 prop(aProperty);
449
0
  bool found;
450
0
  bool isShorthand = Servo_Property_IsShorthand(&prop, &found);
451
0
  if (!found) {
452
0
    aRv.Throw(NS_ERROR_FAILURE);
453
0
  }
454
0
  return isShorthand;
455
0
}
456
457
bool
458
InspectorUtils::CssPropertySupportsType(GlobalObject& aGlobalObject,
459
                                        const nsAString& aProperty,
460
                                        uint32_t aType,
461
                                        ErrorResult& aRv)
462
0
{
463
0
  NS_ConvertUTF16toUTF8 property(aProperty);
464
0
  bool found;
465
0
  bool result = Servo_Property_SupportsType(&property, aType, &found);
466
0
  if (!found) {
467
0
    aRv.Throw(NS_ERROR_FAILURE);
468
0
    return false;
469
0
  }
470
0
  return result;
471
0
}
472
473
/* static */ void
474
InspectorUtils::GetCSSValuesForProperty(GlobalObject& aGlobalObject,
475
                                        const nsAString& aProperty,
476
                                        nsTArray<nsString>& aResult,
477
                                        ErrorResult& aRv)
478
0
{
479
0
  NS_ConvertUTF16toUTF8 property(aProperty);
480
0
  bool found;
481
0
  Servo_Property_GetCSSValuesForProperty(&property, &found, &aResult);
482
0
  if (!found) {
483
0
    aRv.Throw(NS_ERROR_FAILURE);
484
0
  }
485
0
  return;
486
0
}
487
488
/* static */ void
489
InspectorUtils::RgbToColorName(GlobalObject& aGlobalObject,
490
                               uint8_t aR, uint8_t aG, uint8_t aB,
491
                               nsAString& aColorName,
492
                               ErrorResult& aRv)
493
0
{
494
0
  const char* color = NS_RGBToColorName(NS_RGB(aR, aG, aB));
495
0
  if (!color) {
496
0
    aColorName.Truncate();
497
0
    aRv.Throw(NS_ERROR_INVALID_ARG);
498
0
    return;
499
0
  }
500
0
501
0
  aColorName.AssignASCII(color);
502
0
}
503
504
/* static */ void
505
InspectorUtils::ColorToRGBA(GlobalObject& aGlobalObject,
506
                            const nsAString& aColorString,
507
                            Nullable<InspectorRGBATuple>& aResult)
508
0
{
509
0
  nscolor color = NS_RGB(0, 0, 0);
510
0
511
0
  if (!ServoCSSParser::ComputeColor(nullptr, NS_RGB(0, 0, 0), aColorString,
512
0
                                    &color)) {
513
0
    aResult.SetNull();
514
0
    return;
515
0
  }
516
0
517
0
  InspectorRGBATuple& tuple = aResult.SetValue();
518
0
  tuple.mR = NS_GET_R(color);
519
0
  tuple.mG = NS_GET_G(color);
520
0
  tuple.mB = NS_GET_B(color);
521
0
  tuple.mA = nsStyleUtil::ColorComponentToFloat(NS_GET_A(color));
522
0
}
523
524
/* static */ bool
525
InspectorUtils::IsValidCSSColor(GlobalObject& aGlobalObject,
526
                                const nsAString& aColorString)
527
0
{
528
0
  return ServoCSSParser::IsValidCSSColor(aColorString);
529
0
}
530
531
void
532
InspectorUtils::GetBindingURLs(GlobalObject& aGlobalObject,
533
                               Element& aElement,
534
                               nsTArray<nsString>& aResult)
535
0
{
536
0
  nsXBLBinding* binding = aElement.GetXBLBinding();
537
0
538
0
  while (binding) {
539
0
    nsCString spec;
540
0
    nsCOMPtr<nsIURI> bindingURI = binding->PrototypeBinding()->BindingURI();
541
0
    bindingURI->GetSpec(spec);
542
0
    nsString* resultURI = aResult.AppendElement();
543
0
    CopyASCIItoUTF16(spec, *resultURI);
544
0
    binding = binding->GetBaseBinding();
545
0
  }
546
0
}
547
548
/* static */ bool
549
InspectorUtils::SetContentState(GlobalObject& aGlobalObject,
550
                                Element& aElement,
551
                                uint64_t aState,
552
                                ErrorResult& aRv)
553
0
{
554
0
  RefPtr<EventStateManager> esm =
555
0
    inLayoutUtils::GetEventStateManagerFor(aElement);
556
0
  if (!esm) {
557
0
    aRv.Throw(NS_ERROR_INVALID_ARG);
558
0
    return false;
559
0
  }
560
0
561
0
  return esm->SetContentState(&aElement, EventStates(aState));
562
0
}
563
564
/* static */ bool
565
InspectorUtils::RemoveContentState(GlobalObject& aGlobalObject,
566
                                   Element& aElement,
567
                                   uint64_t aState,
568
                                   bool aClearActiveDocument,
569
                                   ErrorResult& aRv)
570
0
{
571
0
  RefPtr<EventStateManager> esm =
572
0
    inLayoutUtils::GetEventStateManagerFor(aElement);
573
0
  if (!esm) {
574
0
    aRv.Throw(NS_ERROR_INVALID_ARG);
575
0
    return false;
576
0
  }
577
0
578
0
  bool result = esm->SetContentState(nullptr, EventStates(aState));
579
0
580
0
  if (aClearActiveDocument && EventStates(aState) == NS_EVENT_STATE_ACTIVE) {
581
0
    EventStateManager* activeESM = static_cast<EventStateManager*>(
582
0
      EventStateManager::GetActiveEventStateManager());
583
0
    if (activeESM == esm) {
584
0
      EventStateManager::ClearGlobalActiveContent(nullptr);
585
0
    }
586
0
  }
587
0
588
0
  return result;
589
0
}
590
591
/* static */ uint64_t
592
InspectorUtils::GetContentState(GlobalObject& aGlobalObject,
593
                                Element& aElement)
594
0
{
595
0
  // NOTE: if this method is removed,
596
0
  // please remove GetInternalValue from EventStates
597
0
  return aElement.State().GetInternalValue();
598
0
}
599
600
/* static */ already_AddRefed<ComputedStyle>
601
InspectorUtils::GetCleanComputedStyleForElement(dom::Element* aElement,
602
                                               nsAtom* aPseudo)
603
0
{
604
0
  MOZ_ASSERT(aElement);
605
0
606
0
  nsIDocument* doc = aElement->GetComposedDoc();
607
0
  if (!doc) {
608
0
    return nullptr;
609
0
  }
610
0
611
0
  nsIPresShell *presShell = doc->GetShell();
612
0
  if (!presShell) {
613
0
    return nullptr;
614
0
  }
615
0
616
0
  nsPresContext *presContext = presShell->GetPresContext();
617
0
  if (!presContext) {
618
0
    return nullptr;
619
0
  }
620
0
621
0
  presContext->EnsureSafeToHandOutCSSRules();
622
0
623
0
  return nsComputedDOMStyle::GetComputedStyle(aElement, aPseudo);
624
0
}
625
626
/* static */ void
627
InspectorUtils::GetUsedFontFaces(GlobalObject& aGlobalObject,
628
                                 nsRange& aRange,
629
                                 uint32_t aMaxRanges,
630
                                 bool aSkipCollapsedWhitespace,
631
                                 nsTArray<nsAutoPtr<InspectorFontFace>>& aResult,
632
                                 ErrorResult& aRv)
633
0
{
634
0
  nsresult rv = aRange.GetUsedFontFaces(aResult, aMaxRanges,
635
0
                                        aSkipCollapsedWhitespace);
636
0
  if (NS_FAILED(rv)) {
637
0
    aRv.Throw(rv);
638
0
  }
639
0
}
640
641
static EventStates
642
GetStatesForPseudoClass(const nsAString& aStatePseudo)
643
0
{
644
0
  if (aStatePseudo.IsEmpty() || aStatePseudo[0] != u':') {
645
0
    return EventStates();
646
0
  }
647
0
  NS_ConvertUTF16toUTF8 statePseudo(Substring(aStatePseudo, 1));
648
0
  return EventStates(Servo_PseudoClass_GetStates(&statePseudo));
649
0
}
650
651
/* static */ void
652
InspectorUtils::GetCSSPseudoElementNames(GlobalObject& aGlobalObject,
653
                                         nsTArray<nsString>& aResult)
654
0
{
655
0
  const CSSPseudoElementTypeBase pseudoCount =
656
0
    static_cast<CSSPseudoElementTypeBase>(CSSPseudoElementType::Count);
657
0
  for (CSSPseudoElementTypeBase i = 0; i < pseudoCount; ++i) {
658
0
    CSSPseudoElementType type = static_cast<CSSPseudoElementType>(i);
659
0
    if (nsCSSPseudoElements::IsEnabled(type, CSSEnabledState::eForAllContent)) {
660
0
      nsAtom* atom = nsCSSPseudoElements::GetPseudoAtom(type);
661
0
      aResult.AppendElement(nsDependentAtomString(atom));
662
0
    }
663
0
  }
664
0
}
665
666
/* static */ void
667
InspectorUtils::AddPseudoClassLock(GlobalObject& aGlobalObject,
668
                                   Element& aElement,
669
                                   const nsAString& aPseudoClass,
670
                                   bool aEnabled)
671
0
{
672
0
  EventStates state = GetStatesForPseudoClass(aPseudoClass);
673
0
  if (state.IsEmpty()) {
674
0
    return;
675
0
  }
676
0
677
0
  aElement.LockStyleStates(state, aEnabled);
678
0
}
679
680
/* static */ void
681
InspectorUtils::RemovePseudoClassLock(GlobalObject& aGlobal,
682
                                      Element& aElement,
683
                                      const nsAString& aPseudoClass)
684
0
{
685
0
  EventStates state = GetStatesForPseudoClass(aPseudoClass);
686
0
  if (state.IsEmpty()) {
687
0
    return;
688
0
  }
689
0
690
0
  aElement.UnlockStyleStates(state);
691
0
}
692
693
/* static */ bool
694
InspectorUtils::HasPseudoClassLock(GlobalObject& aGlobalObject,
695
                                   Element& aElement,
696
                                   const nsAString& aPseudoClass)
697
0
{
698
0
  EventStates state = GetStatesForPseudoClass(aPseudoClass);
699
0
  if (state.IsEmpty()) {
700
0
    return false;
701
0
  }
702
0
703
0
  EventStates locks = aElement.LockedStyleStates().mLocks;
704
0
  return locks.HasAllStates(state);
705
0
}
706
707
/* static */ void
708
InspectorUtils::ClearPseudoClassLocks(GlobalObject& aGlobalObject,
709
                                      Element& aElement)
710
0
{
711
0
  aElement.ClearStyleStateLocks();
712
0
}
713
714
/* static */ void
715
InspectorUtils::ParseStyleSheet(GlobalObject& aGlobalObject,
716
                                StyleSheet& aSheet,
717
                                const nsAString& aInput,
718
                                ErrorResult& aRv)
719
0
{
720
0
721
0
  aRv = aSheet.ReparseSheet(aInput);
722
0
}
723
724
void
725
InspectorUtils::ScrollElementIntoView(GlobalObject& aGlobalObject,
726
                                      Element& aElement)
727
0
{
728
0
  nsIPresShell* presShell = aElement.OwnerDoc()->GetShell();
729
0
  if (!presShell) {
730
0
    return;
731
0
  }
732
0
733
0
  presShell->ScrollContentIntoView(&aElement,
734
0
                                   nsIPresShell::ScrollAxis(),
735
0
                                   nsIPresShell::ScrollAxis(),
736
0
                                   nsIPresShell::SCROLL_OVERFLOW_HIDDEN);
737
0
}
738
739
740
bool
741
InspectorUtils::IsCustomElementName(GlobalObject&,
742
                                    const nsAString& aName,
743
                                    const nsAString& aNamespaceURI)
744
0
{
745
0
  if (aName.IsEmpty()) {
746
0
    return false;
747
0
  }
748
0
749
0
  int32_t namespaceID;
750
0
  nsContentUtils::NameSpaceManager()->RegisterNameSpace(
751
0
    aNamespaceURI,
752
0
    namespaceID);
753
0
754
0
  RefPtr<nsAtom> nameElt = NS_Atomize(aName);
755
0
  return nsContentUtils::IsCustomElementName(
756
0
    nameElt,
757
0
    namespaceID);
758
0
}
759
760
} // namespace dom
761
} // namespace mozilla