#include "CollectionCache.h"
#include "CollectionType.h"
#include "Color.h"
-#include "ContainerNode.h"
+#include "DOMTimeStamp.h"
#include "DocumentTiming.h"
#include "QualifiedName.h"
#include "ScriptExecutionContext.h"
+#include "StringWithDirection.h"
#include "Timer.h"
+#include "TreeScope.h"
#include "ViewportArguments.h"
#include <wtf/FixedArray.h>
-#include <wtf/HashCountedSet.h>
#include <wtf/OwnPtr.h>
#include <wtf/PassOwnPtr.h>
-
-#if USE(JSC)
-#include <runtime/WeakGCMap.h>
-#endif
+#include <wtf/PassRefPtr.h>
namespace WebCore {
-class AsyncScriptRunner;
-class Attr;
class AXObjectCache;
+class Attr;
class CDATASection;
+class CSSPrimitiveValueCache;
+class CSSStyleDeclaration;
+class CSSStyleSelector;
+class CSSStyleSheet;
class CachedCSSStyleSheet;
class CachedResourceLoader;
class CachedScript;
class CanvasRenderingContext;
class CharacterData;
-class CSSStyleDeclaration;
-class CSSStyleSelector;
-class CSSStyleSheet;
class Comment;
+class ContentSecurityPolicy;
class DOMImplementation;
class DOMSelection;
class DOMWindow;
class Database;
class DatabaseThread;
class DocumentFragment;
+class DocumentLoader;
class DocumentMarkerController;
class DocumentType;
class DocumentWeakReference;
class RenderFullScreen;
class ScriptableDocumentParser;
class ScriptElementData;
+class ScriptRunner;
class SecurityOrigin;
class SerializedScriptValue;
class SegmentedString;
class TouchList;
#endif
+#if ENABLE(REQUEST_ANIMATION_FRAME)
+class RequestAnimationFrameCallback;
+class ScriptedAnimationController;
+#endif
+
typedef int ExceptionCode;
class FormElementKey {
enum StyleSelectorUpdateFlag { RecalcStyleImmediately, DeferRecalcStyle };
-class Document : public ContainerNode, public ScriptExecutionContext {
+class Document : public TreeScope, public ScriptExecutionContext {
public:
static PassRefPtr<Document> create(Frame* frame, const KURL& url)
{
MediaQueryMatcher* mediaQueryMatcher();
- using ContainerNode::ref;
- using ContainerNode::deref;
+ using TreeScope::ref;
+ using TreeScope::deref;
- // Nodes belonging to this document hold "self-only" references -
+ // Nodes belonging to this document hold guard references -
// these are enough to keep the document from being destroyed, but
// not enough to keep it from removing its children. This allows a
// node that outlives its document to still have a valid document
- // pointer without introducing reference cycles
-
- void selfOnlyRef()
+ // pointer without introducing reference cycles.
+ void guardRef()
{
ASSERT(!m_deletionHasBegun);
- ++m_selfOnlyRefCount;
+ ++m_guardRefCount;
}
- void selfOnlyDeref()
+
+ void guardDeref()
{
ASSERT(!m_deletionHasBegun);
- --m_selfOnlyRefCount;
- if (!m_selfOnlyRefCount && !refCount()) {
+ --m_guardRefCount;
+ if (!m_guardRefCount && !refCount()) {
#ifndef NDEBUG
m_deletionHasBegun = true;
#endif
}
}
+ virtual void removedLastRef();
+
+ Element* getElementById(const AtomicString& id) const;
+
// DOM methods & attributes for Document
DEFINE_ATTRIBUTE_EVENT_LISTENER(abort);
DEFINE_ATTRIBUTE_EVENT_LISTENER(reset);
DEFINE_ATTRIBUTE_EVENT_LISTENER(search);
DEFINE_ATTRIBUTE_EVENT_LISTENER(selectstart);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(selectionchange);
#if ENABLE(TOUCH_EVENTS)
DEFINE_ATTRIBUTE_EVENT_LISTENER(touchstart);
DEFINE_ATTRIBUTE_EVENT_LISTENER(touchmove);
DocumentType* doctype() const { return m_docType.get(); }
- DOMImplementation* implementation() const;
+ DOMImplementation* implementation();
Element* documentElement() const
{
PassRefPtr<Node> importNode(Node* importedNode, bool deep, ExceptionCode&);
virtual PassRefPtr<Element> createElementNS(const String& namespaceURI, const String& qualifiedName, ExceptionCode&);
PassRefPtr<Element> createElement(const QualifiedName&, bool createdByParser);
- Element* getElementById(const AtomicString&) const;
- bool hasElementWithId(AtomicStringImpl* id) const;
- bool containsMultipleElementsWithId(const AtomicString& id) const;
/**
* Retrieve all nodes that intersect a rect in the window's document, until it is fully enclosed by
String defaultCharset() const;
- // Synonyms backing similar DOM attributes. Use Document::encoding() to avoid virtual dispatch.
String inputEncoding() const { return Document::encoding(); }
String charset() const { return Document::encoding(); }
String characterSet() const { return Document::encoding(); }
PassRefPtr<HTMLAllCollection> all();
- // Find first anchor with the given name.
- // First searches for an element with the given ID, but if that fails, then looks
- // for an anchor with the given name. ID matching is always case sensitive, but
- // Anchor name matching is case sensitive in strict mode and not case sensitive in
- // quirks mode for historical compatibility reasons.
- Element* findAnchor(const String& name);
-
CollectionCache* collectionInfo(CollectionType type)
{
ASSERT(type >= FirstUnnamedDocumentCachedType);
#endif
virtual bool isFrameSet() const { return false; }
+ PassRefPtr<CSSPrimitiveValueCache> cssPrimitiveValueCache() const;
+
+ CSSStyleSelector* styleSelectorIfExists() const { return m_styleSelector.get(); }
+
+ bool usesViewSourceStyles() const { return m_usesViewSourceStyles; }
+ void setUsesViewSourceStyles(bool usesViewSourceStyles) { m_usesViewSourceStyles = usesViewSourceStyles; }
+
+ bool sawElementsInKnownNamespaces() const { return m_sawElementsInKnownNamespaces; }
+
CSSStyleSelector* styleSelector()
{
if (!m_styleSelector)
return m_styleSelector.get();
}
- Element* getElementByAccessKey(const String& key) const;
-
/**
* Updates the pending sheet count and then calls updateStyleSelector.
*/
void styleSelectorChanged(StyleSelectorUpdateFlag);
void recalcStyleSelector();
- bool usesDescendantRules() const { return m_usesDescendantRules; }
- void setUsesDescendantRules(bool b) { m_usesDescendantRules = b; }
- bool usesSiblingRules() const { return m_usesSiblingRules; }
- void setUsesSiblingRules(bool b) { m_usesSiblingRules = b; }
+ bool usesSiblingRules() const { return m_usesSiblingRules || m_usesSiblingRulesOverride; }
+ void setUsesSiblingRules(bool b) { m_usesSiblingRulesOverride = b; }
bool usesFirstLineRules() const { return m_usesFirstLineRules; }
- void setUsesFirstLineRules(bool b) { m_usesFirstLineRules = b; }
bool usesFirstLetterRules() const { return m_usesFirstLetterRules; }
void setUsesFirstLetterRules(bool b) { m_usesFirstLetterRules = b; }
- bool usesBeforeAfterRules() const { return m_usesBeforeAfterRules; }
- void setUsesBeforeAfterRules(bool b) { m_usesBeforeAfterRules = b; }
+ bool usesBeforeAfterRules() const { return m_usesBeforeAfterRules || m_usesBeforeAfterRulesOverride; }
+ void setUsesBeforeAfterRules(bool b) { m_usesBeforeAfterRulesOverride = b; }
bool usesRemUnits() const { return m_usesRemUnits; }
void setUsesRemUnits(bool b) { m_usesRemUnits = b; }
bool usesLinkRules() const { return linkColor() != visitedLinkColor() || m_usesLinkRules; }
// to get visually ordered hebrew and arabic pages right
void setVisuallyOrdered();
bool visuallyOrdered() const { return m_visuallyOrdered; }
+
+ void setDocumentLoader(DocumentLoader* documentLoader) { m_documentLoader = documentLoader; }
+ DocumentLoader* loader() const { return m_documentLoader; }
void open(Document* ownerDocument = 0);
void implicitOpen();
+
+ // close() is the DOM API document.close()
void close();
+ // In some situations (see the code), we ignore document.close().
+ // explicitClose() bypass these checks and actually tries to close the
+ // input stream.
+ void explicitClose();
+ // implicitClose() actually does the work of closing the input stream.
void implicitClose();
+
void cancelParsing();
void write(const SegmentedString& text, Document* ownerDocument = 0);
void setExtraLayoutDelay(int delay) { m_extraLayoutDelay = delay; }
bool shouldScheduleLayout();
+ bool isLayoutTimerActive();
int elapsedTime() const;
void setTextColor(const Color& color) { m_textColor = color; }
// Returns 0 if this is the top level document.
HTMLFrameOwnerElement* ownerElement() const;
- String title() const { return m_title; }
- void setTitle(const String&, Element* titleElement = 0);
+ // Used by DOM bindings; no direction known.
+ String title() const { return m_title.string(); }
+ void setTitle(const String&);
+
+ void setTitleElement(const StringWithDirection&, Element* titleElement);
void removeTitle(Element* titleElement);
String cookie(ExceptionCode&) const;
// Checks to make sure prefix and namespace do not conflict (per DOM Core 3)
static bool hasPrefixNamespaceMismatch(const QualifiedName&);
- void addElementById(const AtomicString& elementId, Element *element);
- void removeElementById(const AtomicString& elementId, Element *element);
-
- void addImageMap(HTMLMapElement*);
- void removeImageMap(HTMLMapElement*);
- HTMLMapElement* getImageMap(const String& url) const;
-
HTMLElement* body() const;
void setBody(PassRefPtr<HTMLElement>, ExceptionCode&);
int docID() const { return m_docID; }
- AsyncScriptRunner* asyncScriptRunner() { return m_asyncScriptRunner.get(); }
+ ScriptRunner* scriptRunner() { return m_scriptRunner.get(); }
#if ENABLE(XSLT)
void applyXSLTransform(ProcessingInstruction* pi);
TransformSource* transformSource() const { return m_transformSource.get(); }
#endif
- void incDOMTreeVersion() { ++m_domTreeVersion; }
- unsigned domTreeVersion() const { return m_domTreeVersion; }
+ void incDOMTreeVersion() { m_domTreeVersion = ++s_globalTreeVersion; }
+ uint64_t domTreeVersion() const { return m_domTreeVersion; }
#ifdef ANDROID_STYLE_VERSION
void incStyleVersion() { ++m_styleVersion; }
void setUseSecureKeyboardEntryWhenActive(bool);
bool useSecureKeyboardEntryWhenActive() const;
- void addNodeListCache() { ++m_numNodeListCaches; }
- void removeNodeListCache() { ASSERT(m_numNodeListCaches > 0); --m_numNodeListCaches; }
- bool hasNodeListCaches() const { return m_numNodeListCaches; }
-
void updateFocusAppearanceSoon(bool restorePreviousSelection);
void cancelFocusAppearanceUpdate();
bool isDNSPrefetchEnabled() const { return m_isDNSPrefetchEnabled; }
void parseDNSPrefetchControlHeader(const String&);
- virtual void reportException(const String& errorMessage, int lineNumber, const String& sourceURL);
- virtual void addMessage(MessageSource, MessageType, MessageLevel, const String& message, unsigned lineNumber, const String& sourceURL);
+ virtual void addMessage(MessageSource, MessageType, MessageLevel, const String& message, unsigned lineNumber, const String& sourceURL, PassRefPtr<ScriptCallStack>);
virtual void postTask(PassOwnPtr<Task>); // Executes the task on context's thread asynchronously.
-#if USE(JSC)
- typedef JSC::WeakGCMap<WebCore::Node*, JSNode*> JSWrapperCache;
- typedef HashMap<DOMWrapperWorld*, JSWrapperCache*> JSWrapperCacheMap;
- JSWrapperCacheMap& wrapperCacheMap() { return m_wrapperCacheMap; }
- JSWrapperCache* getWrapperCache(DOMWrapperWorld* world);
- JSWrapperCache* createWrapperCache(DOMWrapperWorld*);
- void destroyWrapperCache(DOMWrapperWorld*);
- void destroyAllWrapperCaches();
-#endif
+ virtual void suspendScriptedAnimationControllerCallbacks();
+ virtual void resumeScriptedAnimationControllerCallbacks();
virtual void finishedParsing();
void unregisterForMediaVolumeCallbacks(Element*);
void mediaVolumeDidChange();
+ void registerForPrivateBrowsingStateChangedCallbacks(Element*);
+ void unregisterForPrivateBrowsingStateChangedCallbacks(Element*);
+ void privateBrowsingStateDidChange();
+
void setShouldCreateRenderers(bool);
bool shouldCreateRenderers();
#endif
virtual bool isContextThread() const;
- virtual bool isJSExecutionTerminated() const { return false; }
+ virtual bool isJSExecutionForbidden() const { return false; }
void setUsingGeolocation(bool f) { m_usingGeolocation = f; }
bool usingGeolocation() const { return m_usingGeolocation; };
void setContainsValidityStyleRules() { m_containsValidityStyleRules = true; }
void enqueueWindowEvent(PassRefPtr<Event>);
+ void enqueueDocumentEvent(PassRefPtr<Event>);
void enqueuePageshowEvent(PageshowEventPersistence);
void enqueueHashchangeEvent(const String& oldURL, const String& newURL);
void enqueuePopstateEvent(PassRefPtr<SerializedScriptValue> stateObject);
const QualifiedName& idAttributeName() const { return m_idAttributeName; }
#if ENABLE(FULLSCREEN_API)
- bool webkitIsFullScreen() const { return m_isFullScreen; }
- bool webkitFullScreenKeyboardInputAllowed() const { return m_isFullScreen && m_areKeysEnabledInFullScreen; }
+ bool webkitIsFullScreen() const { return m_fullScreenElement.get(); }
+ bool webkitFullScreenKeyboardInputAllowed() const { return m_fullScreenElement.get() && m_areKeysEnabledInFullScreen; }
Element* webkitCurrentFullScreenElement() const { return m_fullScreenElement.get(); }
void webkitRequestFullScreenForElement(Element*, unsigned short flags);
void webkitCancelFullScreen();
void setFullScreenRendererBackgroundColor(Color);
void fullScreenChangeDelayTimerFired(Timer<Document>*);
+ bool fullScreenIsAllowedForElement(Element*) const;
#endif
// Used to allow element that loads data without going through a FrameLoader to delay the 'load' event.
const DocumentTiming* timing() const { return &m_documentTiming; }
- bool mayCauseFlashOfUnstyledContent() const;
+#if ENABLE(REQUEST_ANIMATION_FRAME)
+ int webkitRequestAnimationFrame(PassRefPtr<RequestAnimationFrameCallback>, Element*);
+ void webkitCancelRequestAnimationFrame(int id);
+ void serviceScriptedAnimations(DOMTimeStamp);
+#endif
+
+ virtual EventTarget* errorEventTarget();
+ virtual void logExceptionToConsole(const String& errorMessage, int lineNumber, const String& sourceURL, PassRefPtr<ScriptCallStack>);
void initDNSPrefetch();
+ ContentSecurityPolicy* contentSecurityPolicy() { return m_contentSecurityPolicy.get(); }
+
protected:
- Document(Frame*, const KURL& url, bool isXHTML, bool isHTML, const KURL& baseURL = KURL());
+ Document(Frame*, const KURL&, bool isXHTML, bool isHTML);
void clearXMLVersion() { m_xmlVersion = String(); }
private:
- class DocumentOrderedMap {
- public:
- void add(AtomicStringImpl*, Element*);
- void remove(AtomicStringImpl*, Element*);
- void clear();
-
- bool contains(AtomicStringImpl*) const;
- bool containsMultiple(AtomicStringImpl*) const;
- template<bool keyMatches(AtomicStringImpl*, Element*)> Element* get(AtomicStringImpl*, const Document*) const;
-
- void checkConsistency() const;
-
- private:
- typedef HashMap<AtomicStringImpl*, Element*> Map;
-
- // We maintain the invariant that m_duplicateCounts is the count of all elements with a given key
- // excluding the one referenced in m_map, if any. This means it one less than the total count
- // when the first node with a given key is cached, otherwise the same as the total count.
- mutable Map m_map;
- mutable HashCountedSet<AtomicStringImpl*> m_duplicateCounts;
- };
-
friend class IgnoreDestructiveWriteCountIncrementer;
void detachParser();
void processArguments(const String& features, void* data, ArgumentsCallback);
virtual bool isDocument() const { return true; }
- virtual void removedLastRef();
virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
virtual String nodeName() const;
virtual NodeType nodeType() const;
- virtual bool childTypeAllowed(NodeType);
+ virtual bool childTypeAllowed(NodeType) const;
virtual PassRefPtr<Node> cloneNode(bool deep);
virtual bool canReplaceChild(Node* newChild, Node* oldChild);
virtual const KURL& virtualURL() const; // Same as url(), but needed for ScriptExecutionContext to implement it without a performance loss for direct calls.
virtual KURL virtualCompleteURL(const String&) const; // Same as completeURL() for the same reason as above.
+ virtual double minimumTimerInterval() const;
+
String encoding() const;
- void updateTitle();
+ void updateTitle(const StringWithDirection&);
void updateFocusAppearanceTimerFired(Timer<Document>*);
void updateBaseURL();
void loadEventDelayTimerFired(Timer<Document>*);
+ int m_guardRefCount;
+
OwnPtr<CSSStyleSelector> m_styleSelector;
bool m_didCalculateStyleSelector;
+ bool m_hasDirtyStyleSelector;
+
+ mutable RefPtr<CSSPrimitiveValueCache> m_cssPrimitiveValueCache;
Frame* m_frame;
+ DocumentLoader* m_documentLoader;
OwnPtr<CachedResourceLoader> m_cachedResourceLoader;
RefPtr<DocumentParser> m_parser;
bool m_wellFormed;
RefPtr<Node> m_activeNode;
mutable RefPtr<Element> m_documentElement;
- unsigned m_domTreeVersion;
+ uint64_t m_domTreeVersion;
+ static uint64_t s_globalTreeVersion;
#ifdef ANDROID_STYLE_VERSION
unsigned m_styleVersion;
#endif
bool m_inStyleRecalc;
bool m_closeAfterStyleRecalc;
- bool m_usesDescendantRules;
bool m_usesSiblingRules;
+ bool m_usesSiblingRulesOverride;
bool m_usesFirstLineRules;
bool m_usesFirstLetterRules;
bool m_usesBeforeAfterRules;
+ bool m_usesBeforeAfterRulesOverride;
bool m_usesRemUnits;
bool m_usesLinkRules;
bool m_gotoAnchorNeededAfterStylesheetsLoad;
// http://www.whatwg.org/specs/web-apps/current-work/#ignore-destructive-writes-counter
unsigned m_ignoreDestructiveWriteCount;
- String m_title;
- String m_rawTitle;
+ StringWithDirection m_title;
+ StringWithDirection m_rawTitle;
bool m_titleSetExplicitly;
RefPtr<Element> m_titleElement;
// points during the lifetime of the Document.
int m_extraLayoutDelay;
- OwnPtr<AsyncScriptRunner> m_asyncScriptRunner;
+ OwnPtr<ScriptRunner> m_scriptRunner;
#if ENABLE(XSLT)
OwnPtr<TransformSource> m_transformSource;
RefPtr<Document> m_transformSourceDocument;
#endif
- DocumentOrderedMap m_imageMapsByName;
-
int m_docID; // A unique document identifier used for things like document-specific mapped attributes.
String m_xmlEncoding;
RefPtr<TextResourceDecoder> m_decoder;
- DocumentOrderedMap m_elementsById;
-
- mutable HashMap<StringImpl*, Element*, CaseFoldingHash> m_elementsByAccessKey;
-
InheritedBool m_designMode;
- int m_selfOnlyRefCount;
-
CheckedRadioButtons m_checkedRadioButtons;
typedef HashMap<AtomicStringImpl*, CollectionCache*> NamedCollectionMap;
HashMap<String, RefPtr<HTMLCanvasElement> > m_cssCanvasElements;
- mutable bool m_accessKeyMapValid;
bool m_createRenderers;
bool m_inPageCache;
String m_iconURL;
HashSet<Element*> m_documentActivationCallbackElements;
HashSet<Element*> m_mediaVolumeCallbackElements;
+ HashSet<Element*> m_privateBrowsingStateChangedElements;
bool m_useSecureKeyboardEntryWhenActive;
bool m_isXHTML;
bool m_isHTML;
- unsigned m_numNodeListCaches;
-
-#if USE(JSC)
- JSWrapperCacheMap m_wrapperCacheMap;
- JSWrapperCache* m_normalWorldWrapperCache;
-#endif
+ bool m_usesViewSourceStyles;
+ bool m_sawElementsInKnownNamespaces;
bool m_usingGeolocation;
- OwnPtr<EventQueue> m_eventQueue;
+ RefPtr<EventQueue> m_eventQueue;
#if ENABLE(WML)
bool m_containsWMLContent;
QualifiedName m_idAttributeName;
#if ENABLE(FULLSCREEN_API)
- bool m_isFullScreen;
bool m_areKeysEnabledInFullScreen;
RefPtr<Element> m_fullScreenElement;
RenderFullScreen* m_fullScreenRenderer;
DocumentTiming m_documentTiming;
RefPtr<MediaQueryMatcher> m_mediaQueryMatcher;
-};
+ bool m_writeRecursionIsTooDeep;
+ unsigned m_writeRecursionDepth;
-inline bool Document::DocumentOrderedMap::contains(AtomicStringImpl* id) const
-{
- return m_map.contains(id) || m_duplicateCounts.contains(id);
-}
+#if ENABLE(REQUEST_ANIMATION_FRAME)
+ OwnPtr<ScriptedAnimationController> m_scriptedAnimationController;
+#endif
-inline bool Document::DocumentOrderedMap::containsMultiple(AtomicStringImpl* id) const
-{
- return m_duplicateCounts.contains(id);
-}
+ RefPtr<ContentSecurityPolicy> m_contentSecurityPolicy;
+};
-inline bool Document::hasElementWithId(AtomicStringImpl* id) const
-{
- ASSERT(id);
- return m_elementsById.contains(id);
-}
+// Put these methods here, because they require the Document definition, but we really want to inline them.
-inline bool Document::containsMultipleElementsWithId(const AtomicString& id) const
-{
- return m_elementsById.containsMultiple(id.impl());
-}
-
inline bool Node::isDocumentNode() const
{
return this == m_document;
}
-// here because it uses a Document method but we really want to inline it
inline Node::Node(Document* document, ConstructionType type)
: m_document(document)
, m_previous(0)
, m_nodeFlags(type)
{
if (m_document)
- m_document->selfOnlyRef();
+ m_document->guardRef();
#if !defined(NDEBUG) || (defined(DUMP_NODE_STATISTICS) && DUMP_NODE_STATISTICS)
trackForDebugging();
#endif