Document.cpp 519 KB
Newer Older
1
2
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
4
5
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
8
9
10

/*
 * Base class for all our document implementations.
 */

11
#include "AudioChannelService.h"
12
13
#include "mozilla/dom/Document.h"
#include "DocumentInlines.h"
14
#include "mozilla/AntiTrackingCommon.h"
15
#include "mozilla/ArrayUtils.h"
16
#include "mozilla/AutoRestore.h"
17
#include "mozilla/BinarySearch.h"
18
#include "mozilla/CSSEnabledState.h"
19
#include "mozilla/DebugOnly.h"
20
#include "mozilla/EditorCommands.h"
21
#include "mozilla/EffectSet.h"
22
#include "mozilla/EnumSet.h"
23
#include "mozilla/HTMLEditor.h"
24
#include "mozilla/IdentifierMapEntry.h"
25
#include "mozilla/IntegerRange.h"
26
#include "mozilla/MemoryReporting.h"
27
#include "mozilla/Likely.h"
28
#include "mozilla/LoadInfo.h"
29
#include "mozilla/PresShell.h"
30
#include "mozilla/PresShellInlines.h"
31
#include "mozilla/RestyleManager.h"
32
33
#include "mozilla/StaticPrefs_browser.h"
#include "mozilla/StaticPrefs_dom.h"
34
#include "mozilla/StaticPrefs_fission.h"
35
36
#include "mozilla/StaticPrefs_full_screen_api.h"
#include "mozilla/StaticPrefs_layout.h"
37
#include "mozilla/StaticPrefs_network.h"
38
#include "mozilla/StaticPrefs_page_load.h"
39
40
41
#include "mozilla/StaticPrefs_plugins.h"
#include "mozilla/StaticPrefs_privacy.h"
#include "mozilla/StaticPrefs_security.h"
42
#include "mozilla/StorageAccess.h"
43
#include "mozilla/TextControlElement.h"
44
#include "mozilla/TextEditor.h"
45
#include "mozilla/URLDecorationStripper.h"
46
#include "mozilla/URLExtraData.h"
47
#include "mozilla/Base64.h"
48
#include "mozilla/BasePrincipal.h"
49
#include <algorithm>
50

51
#include "mozilla/Logging.h"
52
#include "plstr.h"
53
#include "mozilla/Sprintf.h"
54

55
#include "mozilla/Telemetry.h"
56
#include "nsIInlineSpellChecker.h"
57
#include "nsIInterfaceRequestor.h"
58
#include "nsIInterfaceRequestorUtils.h"
59
#include "nsILoadContext.h"
60
#include "nsITextControlFrame.h"
61
62
#include "nsCommandManager.h"
#include "nsCommandParams.h"
63
#include "nsNumberControlFrame.h"
64
#include "nsUnicharUtils.h"
65
#include "nsContentList.h"
66
#include "nsCSSPseudoElements.h"
67
#include "nsIObserver.h"
68
#include "nsIBaseWindow.h"
69
#include "nsILayoutHistoryState.h"
70
#include "mozilla/GlobalStyleSheetCache.h"
71
#include "mozilla/css/Loader.h"
72
#include "mozilla/css/ImageLoader.h"
73
#include "nsDocShell.h"
74
#include "nsDocShellLoadTypes.h"
75
#include "nsIDocShellTreeItem.h"
76
#include "nsCOMArray.h"
77
#include "nsQueryObject.h"
78
#include "mozilla/Services.h"
79
#include "nsScreen.h"
80
#include "ChildIterator.h"
81
82
83
#include "nsIX509Cert.h"
#include "nsIX509CertValidity.h"
#include "nsITransportSecurityInfo.h"
84
85
86
#include "nsINSSErrorsService.h"
#include "nsISocketProvider.h"
#include "nsISiteSecurityService.h"
87
#include "PermissionDelegateHandler.h"
88

89
#include "mozilla/AsyncEventDispatcher.h"
90
#include "mozilla/BasicEvents.h"
91
#include "mozilla/EventListenerManager.h"
92
#include "mozilla/EventStateManager.h"
93
#include "mozilla/FullscreenChange.h"
94
#include "mozilla/PendingAnimationTracker.h"
95

