summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/dom/Document.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/dom/Document.cpp')
-rw-r--r--Source/WebCore/dom/Document.cpp349
1 files changed, 108 insertions, 241 deletions
diff --git a/Source/WebCore/dom/Document.cpp b/Source/WebCore/dom/Document.cpp
index a0ddede..b85bdfb 100644
--- a/Source/WebCore/dom/Document.cpp
+++ b/Source/WebCore/dom/Document.cpp
@@ -123,7 +123,7 @@
#include "RenderTextControl.h"
#include "RenderView.h"
#include "RenderWidget.h"
-#include "ScopedEventQueue.h"
+#include "ScopedEventQueue.h"
#include "ScriptCallStack.h"
#include "ScriptController.h"
#include "ScriptElement.h"
@@ -391,7 +391,8 @@ private:
uint64_t Document::s_globalTreeVersion = 0;
Document::Document(Frame* frame, const KURL& url, bool isXHTML, bool isHTML)
- : ContainerNode(0)
+ : TreeScope(this)
+ , m_guardRefCount(0)
, m_compatibilityMode(NoQuirksMode)
, m_compatibilityModeLocked(false)
, m_domTreeVersion(++s_globalTreeVersion)
@@ -406,8 +407,6 @@ Document::Document(Frame* frame, const KURL& url, bool isXHTML, bool isHTML)
, m_containsValidityStyleRules(false)
, m_updateFocusAppearanceRestoresSelection(false)
, m_ignoreDestructiveWriteCount(0)
- , m_title("")
- , m_rawTitle("")
, m_titleSetExplicitly(false)
, m_updateFocusAppearanceTimer(this, &Document::updateFocusAppearanceTimerFired)
, m_startTime(currentTime())
@@ -418,7 +417,6 @@ Document::Document(Frame* frame, const KURL& url, bool isXHTML, bool isHTML)
, m_xmlStandalone(false)
, m_savedRenderer(0)
, m_designMode(inherit)
- , m_selfOnlyRefCount(0)
#if ENABLE(SVG)
, m_svgExtensions(0)
#endif
@@ -426,7 +424,6 @@ Document::Document(Frame* frame, const KURL& url, bool isXHTML, bool isHTML)
, m_hasDashboardRegions(false)
, m_dashboardRegionsDirty(false)
#endif
- , m_accessKeyMapValid(false)
, m_createRenderers(true)
, m_inPageCache(false)
, m_useSecureKeyboardEntryWhenActive(false)
@@ -434,10 +431,6 @@ Document::Document(Frame* frame, const KURL& url, bool isXHTML, bool isHTML)
, m_isHTML(isHTML)
, m_usesViewSourceStyles(false)
, m_sawElementsInKnownNamespaces(false)
- , m_numNodeListCaches(0)
-#if USE(JSC)
- , m_normalWorldWrapperCache(0)
-#endif
, m_usingGeolocation(false)
, m_eventQueue(EventQueue::create(this))
#if ENABLE(WML)
@@ -446,7 +439,6 @@ Document::Document(Frame* frame, const KURL& url, bool isXHTML, bool isHTML)
, m_weakReference(DocumentWeakReference::create(this))
, m_idAttributeName(idAttr)
#if ENABLE(FULLSCREEN_API)
- , m_isFullScreen(0)
, m_areKeysEnabledInFullScreen(0)
, m_fullScreenRenderer(0)
, m_fullScreenChangeDelayTimer(this, &Document::fullScreenChangeDelayTimerFired)
@@ -506,7 +498,7 @@ Document::Document(Frame* frame, const KURL& url, bool isXHTML, bool isHTML)
m_usesLinkRules = false;
m_gotoAnchorNeededAfterStylesheetsLoad = false;
-
+
m_didCalculateStyleSelector = false;
m_hasDirtyStyleSelector = false;
m_pendingStylesheets = 0;
@@ -532,57 +524,6 @@ Document::Document(Frame* frame, const KURL& url, bool isXHTML, bool isHTML)
#endif
}
-void Document::removedLastRef()
-{
- ASSERT(!m_deletionHasBegun);
- if (m_selfOnlyRefCount) {
- // If removing a child removes the last self-only ref, we don't
- // want the document to be destructed until after
- // removeAllChildren returns, so we guard ourselves with an
- // extra self-only ref.
- selfOnlyRef();
-
- // We must make sure not to be retaining any of our children through
- // these extra pointers or we will create a reference cycle.
- m_docType = 0;
- m_focusedNode = 0;
- m_hoverNode = 0;
- m_activeNode = 0;
- m_titleElement = 0;
- m_documentElement = 0;
-#if ENABLE(FULLSCREEN_API)
- m_fullScreenElement = 0;
-#endif
-
- // removeAllChildren() doesn't always unregister IDs, do it upfront to avoid having stale references in the map.
- m_elementsById.clear();
-
- removeAllChildren();
-
- m_markers->detach();
-
- detachParser();
-
- m_cssCanvasElements.clear();
-
-#if ENABLE(REQUEST_ANIMATION_FRAME)
- // FIXME: consider using ActiveDOMObject.
- m_scriptedAnimationController = 0;
-#endif
-
-#ifndef NDEBUG
- m_inRemovedLastRefFunction = false;
-#endif
-
- selfOnlyDeref();
- } else {
-#ifndef NDEBUG
- m_deletionHasBegun = true;
-#endif
- delete this;
- }
-}
-
Document::~Document()
{
ASSERT(!renderer());
@@ -590,15 +531,12 @@ Document::~Document()
ASSERT(!m_savedRenderer);
ASSERT(m_ranges.isEmpty());
ASSERT(!m_styleRecalcTimer.isActive());
+ ASSERT(!m_parentTreeScope);
m_scriptRunner.clear();
removeAllEventListeners();
-#if USE(JSC)
- destroyAllWrapperCaches();
-#endif
-
// Currently we believe that Document can never outlive the parser.
// Although the Document may be replaced synchronously, DocumentParsers
// generally keep at least one reference to an Element which would in turn
@@ -642,41 +580,74 @@ Document::~Document()
m_implementation->ownerDocumentDestroyed();
}
-MediaQueryMatcher* Document::mediaQueryMatcher()
+void Document::removedLastRef()
{
- if (!m_mediaQueryMatcher)
- m_mediaQueryMatcher = MediaQueryMatcher::create(this);
- return m_mediaQueryMatcher.get();
-}
+ ASSERT(!m_deletionHasBegun);
+ if (m_guardRefCount) {
+ // If removing a child removes the last self-only ref, we don't
+ // want the scope to be destructed until after
+ // removeAllChildren returns, so we guard ourselves with an
+ // extra self-only ref.
+ guardRef();
-#if USE(JSC)
-Document::JSWrapperCache* Document::createWrapperCache(DOMWrapperWorld* world)
-{
- JSWrapperCache* wrapperCache = new JSWrapperCache;
- m_wrapperCacheMap.set(world, wrapperCache);
- if (world->isNormal()) {
- ASSERT(!m_normalWorldWrapperCache);
- m_normalWorldWrapperCache = wrapperCache;
+ // We must make sure not to be retaining any of our children through
+ // these extra pointers or we will create a reference cycle.
+ m_docType = 0;
+ m_focusedNode = 0;
+ m_hoverNode = 0;
+ m_activeNode = 0;
+ m_titleElement = 0;
+ m_documentElement = 0;
+#if ENABLE(FULLSCREEN_API)
+ m_fullScreenElement = 0;
+#endif
+ m_styleSelector.clear();
+ m_styleSheets.clear();
+ m_elemSheet.clear();
+ m_mappedElementSheet.clear();
+ m_pageUserSheet.clear();
+ m_pageGroupUserSheets.clear();
+
+ // removeAllChildren() doesn't always unregister IDs,
+ // so tear down scope information upfront to avoid having stale references in the map.
+ destroyTreeScopeData();
+ removeAllChildren();
+
+ m_markers->detach();
+
+ detachParser();
+
+ m_cssCanvasElements.clear();
+
+#if ENABLE(REQUEST_ANIMATION_FRAME)
+ // FIXME: consider using ActiveDOMObject.
+ m_scriptedAnimationController = 0;
+#endif
+
+#ifndef NDEBUG
+ m_inRemovedLastRefFunction = false;
+#endif
+
+ guardDeref();
+ } else {
+#ifndef NDEBUG
+ m_deletionHasBegun = true;
+#endif
+ delete this;
}
- world->didCreateWrapperCache(this);
- return wrapperCache;
}
-void Document::destroyWrapperCache(DOMWrapperWorld* world)
+Element* Document::getElementById(const AtomicString& id) const
{
- Document::JSWrapperCache* wrappers = wrapperCacheMap().take(world);
- ASSERT(wrappers);
- delete wrappers;
- world->didDestroyWrapperCache(this);
+ return TreeScope::getElementById(id);
}
-void Document::destroyAllWrapperCaches()
+MediaQueryMatcher* Document::mediaQueryMatcher()
{
- JSWrapperCacheMap& wrapperCacheMap = this->wrapperCacheMap();
- while (!wrapperCacheMap.isEmpty())
- destroyWrapperCache(wrapperCacheMap.begin()->first);
+ if (!m_mediaQueryMatcher)
+ m_mediaQueryMatcher = MediaQueryMatcher::create(this);
+ return m_mediaQueryMatcher.get();
}
-#endif
void Document::setCompatibilityMode(CompatibilityMode mode)
{
@@ -718,6 +689,7 @@ void Document::setDocType(PassRefPtr<DocumentType> docType)
ASSERT(!m_docType || !docType);
m_docType = docType;
if (m_docType)
+<<<<<<< HEAD
m_docType->setDocument(this);
#ifdef ANDROID_META_SUPPORT
if (m_docType && !ownerElement()
@@ -729,6 +701,9 @@ void Document::setDocType(PassRefPtr<DocumentType> docType)
PlatformBridge::updateViewport(frameView);
}
#endif
+=======
+ m_docType->setTreeScope(this);
+>>>>>>> WebKit.org at r84325
}
DOMImplementation* Document::implementation()
@@ -740,7 +715,7 @@ DOMImplementation* Document::implementation()
void Document::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
{
- ContainerNode::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
+ TreeScope::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
// Invalidate the document element we have cached in case it was replaced.
m_documentElement = 0;
@@ -958,7 +933,7 @@ PassRefPtr<Node> Document::adoptNode(PassRefPtr<Node> source, ExceptionCode& ec)
source->parentNode()->removeChild(source.get(), ec);
}
- source->setDocumentRecursively(this);
+ source->setTreeScopeRecursively(this);
return source;
}
@@ -1033,13 +1008,6 @@ PassRefPtr<Element> Document::createElementNS(const String& namespaceURI, const
return createElement(qName, false);
}
-Element* Document::getElementById(const AtomicString& elementId) const
-{
- if (elementId.isEmpty())
- return 0;
- return m_elementsById.getElementById(elementId.impl(), this);
-}
-
String Document::readyState() const
{
DEFINE_STATIC_LOCAL(const String, loading, ("loading"));
@@ -1266,42 +1234,15 @@ PassRefPtr<Range> Document::caretRangeFromPoint(int x, int y)
return Range::create(this, rangeCompliantPosition, rangeCompliantPosition);
}
-void Document::addElementById(const AtomicString& elementId, Element* element)
-{
- m_elementsById.add(elementId.impl(), element);
-}
-
-void Document::removeElementById(const AtomicString& elementId, Element* element)
-{
- m_elementsById.remove(elementId.impl(), element);
-}
-
-Element* Document::getElementByAccessKey(const String& key) const
-{
- if (key.isEmpty())
- return 0;
- if (!m_accessKeyMapValid) {
- for (Node* n = firstChild(); n; n = n->traverseNextNode()) {
- if (!n->isElementNode())
- continue;
- Element* element = static_cast<Element*>(n);
- const AtomicString& accessKey = element->getAttribute(accesskeyAttr);
- if (!accessKey.isEmpty())
- m_elementsByAccessKey.set(accessKey.impl(), element);
- }
- m_accessKeyMapValid = true;
- }
- return m_elementsByAccessKey.get(key.impl());
-}
-
/*
* Performs three operations:
* 1. Convert control characters to spaces
* 2. Trim leading and trailing spaces
* 3. Collapse internal whitespace.
*/
-static inline String canonicalizedTitle(Document* document, const String& title)
+static inline StringWithDirection canonicalizedTitle(Document* document, const StringWithDirection& titleWithDirection)
{
+ const String& title = titleWithDirection.string();
const UChar* characters = title.characters();
unsigned length = title.length();
unsigned i;
@@ -1317,7 +1258,7 @@ static inline String canonicalizedTitle(Document* document, const String& title)
}
if (i == length)
- return "";
+ return StringWithDirection();
// Replace control characters with spaces, and backslashes with currency symbols, and collapse whitespace.
bool previousCharWasWS = false;
@@ -1342,17 +1283,17 @@ static inline String canonicalizedTitle(Document* document, const String& title)
}
if (!builderIndex && buffer[builderIndex] == ' ')
- return "";
+ return StringWithDirection();
buffer.shrink(builderIndex + 1);
// Replace the backslashes with currency symbols if the encoding requires it.
document->displayBufferModifiedByEncoding(buffer.characters(), buffer.length());
- return String::adopt(buffer);
+ return StringWithDirection(String::adopt(buffer), titleWithDirection.direction());
}
-void Document::updateTitle(const String& title)
+void Document::updateTitle(const StringWithDirection& title)
{
if (m_rawTitle == title)
return;
@@ -1378,16 +1319,17 @@ void Document::setTitle(const String& title)
}
}
- updateTitle(title);
+ // The DOM API has no method of specifying direction, so assume LTR.
+ updateTitle(StringWithDirection(title, LTR));
if (m_titleElement) {
ASSERT(m_titleElement->hasTagName(titleTag));
if (m_titleElement->hasTagName(titleTag))
- static_cast<HTMLTitleElement*>(m_titleElement.get())->setText(m_title);
+ static_cast<HTMLTitleElement*>(m_titleElement.get())->setText(title);
}
}
-void Document::setTitleElement(const String& title, Element* titleElement)
+void Document::setTitleElement(const StringWithDirection& title, Element* titleElement)
{
if (titleElement != m_titleElement) {
if (m_titleElement || m_titleSetExplicitly)
@@ -1412,13 +1354,13 @@ void Document::removeTitle(Element* titleElement)
for (Node* e = headElement->firstChild(); e; e = e->nextSibling())
if (e->hasTagName(titleTag)) {
HTMLTitleElement* titleElement = static_cast<HTMLTitleElement*>(e);
- setTitleElement(titleElement->text(), titleElement);
+ setTitleElement(titleElement->textWithDirection(), titleElement);
break;
}
}
if (!m_titleElement)
- updateTitle("");
+ updateTitle(StringWithDirection());
}
String Document::nodeName() const
@@ -1489,10 +1431,7 @@ void Document::scheduleStyleRecalc()
documentsThatNeedStyleRecalc->add(this);
// FIXME: Why on earth is this here? This is clearly misplaced.
- if (m_accessKeyMapValid) {
- m_accessKeyMapValid = false;
- m_elementsByAccessKey.clear();
- }
+ invalidateAccessKeyMap();
m_styleRecalcTimer.startOneShot(0);
}
@@ -1542,17 +1481,24 @@ void Document::recalcStyle(StyleChange change)
m_inStyleRecalc = true;
suspendPostAttachCallbacks();
RenderWidget::suspendWidgetHierarchyUpdates();
- if (view())
- view()->pauseScheduledEvents();
+<<<<<<< HEAD
#ifdef ANDROID_INSTRUMENT
android::TimeCounter::start(android::TimeCounter::CalculateStyleTimeCounter);
#endif
+=======
+ RefPtr<FrameView> frameView = view();
+ if (frameView) {
+ frameView->pauseScheduledEvents();
+ frameView->beginDeferredRepaints();
+ }
+
+>>>>>>> WebKit.org at r84325
ASSERT(!renderer() || renderArena());
if (!renderer() || !renderArena())
goto bail_out;
-
+
if (m_pendingStyleRecalcShouldForce)
change = Force;
@@ -1596,8 +1542,10 @@ bail_out:
m_usesLinkRules = m_styleSelector->usesLinkRules();
}
- if (view())
- view()->resumeScheduledEvents();
+ if (frameView) {
+ frameView->resumeScheduledEvents();
+ frameView->endDeferredRepaints();
+ }
RenderWidget::resumeWidgetHierarchyUpdates();
resumePostAttachCallbacks();
m_inStyleRecalc = false;
@@ -1794,7 +1742,7 @@ void Document::attach()
RenderObject* render = renderer();
setRenderer(0);
- ContainerNode::attach();
+ TreeScope::attach();
setRenderer(render);
}
@@ -1806,6 +1754,7 @@ void Document::detach()
clearAXObjectCache();
stopActiveDOMObjects();
+ m_eventQueue->cancelQueuedEvents();
#if ENABLE(REQUEST_ANIMATION_FRAME)
// FIXME: consider using ActiveDOMObject.
@@ -1840,7 +1789,7 @@ void Document::detach()
m_focusedNode = 0;
m_activeNode = 0;
- ContainerNode::detach();
+ TreeScope::detach();
unscheduleStyleRecalc();
@@ -2725,7 +2674,8 @@ void Document::processHttpEquiv(const String& equiv, const String& content)
frame->domWindow()->console()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, consoleMessage, 1, String());
}
}
- }
+ } else if (equalIgnoringCase(equiv, "x-webkit-csp"))
+ contentSecurityPolicy()->didReceiveHeader(content);
}
// Though isspace() considers \t and \v to be whitespace, Win IE doesn't.
@@ -2821,7 +2771,7 @@ MouseEventWithHitTestResults Document::prepareMouseEvent(const HitTestRequest& r
}
// DOM Section 1.1.1
-bool Document::childTypeAllowed(NodeType type)
+bool Document::childTypeAllowed(NodeType type) const
{
switch (type) {
case ATTRIBUTE_NODE:
@@ -3957,33 +3907,6 @@ bool Document::parseQualifiedName(const String& qualifiedName, String& prefix, S
return true;
}
-void Document::addImageMap(HTMLMapElement* imageMap)
-{
- AtomicStringImpl* name = imageMap->getName().impl();
- if (!name)
- return;
- m_imageMapsByName.add(name, imageMap);
-}
-
-void Document::removeImageMap(HTMLMapElement* imageMap)
-{
- AtomicStringImpl* name = imageMap->getName().impl();
- if (!name)
- return;
- m_imageMapsByName.remove(name, imageMap);
-}
-
-HTMLMapElement* Document::getImageMap(const String& url) const
-{
- if (url.isNull())
- return 0;
- size_t hashPos = url.find('#');
- String name = (hashPos == notFound ? url : url.substring(hashPos + 1)).impl();
- if (isHTMLDocument())
- return static_cast<HTMLMapElement*>(m_imageMapsByName.getElementByLowercasedMapName(AtomicString(name.lower()).impl(), this));
- return static_cast<HTMLMapElement*>(m_imageMapsByName.getElementByMapName(AtomicString(name).impl(), this));
-}
-
void Document::setDecoder(PassRefPtr<TextResourceDecoder> decoder)
{
m_decoder = decoder;
@@ -4832,29 +4755,6 @@ void Document::resumeScriptedAnimationControllerCallbacks()
#endif
}
-Element* Document::findAnchor(const String& name)
-{
- if (name.isEmpty())
- return 0;
- if (Element* element = getElementById(name))
- return element;
- for (Node* node = this; node; node = node->traverseNextNode()) {
- if (node->hasTagName(aTag)) {
- HTMLAnchorElement* anchor = static_cast<HTMLAnchorElement*>(node);
- if (inQuirksMode()) {
- // Quirks mode, case insensitive comparison of names.
- if (equalIgnoringCase(anchor->name(), name))
- return anchor;
- } else {
- // Strict mode, names need to match exactly.
- if (anchor->name() == name)
- return anchor;
- }
- }
- }
- return 0;
-}
-
String Document::displayStringModifiedByEncoding(const String& str) const
{
if (m_decoder)
@@ -4977,7 +4877,6 @@ void Document::webkitWillEnterFullScreenForElement(Element* element)
ASSERT(page() && page()->settings()->fullScreenEnabled());
m_fullScreenElement = element;
- m_isFullScreen = true;
if (m_fullScreenElement != documentElement())
m_fullScreenElement->detach();
@@ -4988,8 +4887,8 @@ void Document::webkitWillEnterFullScreenForElement(Element* element)
m_fullScreenRenderer->setAnimating(true);
#if USE(ACCELERATED_COMPOSITING)
view()->updateCompositingLayers();
- ASSERT(m_fullScreenRenderer->layer()->backing());
- page()->chrome()->client()->setRootFullScreenLayer(m_fullScreenRenderer->layer()->backing()->graphicsLayer());
+ if (m_fullScreenRenderer->layer()->isComposited())
+ page()->chrome()->client()->setRootFullScreenLayer(m_fullScreenRenderer->layer()->backing()->graphicsLayer());
#endif
}
}
@@ -5000,7 +4899,6 @@ void Document::webkitDidEnterFullScreenForElement(Element*)
m_fullScreenRenderer->setAnimating(false);
#if USE(ACCELERATED_COMPOSITING)
view()->updateCompositingLayers();
- ASSERT(!m_fullScreenRenderer->layer()->backing());
page()->chrome()->client()->setRootFullScreenLayer(0);
#endif
}
@@ -5011,18 +4909,16 @@ void Document::webkitWillExitFullScreenForElement(Element*)
{
if (m_fullScreenRenderer) {
m_fullScreenRenderer->setAnimating(true);
- m_fullScreenRenderer->setAnimating(true);
#if USE(ACCELERATED_COMPOSITING)
view()->updateCompositingLayers();
- ASSERT(m_fullScreenRenderer->layer()->backing());
- page()->chrome()->client()->setRootFullScreenLayer(m_fullScreenRenderer->layer()->backing()->graphicsLayer());
+ if (m_fullScreenRenderer->layer()->isComposited())
+ page()->chrome()->client()->setRootFullScreenLayer(m_fullScreenRenderer->layer()->backing()->graphicsLayer());
#endif
}
}
void Document::webkitDidExitFullScreenForElement(Element*)
{
- m_isFullScreen = false;
m_areKeysEnabledInFullScreen = false;
if (m_fullScreenRenderer)
@@ -5030,7 +4926,8 @@ void Document::webkitDidExitFullScreenForElement(Element*)
if (m_fullScreenElement != documentElement())
m_fullScreenElement->detach();
-
+
+ m_fullScreenElement = 0;
setFullScreenRenderer(0);
#if USE(ACCELERATED_COMPOSITING)
page()->chrome()->client()->setRootFullScreenLayer(0);
@@ -5149,34 +5046,4 @@ PassRefPtr<TouchList> Document::createTouchList(ExceptionCode&) const
}
#endif
-static bool hasHeadSibling(const Document* document)
-{
- Node* de = document->documentElement();
- if (!de)
- return false;
-
- for (Node* i = de->firstChild(); i; i = i->nextSibling()) {
- // A child of the document element which is rather than <head> is
- // typically visible and FOUC safe. So we return true here.
- if (!i->hasTagName(headTag))
- return true;
- }
-
- return false;
-}
-
-bool Document::mayCauseFlashOfUnstyledContent() const
-{
- // Some kind of FOUC is caused by a repaint request before page's <body> arrival
- // because page authors often give background styles to <body>, not to <html>.
- // (And these styles are unavailable before <style> or <link> is given.)
- // This functions is used for checking such possibility of FOUCs.
- // Note that the implementation considers only empty or <head> only contents as a FOUC cause
- // rather than missing <body>, because non-HTML document like SVG and arbitrary XML from foreign namespace
- // should be painted even if there is no <body>.
- if (didLayoutWithPendingStylesheets())
- return true;
- return !hasHeadSibling(this);
-}
-
} // namespace WebCore