content/base/src/nsDocument.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/content/base/src/nsDocument.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,1684 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* vim: set ts=2 sw=2 et tw=80: */
     1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +/*
    1.11 + * Base class for all our document implementations.
    1.12 + */
    1.13 +
    1.14 +#ifndef nsDocument_h___
    1.15 +#define nsDocument_h___
    1.16 +
    1.17 +#include "nsIDocument.h"
    1.18 +
    1.19 +#include "nsCOMPtr.h"
    1.20 +#include "nsAutoPtr.h"
    1.21 +#include "nsCRT.h"
    1.22 +#include "nsWeakReference.h"
    1.23 +#include "nsWeakPtr.h"
    1.24 +#include "nsVoidArray.h"
    1.25 +#include "nsTArray.h"
    1.26 +#include "nsIDOMXMLDocument.h"
    1.27 +#include "nsIDOMDocumentXBL.h"
    1.28 +#include "nsStubDocumentObserver.h"
    1.29 +#include "nsIScriptGlobalObject.h"
    1.30 +#include "nsIContent.h"
    1.31 +#include "nsIPrincipal.h"
    1.32 +#include "nsIParser.h"
    1.33 +#include "nsBindingManager.h"
    1.34 +#include "nsINodeInfo.h"
    1.35 +#include "nsInterfaceHashtable.h"
    1.36 +#include "nsJSThingHashtable.h"
    1.37 +#include "nsIBoxObject.h"
    1.38 +#include "nsPIBoxObject.h"
    1.39 +#include "nsIScriptObjectPrincipal.h"
    1.40 +#include "nsIURI.h"
    1.41 +#include "nsScriptLoader.h"
    1.42 +#include "nsIRadioGroupContainer.h"
    1.43 +#include "nsILayoutHistoryState.h"
    1.44 +#include "nsIRequest.h"
    1.45 +#include "nsILoadGroup.h"
    1.46 +#include "nsTObserverArray.h"
    1.47 +#include "nsStubMutationObserver.h"
    1.48 +#include "nsIChannel.h"
    1.49 +#include "nsCycleCollectionParticipant.h"
    1.50 +#include "nsContentList.h"
    1.51 +#include "nsGkAtoms.h"
    1.52 +#include "nsIApplicationCache.h"
    1.53 +#include "nsIApplicationCacheContainer.h"
    1.54 +#include "nsStyleSet.h"
    1.55 +#include "pldhash.h"
    1.56 +#include "nsAttrAndChildArray.h"
    1.57 +#include "nsDOMAttributeMap.h"
    1.58 +#include "nsIContentViewer.h"
    1.59 +#include "nsIDOMXPathNSResolver.h"
    1.60 +#include "nsIInterfaceRequestor.h"
    1.61 +#include "nsILoadContext.h"
    1.62 +#include "nsIProgressEventSink.h"
    1.63 +#include "nsISecurityEventSink.h"
    1.64 +#include "nsIChannelEventSink.h"
    1.65 +#include "imgIRequest.h"
    1.66 +#include "mozilla/EventListenerManager.h"
    1.67 +#include "mozilla/EventStates.h"
    1.68 +#include "mozilla/MemoryReporting.h"
    1.69 +#include "mozilla/dom/DOMImplementation.h"
    1.70 +#include "mozilla/dom/StyleSheetList.h"
    1.71 +#include "nsIDOMTouchEvent.h"
    1.72 +#include "nsDataHashtable.h"
    1.73 +#include "mozilla/TimeStamp.h"
    1.74 +#include "mozilla/Attributes.h"
    1.75 +#include "nsIDOMXPathEvaluator.h"
    1.76 +#include "jsfriendapi.h"
    1.77 +
    1.78 +#define XML_DECLARATION_BITS_DECLARATION_EXISTS   (1 << 0)
    1.79 +#define XML_DECLARATION_BITS_ENCODING_EXISTS      (1 << 1)
    1.80 +#define XML_DECLARATION_BITS_STANDALONE_EXISTS    (1 << 2)
    1.81 +#define XML_DECLARATION_BITS_STANDALONE_YES       (1 << 3)
    1.82 +
    1.83 +
    1.84 +class nsDOMStyleSheetSetList;
    1.85 +class nsIOutputStream;
    1.86 +class nsDocument;
    1.87 +class nsIDTD;
    1.88 +class nsIRadioVisitor;
    1.89 +class nsIFormControl;
    1.90 +struct nsRadioGroupStruct;
    1.91 +class nsOnloadBlocker;
    1.92 +class nsUnblockOnloadEvent;
    1.93 +class nsChildContentList;
    1.94 +class nsHTMLStyleSheet;
    1.95 +class nsHTMLCSSStyleSheet;
    1.96 +class nsDOMNavigationTiming;
    1.97 +class nsWindowSizes;
    1.98 +class nsHtml5TreeOpExecutor;
    1.99 +class nsDocumentOnStack;
   1.100 +class nsPointerLockPermissionRequest;
   1.101 +class nsISecurityConsoleMessage;
   1.102 +
   1.103 +namespace mozilla {
   1.104 +class EventChainPreVisitor;
   1.105 +namespace dom {
   1.106 +class UndoManager;
   1.107 +class LifecycleCallbacks;
   1.108 +class CallbackFunction;
   1.109 +}
   1.110 +}
   1.111 +
   1.112 +/**
   1.113 + * Right now our identifier map entries contain information for 'name'
   1.114 + * and 'id' mappings of a given string. This is so that
   1.115 + * nsHTMLDocument::ResolveName only has to do one hash lookup instead
   1.116 + * of two. It's not clear whether this still matters for performance.
   1.117 + * 
   1.118 + * We also store the document.all result list here. This is mainly so that
   1.119 + * when all elements with the given ID are removed and we remove
   1.120 + * the ID's nsIdentifierMapEntry, the document.all result is released too.
   1.121 + * Perhaps the document.all results should have their own hashtable
   1.122 + * in nsHTMLDocument.
   1.123 + */
   1.124 +class nsIdentifierMapEntry : public nsStringHashKey
   1.125 +{
   1.126 +public:
   1.127 +  typedef mozilla::dom::Element Element;
   1.128 +  
   1.129 +  nsIdentifierMapEntry(const nsAString& aKey) :
   1.130 +    nsStringHashKey(&aKey), mNameContentList(nullptr)
   1.131 +  {
   1.132 +  }
   1.133 +  nsIdentifierMapEntry(const nsAString *aKey) :
   1.134 +    nsStringHashKey(aKey), mNameContentList(nullptr)
   1.135 +  {
   1.136 +  }
   1.137 +  nsIdentifierMapEntry(const nsIdentifierMapEntry& aOther) :
   1.138 +    nsStringHashKey(&aOther.GetKey())
   1.139 +  {
   1.140 +    NS_ERROR("Should never be called");
   1.141 +  }
   1.142 +  ~nsIdentifierMapEntry();
   1.143 +
   1.144 +  void AddNameElement(nsINode* aDocument, Element* aElement);
   1.145 +  void RemoveNameElement(Element* aElement);
   1.146 +  bool IsEmpty();
   1.147 +  nsBaseContentList* GetNameContentList() {
   1.148 +    return mNameContentList;
   1.149 +  }
   1.150 +  bool HasNameElement() const {
   1.151 +    return mNameContentList && mNameContentList->Length() != 0;
   1.152 +  }
   1.153 +
   1.154 +  /**
   1.155 +   * Returns the element if we know the element associated with this
   1.156 +   * id. Otherwise returns null.
   1.157 +   */
   1.158 +  Element* GetIdElement();
   1.159 +  /**
   1.160 +   * Returns the list of all elements associated with this id.
   1.161 +   */
   1.162 +  const nsSmallVoidArray* GetIdElements() const {
   1.163 +    return &mIdContentList;
   1.164 +  }
   1.165 +  /**
   1.166 +   * If this entry has a non-null image element set (using SetImageElement),
   1.167 +   * the image element will be returned, otherwise the same as GetIdElement().
   1.168 +   */
   1.169 +  Element* GetImageIdElement();
   1.170 +  /**
   1.171 +   * Append all the elements with this id to aElements
   1.172 +   */
   1.173 +  void AppendAllIdContent(nsCOMArray<nsIContent>* aElements);
   1.174 +  /**
   1.175 +   * This can fire ID change callbacks.
   1.176 +   * @return true if the content could be added, false if we failed due
   1.177 +   * to OOM.
   1.178 +   */
   1.179 +  bool AddIdElement(Element* aElement);
   1.180 +  /**
   1.181 +   * This can fire ID change callbacks.
   1.182 +   */
   1.183 +  void RemoveIdElement(Element* aElement);
   1.184 +  /**
   1.185 +   * Set the image element override for this ID. This will be returned by
   1.186 +   * GetIdElement(true) if non-null.
   1.187 +   */
   1.188 +  void SetImageElement(Element* aElement);
   1.189 +  bool HasIdElementExposedAsHTMLDocumentProperty();
   1.190 +
   1.191 +  bool HasContentChangeCallback() { return mChangeCallbacks != nullptr; }
   1.192 +  void AddContentChangeCallback(nsIDocument::IDTargetObserver aCallback,
   1.193 +                                void* aData, bool aForImage);
   1.194 +  void RemoveContentChangeCallback(nsIDocument::IDTargetObserver aCallback,
   1.195 +                                void* aData, bool aForImage);
   1.196 +
   1.197 +  void Traverse(nsCycleCollectionTraversalCallback* aCallback);
   1.198 +
   1.199 +  struct ChangeCallback {
   1.200 +    nsIDocument::IDTargetObserver mCallback;
   1.201 +    void* mData;
   1.202 +    bool mForImage;
   1.203 +  };
   1.204 +
   1.205 +  struct ChangeCallbackEntry : public PLDHashEntryHdr {
   1.206 +    typedef const ChangeCallback KeyType;
   1.207 +    typedef const ChangeCallback* KeyTypePointer;
   1.208 +
   1.209 +    ChangeCallbackEntry(const ChangeCallback* key) :
   1.210 +      mKey(*key) { }
   1.211 +    ChangeCallbackEntry(const ChangeCallbackEntry& toCopy) :
   1.212 +      mKey(toCopy.mKey) { }
   1.213 +
   1.214 +    KeyType GetKey() const { return mKey; }
   1.215 +    bool KeyEquals(KeyTypePointer aKey) const {
   1.216 +      return aKey->mCallback == mKey.mCallback &&
   1.217 +             aKey->mData == mKey.mData &&
   1.218 +             aKey->mForImage == mKey.mForImage;
   1.219 +    }
   1.220 +
   1.221 +    static KeyTypePointer KeyToPointer(KeyType& aKey) { return &aKey; }
   1.222 +    static PLDHashNumber HashKey(KeyTypePointer aKey)
   1.223 +    {
   1.224 +      return mozilla::HashGeneric(aKey->mCallback, aKey->mData);
   1.225 +    }
   1.226 +    enum { ALLOW_MEMMOVE = true };
   1.227 +    
   1.228 +    ChangeCallback mKey;
   1.229 +  };
   1.230 +
   1.231 +  static size_t SizeOfExcludingThis(nsIdentifierMapEntry* aEntry,
   1.232 +                                    mozilla::MallocSizeOf aMallocSizeOf,
   1.233 +                                    void* aArg);
   1.234 +
   1.235 +private:
   1.236 +  void FireChangeCallbacks(Element* aOldElement, Element* aNewElement,
   1.237 +                           bool aImageOnly = false);
   1.238 +
   1.239 +  // empty if there are no elements with this ID.
   1.240 +  // The elements are stored as weak pointers.
   1.241 +  nsSmallVoidArray mIdContentList;
   1.242 +  nsRefPtr<nsBaseContentList> mNameContentList;
   1.243 +  nsAutoPtr<nsTHashtable<ChangeCallbackEntry> > mChangeCallbacks;
   1.244 +  nsRefPtr<Element> mImageElement;
   1.245 +};
   1.246 +
   1.247 +namespace mozilla {
   1.248 +namespace dom {
   1.249 +
   1.250 +class CustomElementHashKey : public PLDHashEntryHdr
   1.251 +{
   1.252 +public:
   1.253 +  typedef CustomElementHashKey *KeyType;
   1.254 +  typedef const CustomElementHashKey *KeyTypePointer;
   1.255 +
   1.256 +  CustomElementHashKey(int32_t aNamespaceID, nsIAtom *aAtom)
   1.257 +    : mNamespaceID(aNamespaceID),
   1.258 +      mAtom(aAtom)
   1.259 +  {}
   1.260 +  CustomElementHashKey(const CustomElementHashKey *aKey)
   1.261 +    : mNamespaceID(aKey->mNamespaceID),
   1.262 +      mAtom(aKey->mAtom)
   1.263 +  {}
   1.264 +  ~CustomElementHashKey()
   1.265 +  {}
   1.266 +
   1.267 +  KeyType GetKey() const { return const_cast<KeyType>(this); }
   1.268 +  bool KeyEquals(const KeyTypePointer aKey) const
   1.269 +  {
   1.270 +    MOZ_ASSERT(mNamespaceID != kNameSpaceID_Unknown,
   1.271 +               "This equals method is not transitive, nor symmetric. "
   1.272 +               "A key with a namespace of kNamespaceID_Unknown should "
   1.273 +               "not be stored in a hashtable.");
   1.274 +    return (kNameSpaceID_Unknown == aKey->mNamespaceID ||
   1.275 +            mNamespaceID == aKey->mNamespaceID) &&
   1.276 +           aKey->mAtom == mAtom;
   1.277 +  }
   1.278 +
   1.279 +  static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; }
   1.280 +  static PLDHashNumber HashKey(const KeyTypePointer aKey)
   1.281 +  {
   1.282 +    return aKey->mAtom->hash();
   1.283 +  }
   1.284 +  enum { ALLOW_MEMMOVE = true };
   1.285 +
   1.286 +private:
   1.287 +  int32_t mNamespaceID;
   1.288 +  nsCOMPtr<nsIAtom> mAtom;
   1.289 +};
   1.290 +
   1.291 +struct LifecycleCallbackArgs
   1.292 +{
   1.293 +  nsString name;
   1.294 +  nsString oldValue;
   1.295 +  nsString newValue;
   1.296 +};
   1.297 +
   1.298 +struct CustomElementData;
   1.299 +
   1.300 +class CustomElementCallback
   1.301 +{
   1.302 +public:
   1.303 +  CustomElementCallback(Element* aThisObject,
   1.304 +                        nsIDocument::ElementCallbackType aCallbackType,
   1.305 +                        mozilla::dom::CallbackFunction* aCallback,
   1.306 +                        CustomElementData* aOwnerData);
   1.307 +  void Traverse(nsCycleCollectionTraversalCallback& aCb) const;
   1.308 +  void Call();
   1.309 +  void SetArgs(LifecycleCallbackArgs& aArgs)
   1.310 +  {
   1.311 +    MOZ_ASSERT(mType == nsIDocument::eAttributeChanged,
   1.312 +               "Arguments are only used by attribute changed callback.");
   1.313 +    mArgs = aArgs;
   1.314 +  }
   1.315 +
   1.316 +private:
   1.317 +  // The this value to use for invocation of the callback.
   1.318 +  nsRefPtr<mozilla::dom::Element> mThisObject;
   1.319 +  nsRefPtr<mozilla::dom::CallbackFunction> mCallback;
   1.320 +  // The type of callback (eCreated, eAttached, etc.)
   1.321 +  nsIDocument::ElementCallbackType mType;
   1.322 +  // Arguments to be passed to the callback,
   1.323 +  // used by the attribute changed callback.
   1.324 +  LifecycleCallbackArgs mArgs;
   1.325 +  // CustomElementData that contains this callback in the
   1.326 +  // callback queue.
   1.327 +  CustomElementData* mOwnerData;
   1.328 +};
   1.329 +
   1.330 +// Each custom element has an associated callback queue and an element is
   1.331 +// being created flag.
   1.332 +struct CustomElementData
   1.333 +{
   1.334 +  CustomElementData(nsIAtom* aType);
   1.335 +  // Objects in this array are transient and empty after each microtask
   1.336 +  // checkpoint.
   1.337 +  nsTArray<nsAutoPtr<CustomElementCallback>> mCallbackQueue;
   1.338 +  // Custom element type, for <button is="x-button"> or <x-button>
   1.339 +  // this would be x-button.
   1.340 +  nsCOMPtr<nsIAtom> mType;
   1.341 +  // The callback that is next to be processed upon calling RunCallbackQueue.
   1.342 +  int32_t mCurrentCallback;
   1.343 +  // Element is being created flag as described in the custom elements spec.
   1.344 +  bool mElementIsBeingCreated;
   1.345 +  // Flag to determine if the created callback has been invoked, thus it
   1.346 +  // determines if other callbacks can be enqueued.
   1.347 +  bool mCreatedCallbackInvoked;
   1.348 +  // The microtask level associated with the callbacks in the callback queue,
   1.349 +  // it is used to determine if a new queue needs to be pushed onto the
   1.350 +  // processing stack.
   1.351 +  int32_t mAssociatedMicroTask;
   1.352 +
   1.353 +  // Empties the callback queue.
   1.354 +  void RunCallbackQueue();
   1.355 +};
   1.356 +
   1.357 +// The required information for a custom element as defined in:
   1.358 +// https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/index.html
   1.359 +struct CustomElementDefinition
   1.360 +{
   1.361 +  CustomElementDefinition(JSObject* aPrototype,
   1.362 +                          nsIAtom* aType,
   1.363 +                          nsIAtom* aLocalName,
   1.364 +                          mozilla::dom::LifecycleCallbacks* aCallbacks,
   1.365 +                          uint32_t aNamespaceID,
   1.366 +                          uint32_t aDocOrder);
   1.367 +
   1.368 +  // The prototype to use for new custom elements of this type.
   1.369 +  JS::Heap<JSObject *> mPrototype;
   1.370 +
   1.371 +  // The type (name) for this custom element.
   1.372 +  nsCOMPtr<nsIAtom> mType;
   1.373 +
   1.374 +  // The localname to (e.g. <button is=type> -- this would be button).
   1.375 +  nsCOMPtr<nsIAtom> mLocalName;
   1.376 +
   1.377 +  // The lifecycle callbacks to call for this custom element.
   1.378 +  nsAutoPtr<mozilla::dom::LifecycleCallbacks> mCallbacks;
   1.379 +
   1.380 +  // Whether we're currently calling the created callback for a custom element
   1.381 +  // of this type.
   1.382 +  bool mElementIsBeingCreated;
   1.383 +
   1.384 +  // Element namespace.
   1.385 +  int32_t mNamespaceID;
   1.386 +
   1.387 +  // The document custom element order.
   1.388 +  uint32_t mDocOrder;
   1.389 +};
   1.390 +
   1.391 +class Registry : public nsISupports
   1.392 +{
   1.393 +public:
   1.394 +  friend class ::nsDocument;
   1.395 +
   1.396 +  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   1.397 +  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Registry)
   1.398 +
   1.399 +  Registry();
   1.400 +  virtual ~Registry();
   1.401 +
   1.402 +protected:
   1.403 +  typedef nsClassHashtable<mozilla::dom::CustomElementHashKey,
   1.404 +                           mozilla::dom::CustomElementDefinition>
   1.405 +    DefinitionMap;
   1.406 +  typedef nsClassHashtable<mozilla::dom::CustomElementHashKey,
   1.407 +                           nsTArray<nsRefPtr<mozilla::dom::Element>>>
   1.408 +    CandidateMap;
   1.409 +
   1.410 +  // Hashtable for custom element definitions in web components.
   1.411 +  // Custom prototypes are in the document's compartment.
   1.412 +  DefinitionMap mCustomDefinitions;
   1.413 +
   1.414 +  // The "upgrade candidates map" from the web components spec. Maps from a
   1.415 +  // namespace id and local name to a list of elements to upgrade if that
   1.416 +  // element is registered as a custom element.
   1.417 +  CandidateMap mCandidatesMap;
   1.418 +};
   1.419 +
   1.420 +} // namespace dom
   1.421 +} // namespace mozilla
   1.422 +
   1.423 +class nsDocHeaderData
   1.424 +{
   1.425 +public:
   1.426 +  nsDocHeaderData(nsIAtom* aField, const nsAString& aData)
   1.427 +    : mField(aField), mData(aData), mNext(nullptr)
   1.428 +  {
   1.429 +  }
   1.430 +
   1.431 +  ~nsDocHeaderData(void)
   1.432 +  {
   1.433 +    delete mNext;
   1.434 +  }
   1.435 +
   1.436 +  nsCOMPtr<nsIAtom> mField;
   1.437 +  nsString          mData;
   1.438 +  nsDocHeaderData*  mNext;
   1.439 +};
   1.440 +
   1.441 +class nsDOMStyleSheetList : public mozilla::dom::StyleSheetList,
   1.442 +                            public nsStubDocumentObserver
   1.443 +{
   1.444 +public:
   1.445 +  nsDOMStyleSheetList(nsIDocument *aDocument);
   1.446 +  virtual ~nsDOMStyleSheetList();
   1.447 +
   1.448 +  NS_DECL_ISUPPORTS_INHERITED
   1.449 +
   1.450 +  // nsIDocumentObserver
   1.451 +  NS_DECL_NSIDOCUMENTOBSERVER_STYLESHEETADDED
   1.452 +  NS_DECL_NSIDOCUMENTOBSERVER_STYLESHEETREMOVED
   1.453 +
   1.454 +  // nsIMutationObserver
   1.455 +  NS_DECL_NSIMUTATIONOBSERVER_NODEWILLBEDESTROYED
   1.456 +
   1.457 +  virtual nsINode* GetParentObject() const MOZ_OVERRIDE
   1.458 +  {
   1.459 +    return mDocument;
   1.460 +  }
   1.461 +
   1.462 +  virtual uint32_t Length() MOZ_OVERRIDE;
   1.463 +  virtual nsCSSStyleSheet* IndexedGetter(uint32_t aIndex, bool& aFound) MOZ_OVERRIDE;
   1.464 +
   1.465 +protected:
   1.466 +  int32_t       mLength;
   1.467 +  nsIDocument*  mDocument;
   1.468 +};
   1.469 +
   1.470 +class nsOnloadBlocker MOZ_FINAL : public nsIRequest
   1.471 +{
   1.472 +public:
   1.473 +  nsOnloadBlocker() {}
   1.474 +
   1.475 +  NS_DECL_ISUPPORTS
   1.476 +  NS_DECL_NSIREQUEST
   1.477 +
   1.478 +private:
   1.479 +  ~nsOnloadBlocker() {}
   1.480 +};
   1.481 +
   1.482 +class nsExternalResourceMap
   1.483 +{
   1.484 +public:
   1.485 +  typedef nsIDocument::ExternalResourceLoad ExternalResourceLoad;
   1.486 +  nsExternalResourceMap();
   1.487 +
   1.488 +  /**
   1.489 +   * Request an external resource document.  This does exactly what
   1.490 +   * nsIDocument::RequestExternalResource is documented to do.
   1.491 +   */
   1.492 +  nsIDocument* RequestResource(nsIURI* aURI,
   1.493 +                               nsINode* aRequestingNode,
   1.494 +                               nsDocument* aDisplayDocument,
   1.495 +                               ExternalResourceLoad** aPendingLoad);
   1.496 +
   1.497 +  /**
   1.498 +   * Enumerate the resource documents.  See
   1.499 +   * nsIDocument::EnumerateExternalResources.
   1.500 +   */
   1.501 +  void EnumerateResources(nsIDocument::nsSubDocEnumFunc aCallback, void* aData);
   1.502 +
   1.503 +  /**
   1.504 +   * Traverse ourselves for cycle-collection
   1.505 +   */
   1.506 +  void Traverse(nsCycleCollectionTraversalCallback* aCallback) const;
   1.507 +
   1.508 +  /**
   1.509 +   * Shut ourselves down (used for cycle-collection unlink), as well
   1.510 +   * as for document destruction.
   1.511 +   */
   1.512 +  void Shutdown()
   1.513 +  {
   1.514 +    mPendingLoads.Clear();
   1.515 +    mMap.Clear();
   1.516 +    mHaveShutDown = true;
   1.517 +  }
   1.518 +
   1.519 +  bool HaveShutDown() const
   1.520 +  {
   1.521 +    return mHaveShutDown;
   1.522 +  }
   1.523 +
   1.524 +  // Needs to be public so we can traverse them sanely
   1.525 +  struct ExternalResource
   1.526 +  {
   1.527 +    ~ExternalResource();
   1.528 +    nsCOMPtr<nsIDocument> mDocument;
   1.529 +    nsCOMPtr<nsIContentViewer> mViewer;
   1.530 +    nsCOMPtr<nsILoadGroup> mLoadGroup;
   1.531 +  };
   1.532 +
   1.533 +  // Hide all our viewers
   1.534 +  void HideViewers();
   1.535 +
   1.536 +  // Show all our viewers
   1.537 +  void ShowViewers();
   1.538 +
   1.539 +protected:
   1.540 +  class PendingLoad : public ExternalResourceLoad,
   1.541 +                      public nsIStreamListener
   1.542 +  {
   1.543 +  public:
   1.544 +    PendingLoad(nsDocument* aDisplayDocument) :
   1.545 +      mDisplayDocument(aDisplayDocument)
   1.546 +    {}
   1.547 +
   1.548 +    NS_DECL_ISUPPORTS
   1.549 +    NS_DECL_NSISTREAMLISTENER
   1.550 +    NS_DECL_NSIREQUESTOBSERVER
   1.551 +
   1.552 +    /**
   1.553 +     * Start aURI loading.  This will perform the necessary security checks and
   1.554 +     * so forth.
   1.555 +     */
   1.556 +    nsresult StartLoad(nsIURI* aURI, nsINode* aRequestingNode);
   1.557 +
   1.558 +    /**
   1.559 +     * Set up an nsIContentViewer based on aRequest.  This is guaranteed to
   1.560 +     * put null in *aViewer and *aLoadGroup on all failures.
   1.561 +     */
   1.562 +    nsresult SetupViewer(nsIRequest* aRequest, nsIContentViewer** aViewer,
   1.563 +                         nsILoadGroup** aLoadGroup);
   1.564 +
   1.565 +  private:
   1.566 +    nsRefPtr<nsDocument> mDisplayDocument;
   1.567 +    nsCOMPtr<nsIStreamListener> mTargetListener;
   1.568 +    nsCOMPtr<nsIURI> mURI;
   1.569 +  };
   1.570 +  friend class PendingLoad;
   1.571 +
   1.572 +  class LoadgroupCallbacks MOZ_FINAL : public nsIInterfaceRequestor
   1.573 +  {
   1.574 +  public:
   1.575 +    LoadgroupCallbacks(nsIInterfaceRequestor* aOtherCallbacks)
   1.576 +      : mCallbacks(aOtherCallbacks)
   1.577 +    {}
   1.578 +    NS_DECL_ISUPPORTS
   1.579 +    NS_DECL_NSIINTERFACEREQUESTOR
   1.580 +  private:
   1.581 +    // The only reason it's safe to hold a strong ref here without leaking is
   1.582 +    // that the notificationCallbacks on a loadgroup aren't the docshell itself
   1.583 +    // but a shim that holds a weak reference to the docshell.
   1.584 +    nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
   1.585 +
   1.586 +    // Use shims for interfaces that docshell implements directly so that we
   1.587 +    // don't hand out references to the docshell.  The shims should all allow
   1.588 +    // getInterface back on us, but other than that each one should only
   1.589 +    // implement one interface.
   1.590 +    
   1.591 +    // XXXbz I wish we could just derive the _allcaps thing from _i
   1.592 +#define DECL_SHIM(_i, _allcaps)                                              \
   1.593 +    class _i##Shim MOZ_FINAL : public nsIInterfaceRequestor,                 \
   1.594 +                               public _i                                     \
   1.595 +    {                                                                        \
   1.596 +    public:                                                                  \
   1.597 +      _i##Shim(nsIInterfaceRequestor* aIfreq, _i* aRealPtr)                  \
   1.598 +        : mIfReq(aIfreq), mRealPtr(aRealPtr)                                 \
   1.599 +      {                                                                      \
   1.600 +        NS_ASSERTION(mIfReq, "Expected non-null here");                      \
   1.601 +        NS_ASSERTION(mRealPtr, "Expected non-null here");                    \
   1.602 +      }                                                                      \
   1.603 +      NS_DECL_ISUPPORTS                                                      \
   1.604 +      NS_FORWARD_NSIINTERFACEREQUESTOR(mIfReq->)                             \
   1.605 +      NS_FORWARD_##_allcaps(mRealPtr->)                                      \
   1.606 +    private:                                                                 \
   1.607 +      nsCOMPtr<nsIInterfaceRequestor> mIfReq;                                \
   1.608 +      nsCOMPtr<_i> mRealPtr;                                                 \
   1.609 +    };
   1.610 +
   1.611 +    DECL_SHIM(nsILoadContext, NSILOADCONTEXT)
   1.612 +    DECL_SHIM(nsIProgressEventSink, NSIPROGRESSEVENTSINK)
   1.613 +    DECL_SHIM(nsIChannelEventSink, NSICHANNELEVENTSINK)
   1.614 +    DECL_SHIM(nsISecurityEventSink, NSISECURITYEVENTSINK)
   1.615 +    DECL_SHIM(nsIApplicationCacheContainer, NSIAPPLICATIONCACHECONTAINER)
   1.616 +#undef DECL_SHIM
   1.617 +  };
   1.618 +  
   1.619 +  /**
   1.620 +   * Add an ExternalResource for aURI.  aViewer and aLoadGroup might be null
   1.621 +   * when this is called if the URI didn't result in an XML document.  This
   1.622 +   * function makes sure to remove the pending load for aURI, if any, from our
   1.623 +   * hashtable, and to notify its observers, if any.
   1.624 +   */
   1.625 +  nsresult AddExternalResource(nsIURI* aURI, nsIContentViewer* aViewer,
   1.626 +                               nsILoadGroup* aLoadGroup,
   1.627 +                               nsIDocument* aDisplayDocument);
   1.628 +  
   1.629 +  nsClassHashtable<nsURIHashKey, ExternalResource> mMap;
   1.630 +  nsRefPtrHashtable<nsURIHashKey, PendingLoad> mPendingLoads;
   1.631 +  bool mHaveShutDown;
   1.632 +};
   1.633 +
   1.634 +class CSPErrorQueue
   1.635 +{
   1.636 +  public:
   1.637 +    /**
   1.638 +     * Note this was designed to be passed string literals. If you give it
   1.639 +     * a dynamically allocated string, it is your responsibility to make sure
   1.640 +     * it never dies and is properly freed!
   1.641 +     */
   1.642 +    void Add(const char* aMessageName);
   1.643 +    void Flush(nsIDocument* aDocument);
   1.644 +
   1.645 +    CSPErrorQueue()
   1.646 +    {
   1.647 +    }
   1.648 +
   1.649 +    ~CSPErrorQueue()
   1.650 +    {
   1.651 +    }
   1.652 +
   1.653 +  private:
   1.654 +    nsAutoTArray<const char*,5> mErrors;
   1.655 +};
   1.656 +
   1.657 +// Base class for our document implementations.
   1.658 +//
   1.659 +// Note that this class *implements* nsIDOMXMLDocument, but it's not
   1.660 +// really an nsIDOMXMLDocument. The reason for implementing
   1.661 +// nsIDOMXMLDocument on this class is to avoid having to duplicate all
   1.662 +// its inherited methods on document classes that *are*
   1.663 +// nsIDOMXMLDocument's. nsDocument's QI should *not* claim to support
   1.664 +// nsIDOMXMLDocument unless someone writes a real implementation of
   1.665 +// the interface.
   1.666 +class nsDocument : public nsIDocument,
   1.667 +                   public nsIDOMXMLDocument, // inherits nsIDOMDocument
   1.668 +                   public nsIDOMDocumentXBL,
   1.669 +                   public nsSupportsWeakReference,
   1.670 +                   public nsIScriptObjectPrincipal,
   1.671 +                   public nsIRadioGroupContainer,
   1.672 +                   public nsIApplicationCacheContainer,
   1.673 +                   public nsStubMutationObserver,
   1.674 +                   public nsIObserver,
   1.675 +                   public nsIDOMXPathEvaluator
   1.676 +{
   1.677 +public:
   1.678 +  typedef mozilla::dom::Element Element;
   1.679 +  using nsIDocument::GetElementsByTagName;
   1.680 +
   1.681 +  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   1.682 +
   1.683 +  NS_DECL_SIZEOF_EXCLUDING_THIS
   1.684 +
   1.685 +  virtual void Reset(nsIChannel *aChannel, nsILoadGroup *aLoadGroup) MOZ_OVERRIDE;
   1.686 +  virtual void ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup,
   1.687 +                          nsIPrincipal* aPrincipal) MOZ_OVERRIDE;
   1.688 +
   1.689 +  // StartDocumentLoad is pure virtual so that subclasses must override it.
   1.690 +  // The nsDocument StartDocumentLoad does some setup, but does NOT set
   1.691 +  // *aDocListener; this is the job of subclasses.
   1.692 +  virtual nsresult StartDocumentLoad(const char* aCommand,
   1.693 +                                     nsIChannel* aChannel,
   1.694 +                                     nsILoadGroup* aLoadGroup,
   1.695 +                                     nsISupports* aContainer,
   1.696 +                                     nsIStreamListener **aDocListener,
   1.697 +                                     bool aReset = true,
   1.698 +                                     nsIContentSink* aContentSink = nullptr) MOZ_OVERRIDE = 0;
   1.699 +
   1.700 +  virtual void StopDocumentLoad() MOZ_OVERRIDE;
   1.701 +
   1.702 +  virtual void NotifyPossibleTitleChange(bool aBoundTitleElement) MOZ_OVERRIDE;
   1.703 +
   1.704 +  virtual void SetDocumentURI(nsIURI* aURI) MOZ_OVERRIDE;
   1.705 +
   1.706 +  virtual void SetChromeXHRDocURI(nsIURI* aURI) MOZ_OVERRIDE;
   1.707 +
   1.708 +  virtual void SetChromeXHRDocBaseURI(nsIURI* aURI) MOZ_OVERRIDE;
   1.709 +
   1.710 +  /**
   1.711 +   * Set the principal responsible for this document.
   1.712 +   */
   1.713 +  virtual void SetPrincipal(nsIPrincipal *aPrincipal) MOZ_OVERRIDE;
   1.714 +
   1.715 +  /**
   1.716 +   * Get the Content-Type of this document.
   1.717 +   */
   1.718 +  // NS_IMETHOD GetContentType(nsAString& aContentType);
   1.719 +  // Already declared in nsIDOMDocument
   1.720 +
   1.721 +  /**
   1.722 +   * Set the Content-Type of this document.
   1.723 +   */
   1.724 +  virtual void SetContentType(const nsAString& aContentType) MOZ_OVERRIDE;
   1.725 +
   1.726 +  virtual nsresult SetBaseURI(nsIURI* aURI) MOZ_OVERRIDE;
   1.727 +
   1.728 +  /**
   1.729 +   * Get/Set the base target of a link in a document.
   1.730 +   */
   1.731 +  virtual void GetBaseTarget(nsAString &aBaseTarget) MOZ_OVERRIDE;
   1.732 +
   1.733 +  /**
   1.734 +   * Return a standard name for the document's character set. This will
   1.735 +   * trigger a startDocumentLoad if necessary to answer the question.
   1.736 +   */
   1.737 +  virtual void SetDocumentCharacterSet(const nsACString& aCharSetID) MOZ_OVERRIDE;
   1.738 +
   1.739 +  /**
   1.740 +   * Add an observer that gets notified whenever the charset changes.
   1.741 +   */
   1.742 +  virtual nsresult AddCharSetObserver(nsIObserver* aObserver) MOZ_OVERRIDE;
   1.743 +
   1.744 +  /**
   1.745 +   * Remove a charset observer.
   1.746 +   */
   1.747 +  virtual void RemoveCharSetObserver(nsIObserver* aObserver) MOZ_OVERRIDE;
   1.748 +
   1.749 +  virtual Element* AddIDTargetObserver(nsIAtom* aID, IDTargetObserver aObserver,
   1.750 +                                       void* aData, bool aForImage) MOZ_OVERRIDE;
   1.751 +  virtual void RemoveIDTargetObserver(nsIAtom* aID, IDTargetObserver aObserver,
   1.752 +                                      void* aData, bool aForImage) MOZ_OVERRIDE;
   1.753 +
   1.754 +  /**
   1.755 +   * Access HTTP header data (this may also get set from other sources, like
   1.756 +   * HTML META tags).
   1.757 +   */
   1.758 +  virtual void GetHeaderData(nsIAtom* aHeaderField, nsAString& aData) const MOZ_OVERRIDE;
   1.759 +  virtual void SetHeaderData(nsIAtom* aheaderField,
   1.760 +                             const nsAString& aData) MOZ_OVERRIDE;
   1.761 +
   1.762 +  /**
   1.763 +   * Create a new presentation shell that will use aContext for
   1.764 +   * its presentation context (presentation contexts <b>must not</b> be
   1.765 +   * shared among multiple presentation shells).
   1.766 +   */
   1.767 +  virtual already_AddRefed<nsIPresShell> CreateShell(nsPresContext* aContext,
   1.768 +                                                     nsViewManager* aViewManager,
   1.769 +                                                     nsStyleSet* aStyleSet) MOZ_OVERRIDE;
   1.770 +  virtual void DeleteShell() MOZ_OVERRIDE;
   1.771 +
   1.772 +  virtual nsresult GetAllowPlugins(bool* aAllowPlugins) MOZ_OVERRIDE;
   1.773 +
   1.774 +  virtual already_AddRefed<mozilla::dom::UndoManager> GetUndoManager() MOZ_OVERRIDE;
   1.775 +
   1.776 +  virtual nsresult SetSubDocumentFor(Element* aContent,
   1.777 +                                     nsIDocument* aSubDoc) MOZ_OVERRIDE;
   1.778 +  virtual nsIDocument* GetSubDocumentFor(nsIContent* aContent) const MOZ_OVERRIDE;
   1.779 +  virtual Element* FindContentForSubDocument(nsIDocument *aDocument) const MOZ_OVERRIDE;
   1.780 +  virtual Element* GetRootElementInternal() const MOZ_OVERRIDE;
   1.781 +
   1.782 +  /**
   1.783 +   * Get the style sheets owned by this document.
   1.784 +   * These are ordered, highest priority last
   1.785 +   */
   1.786 +  virtual int32_t GetNumberOfStyleSheets() const MOZ_OVERRIDE;
   1.787 +  virtual nsIStyleSheet* GetStyleSheetAt(int32_t aIndex) const MOZ_OVERRIDE;
   1.788 +  virtual int32_t GetIndexOfStyleSheet(nsIStyleSheet* aSheet) const MOZ_OVERRIDE;
   1.789 +  virtual void AddStyleSheet(nsIStyleSheet* aSheet) MOZ_OVERRIDE;
   1.790 +  virtual void RemoveStyleSheet(nsIStyleSheet* aSheet) MOZ_OVERRIDE;
   1.791 +
   1.792 +  virtual void UpdateStyleSheets(nsCOMArray<nsIStyleSheet>& aOldSheets,
   1.793 +                                 nsCOMArray<nsIStyleSheet>& aNewSheets) MOZ_OVERRIDE;
   1.794 +  virtual void AddStyleSheetToStyleSets(nsIStyleSheet* aSheet);
   1.795 +  virtual void RemoveStyleSheetFromStyleSets(nsIStyleSheet* aSheet);
   1.796 +
   1.797 +  virtual void InsertStyleSheetAt(nsIStyleSheet* aSheet, int32_t aIndex) MOZ_OVERRIDE;
   1.798 +  virtual void SetStyleSheetApplicableState(nsIStyleSheet* aSheet,
   1.799 +                                            bool aApplicable) MOZ_OVERRIDE;
   1.800 +
   1.801 +  virtual int32_t GetNumberOfCatalogStyleSheets() const MOZ_OVERRIDE;
   1.802 +  virtual nsIStyleSheet* GetCatalogStyleSheetAt(int32_t aIndex) const MOZ_OVERRIDE;
   1.803 +  virtual void AddCatalogStyleSheet(nsCSSStyleSheet* aSheet) MOZ_OVERRIDE;
   1.804 +  virtual void EnsureCatalogStyleSheet(const char *aStyleSheetURI) MOZ_OVERRIDE;
   1.805 +
   1.806 +  virtual nsresult LoadAdditionalStyleSheet(additionalSheetType aType, nsIURI* aSheetURI) MOZ_OVERRIDE;
   1.807 +  virtual void RemoveAdditionalStyleSheet(additionalSheetType aType, nsIURI* sheetURI) MOZ_OVERRIDE;
   1.808 +  virtual nsIStyleSheet* FirstAdditionalAuthorSheet() MOZ_OVERRIDE;
   1.809 +
   1.810 +  virtual nsIChannel* GetChannel() const MOZ_OVERRIDE {
   1.811 +    return mChannel;
   1.812 +  }
   1.813 +
   1.814 +  virtual void SetScriptGlobalObject(nsIScriptGlobalObject* aGlobalObject) MOZ_OVERRIDE;
   1.815 +
   1.816 +  virtual void SetScriptHandlingObject(nsIScriptGlobalObject* aScriptObject) MOZ_OVERRIDE;
   1.817 +
   1.818 +  virtual nsIGlobalObject* GetScopeObject() const MOZ_OVERRIDE;
   1.819 +  void SetScopeObject(nsIGlobalObject* aGlobal) MOZ_OVERRIDE;
   1.820 +  /**
   1.821 +   * Get the script loader for this document
   1.822 +   */
   1.823 +  virtual nsScriptLoader* ScriptLoader() MOZ_OVERRIDE;
   1.824 +
   1.825 +  /**
   1.826 +   * Add/Remove an element to the document's id and name hashes
   1.827 +   */
   1.828 +  virtual void AddToIdTable(Element* aElement, nsIAtom* aId) MOZ_OVERRIDE;
   1.829 +  virtual void RemoveFromIdTable(Element* aElement, nsIAtom* aId) MOZ_OVERRIDE;
   1.830 +  virtual void AddToNameTable(Element* aElement, nsIAtom* aName) MOZ_OVERRIDE;
   1.831 +  virtual void RemoveFromNameTable(Element* aElement, nsIAtom* aName) MOZ_OVERRIDE;
   1.832 +
   1.833 +  /**
   1.834 +   * Add a new observer of document change notifications. Whenever
   1.835 +   * content is changed, appended, inserted or removed the observers are
   1.836 +   * informed.
   1.837 +   */
   1.838 +  virtual void AddObserver(nsIDocumentObserver* aObserver) MOZ_OVERRIDE;
   1.839 +
   1.840 +  /**
   1.841 +   * Remove an observer of document change notifications. This will
   1.842 +   * return false if the observer cannot be found.
   1.843 +   */
   1.844 +  virtual bool RemoveObserver(nsIDocumentObserver* aObserver) MOZ_OVERRIDE;
   1.845 +
   1.846 +  // Observation hooks used to propagate notifications to document
   1.847 +  // observers.
   1.848 +  virtual void BeginUpdate(nsUpdateType aUpdateType) MOZ_OVERRIDE;
   1.849 +  virtual void EndUpdate(nsUpdateType aUpdateType) MOZ_OVERRIDE;
   1.850 +  virtual void BeginLoad() MOZ_OVERRIDE;
   1.851 +  virtual void EndLoad() MOZ_OVERRIDE;
   1.852 +
   1.853 +  virtual void SetReadyStateInternal(ReadyState rs) MOZ_OVERRIDE;
   1.854 +
   1.855 +  virtual void ContentStateChanged(nsIContent* aContent,
   1.856 +                                   mozilla::EventStates aStateMask)
   1.857 +                                     MOZ_OVERRIDE;
   1.858 +  virtual void DocumentStatesChanged(
   1.859 +                 mozilla::EventStates aStateMask) MOZ_OVERRIDE;
   1.860 +
   1.861 +  virtual void StyleRuleChanged(nsIStyleSheet* aStyleSheet,
   1.862 +                                nsIStyleRule* aOldStyleRule,
   1.863 +                                nsIStyleRule* aNewStyleRule) MOZ_OVERRIDE;
   1.864 +  virtual void StyleRuleAdded(nsIStyleSheet* aStyleSheet,
   1.865 +                              nsIStyleRule* aStyleRule) MOZ_OVERRIDE;
   1.866 +  virtual void StyleRuleRemoved(nsIStyleSheet* aStyleSheet,
   1.867 +                                nsIStyleRule* aStyleRule) MOZ_OVERRIDE;
   1.868 +
   1.869 +  virtual void FlushPendingNotifications(mozFlushType aType) MOZ_OVERRIDE;
   1.870 +  virtual void FlushExternalResources(mozFlushType aType) MOZ_OVERRIDE;
   1.871 +  virtual void SetXMLDeclaration(const char16_t *aVersion,
   1.872 +                                 const char16_t *aEncoding,
   1.873 +                                 const int32_t aStandalone) MOZ_OVERRIDE;
   1.874 +  virtual void GetXMLDeclaration(nsAString& aVersion,
   1.875 +                                 nsAString& aEncoding,
   1.876 +                                 nsAString& Standalone) MOZ_OVERRIDE;
   1.877 +  virtual bool IsScriptEnabled() MOZ_OVERRIDE;
   1.878 +
   1.879 +  virtual void OnPageShow(bool aPersisted, mozilla::dom::EventTarget* aDispatchStartTarget) MOZ_OVERRIDE;
   1.880 +  virtual void OnPageHide(bool aPersisted, mozilla::dom::EventTarget* aDispatchStartTarget) MOZ_OVERRIDE;
   1.881 +
   1.882 +  virtual void WillDispatchMutationEvent(nsINode* aTarget) MOZ_OVERRIDE;
   1.883 +  virtual void MutationEventDispatched(nsINode* aTarget) MOZ_OVERRIDE;
   1.884 +
   1.885 +  // nsINode
   1.886 +  virtual bool IsNodeOfType(uint32_t aFlags) const MOZ_OVERRIDE;
   1.887 +  virtual nsIContent *GetChildAt(uint32_t aIndex) const MOZ_OVERRIDE;
   1.888 +  virtual nsIContent * const * GetChildArray(uint32_t* aChildCount) const MOZ_OVERRIDE;
   1.889 +  virtual int32_t IndexOf(const nsINode* aPossibleChild) const MOZ_OVERRIDE;
   1.890 +  virtual uint32_t GetChildCount() const MOZ_OVERRIDE;
   1.891 +  virtual nsresult InsertChildAt(nsIContent* aKid, uint32_t aIndex,
   1.892 +                                 bool aNotify) MOZ_OVERRIDE;
   1.893 +  virtual nsresult AppendChildTo(nsIContent* aKid, bool aNotify);
   1.894 +  virtual void RemoveChildAt(uint32_t aIndex, bool aNotify) MOZ_OVERRIDE;
   1.895 +  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE
   1.896 +  {
   1.897 +    return NS_ERROR_NOT_IMPLEMENTED;
   1.898 +  }
   1.899 +
   1.900 +  // nsIRadioGroupContainer
   1.901 +  NS_IMETHOD WalkRadioGroup(const nsAString& aName,
   1.902 +                            nsIRadioVisitor* aVisitor,
   1.903 +                            bool aFlushContent) MOZ_OVERRIDE;
   1.904 +  virtual void
   1.905 +    SetCurrentRadioButton(const nsAString& aName,
   1.906 +                          mozilla::dom::HTMLInputElement* aRadio) MOZ_OVERRIDE;
   1.907 +  virtual mozilla::dom::HTMLInputElement*
   1.908 +    GetCurrentRadioButton(const nsAString& aName) MOZ_OVERRIDE;
   1.909 +  NS_IMETHOD
   1.910 +    GetNextRadioButton(const nsAString& aName,
   1.911 +                       const bool aPrevious,
   1.912 +                       mozilla::dom::HTMLInputElement*  aFocusedRadio,
   1.913 +                       mozilla::dom::HTMLInputElement** aRadioOut) MOZ_OVERRIDE;
   1.914 +  virtual void AddToRadioGroup(const nsAString& aName,
   1.915 +                               nsIFormControl* aRadio) MOZ_OVERRIDE;
   1.916 +  virtual void RemoveFromRadioGroup(const nsAString& aName,
   1.917 +                                    nsIFormControl* aRadio) MOZ_OVERRIDE;
   1.918 +  virtual uint32_t GetRequiredRadioCount(const nsAString& aName) const MOZ_OVERRIDE;
   1.919 +  virtual void RadioRequiredChanged(const nsAString& aName,
   1.920 +                                    nsIFormControl* aRadio) MOZ_OVERRIDE;
   1.921 +  virtual bool GetValueMissingState(const nsAString& aName) const MOZ_OVERRIDE;
   1.922 +  virtual void SetValueMissingState(const nsAString& aName, bool aValue) MOZ_OVERRIDE;
   1.923 +
   1.924 +  // for radio group
   1.925 +  nsRadioGroupStruct* GetRadioGroup(const nsAString& aName) const;
   1.926 +  nsRadioGroupStruct* GetOrCreateRadioGroup(const nsAString& aName);
   1.927 +
   1.928 +  virtual nsViewportInfo GetViewportInfo(const mozilla::ScreenIntSize& aDisplaySize) MOZ_OVERRIDE;
   1.929 +
   1.930 +private:
   1.931 +  nsRadioGroupStruct* GetRadioGroupInternal(const nsAString& aName) const;
   1.932 +  void SendToConsole(nsCOMArray<nsISecurityConsoleMessage>& aMessages);
   1.933 +
   1.934 +public:
   1.935 +  // nsIDOMNode
   1.936 +  NS_FORWARD_NSIDOMNODE_TO_NSINODE_OVERRIDABLE
   1.937 +
   1.938 +  // nsIDOMDocument
   1.939 +  NS_DECL_NSIDOMDOCUMENT
   1.940 +
   1.941 +  // nsIDOMXMLDocument
   1.942 +  NS_DECL_NSIDOMXMLDOCUMENT
   1.943 +
   1.944 +  // nsIDOMDocumentXBL
   1.945 +  NS_DECL_NSIDOMDOCUMENTXBL
   1.946 +
   1.947 +  // nsIDOMEventTarget
   1.948 +  virtual nsresult PreHandleEvent(
   1.949 +                     mozilla::EventChainPreVisitor& aVisitor) MOZ_OVERRIDE;
   1.950 +  virtual mozilla::EventListenerManager*
   1.951 +    GetOrCreateListenerManager() MOZ_OVERRIDE;
   1.952 +  virtual mozilla::EventListenerManager*
   1.953 +    GetExistingListenerManager() const MOZ_OVERRIDE;
   1.954 +
   1.955 +  // nsIScriptObjectPrincipal
   1.956 +  virtual nsIPrincipal* GetPrincipal() MOZ_OVERRIDE;
   1.957 +
   1.958 +  // nsIApplicationCacheContainer
   1.959 +  NS_DECL_NSIAPPLICATIONCACHECONTAINER
   1.960 +
   1.961 +  // nsIObserver
   1.962 +  NS_DECL_NSIOBSERVER
   1.963 +
   1.964 +  NS_DECL_NSIDOMXPATHEVALUATOR
   1.965 +
   1.966 +  virtual nsresult Init();
   1.967 +
   1.968 +  virtual nsresult CreateElem(const nsAString& aName, nsIAtom *aPrefix,
   1.969 +                              int32_t aNamespaceID,
   1.970 +                              nsIContent **aResult) MOZ_OVERRIDE;
   1.971 +
   1.972 +  virtual NS_HIDDEN_(void) Sanitize();
   1.973 +
   1.974 +  virtual NS_HIDDEN_(void) EnumerateSubDocuments(nsSubDocEnumFunc aCallback,
   1.975 +                                                 void *aData);
   1.976 +
   1.977 +  virtual NS_HIDDEN_(bool) CanSavePresentation(nsIRequest *aNewRequest);
   1.978 +  virtual NS_HIDDEN_(void) Destroy();
   1.979 +  virtual NS_HIDDEN_(void) RemovedFromDocShell();
   1.980 +  virtual NS_HIDDEN_(already_AddRefed<nsILayoutHistoryState>) GetLayoutHistoryState() const;
   1.981 +
   1.982 +  virtual NS_HIDDEN_(void) BlockOnload();
   1.983 +  virtual NS_HIDDEN_(void) UnblockOnload(bool aFireSync);
   1.984 +
   1.985 +  virtual NS_HIDDEN_(void) AddStyleRelevantLink(mozilla::dom::Link* aLink);
   1.986 +  virtual NS_HIDDEN_(void) ForgetLink(mozilla::dom::Link* aLink);
   1.987 +
   1.988 +  NS_HIDDEN_(void) ClearBoxObjectFor(nsIContent* aContent);
   1.989 +  already_AddRefed<nsIBoxObject> GetBoxObjectFor(mozilla::dom::Element* aElement,
   1.990 +                                                 mozilla::ErrorResult& aRv) MOZ_OVERRIDE;
   1.991 +
   1.992 +  virtual NS_HIDDEN_(Element*)
   1.993 +    GetAnonymousElementByAttribute(nsIContent* aElement,
   1.994 +                                   nsIAtom* aAttrName,
   1.995 +                                   const nsAString& aAttrValue) const;
   1.996 +
   1.997 +  virtual NS_HIDDEN_(Element*) ElementFromPointHelper(float aX, float aY,
   1.998 +                                                      bool aIgnoreRootScrollFrame,
   1.999 +                                                      bool aFlushLayout);
  1.1000 +
  1.1001 +  virtual NS_HIDDEN_(nsresult) NodesFromRectHelper(float aX, float aY,
  1.1002 +                                                   float aTopSize, float aRightSize,
  1.1003 +                                                   float aBottomSize, float aLeftSize,
  1.1004 +                                                   bool aIgnoreRootScrollFrame,
  1.1005 +                                                   bool aFlushLayout,
  1.1006 +                                                   nsIDOMNodeList** aReturn);
  1.1007 +
  1.1008 +  virtual NS_HIDDEN_(void) FlushSkinBindings();
  1.1009 +
  1.1010 +  virtual NS_HIDDEN_(nsresult) InitializeFrameLoader(nsFrameLoader* aLoader);
  1.1011 +  virtual NS_HIDDEN_(nsresult) FinalizeFrameLoader(nsFrameLoader* aLoader);
  1.1012 +  virtual NS_HIDDEN_(void) TryCancelFrameLoaderInitialization(nsIDocShell* aShell);
  1.1013 +  virtual NS_HIDDEN_(bool) FrameLoaderScheduledToBeFinalized(nsIDocShell* aShell);
  1.1014 +  virtual NS_HIDDEN_(nsIDocument*)
  1.1015 +    RequestExternalResource(nsIURI* aURI,
  1.1016 +                            nsINode* aRequestingNode,
  1.1017 +                            ExternalResourceLoad** aPendingLoad);
  1.1018 +  virtual NS_HIDDEN_(void)
  1.1019 +    EnumerateExternalResources(nsSubDocEnumFunc aCallback, void* aData);
  1.1020 +
  1.1021 +  nsTArray<nsCString> mHostObjectURIs;
  1.1022 +
  1.1023 +  // Returns our (lazily-initialized) animation controller.
  1.1024 +  // If HasAnimationController is true, this is guaranteed to return non-null.
  1.1025 +  nsSMILAnimationController* GetAnimationController() MOZ_OVERRIDE;
  1.1026 +
  1.1027 +  void SetImagesNeedAnimating(bool aAnimating) MOZ_OVERRIDE;
  1.1028 +
  1.1029 +  virtual void SuppressEventHandling(SuppressionType aWhat,
  1.1030 +                                     uint32_t aIncrease) MOZ_OVERRIDE;
  1.1031 +
  1.1032 +  virtual void UnsuppressEventHandlingAndFireEvents(SuppressionType aWhat,
  1.1033 +                                                    bool aFireEvents) MOZ_OVERRIDE;
  1.1034 +
  1.1035 +  void DecreaseEventSuppression() {
  1.1036 +    MOZ_ASSERT(mEventsSuppressed);
  1.1037 +    --mEventsSuppressed;
  1.1038 +    MaybeRescheduleAnimationFrameNotifications();
  1.1039 +  }
  1.1040 +
  1.1041 +  void ResumeAnimations() {
  1.1042 +    MOZ_ASSERT(mAnimationsPaused);
  1.1043 +    --mAnimationsPaused;
  1.1044 +    MaybeRescheduleAnimationFrameNotifications();
  1.1045 +  }
  1.1046 +
  1.1047 +  virtual nsIDocument* GetTemplateContentsOwner() MOZ_OVERRIDE;
  1.1048 +
  1.1049 +  NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsDocument,
  1.1050 +                                                                   nsIDocument)
  1.1051 +
  1.1052 +  void DoNotifyPossibleTitleChange();
  1.1053 +
  1.1054 +  nsExternalResourceMap& ExternalResourceMap()
  1.1055 +  {
  1.1056 +    return mExternalResourceMap;
  1.1057 +  }
  1.1058 +
  1.1059 +  void SetLoadedAsData(bool aLoadedAsData) { mLoadedAsData = aLoadedAsData; }
  1.1060 +  void SetLoadedAsInteractiveData(bool aLoadedAsInteractiveData)
  1.1061 +  {
  1.1062 +    mLoadedAsInteractiveData = aLoadedAsInteractiveData;
  1.1063 +  }
  1.1064 +
  1.1065 +  nsresult CloneDocHelper(nsDocument* clone) const;
  1.1066 +
  1.1067 +  void MaybeInitializeFinalizeFrameLoaders();
  1.1068 +
  1.1069 +  void MaybeEndOutermostXBLUpdate();
  1.1070 +
  1.1071 +  virtual void MaybePreLoadImage(nsIURI* uri,
  1.1072 +                                 const nsAString &aCrossOriginAttr) MOZ_OVERRIDE;
  1.1073 +
  1.1074 +  virtual void PreloadStyle(nsIURI* uri, const nsAString& charset,
  1.1075 +                            const nsAString& aCrossOriginAttr) MOZ_OVERRIDE;
  1.1076 +
  1.1077 +  virtual nsresult LoadChromeSheetSync(nsIURI* uri, bool isAgentSheet,
  1.1078 +                                       nsCSSStyleSheet** sheet) MOZ_OVERRIDE;
  1.1079 +
  1.1080 +  virtual nsISupports* GetCurrentContentSink() MOZ_OVERRIDE;
  1.1081 +
  1.1082 +  virtual mozilla::EventStates GetDocumentState() MOZ_OVERRIDE;
  1.1083 +
  1.1084 +  virtual void RegisterHostObjectUri(const nsACString& aUri) MOZ_OVERRIDE;
  1.1085 +  virtual void UnregisterHostObjectUri(const nsACString& aUri) MOZ_OVERRIDE;
  1.1086 +
  1.1087 +  // Only BlockOnload should call this!
  1.1088 +  void AsyncBlockOnload();
  1.1089 +
  1.1090 +  virtual void SetScrollToRef(nsIURI *aDocumentURI) MOZ_OVERRIDE;
  1.1091 +  virtual void ScrollToRef() MOZ_OVERRIDE;
  1.1092 +  virtual void ResetScrolledToRefAlready() MOZ_OVERRIDE;
  1.1093 +  virtual void SetChangeScrollPosWhenScrollingToRef(bool aValue) MOZ_OVERRIDE;
  1.1094 +
  1.1095 +  virtual Element *GetElementById(const nsAString& aElementId) MOZ_OVERRIDE;
  1.1096 +  virtual const nsSmallVoidArray* GetAllElementsForId(const nsAString& aElementId) const MOZ_OVERRIDE;
  1.1097 +
  1.1098 +  virtual Element *LookupImageElement(const nsAString& aElementId) MOZ_OVERRIDE;
  1.1099 +  virtual void MozSetImageElement(const nsAString& aImageElementId,
  1.1100 +                                  Element* aElement) MOZ_OVERRIDE;
  1.1101 +
  1.1102 +  virtual NS_HIDDEN_(nsresult) AddImage(imgIRequest* aImage);
  1.1103 +  virtual NS_HIDDEN_(nsresult) RemoveImage(imgIRequest* aImage, uint32_t aFlags);
  1.1104 +  virtual NS_HIDDEN_(nsresult) SetImageLockingState(bool aLocked);
  1.1105 +
  1.1106 +  // AddPlugin adds a plugin-related element to mPlugins when the element is
  1.1107 +  // added to the tree.
  1.1108 +  virtual nsresult AddPlugin(nsIObjectLoadingContent* aPlugin) MOZ_OVERRIDE;
  1.1109 +  // RemovePlugin removes a plugin-related element to mPlugins when the
  1.1110 +  // element is removed from the tree.
  1.1111 +  virtual void RemovePlugin(nsIObjectLoadingContent* aPlugin) MOZ_OVERRIDE;
  1.1112 +  // GetPlugins returns the plugin-related elements from
  1.1113 +  // the frame and any subframes.
  1.1114 +  virtual void GetPlugins(nsTArray<nsIObjectLoadingContent*>& aPlugins) MOZ_OVERRIDE;
  1.1115 +
  1.1116 +  virtual nsresult GetStateObject(nsIVariant** aResult) MOZ_OVERRIDE;
  1.1117 +
  1.1118 +  virtual nsDOMNavigationTiming* GetNavigationTiming() const MOZ_OVERRIDE;
  1.1119 +  virtual nsresult SetNavigationTiming(nsDOMNavigationTiming* aTiming) MOZ_OVERRIDE;
  1.1120 +
  1.1121 +  virtual Element* FindImageMap(const nsAString& aNormalizedMapName) MOZ_OVERRIDE;
  1.1122 +
  1.1123 +  virtual Element* GetFullScreenElement() MOZ_OVERRIDE;
  1.1124 +  virtual void AsyncRequestFullScreen(Element* aElement) MOZ_OVERRIDE;
  1.1125 +  virtual void RestorePreviousFullScreenState() MOZ_OVERRIDE;
  1.1126 +  virtual bool IsFullscreenLeaf() MOZ_OVERRIDE;
  1.1127 +  virtual bool IsFullScreenDoc() MOZ_OVERRIDE;
  1.1128 +  virtual void SetApprovedForFullscreen(bool aIsApproved) MOZ_OVERRIDE;
  1.1129 +  virtual nsresult RemoteFrameFullscreenChanged(nsIDOMElement* aFrameElement,
  1.1130 +                                                const nsAString& aNewOrigin) MOZ_OVERRIDE;
  1.1131 +
  1.1132 +  virtual nsresult RemoteFrameFullscreenReverted() MOZ_OVERRIDE;
  1.1133 +  virtual nsIDocument* GetFullscreenRoot() MOZ_OVERRIDE;
  1.1134 +  virtual void SetFullscreenRoot(nsIDocument* aRoot) MOZ_OVERRIDE;
  1.1135 +
  1.1136 +  static void ExitFullscreen(nsIDocument* aDoc);
  1.1137 +
  1.1138 +  // This is called asynchronously by nsIDocument::AsyncRequestFullScreen()
  1.1139 +  // to move this document into full-screen mode if allowed. aWasCallerChrome
  1.1140 +  // should be true when nsIDocument::AsyncRequestFullScreen() was called
  1.1141 +  // by chrome code. aNotifyOnOriginChange denotes whether we should send a
  1.1142 +  // fullscreen-origin-change notification if requesting fullscreen in this
  1.1143 +  // document causes the origin which is fullscreen to change. We may want to
  1.1144 +  // *not* send this notification if we're calling RequestFullscreen() as part
  1.1145 +  // of a continuation of a request in a subdocument, whereupon the caller will
  1.1146 +  // need to send the notification with the origin of the document which
  1.1147 +  // originally requested fullscreen, not *this* document's origin.
  1.1148 +  void RequestFullScreen(Element* aElement,
  1.1149 +                         bool aWasCallerChrome,
  1.1150 +                         bool aNotifyOnOriginChange);
  1.1151 +
  1.1152 +  // Removes all elements from the full-screen stack, removing full-scren
  1.1153 +  // styles from the top element in the stack.
  1.1154 +  void CleanupFullscreenState();
  1.1155 +
  1.1156 +  // Add/remove "fullscreen-approved" observer service notification listener.
  1.1157 +  // Chrome sends us a notification when fullscreen is approved for a
  1.1158 +  // document, with the notification subject as the document that was approved.
  1.1159 +  // We maintain this listener while in fullscreen mode.
  1.1160 +  nsresult AddFullscreenApprovedObserver();
  1.1161 +  nsresult RemoveFullscreenApprovedObserver();
  1.1162 +
  1.1163 +  // Pushes aElement onto the full-screen stack, and removes full-screen styles
  1.1164 +  // from the former full-screen stack top, and its ancestors, and applies the
  1.1165 +  // styles to aElement. aElement becomes the new "full-screen element".
  1.1166 +  bool FullScreenStackPush(Element* aElement);
  1.1167 +
  1.1168 +  // Remove the top element from the full-screen stack. Removes the full-screen
  1.1169 +  // styles from the former top element, and applies them to the new top
  1.1170 +  // element, if there is one.
  1.1171 +  void FullScreenStackPop();
  1.1172 +
  1.1173 +  // Returns the top element from the full-screen stack.
  1.1174 +  Element* FullScreenStackTop();
  1.1175 +
  1.1176 +  // DOM-exposed fullscreen API
  1.1177 +  virtual bool MozFullScreenEnabled() MOZ_OVERRIDE;
  1.1178 +  virtual Element* GetMozFullScreenElement(mozilla::ErrorResult& rv) MOZ_OVERRIDE;
  1.1179 +
  1.1180 +  void RequestPointerLock(Element* aElement) MOZ_OVERRIDE;
  1.1181 +  bool ShouldLockPointer(Element* aElement, Element* aCurrentLock,
  1.1182 +                         bool aNoFocusCheck = false);
  1.1183 +  bool SetPointerLock(Element* aElement, int aCursorStyle);
  1.1184 +  static void UnlockPointer(nsIDocument* aDoc = nullptr);
  1.1185 +
  1.1186 +  // This method may fire a DOM event; if it does so it will happen
  1.1187 +  // synchronously.
  1.1188 +  void UpdateVisibilityState();
  1.1189 +  // Posts an event to call UpdateVisibilityState
  1.1190 +  virtual void PostVisibilityUpdateEvent() MOZ_OVERRIDE;
  1.1191 +
  1.1192 +  virtual void DocAddSizeOfExcludingThis(nsWindowSizes* aWindowSizes) const MOZ_OVERRIDE;
  1.1193 +  // DocAddSizeOfIncludingThis is inherited from nsIDocument.
  1.1194 +
  1.1195 +  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
  1.1196 +
  1.1197 +  virtual void EnqueueLifecycleCallback(nsIDocument::ElementCallbackType aType,
  1.1198 +                                        Element* aCustomElement,
  1.1199 +                                        mozilla::dom::LifecycleCallbackArgs* aArgs = nullptr,
  1.1200 +                                        mozilla::dom::CustomElementDefinition* aDefinition = nullptr) MOZ_OVERRIDE;
  1.1201 +
  1.1202 +  static void ProcessTopElementQueue(bool aIsBaseQueue = false);
  1.1203 +
  1.1204 +  void GetCustomPrototype(int32_t aNamespaceID,
  1.1205 +                          nsIAtom* aAtom,
  1.1206 +                          JS::MutableHandle<JSObject*> prototype)
  1.1207 +  {
  1.1208 +    if (!mRegistry) {
  1.1209 +      prototype.set(nullptr);
  1.1210 +      return;
  1.1211 +    }
  1.1212 +
  1.1213 +    mozilla::dom::CustomElementHashKey key(aNamespaceID, aAtom);
  1.1214 +    mozilla::dom::CustomElementDefinition* definition;
  1.1215 +    if (mRegistry->mCustomDefinitions.Get(&key, &definition)) {
  1.1216 +      prototype.set(definition->mPrototype);
  1.1217 +    } else {
  1.1218 +      prototype.set(nullptr);
  1.1219 +    }
  1.1220 +  }
  1.1221 +
  1.1222 +  static bool RegisterEnabled();
  1.1223 +
  1.1224 +  virtual nsresult RegisterUnresolvedElement(mozilla::dom::Element* aElement,
  1.1225 +                                             nsIAtom* aTypeName = nullptr) MOZ_OVERRIDE;
  1.1226 +
  1.1227 +  // WebIDL bits
  1.1228 +  virtual mozilla::dom::DOMImplementation*
  1.1229 +    GetImplementation(mozilla::ErrorResult& rv) MOZ_OVERRIDE;
  1.1230 +  virtual void
  1.1231 +    RegisterElement(JSContext* aCx, const nsAString& aName,
  1.1232 +                    const mozilla::dom::ElementRegistrationOptions& aOptions,
  1.1233 +                    JS::MutableHandle<JSObject*> aRetval,
  1.1234 +                    mozilla::ErrorResult& rv) MOZ_OVERRIDE;
  1.1235 +  virtual mozilla::dom::StyleSheetList* StyleSheets() MOZ_OVERRIDE;
  1.1236 +  virtual void SetSelectedStyleSheetSet(const nsAString& aSheetSet) MOZ_OVERRIDE;
  1.1237 +  virtual void GetLastStyleSheetSet(nsString& aSheetSet) MOZ_OVERRIDE;
  1.1238 +  virtual mozilla::dom::DOMStringList* StyleSheetSets() MOZ_OVERRIDE;
  1.1239 +  virtual void EnableStyleSheetsForSet(const nsAString& aSheetSet) MOZ_OVERRIDE;
  1.1240 +  using nsIDocument::CreateElement;
  1.1241 +  using nsIDocument::CreateElementNS;
  1.1242 +  virtual already_AddRefed<Element> CreateElement(const nsAString& aTagName,
  1.1243 +                                                  const nsAString& aTypeExtension,
  1.1244 +                                                  mozilla::ErrorResult& rv) MOZ_OVERRIDE;
  1.1245 +  virtual already_AddRefed<Element> CreateElementNS(const nsAString& aNamespaceURI,
  1.1246 +                                                    const nsAString& aQualifiedName,
  1.1247 +                                                    const nsAString& aTypeExtension,
  1.1248 +                                                    mozilla::ErrorResult& rv) MOZ_OVERRIDE;
  1.1249 +  virtual void UseRegistryFromDocument(nsIDocument* aDocument) MOZ_OVERRIDE;
  1.1250 +
  1.1251 +  virtual void UnblockDOMContentLoaded() MOZ_OVERRIDE;
  1.1252 +
  1.1253 +protected:
  1.1254 +  friend class nsNodeUtils;
  1.1255 +  friend class nsDocumentOnStack;
  1.1256 +
  1.1257 +  void IncreaseStackRefCnt()
  1.1258 +  {
  1.1259 +    ++mStackRefCnt;
  1.1260 +  }
  1.1261 +
  1.1262 +  void DecreaseStackRefCnt()
  1.1263 +  {
  1.1264 +    if (--mStackRefCnt == 0 && mNeedsReleaseAfterStackRefCntRelease) {
  1.1265 +      mNeedsReleaseAfterStackRefCntRelease = false;
  1.1266 +      NS_RELEASE_THIS();
  1.1267 +    }
  1.1268 +  }
  1.1269 +
  1.1270 +  // Returns true if a request for DOM full-screen is currently enabled in
  1.1271 +  // this document. This returns true if there are no windowed plugins in this
  1.1272 +  // doc tree, and if the document is visible, and if the api is not
  1.1273 +  // disabled by pref. aIsCallerChrome must contain the return value of
  1.1274 +  // nsContentUtils::IsCallerChrome() from the context we're checking.
  1.1275 +  // If aLogFailure is true, an appropriate warning message is logged to the
  1.1276 +  // console, and a "mozfullscreenerror" event is dispatched to this document.
  1.1277 +  bool IsFullScreenEnabled(bool aIsCallerChrome, bool aLogFailure);
  1.1278 +
  1.1279 +  /**
  1.1280 +   * Check that aId is not empty and log a message to the console
  1.1281 +   * service if it is.
  1.1282 +   * @returns true if aId looks correct, false otherwise.
  1.1283 +   */
  1.1284 +  inline bool CheckGetElementByIdArg(const nsAString& aId)
  1.1285 +  {
  1.1286 +    if (aId.IsEmpty()) {
  1.1287 +      ReportEmptyGetElementByIdArg();
  1.1288 +      return false;
  1.1289 +    }
  1.1290 +    return true;
  1.1291 +  }
  1.1292 +
  1.1293 +  void ReportEmptyGetElementByIdArg();
  1.1294 +
  1.1295 +  void DispatchContentLoadedEvents();
  1.1296 +
  1.1297 +  void RetrieveRelevantHeaders(nsIChannel *aChannel);
  1.1298 +
  1.1299 +  void TryChannelCharset(nsIChannel *aChannel,
  1.1300 +                         int32_t& aCharsetSource,
  1.1301 +                         nsACString& aCharset,
  1.1302 +                         nsHtml5TreeOpExecutor* aExecutor);
  1.1303 +
  1.1304 +  // Call this before the document does something that will unbind all content.
  1.1305 +  // That will stop us from doing a lot of work as each element is removed.
  1.1306 +  void DestroyElementMaps();
  1.1307 +
  1.1308 +  // Refreshes the hrefs of all the links in the document.
  1.1309 +  void RefreshLinkHrefs();
  1.1310 +
  1.1311 +  nsIContent* GetFirstBaseNodeWithHref();
  1.1312 +  nsresult SetFirstBaseNodeWithHref(nsIContent *node);
  1.1313 +
  1.1314 +  // Get the first <title> element with the given IsNodeOfType type, or
  1.1315 +  // return null if there isn't one
  1.1316 +  nsIContent* GetTitleContent(uint32_t aNodeType);
  1.1317 +  // Find the first "title" element in the given IsNodeOfType type and
  1.1318 +  // append the concatenation of its text node children to aTitle. Do
  1.1319 +  // nothing if there is no such element.
  1.1320 +  void GetTitleFromElement(uint32_t aNodeType, nsAString& aTitle);
  1.1321 +public:
  1.1322 +  // Get our title
  1.1323 +  virtual void GetTitle(nsString& aTitle) MOZ_OVERRIDE;
  1.1324 +  // Set our title
  1.1325 +  virtual void SetTitle(const nsAString& aTitle, mozilla::ErrorResult& rv) MOZ_OVERRIDE;
  1.1326 +
  1.1327 +  static void XPCOMShutdown();
  1.1328 +
  1.1329 +  bool mIsTopLevelContentDocument:1;
  1.1330 +
  1.1331 +  bool IsTopLevelContentDocument();
  1.1332 +
  1.1333 +  void SetIsTopLevelContentDocument(bool aIsTopLevelContentDocument);
  1.1334 +
  1.1335 +  js::ExpandoAndGeneration mExpandoAndGeneration;
  1.1336 +
  1.1337 +protected:
  1.1338 +  already_AddRefed<nsIPresShell> doCreateShell(nsPresContext* aContext,
  1.1339 +                                               nsViewManager* aViewManager,
  1.1340 +                                               nsStyleSet* aStyleSet,
  1.1341 +                                               nsCompatibility aCompatMode);
  1.1342 +
  1.1343 +  void RemoveDocStyleSheetsFromStyleSets();
  1.1344 +  void RemoveStyleSheetsFromStyleSets(nsCOMArray<nsIStyleSheet>& aSheets, 
  1.1345 +                                      nsStyleSet::sheetType aType);
  1.1346 +  void ResetStylesheetsToURI(nsIURI* aURI);
  1.1347 +  void FillStyleSet(nsStyleSet* aStyleSet);
  1.1348 +
  1.1349 +  // Return whether all the presshells for this document are safe to flush
  1.1350 +  bool IsSafeToFlush() const;
  1.1351 +
  1.1352 +  void DispatchPageTransition(mozilla::dom::EventTarget* aDispatchTarget,
  1.1353 +                              const nsAString& aType,
  1.1354 +                              bool aPersisted);
  1.1355 +
  1.1356 +  virtual nsPIDOMWindow *GetWindowInternal() const MOZ_OVERRIDE;
  1.1357 +  virtual nsIScriptGlobalObject* GetScriptHandlingObjectInternal() const MOZ_OVERRIDE;
  1.1358 +  virtual bool InternalAllowXULXBL() MOZ_OVERRIDE;
  1.1359 +
  1.1360 +#define NS_DOCUMENT_NOTIFY_OBSERVERS(func_, params_)                        \
  1.1361 +  NS_OBSERVER_ARRAY_NOTIFY_XPCOM_OBSERVERS(mObservers, nsIDocumentObserver, \
  1.1362 +                                           func_, params_);
  1.1363 +
  1.1364 +#ifdef DEBUG
  1.1365 +  void VerifyRootContentState();
  1.1366 +#endif
  1.1367 +
  1.1368 +  nsDocument(const char* aContentType);
  1.1369 +  virtual ~nsDocument();
  1.1370 +
  1.1371 +  void EnsureOnloadBlocker();
  1.1372 +
  1.1373 +  void NotifyStyleSheetApplicableStateChanged();
  1.1374 +
  1.1375 +  nsTArray<nsIObserver*> mCharSetObservers;
  1.1376 +
  1.1377 +  PLDHashTable *mSubDocuments;
  1.1378 +
  1.1379 +  // Array of owning references to all children
  1.1380 +  nsAttrAndChildArray mChildren;
  1.1381 +
  1.1382 +  // Pointer to our parser if we're currently in the process of being
  1.1383 +  // parsed into.
  1.1384 +  nsCOMPtr<nsIParser> mParser;
  1.1385 +
  1.1386 +  // Weak reference to our sink for in case we no longer have a parser.  This
  1.1387 +  // will allow us to flush out any pending stuff from the sink even if
  1.1388 +  // EndLoad() has already happened.
  1.1389 +  nsWeakPtr mWeakSink;
  1.1390 +
  1.1391 +  nsCOMArray<nsIStyleSheet> mStyleSheets;
  1.1392 +  nsCOMArray<nsIStyleSheet> mCatalogSheets;
  1.1393 +  nsCOMArray<nsIStyleSheet> mAdditionalSheets[SheetTypeCount];
  1.1394 +
  1.1395 +  // Array of observers
  1.1396 +  nsTObserverArray<nsIDocumentObserver*> mObservers;
  1.1397 +
  1.1398 +  // Weak reference to the scope object (aka the script global object)
  1.1399 +  // that, unlike mScriptGlobalObject, is never unset once set. This
  1.1400 +  // is a weak reference to avoid leaks due to circular references.
  1.1401 +  nsWeakPtr mScopeObject;
  1.1402 +
  1.1403 +  // Stack of full-screen elements. When we request full-screen we push the
  1.1404 +  // full-screen element onto this stack, and when we cancel full-screen we
  1.1405 +  // pop one off this stack, restoring the previous full-screen state
  1.1406 +  nsTArray<nsWeakPtr> mFullScreenStack;
  1.1407 +
  1.1408 +  // The root of the doc tree in which this document is in. This is only
  1.1409 +  // non-null when this document is in fullscreen mode.
  1.1410 +  nsWeakPtr mFullscreenRoot;
  1.1411 +
  1.1412 +private:
  1.1413 +  // Array representing the processing stack in the custom elements
  1.1414 +  // specification. The processing stack is conceptually a stack of
  1.1415 +  // element queues. Each queue is represented by a sequence of
  1.1416 +  // CustomElementData in this array, separated by nullptr that
  1.1417 +  // represent the boundaries of the items in the stack. The first
  1.1418 +  // queue in the stack is the base element queue.
  1.1419 +  static mozilla::Maybe<nsTArray<mozilla::dom::CustomElementData*>> sProcessingStack;
  1.1420 +
  1.1421 +  // Flag to prevent re-entrance into base element queue as described in the
  1.1422 +  // custom elements speicification.
  1.1423 +  static bool sProcessingBaseElementQueue;
  1.1424 +
  1.1425 +  static bool CustomElementConstructor(JSContext* aCx, unsigned aArgc, JS::Value* aVp);
  1.1426 +
  1.1427 +public:
  1.1428 +  static void ProcessBaseElementQueue();
  1.1429 +
  1.1430 +  // Modify the prototype and "is" attribute of newly created custom elements.
  1.1431 +  virtual void SwizzleCustomElement(Element* aElement,
  1.1432 +                                    const nsAString& aTypeExtension,
  1.1433 +                                    uint32_t aNamespaceID,
  1.1434 +                                    mozilla::ErrorResult& rv);
  1.1435 +
  1.1436 +  static bool IsRegisterElementEnabled(JSContext* aCx, JSObject* aObject);
  1.1437 +
  1.1438 +  // The "registry" from the web components spec.
  1.1439 +  nsRefPtr<mozilla::dom::Registry> mRegistry;
  1.1440 +
  1.1441 +  nsRefPtr<mozilla::EventListenerManager> mListenerManager;
  1.1442 +  nsRefPtr<mozilla::dom::StyleSheetList> mDOMStyleSheets;
  1.1443 +  nsRefPtr<nsDOMStyleSheetSetList> mStyleSheetSetList;
  1.1444 +  nsRefPtr<nsScriptLoader> mScriptLoader;
  1.1445 +  nsDocHeaderData* mHeaderData;
  1.1446 +  /* mIdentifierMap works as follows for IDs:
  1.1447 +   * 1) Attribute changes affect the table immediately (removing and adding
  1.1448 +   *    entries as needed).
  1.1449 +   * 2) Removals from the DOM affect the table immediately
  1.1450 +   * 3) Additions to the DOM always update existing entries for names, and add
  1.1451 +   *    new ones for IDs.
  1.1452 +   */
  1.1453 +  nsTHashtable<nsIdentifierMapEntry> mIdentifierMap;
  1.1454 +
  1.1455 +  nsClassHashtable<nsStringHashKey, nsRadioGroupStruct> mRadioGroups;
  1.1456 +
  1.1457 +  // Recorded time of change to 'loading' state.
  1.1458 +  mozilla::TimeStamp mLoadingTimeStamp;
  1.1459 +
  1.1460 +  // True if the document has been detached from its content viewer.
  1.1461 +  bool mIsGoingAway:1;
  1.1462 +  // True if the document is being destroyed.
  1.1463 +  bool mInDestructor:1;
  1.1464 +
  1.1465 +  // True if this document has ever had an HTML or SVG <title> element
  1.1466 +  // bound to it
  1.1467 +  bool mMayHaveTitleElement:1;
  1.1468 +
  1.1469 +  bool mHasWarnedAboutBoxObjects:1;
  1.1470 +
  1.1471 +  bool mDelayFrameLoaderInitialization:1;
  1.1472 +
  1.1473 +  bool mSynchronousDOMContentLoaded:1;
  1.1474 +
  1.1475 +  bool mInXBLUpdate:1;
  1.1476 +
  1.1477 +  // Whether we're currently holding a lock on all of our images.
  1.1478 +  bool mLockingImages:1;
  1.1479 +
  1.1480 +  // Whether we currently require our images to animate
  1.1481 +  bool mAnimatingImages:1;
  1.1482 +
  1.1483 +  // Whether we're currently under a FlushPendingNotifications call to
  1.1484 +  // our presshell.  This is used to handle flush reentry correctly.
  1.1485 +  bool mInFlush:1;
  1.1486 +
  1.1487 +  // Parser aborted. True if the parser of this document was forcibly
  1.1488 +  // terminated instead of letting it finish at its own pace.
  1.1489 +  bool mParserAborted:1;
  1.1490 +
  1.1491 +  // Whether this document has been approved for fullscreen, either by explicit
  1.1492 +  // approval via the fullscreen-approval UI, or because it received
  1.1493 +  // approval because its document's host already had the "fullscreen"
  1.1494 +  // permission granted when the document requested fullscreen.
  1.1495 +  // 
  1.1496 +  // Note if a document's principal doesn't have a host, the permission manager
  1.1497 +  // can't store permissions for it, so we can only manage approval using this
  1.1498 +  // flag.
  1.1499 +  //
  1.1500 +  // Note we must track this separately from the "fullscreen" permission,
  1.1501 +  // so that pending pointer lock requests can determine whether documents
  1.1502 +  // whose principal doesn't have a host (i.e. those which can't store
  1.1503 +  // permissions in the permission manager) have been approved for fullscreen.
  1.1504 +  bool mIsApprovedForFullscreen:1;
  1.1505 +
  1.1506 +  // Whether this document has a fullscreen approved observer. Only documents
  1.1507 +  // which request fullscreen and which don't have a pre-existing approval for
  1.1508 +  // fullscreen will have an observer.
  1.1509 +  bool mHasFullscreenApprovedObserver:1;
  1.1510 +
  1.1511 +  friend class nsPointerLockPermissionRequest;
  1.1512 +  friend class nsCallRequestFullScreen;
  1.1513 +  // When set, trying to lock the pointer doesn't require permission from the
  1.1514 +  // user.
  1.1515 +  bool mAllowRelocking:1;
  1.1516 +
  1.1517 +  bool mAsyncFullscreenPending:1;
  1.1518 +
  1.1519 +  // Keeps track of whether we have a pending
  1.1520 +  // 'style-sheet-applicable-state-changed' notification.
  1.1521 +  bool mSSApplicableStateNotificationPending:1;
  1.1522 +
  1.1523 +  uint32_t mCancelledPointerLockRequests;
  1.1524 +
  1.1525 +  uint8_t mXMLDeclarationBits;
  1.1526 +
  1.1527 +  nsInterfaceHashtable<nsPtrHashKey<nsIContent>, nsPIBoxObject> *mBoxObjectTable;
  1.1528 +
  1.1529 +  // A document "without a browsing context" that owns the content of
  1.1530 +  // HTMLTemplateElement.
  1.1531 +  nsCOMPtr<nsIDocument> mTemplateContentsOwner;
  1.1532 +
  1.1533 +  // Our update nesting level
  1.1534 +  uint32_t mUpdateNestLevel;
  1.1535 +
  1.1536 +  // The application cache that this document is associated with, if
  1.1537 +  // any.  This can change during the lifetime of the document.
  1.1538 +  nsCOMPtr<nsIApplicationCache> mApplicationCache;
  1.1539 +
  1.1540 +  nsCOMPtr<nsIContent> mFirstBaseNodeWithHref;
  1.1541 +
  1.1542 +  mozilla::EventStates mDocumentState;
  1.1543 +  mozilla::EventStates mGotDocumentState;
  1.1544 +
  1.1545 +  nsRefPtr<nsDOMNavigationTiming> mTiming;
  1.1546 +private:
  1.1547 +  friend class nsUnblockOnloadEvent;
  1.1548 +  // Recomputes the visibility state but doesn't set the new value.
  1.1549 +  mozilla::dom::VisibilityState GetVisibilityState() const;
  1.1550 +  void NotifyStyleSheetAdded(nsIStyleSheet* aSheet, bool aDocumentSheet);
  1.1551 +  void NotifyStyleSheetRemoved(nsIStyleSheet* aSheet, bool aDocumentSheet);
  1.1552 +
  1.1553 +  void PostUnblockOnloadEvent();
  1.1554 +  void DoUnblockOnload();
  1.1555 +
  1.1556 +  nsresult CheckFrameOptions();
  1.1557 +  nsresult InitCSP(nsIChannel* aChannel);
  1.1558 +
  1.1559 +  void FlushCSPWebConsoleErrorQueue()
  1.1560 +  {
  1.1561 +    mCSPWebConsoleErrorQueue.Flush(this);
  1.1562 +  }
  1.1563 +
  1.1564 +  /**
  1.1565 +   * Find the (non-anonymous) content in this document for aFrame. It will
  1.1566 +   * be aFrame's content node if that content is in this document and not
  1.1567 +   * anonymous. Otherwise, when aFrame is in a subdocument, we use the frame
  1.1568 +   * element containing the subdocument containing aFrame, and/or find the
  1.1569 +   * nearest non-anonymous ancestor in this document.
  1.1570 +   * Returns null if there is no such element.
  1.1571 +   */
  1.1572 +  nsIContent* GetContentInThisDocument(nsIFrame* aFrame) const;
  1.1573 +
  1.1574 +  // Just like EnableStyleSheetsForSet, but doesn't check whether
  1.1575 +  // aSheetSet is null and allows the caller to control whether to set
  1.1576 +  // aSheetSet as the preferred set in the CSSLoader.
  1.1577 +  void EnableStyleSheetsForSetInternal(const nsAString& aSheetSet,
  1.1578 +                                       bool aUpdateCSSLoader);
  1.1579 +
  1.1580 +  // Revoke any pending notifications due to mozRequestAnimationFrame calls
  1.1581 +  void RevokeAnimationFrameNotifications();
  1.1582 +  // Reschedule any notifications we need to handle
  1.1583 +  // mozRequestAnimationFrame, if it's OK to do so.
  1.1584 +  void MaybeRescheduleAnimationFrameNotifications();
  1.1585 +
  1.1586 +  // These are not implemented and not supported.
  1.1587 +  nsDocument(const nsDocument& aOther);
  1.1588 +  nsDocument& operator=(const nsDocument& aOther);
  1.1589 +
  1.1590 +  // The layout history state that should be used by nodes in this
  1.1591 +  // document.  We only actually store a pointer to it when:
  1.1592 +  // 1)  We have no script global object.
  1.1593 +  // 2)  We haven't had Destroy() called on us yet.
  1.1594 +  nsCOMPtr<nsILayoutHistoryState> mLayoutHistoryState;
  1.1595 +
  1.1596 +  // Currently active onload blockers
  1.1597 +  uint32_t mOnloadBlockCount;
  1.1598 +  // Onload blockers which haven't been activated yet
  1.1599 +  uint32_t mAsyncOnloadBlockCount;
  1.1600 +  nsCOMPtr<nsIRequest> mOnloadBlocker;
  1.1601 +
  1.1602 +  // A hashtable of styled links keyed by address pointer.
  1.1603 +  nsTHashtable<nsPtrHashKey<mozilla::dom::Link> > mStyledLinks;
  1.1604 +#ifdef DEBUG
  1.1605 +  // Indicates whether mStyledLinks was cleared or not.  This is used to track
  1.1606 +  // state so we can provide useful assertions to consumers of ForgetLink and
  1.1607 +  // AddStyleRelevantLink.
  1.1608 +  bool mStyledLinksCleared;
  1.1609 +#endif
  1.1610 +
  1.1611 +  // Member to store out last-selected stylesheet set.
  1.1612 +  nsString mLastStyleSheetSet;
  1.1613 +
  1.1614 +  nsTArray<nsRefPtr<nsFrameLoader> > mInitializableFrameLoaders;
  1.1615 +  nsTArray<nsRefPtr<nsFrameLoader> > mFinalizableFrameLoaders;
  1.1616 +  nsRefPtr<nsRunnableMethod<nsDocument> > mFrameLoaderRunner;
  1.1617 +
  1.1618 +  nsRevocableEventPtr<nsRunnableMethod<nsDocument, void, false> >
  1.1619 +    mPendingTitleChangeEvent;
  1.1620 +
  1.1621 +  nsExternalResourceMap mExternalResourceMap;
  1.1622 +
  1.1623 +  // All images in process of being preloaded
  1.1624 +  nsCOMArray<imgIRequest> mPreloadingImages;
  1.1625 +
  1.1626 +  nsRefPtr<mozilla::dom::DOMImplementation> mDOMImplementation;
  1.1627 +
  1.1628 +  nsRefPtr<nsContentList> mImageMaps;
  1.1629 +
  1.1630 +  nsCString mScrollToRef;
  1.1631 +  uint8_t mScrolledToRefAlready : 1;
  1.1632 +  uint8_t mChangeScrollPosWhenScrollingToRef : 1;
  1.1633 +
  1.1634 +  // Tracking for images in the document.
  1.1635 +  nsDataHashtable< nsPtrHashKey<imgIRequest>, uint32_t> mImageTracker;
  1.1636 +
  1.1637 +  // Tracking for plugins in the document.
  1.1638 +  nsTHashtable< nsPtrHashKey<nsIObjectLoadingContent> > mPlugins;
  1.1639 +
  1.1640 +  nsRefPtr<mozilla::dom::UndoManager> mUndoManager;
  1.1641 +
  1.1642 +  enum ViewportType {
  1.1643 +    DisplayWidthHeight,
  1.1644 +    DisplayWidthHeightNoZoom,
  1.1645 +    Specified,
  1.1646 +    Unknown
  1.1647 +  };
  1.1648 +
  1.1649 +  ViewportType mViewportType;
  1.1650 +
  1.1651 +  // These member variables cache information about the viewport so we don't have to
  1.1652 +  // recalculate it each time.
  1.1653 +  bool mValidWidth, mValidHeight;
  1.1654 +  mozilla::LayoutDeviceToScreenScale mScaleMinFloat;
  1.1655 +  mozilla::LayoutDeviceToScreenScale mScaleMaxFloat;
  1.1656 +  mozilla::LayoutDeviceToScreenScale mScaleFloat;
  1.1657 +  mozilla::CSSToLayoutDeviceScale mPixelRatio;
  1.1658 +  bool mAutoSize, mAllowZoom, mAllowDoubleTapZoom, mValidScaleFloat, mValidMaxScale, mScaleStrEmpty, mWidthStrEmpty;
  1.1659 +  mozilla::CSSIntSize mViewportSize;
  1.1660 +
  1.1661 +  nsrefcnt mStackRefCnt;
  1.1662 +  bool mNeedsReleaseAfterStackRefCntRelease;
  1.1663 +
  1.1664 +  CSPErrorQueue mCSPWebConsoleErrorQueue;
  1.1665 +
  1.1666 +#ifdef DEBUG
  1.1667 +protected:
  1.1668 +  bool mWillReparent;
  1.1669 +#endif
  1.1670 +};
  1.1671 +
  1.1672 +class nsDocumentOnStack
  1.1673 +{
  1.1674 +public:
  1.1675 +  nsDocumentOnStack(nsDocument* aDoc) : mDoc(aDoc)
  1.1676 +  {
  1.1677 +    mDoc->IncreaseStackRefCnt();
  1.1678 +  }
  1.1679 +  ~nsDocumentOnStack()
  1.1680 +  {
  1.1681 +    mDoc->DecreaseStackRefCnt();
  1.1682 +  }
  1.1683 +private:
  1.1684 +  nsDocument* mDoc;
  1.1685 +};
  1.1686 +
  1.1687 +#endif /* nsDocument_h___ */

mercurial