96
#include "mozilla/dom/Attr.h"
97
#include "mozilla/dom/BindingDeclarations.h"
98
#include "mozilla/dom/BrowsingContext.h"
99
#include "mozilla/dom/ContentChild.h"
100
#include "mozilla/dom/CSSImportRule.h"
101
#include "mozilla/dom/CSPDictionariesBinding.h"
102
#include "mozilla/dom/DOMIntersectionObserver.h"
103
#include "mozilla/dom/Element.h"
104
#include "mozilla/dom/Event.h"
105
#include "mozilla/dom/FeaturePolicy.h"
106
#include "mozilla/dom/FeaturePolicyUtils.h"
107
#include "mozilla/dom/FramingChecker.h"
108
#include "mozilla/dom/HTMLAllCollection.h"
109
#include "mozilla/dom/HTMLMetaElement.h"
110
#include "mozilla/dom/HTMLSharedElement.h"
111
#include "mozilla/dom/MutationObservers.h"
112
#include "mozilla/dom/Navigator.h"
113
#include "mozilla/dom/Performance.h"
114
#include "mozilla/dom/TreeOrderedArrayInlines.h"
115
116
#include "mozilla/dom/ResizeObserver.h"
#include "mozilla/dom/ResizeObserverController.h"
117
#include "mozilla/dom/ServiceWorkerContainer.h"
118
#include "mozilla/dom/ScriptLoader.h"
119
#include "mozilla/dom/ShadowIncludingTreeIterator.h"
120
#include "mozilla/dom/StyleSheetList.h"
121
#include "mozilla/dom/SVGUseElement.h"
122
#include "mozilla/dom/UserActivation.h"
123
#include "mozilla/net/CookieSettings.h"
124
#include "nsGenericHTMLElement.h"
125
#include "mozilla/dom/CDATASection.h"
126
#include "mozilla/dom/ProcessingInstruction.h"
127
#include "mozilla/dom/PostMessageEvent.h"
128
#include "mozilla/ipc/IdleSchedulerChild.h"
129
#include "nsDOMString.h"
130
#include "nsLayoutUtils.h"  // for GetFrameForPoint
131
#include "nsIFrame.h"
132
#include "nsIBrowserChild.h"
133
#include "nsImportModule.h"
134

135
#include "nsRange.h"
136
#include "mozilla/dom/DocumentType.h"
137
#include "mozilla/dom/NodeIterator.h"
138
139
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/PromiseNativeHandler.h"
140
#include "mozilla/dom/TreeWalker.h"
141

142
#include "nsIServiceManager.h"
143
#include "mozilla/dom/ServiceWorkerManager.h"
144
#include "imgLoader.h"
peterl%netscape.com's avatar
peterl%netscape.com committed
145

146
#include "nsAboutProtocolUtils.h"
147
#include "nsCanvasFrame.h"
148
#include "nsContentCID.h"
149
#include "nsContentSecurityUtils.h"
150
#include "nsError.h"
151
#include "nsPresContext.h"
152
#include "nsThreadUtils.h"
153
#include "nsNodeInfoManager.h"
154
#include "nsIBrowserUsage.h"
155
#include "nsIEditingSession.h"
156
#include "nsIFileChannel.h"
157
158
159
#include "nsIMultiPartChannel.h"
#include "nsIRefreshURI.h"
#include "nsIWebNavigation.h"
160
#include "nsIScriptError.h"
161
#include "nsISimpleEnumerator.h"
162
#include "nsIRequestContext.h"
163
#include "nsStyleSheetService.h"
mjudge%netscape.com's avatar
mjudge%netscape.com committed
164

165
#include "nsNetUtil.h"  // for NS_NewURI
166
167
168
#include "nsIInputStreamChannel.h"
#include "nsIAuthPrompt.h"
#include "nsIAuthPrompt2.h"
169

norris%netscape.com's avatar
norris%netscape.com committed
170
#include "nsIScriptSecurityManager.h"
171
172
#include "nsIPermission.h"
#include "nsPermissionManager.h"
173
#include "nsIPrincipal.h"
174
#include "nsIPrivateBrowsingChannel.h"
175
#include "ExpandedPrincipal.h"
176
#include "mozilla/NullPrincipal.h"
norris%netscape.com's avatar
norris%netscape.com committed
177

178
#include "nsPIDOMWindow.h"
179
#include "nsFocusManager.h"
180
#include "nsICookiePermission.h"
181
#include "nsICookieService.h"
kipp's avatar
kipp committed
182

183
#include "nsBidiUtils.h"
184

185
#include "nsContentCreatorFunctions.h"
186

187
#include "nsIScriptContext.h"
188
#include "nsHTMLDocument.h"
189
#include "nsIRequest.h"
190
#include "mozilla/dom/BlobURLProtocolHandler.h"
191

192
#include "nsCharsetSource.h"
193
#include "nsIParser.h"
194
#include "nsIContentSink.h"
195

196
#include "mozilla/EventDispatcher.h"
197
#include "mozilla/EventStates.h"
198
#include "mozilla/InternalMutationEvent.h"
199
#include "nsDOMCID.h"
200

201
#include "jsapi.h"
202
#include "nsIXPConnect.h"
203
#include "xpcpublic.h"
204
#include "nsCCUncollectableMarker.h"
205
#include "nsIContentPolicy.h"
206
207
208
#include "nsContentPolicyUtils.h"
#include "nsICategoryManager.h"
#include "nsIDocumentLoaderFactory.h"
209
#include "nsIDocumentLoader.h"
210
211
212
#include "nsIContentViewer.h"
#include "nsIXMLContentSink.h"
#include "nsIPrompt.h"
213
#include "nsIPropertyBag2.h"
214
#include "mozilla/dom/PageTransitionEvent.h"
215
#include "mozilla/dom/StyleSheetApplicableStateChangeEvent.h"
216
#include "nsJSUtils.h"
217
#include "nsFrameLoader.h"
218
#include "nsEscape.h"
219
#include "nsObjectLoadingContent.h"
220
#include "nsHtml5TreeOpExecutor.h"
221
#include "mozilla/dom/HTMLFormElement.h"
222
#include "mozilla/dom/HTMLLinkElement.h"
223
#include "mozilla/dom/HTMLMediaElement.h"
224
#include "mozilla/dom/HTMLIFrameElement.h"
225
#include "mozilla/dom/HTMLImageElement.h"
226
#include "mozilla/dom/HTMLTextAreaElement.h"
227
#include "mozilla/dom/MediaSource.h"
228

229
#include "mozAutoDocUpdate.h"
230
#include "nsGlobalWindow.h"
231
#include "mozilla/Encoding.h"
232
#include "nsDOMNavigationTiming.h"
233

234
#include "mozilla/SMILAnimationController.h"
235
#include "imgIContainer.h"
236
#include "nsSVGUtils.h"
237

238
239
#include "nsRefreshDriver.h"

240
241
// FOR CSP (autogenerated by xpidl)
#include "nsIContentSecurityPolicy.h"
242
#include "mozilla/dom/nsCSPContext.h"
243
#include "mozilla/dom/nsCSPService.h"
244
#include "mozilla/dom/nsCSPUtils.h"
245
246
#include "nsHTMLStyleSheet.h"
#include "nsHTMLCSSStyleSheet.h"
247
#include "mozilla/dom/DOMImplementation.h"
248
#include "mozilla/dom/ShadowRoot.h"
249
250
#include "mozilla/dom/Comment.h"
#include "nsTextNode.h"
251
#include "mozilla/dom/Link.h"
252
#include "mozilla/dom/HTMLCollectionBinding.h"
253
#include "mozilla/dom/HTMLElementBinding.h"
254
#include "nsXULAppAPI.h"
255
#include "mozilla/dom/Touch.h"
256
#include "mozilla/dom/TouchEvent.h"
257

258
259
#include "mozilla/Preferences.h"

260
#include "imgILoader.h"
261
#include "imgRequestProxy.h"
262
#include "nsWrapperCacheInlines.h"
263
#include "nsSandboxFlags.h"
264
#include "mozilla/dom/AnimatableBinding.h"
265
#include "mozilla/dom/AnonymousContent.h"
266
#include "mozilla/dom/BindingUtils.h"
267
268
#include "mozilla/dom/ClientInfo.h"
#include "mozilla/dom/ClientState.h"
269
#include "mozilla/dom/DocumentFragment.h"
270
#include "mozilla/dom/DocumentTimeline.h"
271
#include "mozilla/dom/Event.h"
272
#include "mozilla/dom/HTMLBodyElement.h"
273
#include "mozilla/dom/HTMLInputElement.h"
274
#include "mozilla/dom/ImageTracker.h"
275
#include "mozilla/dom/MediaQueryList.h"
276
#include "mozilla/dom/NodeFilterBinding.h"
277
#include "mozilla/OwningNonNull.h"
278
#include "mozilla/dom/BrowserChild.h"
279
#include "mozilla/dom/WebComponentsBinding.h"
280
281
#include "mozilla/dom/CustomElementRegistryBinding.h"
#include "mozilla/dom/CustomElementRegistry.h"
282
#include "mozilla/dom/ServiceWorkerDescriptor.h"
283
#include "mozilla/dom/TimeoutManager.h"
284
#include "mozilla/dom/DocumentL10n.h"
285
#include "mozilla/ExtensionPolicyService.h"
286
#include "nsFrame.h"
287
#include "nsDOMCaretPosition.h"
288
#include "nsViewportInfo.h"
289
#include "mozilla/StaticPtr.h"
290
291
#include "nsIHttpChannelInternal.h"
#include "nsISecurityConsoleMessage.h"
292
#include "nsCharSeparatedTokenizer.h"
293
#include "mozilla/dom/XPathEvaluator.h"
294
#include "mozilla/dom/XPathNSResolverBinding.h"
295
#include "mozilla/dom/XPathResult.h"
296
#include "nsIDocumentEncoder.h"
297
#include "nsIDocumentActivity.h"
298
#include "nsIStructuredCloneContainer.h"
299
#include "nsIMutableArray.h"
300
#include "mozilla/dom/DOMStringList.h"
301
#include "nsWindowSizes.h"
302
#include "mozilla/dom/Location.h"
303
#include "mozilla/dom/FontFaceSet.h"
304
#include "nsISupportsPrimitives.h"
305
#include "mozilla/ServoStyleSet.h"
306
307
#include "mozilla/StyleSheet.h"
#include "mozilla/StyleSheetInlines.h"
308
#include "mozilla/dom/SVGDocument.h"
309
#include "mozilla/dom/SVGSVGElement.h"
310
#include "mozilla/dom/DocGroup.h"
311
#include "mozilla/dom/TabGroup.h"
312
#include "mozilla/dom/ChromeObserver.h"
313
#ifdef MOZ_XUL
314
315
#  include "mozilla/dom/XULBroadcastManager.h"
#  include "mozilla/dom/XULPersist.h"
316
#  include "nsIAppWindow.h"
317
#  include "nsIChromeRegistry.h"
318
#  include "nsXULPrototypeDocument.h"
319
320
321
#  include "nsXULCommandDispatcher.h"
#  include "nsXULPopupManager.h"
#  include "nsIDocShellTreeOwner.h"
322
#endif
323

324
325
#include "mozilla/DocLoadingTimelineMarker.h"

326
327
#include "mozilla/dom/WindowGlobalChild.h"

328
329
#include "nsISpeculativeConnect.h"

330
331
#include "mozilla/MediaManager.h"

332
#include "AutoplayPolicy.h"
333
#include "nsIURIMutator.h"
334
#include "mozilla/DocumentStyleRootIterator.h"
335
#include "mozilla/PendingFullscreenEvent.h"
336
#include "mozilla/RestyleManager.h"
337
#include "mozilla/ClearOnShutdown.h"
338
#include "mozilla/ResultExtensions.h"
339
#include "nsHTMLTags.h"
340
#include "MobileViewportManager.h"
341
#include "NodeUbiReporting.h"
342
#include "nsICookieService.h"
343
#include "mozilla/net/ChannelEventQueue.h"
344
#include "mozilla/net/RequestContextService.h"
345
#include "StorageAccessPermissionRequest.h"
346
#include "mozilla/dom/WindowProxyHolder.h"
347
#include "ThirdPartyUtil.h"
348
349
#include "nsHtml5Module.h"
#include "nsHtml5Parser.h"
350

351
352
353
354
355
#define XML_DECLARATION_BITS_DECLARATION_EXISTS (1 << 0)
#define XML_DECLARATION_BITS_ENCODING_EXISTS (1 << 1)
#define XML_DECLARATION_BITS_STANDALONE_EXISTS (1 << 2)
#define XML_DECLARATION_BITS_STANDALONE_YES (1 << 3)

356
357
#define NS_MAX_DOCUMENT_WRITE_DEPTH 20

358
359
mozilla::LazyLogModule gPageCacheLog("PageCache");

360
361
namespace mozilla {
namespace dom {
362

363
364
typedef nsTArray<Link*> LinkArray;

365
366
367
AutoTArray<Document*, 8>* Document::sLoadingForegroundTopLevelContentDocument =
    nullptr;

368
369
static LazyLogModule gDocumentLeakPRLog("DocumentLeak");
static LazyLogModule gCspPRLog("CSP");
370
LazyLogModule gUserInteractionPRLog("UserInteraction");
371

372
373
static nsresult GetHttpChannelHelper(nsIChannel* aChannel,
                                     nsIHttpChannel** aHttpChannel) {
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
  nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel);
  if (httpChannel) {
    httpChannel.forget(aHttpChannel);
    return NS_OK;
  }

  nsCOMPtr<nsIMultiPartChannel> multipart = do_QueryInterface(aChannel);
  if (!multipart) {
    *aHttpChannel = nullptr;
    return NS_OK;
  }

  nsCOMPtr<nsIChannel> baseChannel;
  nsresult rv = multipart->GetBaseChannel(getter_AddRefs(baseChannel));
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }

  httpChannel = do_QueryInterface(baseChannel);
  httpChannel.forget(aHttpChannel);

  return NS_OK;
}

398
399
}  // namespace dom

400
#define NAME_NOT_VALID ((nsSimpleContentList*)1)
401

402
IdentifierMapEntry::IdentifierMapEntry(
403
    const IdentifierMapEntry::DependentAtomOrString* aKey)
404
    : mKey(aKey ? *aKey : nullptr) {}
405

406
IdentifierMapEntry::~IdentifierMapEntry() {}
407

408
IdentifierMapEntry::IdentifierMapEntry(IdentifierMapEntry&& aOther)
409
410
411
412
413
414
415
    : PLDHashEntryHdr(std::move(aOther)),
      mKey(std::move(aOther.mKey)),
      mIdContentList(std::move(aOther.mIdContentList)),
      mNameContentList(std::move(aOther.mNameContentList)),
      mChangeCallbacks(std::move(aOther.mChangeCallbacks)),
      mImageElement(std::move(aOther.mImageElement)) {}

416
void IdentifierMapEntry::Traverse(
417
    nsCycleCollectionTraversalCallback* aCallback) {
418
419
  NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*aCallback,
                                     "mIdentifierMap mNameContentList");
420
  aCallback->NoteXPCOMChild(static_cast<nsINodeList*>(mNameContentList));
421

422
423
424
425
426
427
  if (mImageElement) {
    NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*aCallback,
                                       "mIdentifierMap mImageElement element");
    nsIContent* imageElement = mImageElement;
    aCallback->NoteXPCOMChild(imageElement);
  }
428
429
}

430
bool IdentifierMapEntry::IsEmpty() {
431
  return mIdContentList->IsEmpty() && !mNameContentList && !mChangeCallbacks &&
432
         !mImageElement;
433
434
}

435
bool IdentifierMapEntry::HasNameElement() const {
436
437
438
  return mNameContentList && mNameContentList->Length() != 0;
}

439
void IdentifierMapEntry::AddContentChangeCallback(
440
    Document::IDTargetObserver aCallback, void* aData, bool aForImage) {
441
442
443
444
  if (!mChangeCallbacks) {
    mChangeCallbacks = new nsTHashtable<ChangeCallbackEntry>;
  }

445
  ChangeCallback cc = {aCallback, aData, aForImage};
446
447
448
  mChangeCallbacks->PutEntry(cc);
}

449
void IdentifierMapEntry::RemoveContentChangeCallback(
450
    Document::IDTargetObserver aCallback, void* aData, bool aForImage) {
451
452
  if (!mChangeCallbacks) return;
  ChangeCallback cc = {aCallback, aData, aForImage};
453
454
  mChangeCallbacks->RemoveEntry(cc);
  if (mChangeCallbacks->Count() == 0) {
455
    mChangeCallbacks = nullptr;
456
457
458
  }
}

459
460
461
void IdentifierMapEntry::FireChangeCallbacks(Element* aOldElement,
                                             Element* aNewElement,
                                             bool aImageOnly) {
462
  if (!mChangeCallbacks) return;
463

464
  for (auto iter = mChangeCallbacks->ConstIter(); !iter.Done(); iter.Next()) {
465
    IdentifierMapEntry::ChangeCallbackEntry* entry = iter.Get();
466
467
468
469
470
471
472
473
474
475
    // Don't fire image changes for non-image observers, and don't fire element
    // changes for image observers when an image override is active.
    if (entry->mKey.mForImage ? (mImageElement && !aImageOnly) : aImageOnly) {
      continue;
    }

    if (!entry->mKey.mCallback(aOldElement, aNewElement, entry->mKey.mData)) {
      iter.Remove();
    }
  }
476
477
}

478
void IdentifierMapEntry::AddIdElement(Element* aElement) {
479
  MOZ_ASSERT(aElement, "Must have element");
480
  MOZ_ASSERT(!mIdContentList->Contains(nullptr), "Why is null in our list?");
481

482
483
484
  size_t index = mIdContentList.Insert(*aElement);
  if (index == 0) {
    Element* oldElement = mIdContentList->SafeElementAt(1);
485
    FireChangeCallbacks(oldElement, aElement);
486
  }
487
488
}

489
void IdentifierMapEntry::RemoveIdElement(Element* aElement) {
490
  MOZ_ASSERT(aElement, "Missing element");
491

492
493
494
  // This should only be called while the document is in an update.
  // Assertions near the call to this method guarantee this.

495
496
497
  // This could fire in OOM situations
  // Only assert this in HTML documents for now as XUL does all sorts of weird
  // crap.
498
  NS_ASSERTION(!aElement->OwnerDoc()->IsHTMLDocument() ||
499
                   mIdContentList->Contains(aElement),
500
501
               "Removing id entry that doesn't exist");

502
503
  // XXXbz should this ever Compact() I guess when all the content is gone
  // we'll just get cleaned up in the natural order of things...
504
505
  Element* currentElement = mIdContentList->SafeElementAt(0);
  mIdContentList.RemoveElement(*aElement);
506
  if (currentElement == aElement) {
507
    FireChangeCallbacks(currentElement, mIdContentList->SafeElementAt(0));
508
  }
509
510
}

511
void IdentifierMapEntry::SetImageElement(Element* aElement) {
512
513
514
515
  Element* oldElement = GetImageIdElement();
  mImageElement = aElement;
  Element* newElement = GetImageIdElement();
  if (oldElement != newElement) {
516
    FireChangeCallbacks(oldElement, newElement, true);
517
  }
518
519
}

520
521
522
523
524
525
526
527
528
529
530
531
532
void IdentifierMapEntry::ClearAndNotify() {
  Element* currentElement = mIdContentList->SafeElementAt(0);
  mIdContentList.Clear();
  if (currentElement) {
    FireChangeCallbacks(currentElement, nullptr);
  }
  mNameContentList = nullptr;
  if (mImageElement) {
    SetImageElement(nullptr);
  }
  mChangeCallbacks = nullptr;
}

533
namespace dom {
534

535
536
537
class SimpleHTMLCollection final : public nsSimpleContentList,
                                   public nsIHTMLCollection {
 public:
538
539
540
541
  explicit SimpleHTMLCollection(nsINode* aRoot) : nsSimpleContentList(aRoot) {}

  NS_DECL_ISUPPORTS_INHERITED

542
  virtual nsINode* GetParentObject() override {
543
544
    return nsSimpleContentList::GetParentObject();
  }
545
546
  virtual uint32_t Length() override { return nsSimpleContentList::Length(); }
  virtual Element* GetElementAt(uint32_t aIndex) override {
547
548
549
550
    return mElements.SafeElementAt(aIndex)->AsElement();
  }

  virtual Element* GetFirstNamedElement(const nsAString& aName,
551
                                        bool& aFound) override {
552
    aFound = false;
553
    RefPtr<nsAtom> name = NS_Atomize(aName);
554
555
556
557
558
559
560
561
562
563
564
565
566
    for (uint32_t i = 0; i < mElements.Length(); i++) {
      MOZ_DIAGNOSTIC_ASSERT(mElements[i]);
      Element* element = mElements[i]->AsElement();
      if (element->GetID() == name ||
          (element->HasName() &&
           element->GetParsedAttr(nsGkAtoms::name)->GetAtomValue() == name)) {
        aFound = true;
        return element;
      }
    }
    return nullptr;
  }

567
  virtual void GetSupportedNames(nsTArray<nsString>& aNames) override {
568
    AutoTArray<nsAtom*, 8> atoms;
569
570
571
572
    for (uint32_t i = 0; i < mElements.Length(); i++) {
      MOZ_DIAGNOSTIC_ASSERT(mElements[i]);
      Element* element = mElements[i]->AsElement();

573
      nsAtom* id = element->GetID();
574
575
576
577
578
579
      MOZ_ASSERT(id != nsGkAtoms::_empty);
      if (id && !atoms.Contains(id)) {
        atoms.AppendElement(id);
      }

      if (element->HasName()) {
580
        nsAtom* name = element->GetParsedAttr(nsGkAtoms::name)->GetAtomValue();
581
582
583
584
585
586
587
588
589
590
591
592
593
        MOZ_ASSERT(name && name != nsGkAtoms::_empty);
        if (name && !atoms.Contains(name)) {
          atoms.AppendElement(name);
        }
      }
    }

    nsString* names = aNames.AppendElements(atoms.Length());
    for (uint32_t i = 0; i < atoms.Length(); i++) {
      atoms[i]->ToString(names[i]);
    }
  }

594
  virtual JSObject* GetWrapperPreserveColorInternal() override {
595
596
    return nsWrapperCache::GetWrapperPreserveColor();
  }
597
598
  virtual void PreserveWrapperInternal(
      nsISupports* aScriptObjectHolder) override {
599
600
    nsWrapperCache::PreserveWrapper(aScriptObjectHolder);
  }
601
602
  virtual JSObject* WrapObject(JSContext* aCx,
                               JS::Handle<JSObject*> aGivenProto) override {
603
    return HTMLCollection_Binding::Wrap(aCx, this, aGivenProto);
604
605
606
607
  }

  using nsBaseContentList::Item;

608
 private:
609
610
611
612
  virtual ~SimpleHTMLCollection() {}
};

NS_IMPL_ISUPPORTS_INHERITED(SimpleHTMLCollection, nsSimpleContentList,
613
                            nsIHTMLCollection)
614

615
}  // namespace dom
616

617
void IdentifierMapEntry::AddNameElement(nsINode* aNode, Element* aElement) {
618
  if (!mNameContentList) {
619
    mNameContentList = new dom::SimpleHTMLCollection(aNode);
620
  }
621
622

  mNameContentList->AppendElement(aElement);
623
624
}

625
void IdentifierMapEntry::RemoveNameElement(Element* aElement) {
626
627
628
  if (mNameContentList) {
    mNameContentList->RemoveElement(aElement);
  }
629
630
}

631
bool IdentifierMapEntry::HasIdElementExposedAsHTMLDocumentProperty() {
632
633
634
635
636
  Element* idElement = GetIdElement();
  return idElement &&
         nsGenericHTMLElement::ShouldExposeIdAsHTMLDocumentProperty(idElement);
}

637
size_t IdentifierMapEntry::SizeOfExcludingThis(
638
    MallocSizeOf aMallocSizeOf) const {
639
  return mKey.mString.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
640
641
}

642
643
// Helper structs for the content->subdoc map

644
645
class SubDocMapEntry : public PLDHashEntryHdr {
 public:
646
  // Both of these are strong references
647
  Element* mKey;  // must be first, to look like PLDHashEntryStub
648
  dom::Document* mSubDocument;
649
650
};

651
class OnloadBlocker final : public nsIRequest {
652
 public:
653
  OnloadBlocker() {}
654
655
656
657
658

  NS_DECL_ISUPPORTS
  NS_DECL_NSIREQUEST

 private:
659
  ~OnloadBlocker() {}
660
661
};

662
NS_IMPL_ISUPPORTS(OnloadBlocker, nsIRequest)
663
664

NS_IMETHODIMP
665
OnloadBlocker::GetName(nsACString& aResult) {
666
667
668
669
670
  aResult.AssignLiteral("about:document-onload-blocker");
  return NS_OK;
}

NS_IMETHODIMP
671
OnloadBlocker::IsPending(bool* _retval) {
672
  *_retval = true;
673
674
675
676
  return NS_OK;
}

NS_IMETHODIMP
677
OnloadBlocker::GetStatus(nsresult* status) {
678
679
  *status = NS_OK;
  return NS_OK;
680
}
681
682

NS_IMETHODIMP
683
OnloadBlocker::Cancel(nsresult status) { return NS_OK; }
684
NS_IMETHODIMP
685
OnloadBlocker::Suspend(void) { return NS_OK; }
686
NS_IMETHODIMP
687
OnloadBlocker::Resume(void) { return NS_OK; }
688
689

NS_IMETHODIMP
690
OnloadBlocker::GetLoadGroup(nsILoadGroup** aLoadGroup) {
691
  *aLoadGroup = nullptr;
692
693
694
695
  return NS_OK;
}

NS_IMETHODIMP
696
OnloadBlocker::SetLoadGroup(nsILoadGroup* aLoadGroup) { return NS_OK; }
697
698

NS_IMETHODIMP
699
OnloadBlocker::GetLoadFlags(nsLoadFlags* aLoadFlags) {
700
701
702
703
704
  *aLoadFlags = nsIRequest::LOAD_NORMAL;
  return NS_OK;
}

NS_IMETHODIMP
705
OnloadBlocker::SetLoadFlags(nsLoadFlags aLoadFlags) { return NS_OK; }
706

707
708
// ==================================================================

709
710
711
namespace dom {

ExternalResourceMap::ExternalResourceMap() : mHaveShutDown(false) {}
712

713
Document* ExternalResourceMap::RequestResource(
714
715
    nsIURI* aURI, nsIReferrerInfo* aReferrerInfo, nsINode* aRequestingNode,
    Document* aDisplayDocument, ExternalResourceLoad** aPendingLoad) {
716
717
718
  // If we ever start allowing non-same-origin loads here, we might need to do
  // something interesting with aRequestingPrincipal even for the hashtable
  // gets.
719
720
  MOZ_ASSERT(aURI, "Must have a URI");
  MOZ_ASSERT(aRequestingNode, "Must have a node");
721
  MOZ_ASSERT(aReferrerInfo, "Must have a referrerInfo");
722
  *aPendingLoad = nullptr;
723
  if (mHaveShutDown) {
724
    return nullptr;
725
  }
726

727
728
  // First, make sure we strip the ref from aURI.
  nsCOMPtr<nsIURI> clone;
729
  nsresult rv = NS_GetURIWithoutRef(aURI, getter_AddRefs(clone));
730
  if (NS_FAILED(rv) || !clone) {
731
    return nullptr;
732
  }
733

734
735
736
737
738
739
  ExternalResource* resource;
  mMap.Get(clone, &resource);
  if (resource) {
    return resource->mDocument;
  }

740
741
742
  RefPtr<PendingLoad>& loadEntry = mPendingLoads.GetOrInsert(clone);
  if (loadEntry) {
    RefPtr<PendingLoad> load(loadEntry);
743
    load.forget(aPendingLoad);
744
    return nullptr;
745
746
  }

747
748
  RefPtr<PendingLoad> load(new PendingLoad(aDisplayDocument));
  loadEntry = load;
749

750
  if (NS_FAILED(load->StartLoad(clone, aReferrerInfo, aRequestingNode))) {
751
752
    // Make sure we don't thrash things by trying this load again, since
    // chances are it failed for good reasons (security check, etc).
753
    AddExternalResource(clone, nullptr, nullptr, aDisplayDocument);
754
  } else {
755
    load.forget(aPendingLoad);
756