Merge from Chromium at DEPS revision r213371
This commit was generated by merge_to_master.py.
Change-Id: I03fae1c1dae6e5de12e56e0a6c3780252291bfae
diff --git a/Source/core/dom/CheckedRadioButtons.cpp b/Source/core/dom/CheckedRadioButtons.cpp
index a628b43..d8d7a46 100644
--- a/Source/core/dom/CheckedRadioButtons.cpp
+++ b/Source/core/dom/CheckedRadioButtons.cpp
@@ -260,7 +260,7 @@
if (it->value->isEmpty()) {
// FIXME: We may skip deallocating the empty RadioButtonGroup for
// performance improvement. If we do so, we need to change the key type
- // of m_nameToGroupMap from AtomicStringImpl* to RefPtr<AtomicStringImpl>.
+ // of m_nameToGroupMap from StringImpl* to AtomicString.
m_nameToGroupMap->remove(it);
if (m_nameToGroupMap->isEmpty())
m_nameToGroupMap.clear();
diff --git a/Source/core/dom/CheckedRadioButtons.h b/Source/core/dom/CheckedRadioButtons.h
index 32bb5fe..6a1585b 100644
--- a/Source/core/dom/CheckedRadioButtons.h
+++ b/Source/core/dom/CheckedRadioButtons.h
@@ -24,6 +24,7 @@
#include "wtf/Forward.h"
#include "wtf/HashMap.h"
#include "wtf/OwnPtr.h"
+#include "wtf/text/StringHash.h"
namespace WebCore {
@@ -44,7 +45,7 @@
bool isInRequiredGroup(HTMLInputElement*) const;
private:
- typedef HashMap<AtomicStringImpl*, OwnPtr<RadioButtonGroup> > NameToGroupMap;
+ typedef HashMap<StringImpl*, OwnPtr<RadioButtonGroup> > NameToGroupMap;
OwnPtr<NameToGroupMap> m_nameToGroupMap;
};
diff --git a/Source/core/dom/CustomElement.cpp b/Source/core/dom/CustomElement.cpp
new file mode 100644
index 0000000..de0b688
--- /dev/null
+++ b/Source/core/dom/CustomElement.cpp
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Google Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/dom/CustomElement.h"
+
+#include "core/dom/CustomElementCallbackScheduler.h"
+#include "core/dom/CustomElementRegistrationContext.h"
+#include "core/dom/Element.h"
+
+namespace WebCore {
+
+void CustomElement::define(Element* element, PassRefPtr<CustomElementDefinition> passDefinition)
+{
+ RefPtr<CustomElementDefinition> definition(passDefinition);
+ element->setCustomElementState(Element::Defined);
+ definitions().add(element, definition);
+ CustomElementCallbackScheduler::scheduleCreatedCallback(definition->callbacks(), element);
+}
+
+void CustomElement::attributeDidChange(Element* element, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue)
+{
+ ASSERT(element->customElementState() == Element::Upgraded);
+ CustomElementCallbackScheduler::scheduleAttributeChangedCallback(definitions().get(element)->callbacks(), element, name, oldValue, newValue);
+}
+
+void CustomElement::didEnterDocument(Element* element)
+{
+ ASSERT(element->customElementState() == Element::Upgraded);
+ CustomElementCallbackScheduler::scheduleEnteredDocumentCallback(definitions().get(element)->callbacks(), element);
+}
+
+void CustomElement::didLeaveDocument(Element* element)
+{
+ ASSERT(element->customElementState() == Element::Upgraded);
+ CustomElementCallbackScheduler::scheduleLeftDocumentCallback(definitions().get(element)->callbacks(), element);
+}
+
+void CustomElement::wasDestroyed(Element* element)
+{
+ definitions().remove(element);
+
+ // FIXME: Elements should only depend on their document's
+ // registration context at creation; maintain a mapping to
+ // registration context for upgrade candidates.
+ if (element->document() && element->document()->registrationContext())
+ element->document()->registrationContext()->customElementWasDestroyed(element);
+}
+
+void CustomElement::DefinitionMap::add(Element* element, PassRefPtr<CustomElementDefinition> definition)
+{
+ ASSERT(definition.get());
+ DefinitionMap::ElementDefinitionHashMap::AddResult result = m_definitions.add(element, definition);
+ ASSERT(result.isNewEntry);
+}
+
+void CustomElement::DefinitionMap::remove(Element* element)
+{
+ m_definitions.remove(element);
+}
+
+CustomElementDefinition* CustomElement::DefinitionMap::get(Element* element)
+{
+ DefinitionMap::ElementDefinitionHashMap::const_iterator it = m_definitions.find(element);
+ ASSERT(it != m_definitions.end());
+ return it->value.get();
+}
+
+CustomElement::DefinitionMap& CustomElement::definitions()
+{
+ DEFINE_STATIC_LOCAL(DefinitionMap, definitionMap, ());
+ return definitionMap;
+}
+
+} // namespace WebCore
diff --git a/Source/core/dom/CustomElement.h b/Source/core/dom/CustomElement.h
new file mode 100644
index 0000000..21bc28c
--- /dev/null
+++ b/Source/core/dom/CustomElement.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Google Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CustomElement_h
+#define CustomElement_h
+
+#include "core/dom/CustomElementDefinition.h"
+#include "wtf/HashMap.h"
+#include "wtf/Noncopyable.h"
+#include "wtf/PassRefPtr.h"
+#include "wtf/RefPtr.h"
+#include "wtf/text/AtomicString.h"
+
+namespace WebCore {
+
+class Element;
+
+class CustomElement {
+public:
+ static void define(Element*, PassRefPtr<CustomElementDefinition>);
+ static void attributeDidChange(Element*, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue);
+ static void didEnterDocument(Element*);
+ static void didLeaveDocument(Element*);
+ static void wasDestroyed(Element*);
+
+private:
+ CustomElement();
+
+ class DefinitionMap {
+ WTF_MAKE_NONCOPYABLE(DefinitionMap);
+ public:
+ DefinitionMap() { }
+ ~DefinitionMap() { }
+
+ void add(Element*, PassRefPtr<CustomElementDefinition>);
+ void remove(Element*);
+ CustomElementDefinition* get(Element*);
+
+ private:
+ typedef HashMap<Element*, RefPtr<CustomElementDefinition> > ElementDefinitionHashMap;
+ ElementDefinitionHashMap m_definitions;
+ };
+
+ static DefinitionMap& definitions();
+};
+
+}
+
+#endif // CustomElement_h
diff --git a/Source/core/dom/CustomElementRegistrationContext.cpp b/Source/core/dom/CustomElementRegistrationContext.cpp
index 4ed6abf..c3a0cad 100644
--- a/Source/core/dom/CustomElementRegistrationContext.cpp
+++ b/Source/core/dom/CustomElementRegistrationContext.cpp
@@ -34,7 +34,7 @@
#include "HTMLNames.h"
#include "MathMLNames.h"
#include "SVGNames.h"
-#include "core/dom/CustomElementCallbackScheduler.h"
+#include "core/dom/CustomElement.h"
#include "core/dom/CustomElementDefinition.h"
#include "core/dom/CustomElementRegistry.h"
#include "core/dom/CustomElementUpgradeCandidateMap.h"
@@ -56,10 +56,6 @@
virtual PassRefPtr<Element> createCustomTagElement(Document*, const QualifiedName&) OVERRIDE;
virtual void didGiveTypeExtension(Element*) OVERRIDE { }
-
- virtual void customElementAttributeDidChange(Element*, const AtomicString&, const AtomicString&, const AtomicString&) OVERRIDE { }
- virtual void customElementDidEnterDocument(Element*) OVERRIDE { }
- virtual void customElementDidLeaveDocument(Element*) OVERRIDE { }
};
PassRefPtr<Element> NullRegistrationContext::createCustomTagElement(Document* document, const QualifiedName& tagName)
@@ -96,18 +92,13 @@
virtual PassRefPtr<Element> createCustomTagElement(Document*, const QualifiedName&) OVERRIDE;
virtual void didGiveTypeExtension(Element*) OVERRIDE;
- virtual void customElementAttributeDidChange(Element*, const AtomicString&, const AtomicString&, const AtomicString&) OVERRIDE;
- virtual void customElementDidEnterDocument(Element*) OVERRIDE;
- virtual void customElementDidLeaveDocument(Element*) OVERRIDE;
- virtual void customElementIsBeingDestroyed(Element*) OVERRIDE;
+ virtual void customElementWasDestroyed(Element*) OVERRIDE;
private:
void resolve(Element*);
void didResolveElement(CustomElementDefinition*, Element*);
void didCreateUnresolvedElement(const CustomElementDescriptor&, Element*);
- CustomElementDefinition* definitionFor(Element*) const;
-
CustomElementRegistry m_registry;
// Element creation
@@ -166,8 +157,7 @@
void ActiveRegistrationContext::didResolveElement(CustomElementDefinition* definition, Element* element)
{
- element->setCustomElementState(Element::Defined);
- CustomElementCallbackScheduler::scheduleCreatedCallback(definition->callbacks(), element);
+ CustomElement::define(element, definition);
}
void ActiveRegistrationContext::didCreateUnresolvedElement(const CustomElementDescriptor& descriptor, Element* element)
@@ -176,39 +166,10 @@
m_candidates.add(descriptor, element);
}
-CustomElementDefinition* ActiveRegistrationContext::definitionFor(Element* element) const
-{
- ASSERT(element->customElementState() == Element::Defined || element->customElementState() == Element::Upgraded);
- ASSERT(element->document()->registrationContext() == this);
- const CustomElementDescriptor& descriptor = describe(element);
- return m_registry.find(descriptor);
-}
-
-void ActiveRegistrationContext::customElementAttributeDidChange(Element* element, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue)
-{
- ASSERT(element->customElementState() == Element::Upgraded);
- CustomElementDefinition* definition = definitionFor(element);
- CustomElementCallbackScheduler::scheduleAttributeChangedCallback(definition->callbacks(), element, name, oldValue, newValue);
-}
-
-void ActiveRegistrationContext::customElementDidEnterDocument(Element* element)
-{
- ASSERT(element->customElementState() == Element::Upgraded);
- CustomElementDefinition* definition = definitionFor(element);
- CustomElementCallbackScheduler::scheduleEnteredDocumentCallback(definition->callbacks(), element);
-}
-
-void ActiveRegistrationContext::customElementDidLeaveDocument(Element* element)
-{
- ASSERT(element->customElementState() == Element::Upgraded);
- CustomElementDefinition* definition = definitionFor(element);
- CustomElementCallbackScheduler::scheduleLeftDocumentCallback(definition->callbacks(), element);
-}
-
-void ActiveRegistrationContext::customElementIsBeingDestroyed(Element* element)
+void ActiveRegistrationContext::customElementWasDestroyed(Element* element)
{
m_candidates.remove(element);
- CustomElementRegistrationContext::customElementIsBeingDestroyed(element);
+ CustomElementRegistrationContext::customElementWasDestroyed(element);
}
PassRefPtr<CustomElementRegistrationContext> CustomElementRegistrationContext::create()
@@ -276,7 +237,7 @@
element->document()->registrationContext()->didGiveTypeExtension(element);
}
-void CustomElementRegistrationContext::customElementIsBeingDestroyed(Element* element)
+void CustomElementRegistrationContext::customElementWasDestroyed(Element* element)
{
ASSERT(element->isCustomElement());
typeExtensionMap()->remove(element);
diff --git a/Source/core/dom/CustomElementRegistrationContext.h b/Source/core/dom/CustomElementRegistrationContext.h
index e909255..c0c89da 100644
--- a/Source/core/dom/CustomElementRegistrationContext.h
+++ b/Source/core/dom/CustomElementRegistrationContext.h
@@ -54,8 +54,11 @@
virtual ~CustomElementRegistrationContext() { }
// Model
+ // FIXME: Move this to CustomElementRegistry
static bool isValidTypeName(const AtomicString& type);
+ // FIXME: Move this to CustomElement
static bool isCustomTagName(const AtomicString& localName);
+ // FIXME: Privatize this when CustomElementWrapper uses the definition map.
static CustomElementDescriptor describe(Element*);
// Definitions
@@ -67,10 +70,7 @@
static void setTypeExtension(Element*, const AtomicString& type);
// Instance lifecycle
- virtual void customElementAttributeDidChange(Element*, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue) = 0;
- virtual void customElementDidEnterDocument(Element*) = 0;
- virtual void customElementDidLeaveDocument(Element*) = 0;
- virtual void customElementIsBeingDestroyed(Element*);
+ virtual void customElementWasDestroyed(Element*);
protected:
CustomElementRegistrationContext() { }
diff --git a/Source/core/dom/DecodedDataDocumentParser.cpp b/Source/core/dom/DecodedDataDocumentParser.cpp
index 2f76a28..610d44e 100644
--- a/Source/core/dom/DecodedDataDocumentParser.cpp
+++ b/Source/core/dom/DecodedDataDocumentParser.cpp
@@ -27,10 +27,58 @@
#include "core/dom/DecodedDataDocumentParser.h"
#include "core/dom/Document.h"
+#include "core/dom/Element.h"
#include "core/loader/TextResourceDecoder.h"
+#include "wtf/text/TextEncodingRegistry.h"
namespace WebCore {
+namespace {
+
+class TitleEncodingFixer {
+public:
+ explicit TitleEncodingFixer(Document* document)
+ : m_document(document)
+ , m_firstEncoding(document->decoder()->encoding())
+ {
+ }
+
+ // It's possible for the encoding of the document to change while we're decoding
+ // data. That can only occur while we're processing the <head> portion of the
+ // document. There isn't much user-visible content in the <head>, but there is
+ // the <title> element. This function detects that situation and re-decodes the
+ // document's title so that the user doesn't see an incorrectly decoded title
+ // in the title bar.
+ inline void fixTitleEncodingIfNeeded()
+ {
+ if (m_firstEncoding == m_document->decoder()->encoding())
+ return; // In the common case, the encoding doesn't change and there isn't any work to do.
+ fixTitleEncoding();
+ }
+
+private:
+ void fixTitleEncoding();
+
+ Document* m_document;
+ WTF::TextEncoding m_firstEncoding;
+};
+
+void TitleEncodingFixer::fixTitleEncoding()
+{
+ RefPtr<Element> titleElement = m_document->titleElement();
+ if (!titleElement
+ || titleElement->firstElementChild()
+ || m_firstEncoding != Latin1Encoding()
+ || !titleElement->textContent().containsOnlyLatin1())
+ return; // Either we don't have a title yet or something bizzare as happened and we give up.
+ CString originalBytes = titleElement->textContent().latin1();
+ OwnPtr<TextCodec> codec = newTextCodec(m_document->decoder()->encoding());
+ String correctlyDecodedTitle = codec->decode(originalBytes.data(), originalBytes.length(), true);
+ titleElement->setTextContent(correctlyDecodedTitle, IGNORE_EXCEPTION);
+}
+
+}
+
DecodedDataDocumentParser::DecodedDataDocumentParser(Document* document)
: DocumentParser(document)
{
@@ -41,7 +89,12 @@
if (!length)
return 0;
+ TitleEncodingFixer encodingFixer(document());
+
String decoded = document()->decoder()->decode(data, length);
+
+ encodingFixer.fixTitleEncodingIfNeeded();
+
if (decoded.isEmpty())
return 0;
diff --git a/Source/core/dom/Document.cpp b/Source/core/dom/Document.cpp
index d4b4fc7..42aaace 100644
--- a/Source/core/dom/Document.cpp
+++ b/Source/core/dom/Document.cpp
@@ -398,7 +398,6 @@
, m_inStyleRecalc(false)
, m_closeAfterStyleRecalc(false)
, m_gotoAnchorNeededAfterStylesheetsLoad(false)
- , m_pendingStyleRecalcShouldForce(false)
, m_containsValidityStyleRules(false)
, m_updateFocusAppearanceRestoresSelection(false)
, m_ignoreDestructiveWriteCount(0)
@@ -1133,7 +1132,7 @@
m_contentLanguage = language;
// Document's style depends on the content language.
- scheduleForcedStyleRecalc();
+ setNeedsStyleRecalc();
}
void Document::setXMLVersion(const String& version, ExceptionCode& ec)
@@ -1317,7 +1316,7 @@
else if (!m_titleElement) {
if (HTMLElement* headElement = head()) {
m_titleElement = createElement(titleTag, false);
- headElement->appendChild(m_titleElement, ASSERT_NO_EXCEPTION);
+ headElement->appendChild(m_titleElement, ASSERT_NO_EXCEPTION, AttachLazily);
}
}
@@ -1529,12 +1528,6 @@
return TreeWalker::create(root, whatToShow, filter);
}
-void Document::scheduleForcedStyleRecalc()
-{
- m_pendingStyleRecalcShouldForce = true;
- scheduleStyleRecalc();
-}
-
void Document::scheduleStyleRecalc()
{
if (shouldDisplaySeamlesslyWithParent()) {
@@ -1547,7 +1540,7 @@
if (m_styleRecalcTimer.isActive())
return;
- ASSERT(childNeedsStyleRecalc() || m_pendingStyleRecalcShouldForce);
+ ASSERT(needsStyleRecalc() || childNeedsStyleRecalc());
m_styleRecalcTimer.startOneShot(0);
@@ -1556,10 +1549,8 @@
void Document::unscheduleStyleRecalc()
{
- ASSERT(!childNeedsStyleRecalc());
-
+ ASSERT(!attached() || (!needsStyleRecalc() && !childNeedsStyleRecalc()));
m_styleRecalcTimer.stop();
- m_pendingStyleRecalcShouldForce = false;
}
bool Document::hasPendingStyleRecalc() const
@@ -1569,7 +1560,7 @@
bool Document::hasPendingForcedStyleRecalc() const
{
- return m_styleRecalcTimer.isActive() && m_pendingStyleRecalcShouldForce;
+ return hasPendingStyleRecalc() && styleChangeType() == SubtreeStyleChange;
}
void Document::styleRecalcTimerFired(Timer<Document>*)
@@ -1577,11 +1568,6 @@
updateStyleIfNeeded();
}
-bool Document::childNeedsAndNotInStyleRecalc()
-{
- return childNeedsStyleRecalc() && !m_inStyleRecalc;
-}
-
void Document::recalcStyle(StyleChange change)
{
// we should not enter style recalc while painting
@@ -1625,7 +1611,7 @@
if (!renderer() || !renderArena())
goto bailOut;
- if (m_pendingStyleRecalcShouldForce)
+ if (styleChangeType() == SubtreeStyleChange)
change = Force;
// Recalculating the root style (on the document) is not needed in the common case.
@@ -1655,6 +1641,11 @@
clearChildNeedsStyleRecalc();
unscheduleStyleRecalc();
+ // FIXME: SVG <use> element can schedule a recalc in the middle of an already running one.
+ // See DocumentStyleSheetCollection::updateActiveStyleSheets.
+ if (m_styleSheetCollection->needsUpdateActiveStylesheetsOnStyleRecalc())
+ setNeedsStyleRecalc();
+
m_inStyleRecalc = false;
// Pseudo element removal and similar may only work with these flags still set. Reset them after the style recalc.
@@ -1690,7 +1681,7 @@
ASSERT(isMainThread());
ASSERT(!view() || (!view()->isInLayout() && !view()->isPainting()));
- if (!m_pendingStyleRecalcShouldForce && !childNeedsStyleRecalc())
+ if (!needsStyleRecalc() && !childNeedsStyleRecalc())
return;
AnimationUpdateBlock animationUpdateBlock(m_frame ? m_frame->animation() : 0);
@@ -2012,7 +2003,7 @@
// FIXME: How is possible to not have a renderer here?
if (renderer())
renderer()->style()->setRTLOrdering(VisualOrder);
- scheduleForcedStyleRecalc();
+ setNeedsStyleRecalc();
}
PassRefPtr<DocumentParser> Document::createParser()
@@ -2044,6 +2035,7 @@
setURL(ownerDocument->url());
m_cookieURL = ownerDocument->cookieURL();
setSecurityOrigin(ownerDocument->securityOrigin());
+ InspectorInstrumentation::childDocumentOpened(this);
}
if (m_frame) {
@@ -2637,7 +2629,16 @@
parseDNSPrefetchControlHeader(content);
else if (equalIgnoringCase(equiv, "x-frame-options"))
processHttpEquivXFrameOptions(content);
- else if (equalIgnoringCase(equiv, "content-security-policy"))
+ else if (equalIgnoringCase(equiv, "content-security-policy")
+ || equalIgnoringCase(equiv, "content-security-policy-report-only")
+ || equalIgnoringCase(equiv, "x-webkit-csp")
+ || equalIgnoringCase(equiv, "x-webkit-csp-report-only"))
+ processHttpEquivContentSecurityPolicy(equiv, content);
+}
+
+void Document::processHttpEquivContentSecurityPolicy(const String& equiv, const String& content)
+{
+ if (equalIgnoringCase(equiv, "content-security-policy"))
contentSecurityPolicy()->didReceiveHeader(content, ContentSecurityPolicy::Enforce);
else if (equalIgnoringCase(equiv, "content-security-policy-report-only"))
contentSecurityPolicy()->didReceiveHeader(content, ContentSecurityPolicy::Report);
@@ -2645,6 +2646,8 @@
contentSecurityPolicy()->didReceiveHeader(content, ContentSecurityPolicy::PrefixedEnforce);
else if (equalIgnoringCase(equiv, "x-webkit-csp-report-only"))
contentSecurityPolicy()->didReceiveHeader(content, ContentSecurityPolicy::PrefixedReport);
+ else
+ ASSERT_NOT_REACHED();
}
void Document::processHttpEquivDefaultStyle(const String& content)
@@ -2995,7 +2998,7 @@
bool needsRecalc = m_styleSheetCollection->updateActiveStyleSheets(updateMode);
if (updateType >= DeferRecalcStyle) {
- scheduleForcedStyleRecalc();
+ setNeedsStyleRecalc();
return;
}
@@ -3924,7 +3927,7 @@
{
m_designMode = value;
for (Frame* frame = m_frame; frame && frame->document(); frame = frame->tree()->traverseNext(m_frame))
- frame->document()->scheduleForcedStyleRecalc();
+ frame->document()->setNeedsStyleRecalc();
}
Document::InheritedBool Document::getDesignMode() const
@@ -4077,6 +4080,11 @@
if (!m_documentTiming.domContentLoadedEventEnd)
m_documentTiming.domContentLoadedEventEnd = monotonicallyIncreasingTime();
+ // The loader's finishedParsing() method may invoke script that causes this object to
+ // be dereferenced (when this document is in an iframe and the onload causes the iframe's src to change).
+ // Keep it alive until we are done.
+ RefPtr<Document> protect(this);
+
if (RefPtr<Frame> f = frame()) {
// FrameLoader::finishedParsing() might end up calling Document::implicitClose() if all
// resource loads are complete. HTMLObjectElements can start loading their resources from
diff --git a/Source/core/dom/Document.h b/Source/core/dom/Document.h
index cfd2f8f..3c47aa6 100644
--- a/Source/core/dom/Document.h
+++ b/Source/core/dom/Document.h
@@ -482,7 +482,6 @@
PassRefPtr<Text> createEditingTextNode(const String&);
void recalcStyle(StyleChange = NoChange);
- bool childNeedsAndNotInStyleRecalc();
void updateStyleIfNeeded();
void updateStyleForNodeIfNeeded(Node*);
void updateLayout();
@@ -654,8 +653,7 @@
// Updates for :target (CSS3 selector).
void setCSSTarget(Element*);
Element* cssTarget() const { return m_cssTarget; }
-
- void scheduleForcedStyleRecalc();
+
void scheduleStyleRecalc();
void unscheduleStyleRecalc();
bool hasPendingStyleRecalc() const;
@@ -754,6 +752,7 @@
String title() const { return m_title.string(); }
void setTitle(const String&);
+ Element* titleElement() const { return m_titleElement.get(); }
void setTitleElement(const StringWithDirection&, Element* titleElement);
void removeTitle(Element* titleElement);
@@ -1112,6 +1111,7 @@
void processHttpEquivRefresh(const String& content);
void processHttpEquivSetCookie(const String& content);
void processHttpEquivXFrameOptions(const String& content);
+ void processHttpEquivContentSecurityPolicy(const String& equiv, const String& content);
Timer<Document> m_styleResolverThrowawayTimer;
double m_lastStyleResolverAccessTime;
@@ -1198,9 +1198,8 @@
bool m_visuallyOrdered;
ReadyState m_readyState;
bool m_bParsing;
-
+
Timer<Document> m_styleRecalcTimer;
- bool m_pendingStyleRecalcShouldForce;
bool m_inStyleRecalc;
bool m_closeAfterStyleRecalc;
diff --git a/Source/core/dom/DocumentOrderedMap.cpp b/Source/core/dom/DocumentOrderedMap.cpp
index 9f62cdb..76f236a 100644
--- a/Source/core/dom/DocumentOrderedMap.cpp
+++ b/Source/core/dom/DocumentOrderedMap.cpp
@@ -42,22 +42,22 @@
using namespace HTMLNames;
-inline bool keyMatchesId(AtomicStringImpl* key, Element* element)
+inline bool keyMatchesId(StringImpl* key, Element* element)
{
return element->getIdAttribute().impl() == key;
}
-inline bool keyMatchesMapName(AtomicStringImpl* key, Element* element)
+inline bool keyMatchesMapName(StringImpl* key, Element* element)
{
return element->hasTagName(mapTag) && toHTMLMapElement(element)->getName().impl() == key;
}
-inline bool keyMatchesLowercasedMapName(AtomicStringImpl* key, Element* element)
+inline bool keyMatchesLowercasedMapName(StringImpl* key, Element* element)
{
return element->hasTagName(mapTag) && toHTMLMapElement(element)->getName().lower().impl() == key;
}
-inline bool keyMatchesLabelForAttribute(AtomicStringImpl* key, Element* element)
+inline bool keyMatchesLabelForAttribute(StringImpl* key, Element* element)
{
return isHTMLLabelElement(element) && element->getAttribute(forAttr).impl() == key;
}
@@ -68,7 +68,7 @@
m_duplicateCounts.clear();
}
-void DocumentOrderedMap::add(AtomicStringImpl* key, Element* element)
+void DocumentOrderedMap::add(StringImpl* key, Element* element)
{
ASSERT(key);
ASSERT(element);
@@ -98,7 +98,7 @@
m_duplicateCounts.add(key);
}
-void DocumentOrderedMap::remove(AtomicStringImpl* key, Element* element)
+void DocumentOrderedMap::remove(StringImpl* key, Element* element)
{
ASSERT(key);
ASSERT(element);
@@ -111,8 +111,8 @@
m_duplicateCounts.remove(key);
}
-template<bool keyMatches(AtomicStringImpl*, Element*)>
-inline Element* DocumentOrderedMap::get(AtomicStringImpl* key, const TreeScope* scope) const
+template<bool keyMatches(StringImpl*, Element*)>
+inline Element* DocumentOrderedMap::get(StringImpl* key, const TreeScope* scope) const
{
ASSERT(key);
ASSERT(scope);
@@ -138,22 +138,22 @@
return 0;
}
-Element* DocumentOrderedMap::getElementById(AtomicStringImpl* key, const TreeScope* scope) const
+Element* DocumentOrderedMap::getElementById(StringImpl* key, const TreeScope* scope) const
{
return get<keyMatchesId>(key, scope);
}
-Element* DocumentOrderedMap::getElementByMapName(AtomicStringImpl* key, const TreeScope* scope) const
+Element* DocumentOrderedMap::getElementByMapName(StringImpl* key, const TreeScope* scope) const
{
return get<keyMatchesMapName>(key, scope);
}
-Element* DocumentOrderedMap::getElementByLowercasedMapName(AtomicStringImpl* key, const TreeScope* scope) const
+Element* DocumentOrderedMap::getElementByLowercasedMapName(StringImpl* key, const TreeScope* scope) const
{
return get<keyMatchesLowercasedMapName>(key, scope);
}
-Element* DocumentOrderedMap::getElementByLabelForAttribute(AtomicStringImpl* key, const TreeScope* scope) const
+Element* DocumentOrderedMap::getElementByLabelForAttribute(StringImpl* key, const TreeScope* scope) const
{
return get<keyMatchesLabelForAttribute>(key, scope);
}
diff --git a/Source/core/dom/DocumentOrderedMap.h b/Source/core/dom/DocumentOrderedMap.h
index 9fe076a..b6fc8e0 100644
--- a/Source/core/dom/DocumentOrderedMap.h
+++ b/Source/core/dom/DocumentOrderedMap.h
@@ -33,7 +33,7 @@
#include "wtf/HashCountedSet.h"
#include "wtf/HashMap.h"
-#include "wtf/text/AtomicStringImpl.h"
+#include "wtf/text/StringImpl.h"
namespace WebCore {
@@ -42,38 +42,38 @@
class DocumentOrderedMap {
public:
- void add(AtomicStringImpl*, Element*);
- void remove(AtomicStringImpl*, Element*);
+ void add(StringImpl*, Element*);
+ void remove(StringImpl*, Element*);
void clear();
- bool contains(AtomicStringImpl*) const;
- bool containsMultiple(AtomicStringImpl*) const;
+ bool contains(StringImpl*) const;
+ bool containsMultiple(StringImpl*) const;
// concrete instantiations of the get<>() method template
- Element* getElementById(AtomicStringImpl*, const TreeScope*) const;
- Element* getElementByMapName(AtomicStringImpl*, const TreeScope*) const;
- Element* getElementByLowercasedMapName(AtomicStringImpl*, const TreeScope*) const;
- Element* getElementByLabelForAttribute(AtomicStringImpl*, const TreeScope*) const;
+ Element* getElementById(StringImpl*, const TreeScope*) const;
+ Element* getElementByMapName(StringImpl*, const TreeScope*) const;
+ Element* getElementByLowercasedMapName(StringImpl*, const TreeScope*) const;
+ Element* getElementByLabelForAttribute(StringImpl*, const TreeScope*) const;
void checkConsistency() const;
private:
- template<bool keyMatches(AtomicStringImpl*, Element*)> Element* get(AtomicStringImpl*, const TreeScope*) const;
+ template<bool keyMatches(StringImpl*, Element*)> Element* get(StringImpl*, const TreeScope*) const;
- typedef HashMap<AtomicStringImpl*, Element*> Map;
+ typedef HashMap<StringImpl*, 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;
+ mutable HashCountedSet<StringImpl*> m_duplicateCounts;
};
-inline bool DocumentOrderedMap::contains(AtomicStringImpl* id) const
+inline bool DocumentOrderedMap::contains(StringImpl* id) const
{
return m_map.contains(id) || m_duplicateCounts.contains(id);
}
-inline bool DocumentOrderedMap::containsMultiple(AtomicStringImpl* id) const
+inline bool DocumentOrderedMap::containsMultiple(StringImpl* id) const
{
return m_duplicateCounts.contains(id);
}
diff --git a/Source/core/dom/DocumentStyleSheetCollection.cpp b/Source/core/dom/DocumentStyleSheetCollection.cpp
index e2088d8..d45931c 100644
--- a/Source/core/dom/DocumentStyleSheetCollection.cpp
+++ b/Source/core/dom/DocumentStyleSheetCollection.cpp
@@ -254,7 +254,6 @@
// https://bugs.webkit.org/show_bug.cgi?id=54344
// FIXME: This should be fixed in SVG and the call site replaced by ASSERT(!m_inStyleRecalc).
m_needsUpdateActiveStylesheetsOnStyleRecalc = true;
- m_document->scheduleForcedStyleRecalc();
return false;
}
diff --git a/Source/core/dom/Element.cpp b/Source/core/dom/Element.cpp
index 7affb64..dc64b8d 100644
--- a/Source/core/dom/Element.cpp
+++ b/Source/core/dom/Element.cpp
@@ -33,6 +33,7 @@
#include "SVGNames.h"
#include "XMLNames.h"
#include "core/accessibility/AXObjectCache.h"
+#include "core/animation/DocumentTimeline.h"
#include "core/css/CSSParser.h"
#include "core/css/CSSStyleSheet.h"
#include "core/css/CSSValuePool.h"
@@ -43,6 +44,7 @@
#include "core/dom/Attribute.h"
#include "core/dom/ClientRect.h"
#include "core/dom/ClientRectList.h"
+#include "core/dom/CustomElement.h"
#include "core/dom/CustomElementRegistrationContext.h"
#include "core/dom/DatasetDOMStringMap.h"
#include "core/dom/Document.h"
@@ -208,8 +210,8 @@
data->clearShadow();
}
- if (isCustomElement() && document() && document()->registrationContext())
- document()->registrationContext()->customElementIsBeingDestroyed(this);
+ if (isCustomElement())
+ CustomElement::wasDestroyed(this);
if (hasSyntheticAttrChildNodes())
detachAllAttrNodesFromElement();
@@ -373,34 +375,31 @@
return rareData->attributeMap();
}
-void Element::addActiveAnimation(Animation* animation)
+ActiveAnimations* Element::activeAnimations() const
{
- ElementRareData* rareData = ensureElementRareData();
- if (!rareData->activeAnimations())
- rareData->setActiveAnimations(adoptPtr(new Vector<Animation*>));
- rareData->activeAnimations()->append(animation);
+ if (hasActiveAnimations())
+ return elementRareData()->activeAnimations();
+ return 0;
}
-void Element::removeActiveAnimation(Animation* animation)
+ActiveAnimations* Element::ensureActiveAnimations()
{
- ElementRareData* rareData = elementRareData();
- ASSERT(rareData);
- size_t position = rareData->activeAnimations()->find(animation);
- ASSERT(position != notFound);
- rareData->activeAnimations()->remove(position);
+ ElementRareData* rareData = ensureElementRareData();
+ if (!elementRareData()->activeAnimations())
+ rareData->setActiveAnimations(adoptPtr(new ActiveAnimations()));
+ return rareData->activeAnimations();
}
bool Element::hasActiveAnimations() const
{
- return hasRareData() && elementRareData()->activeAnimations()
- && elementRareData()->activeAnimations()->size();
-}
+ if (!RuntimeEnabledFeatures::webAnimationsEnabled())
+ return false;
-Vector<Animation*>* Element::activeAnimations() const
-{
- if (!elementRareData())
- return 0;
- return elementRareData()->activeAnimations();
+ if (!hasRareData())
+ return false;
+
+ ActiveAnimations* activeAnimations = elementRareData()->activeAnimations();
+ return activeAnimations && !activeAnimations->isEmpty();
}
Node::NodeType Element::nodeType() const
@@ -1200,37 +1199,6 @@
return RenderObject::createObject(this, style);
}
-#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
-bool Element::isDateTimeEditElement() const
-{
- return false;
-}
-
-bool Element::isDateTimeFieldElement() const
-{
- return false;
-}
-
-bool Element::isPickerIndicatorElement() const
-{
- return false;
-}
-#endif
-
-bool Element::isClearButtonElement() const
-{
- return false;
-}
-
-bool Element::wasChangedSinceLastFormControlChangeEvent() const
-{
- return false;
-}
-
-void Element::setChangedSinceLastFormControlChangeEvent(bool)
-{
-}
-
bool Element::isInert() const
{
const Element* dialog = document()->activeModalDialog();
@@ -1265,7 +1233,7 @@
return InsertionDone;
if (isUpgradedCustomElement())
- document()->registrationContext()->customElementDidEnterDocument(this);
+ CustomElement::didEnterDocument(this);
const AtomicString& idValue = getIdAttribute();
if (!idValue.isNull())
@@ -1326,14 +1294,14 @@
if (hasPendingResources())
document()->accessSVGExtensions()->removeElementFromPendingResources(this);
- if (isUpgradedCustomElement() && document()->registrationContext())
- document()->registrationContext()->customElementDidLeaveDocument(this);
+ if (isUpgradedCustomElement())
+ CustomElement::didLeaveDocument(this);
}
}
void Element::createRendererIfNeeded(const AttachContext& context)
{
- NodeRenderingContext(this, context).createRendererForElementIfNeeded();
+ NodeRenderingContext(this, context.resolvedStyle).createRendererForElementIfNeeded();
}
void Element::attach(const AttachContext& context)
@@ -1464,12 +1432,12 @@
willRecalcStyle(change);
// Ref currentStyle in case it would otherwise be deleted when setting the new style in the renderer.
- RefPtr<RenderStyle> currentStyle(renderStyle());
- bool hasParentStyle = parentNodeForRenderingAndStyle() ? static_cast<bool>(parentNodeForRenderingAndStyle()->renderStyle()) : false;
+ RefPtr<RenderStyle> currentStyle = renderStyle();
+ bool hasParentStyle = static_cast<bool>(parentRenderStyle());
bool hasDirectAdjacentRules = childrenAffectedByDirectAdjacentRules();
bool hasIndirectAdjacentRules = childrenAffectedByForwardPositionalRules();
- if ((change > NoChange || needsStyleRecalc())) {
+ if (change > NoChange || needsStyleRecalc()) {
if (hasRareData())
elementRareData()->resetComputedStyle();
}
@@ -1528,11 +1496,12 @@
}
StyleResolverParentPusher parentPusher(this);
- // FIXME: This does not care about sibling combinators. Will be necessary in XBL2 world.
if (ElementShadow* shadow = this->shadow()) {
- if (shouldRecalcStyle(change, shadow)) {
- parentPusher.push();
- shadow->recalcStyle(change);
+ for (ShadowRoot* root = shadow->youngestShadowRoot(); root; root = root->olderShadowRoot()) {
+ if (shouldRecalcStyle(change, root)) {
+ parentPusher.push();
+ root->recalcStyle(change);
+ }
}
}
@@ -1673,7 +1642,7 @@
return false;
}
-static void checkForEmptyStyleChange(Element* element, RenderStyle* style)
+static void inline checkForEmptyStyleChange(Element* element, RenderStyle* style)
{
if (!style && !element->styleAffectedByEmpty())
return;
@@ -1685,80 +1654,74 @@
static void checkForSiblingStyleChanges(Element* e, RenderStyle* style, bool finishedParsingCallback,
Node* beforeChange, Node* afterChange, int childCountDelta)
{
+ if (!e->attached() || e->document()->hasPendingForcedStyleRecalc() || e->styleChangeType() == SubtreeStyleChange)
+ return;
+
// :empty selector.
checkForEmptyStyleChange(e, style);
if (!style || (e->needsStyleRecalc() && e->childrenAffectedByPositionalRules()))
return;
- // :first-child. In the parser callback case, we don't have to check anything, since we were right the first time.
- // In the DOM case, we only need to do something if |afterChange| is not 0.
- // |afterChange| is 0 in the parser case, so it works out that we'll skip this block.
- if (e->childrenAffectedByFirstChildRules() && afterChange) {
- // Find our new first child.
- Node* newFirstChild = 0;
- for (newFirstChild = e->firstChild(); newFirstChild && !newFirstChild->isElementNode(); newFirstChild = newFirstChild->nextSibling()) {};
-
- // Find the first element node following |afterChange|
- Node* firstElementAfterInsertion = 0;
- for (firstElementAfterInsertion = afterChange;
- firstElementAfterInsertion && !firstElementAfterInsertion->isElementNode();
- firstElementAfterInsertion = firstElementAfterInsertion->nextSibling()) {};
-
- // This is the insert/append case.
- if (newFirstChild != firstElementAfterInsertion && firstElementAfterInsertion && firstElementAfterInsertion->attached() &&
- firstElementAfterInsertion->renderStyle() && firstElementAfterInsertion->renderStyle()->firstChildState())
- firstElementAfterInsertion->setNeedsStyleRecalc();
-
- // We also have to handle node removal.
- if (childCountDelta < 0 && newFirstChild == firstElementAfterInsertion && newFirstChild && (!newFirstChild->renderStyle() || !newFirstChild->renderStyle()->firstChildState()))
- newFirstChild->setNeedsStyleRecalc();
- }
-
- // :last-child. In the parser callback case, we don't have to check anything, since we were right the first time.
- // In the DOM case, we only need to do something if |afterChange| is not 0.
- if (e->childrenAffectedByLastChildRules() && beforeChange) {
- // Find our new last child.
- Node* newLastChild = 0;
- for (newLastChild = e->lastChild(); newLastChild && !newLastChild->isElementNode(); newLastChild = newLastChild->previousSibling()) {};
-
- // Find the last element node going backwards from |beforeChange|
- Node* lastElementBeforeInsertion = 0;
- for (lastElementBeforeInsertion = beforeChange;
- lastElementBeforeInsertion && !lastElementBeforeInsertion->isElementNode();
- lastElementBeforeInsertion = lastElementBeforeInsertion->previousSibling()) {};
-
- if (newLastChild != lastElementBeforeInsertion && lastElementBeforeInsertion && lastElementBeforeInsertion->attached() &&
- lastElementBeforeInsertion->renderStyle() && lastElementBeforeInsertion->renderStyle()->lastChildState())
- lastElementBeforeInsertion->setNeedsStyleRecalc();
-
- // We also have to handle node removal. The parser callback case is similar to node removal as well in that we need to change the last child
- // to match now.
- if ((childCountDelta < 0 || finishedParsingCallback) && newLastChild == lastElementBeforeInsertion && newLastChild && (!newLastChild->renderStyle() || !newLastChild->renderStyle()->lastChildState()))
- newLastChild->setNeedsStyleRecalc();
- }
-
- // The + selector. We need to invalidate the first element following the insertion point. It is the only possible element
- // that could be affected by this DOM change.
- if (e->childrenAffectedByDirectAdjacentRules() && afterChange) {
- Node* firstElementAfterInsertion = 0;
- for (firstElementAfterInsertion = afterChange;
- firstElementAfterInsertion && !firstElementAfterInsertion->isElementNode();
- firstElementAfterInsertion = firstElementAfterInsertion->nextSibling()) {};
- if (firstElementAfterInsertion && firstElementAfterInsertion->attached())
- firstElementAfterInsertion->setNeedsStyleRecalc();
- }
-
// Forward positional selectors include the ~ selector, nth-child, nth-of-type, first-of-type and only-of-type.
// Backward positional selectors include nth-last-child, nth-last-of-type, last-of-type and only-of-type.
// We have to invalidate everything following the insertion point in the forward case, and everything before the insertion point in the
// backward case.
// |afterChange| is 0 in the parser callback case, so we won't do any work for the forward case if we don't have to.
// For performance reasons we just mark the parent node as changed, since we don't want to make childrenChanged O(n^2) by crawling all our kids
- // here. recalcStyle will then force a walk of the children when it sees that this has happened.
- if ((e->childrenAffectedByForwardPositionalRules() && afterChange)
- || (e->childrenAffectedByBackwardPositionalRules() && beforeChange))
+ // here. recalcStyle will then force a walk of the children when it sees that this has happened.
+ if ((e->childrenAffectedByForwardPositionalRules() && afterChange) || (e->childrenAffectedByBackwardPositionalRules() && beforeChange)) {
e->setNeedsStyleRecalc();
+ return;
+ }
+
+ // :first-child. In the parser callback case, we don't have to check anything, since we were right the first time.
+ // In the DOM case, we only need to do something if |afterChange| is not 0.
+ // |afterChange| is 0 in the parser case, so it works out that we'll skip this block.
+ if (e->childrenAffectedByFirstChildRules() && afterChange) {
+ // Find our new first child.
+ Node* newFirstChild = e->firstElementChild();
+ RenderStyle* newFirstChildStyle = newFirstChild ? newFirstChild->renderStyle() : 0;
+
+ // Find the first element node following |afterChange|
+ Node* firstElementAfterInsertion = afterChange->isElementNode() ? afterChange : afterChange->nextElementSibling();
+ RenderStyle* firstElementAfterInsertionStyle = firstElementAfterInsertion ? firstElementAfterInsertion->renderStyle() : 0;
+
+ // This is the insert/append case.
+ if (newFirstChild != firstElementAfterInsertion && firstElementAfterInsertionStyle && firstElementAfterInsertionStyle->firstChildState())
+ firstElementAfterInsertion->setNeedsStyleRecalc();
+
+ // We also have to handle node removal.
+ if (childCountDelta < 0 && newFirstChild == firstElementAfterInsertion && newFirstChild && (!newFirstChildStyle || !newFirstChildStyle->firstChildState()))
+ newFirstChild->setNeedsStyleRecalc();
+ }
+
+ // :last-child. In the parser callback case, we don't have to check anything, since we were right the first time.
+ // In the DOM case, we only need to do something if |afterChange| is not 0.
+ if (e->childrenAffectedByLastChildRules() && beforeChange) {
+ // Find our new last child.
+ Node* newLastChild = e->lastElementChild();
+ RenderStyle* newLastChildStyle = newLastChild ? newLastChild->renderStyle() : 0;
+
+ // Find the last element node going backwards from |beforeChange|
+ Node* lastElementBeforeInsertion = beforeChange->isElementNode() ? beforeChange : beforeChange->previousElementSibling();
+ RenderStyle* lastElementBeforeInsertionStyle = lastElementBeforeInsertion ? lastElementBeforeInsertion->renderStyle() : 0;
+
+ if (newLastChild != lastElementBeforeInsertion && lastElementBeforeInsertionStyle && lastElementBeforeInsertionStyle->lastChildState())
+ lastElementBeforeInsertion->setNeedsStyleRecalc();
+
+ // We also have to handle node removal. The parser callback case is similar to node removal as well in that we need to change the last child
+ // to match now.
+ if ((childCountDelta < 0 || finishedParsingCallback) && newLastChild == lastElementBeforeInsertion && newLastChild && (!newLastChildStyle || !newLastChildStyle->lastChildState()))
+ newLastChild->setNeedsStyleRecalc();
+ }
+
+ // The + selector. We need to invalidate the first element following the insertion point. It is the only possible element
+ // that could be affected by this DOM change.
+ if (e->childrenAffectedByDirectAdjacentRules() && afterChange) {
+ if (Node* firstElementAfterInsertion = afterChange->nextElementSibling())
+ firstElementAfterInsertion->setNeedsStyleRecalc();
+ }
}
void Element::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
@@ -1769,7 +1732,7 @@
else
checkForSiblingStyleChanges(this, renderStyle(), false, beforeChange, afterChange, childCountDelta);
- if (ElementShadow * shadow = this->shadow())
+ if (ElementShadow* shadow = this->shadow())
shadow->invalidateDistribution();
}
@@ -2157,11 +2120,6 @@
return content.toString();
}
-String Element::title() const
-{
- return String();
-}
-
const AtomicString& Element::pseudo() const
{
return getAttribute(pseudoAttr);
@@ -2475,16 +2433,6 @@
return 0;
}
-bool Element::matchesReadOnlyPseudoClass() const
-{
- return false;
-}
-
-bool Element::matchesReadWritePseudoClass() const
-{
- return false;
-}
-
bool Element::webkitMatchesSelector(const String& selector, ExceptionCode& ec)
{
if (selector.isEmpty()) {
@@ -2498,11 +2446,6 @@
return selectorQuery->matches(this);
}
-bool Element::shouldAppearIndeterminate() const
-{
- return false;
-}
-
DOMTokenList* Element::classList()
{
ElementRareData* data = ensureElementRareData();
@@ -2822,7 +2765,7 @@
setNeedsStyleRecalc();
if (isUpgradedCustomElement())
- document()->registrationContext()->customElementAttributeDidChange(this, name.localName(), oldValue, newValue);
+ CustomElement::attributeDidChange(this, name.localName(), oldValue, newValue);
}
if (OwnPtr<MutationObserverInterestGroup> recipients = MutationObserverInterestGroup::createForAttributesMutation(this, name))
@@ -3096,9 +3039,9 @@
struct PresentationAttributeCacheKey {
PresentationAttributeCacheKey() : tagName(0) { }
- AtomicStringImpl* tagName;
+ StringImpl* tagName;
// Only the values need refcounting.
- Vector<pair<AtomicStringImpl*, AtomicString>, 3> attributesAndValues;
+ Vector<pair<StringImpl*, AtomicString>, 3> attributesAndValues;
};
struct PresentationAttributeCacheEntry {
@@ -3318,7 +3261,7 @@
inlineStyle->addSubresourceStyleURLs(urls, document()->elementSheet()->contents());
}
-static inline bool attributeNameSort(const pair<AtomicStringImpl*, AtomicString>& p1, const pair<AtomicStringImpl*, AtomicString>& p2)
+static inline bool attributeNameSort(const pair<StringImpl*, AtomicString>& p1, const pair<StringImpl*, AtomicString>& p2)
{
// Sort based on the attribute name pointers. It doesn't matter what the order is as long as it is always the same.
return p1.first < p2.first;
diff --git a/Source/core/dom/Element.h b/Source/core/dom/Element.h
index 35f6e17..989019c 100644
--- a/Source/core/dom/Element.h
+++ b/Source/core/dom/Element.h
@@ -37,7 +37,7 @@
namespace WebCore {
-class Animation;
+class ActiveAnimations;
class Attr;
class Attribute;
class ClientRect;
@@ -513,7 +513,7 @@
String textFromChildren();
- virtual String title() const;
+ virtual String title() const { return String(); }
const AtomicString& pseudo() const;
void setPseudo(const AtomicString&);
@@ -531,10 +531,10 @@
PseudoElement* pseudoElement(PseudoId) const;
RenderObject* pseudoElementRenderer(PseudoId) const;
- virtual bool matchesReadOnlyPseudoClass() const;
- virtual bool matchesReadWritePseudoClass() const;
+ virtual bool matchesReadOnlyPseudoClass() const { return false; }
+ virtual bool matchesReadWritePseudoClass() const { return false; }
bool webkitMatchesSelector(const String& selectors, ExceptionCode&);
- virtual bool shouldAppearIndeterminate() const;
+ virtual bool shouldAppearIndeterminate() const { return false; }
DOMTokenList* classList();
@@ -547,9 +547,9 @@
virtual bool isInputFieldSpeechButtonElement() const { return false; }
#endif
#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
- virtual bool isDateTimeEditElement() const;
- virtual bool isDateTimeFieldElement() const;
- virtual bool isPickerIndicatorElement() const;
+ virtual bool isDateTimeEditElement() const { return false; }
+ virtual bool isDateTimeFieldElement() const { return false; }
+ virtual bool isPickerIndicatorElement() const { return false; }
#endif
virtual bool isFormControlElement() const { return false; }
@@ -564,14 +564,15 @@
virtual bool isOutOfRange() const { return false; }
virtual bool isFrameElementBase() const { return false; }
virtual bool isPasswordGeneratorButtonElement() const { return false; }
- virtual bool isClearButtonElement() const;
+ virtual bool isClearButtonElement() const { return false; }
virtual bool canContainRangeEndPoint() const { return true; }
virtual const AtomicString& formControlType() const { return nullAtom; }
- virtual bool wasChangedSinceLastFormControlChangeEvent() const;
- virtual void setChangedSinceLastFormControlChangeEvent(bool);
+ // FIXME: Only HTMLInputElement uses these, they don't need to be virtual.
+ virtual bool wasChangedSinceLastFormControlChangeEvent() const { return false; }
+ virtual void setChangedSinceLastFormControlChangeEvent(bool) { }
virtual void dispatchFormControlChangeEvent() { }
// Used for disabled form elements; if true, prevents mouse events from being dispatched
@@ -622,10 +623,9 @@
IntSize savedLayerScrollOffset() const;
void setSavedLayerScrollOffset(const IntSize&);
- void addActiveAnimation(Animation*);
- void removeActiveAnimation(Animation*);
+ ActiveAnimations* activeAnimations() const;
+ ActiveAnimations* ensureActiveAnimations();
bool hasActiveAnimations() const;
- Vector<Animation*>* activeAnimations() const;
InputMethodContext* getInputContext();
diff --git a/Source/core/dom/ElementRareData.h b/Source/core/dom/ElementRareData.h
index 4b86859..117e93a 100644
--- a/Source/core/dom/ElementRareData.h
+++ b/Source/core/dom/ElementRareData.h
@@ -22,6 +22,7 @@
#ifndef ElementRareData_h
#define ElementRareData_h
+#include "core/animation/ActiveAnimations.h"
#include "core/dom/DatasetDOMStringMap.h"
#include "core/dom/NamedNodeMap.h"
#include "core/dom/NodeRareData.h"
@@ -34,7 +35,6 @@
namespace WebCore {
-class Animation;
class HTMLElement;
class ElementRareData : public NodeRareData {
@@ -128,10 +128,10 @@
IntSize savedLayerScrollOffset() const { return m_savedLayerScrollOffset; }
void setSavedLayerScrollOffset(IntSize size) { m_savedLayerScrollOffset = size; }
- Vector<Animation*>* activeAnimations() { return m_activeAnimations.get(); }
- void setActiveAnimations(PassOwnPtr<Vector<Animation*> > animations)
+ ActiveAnimations* activeAnimations() { return m_activeAnimations.get(); }
+ void setActiveAnimations(PassOwnPtr<ActiveAnimations> activeAnimations)
{
- m_activeAnimations = animations;
+ m_activeAnimations = activeAnimations;
}
bool hasPendingResources() const { return m_hasPendingResources; }
@@ -178,8 +178,7 @@
OwnPtr<ElementShadow> m_shadow;
OwnPtr<NamedNodeMap> m_attributeMap;
OwnPtr<InputMethodContext> m_inputMethodContext;
-
- OwnPtr<Vector<Animation*> > m_activeAnimations;
+ OwnPtr<ActiveAnimations> m_activeAnimations;
RefPtr<PseudoElement> m_generatedBefore;
RefPtr<PseudoElement> m_generatedAfter;
diff --git a/Source/core/dom/EventPathWalker.cpp b/Source/core/dom/EventPathWalker.cpp
index a3b9760..4c28e19 100644
--- a/Source/core/dom/EventPathWalker.cpp
+++ b/Source/core/dom/EventPathWalker.cpp
@@ -62,14 +62,14 @@
}
if (!m_node->isShadowRoot()) {
m_node = m_node->parentNode();
- if (!(m_node && m_node->isShadowRoot() && ScopeContentDistribution::assignedTo(toShadowRoot(m_node))))
+ if (!(m_node && m_node->isShadowRoot() && toShadowRoot(m_node)->insertionPoint()))
m_distributedNode = m_node;
m_isVisitingInsertionPointInReprojection = false;
return;
}
const ShadowRoot* shadowRoot = toShadowRoot(m_node);
- if (InsertionPoint* insertionPoint = ScopeContentDistribution::assignedTo(shadowRoot)) {
+ if (InsertionPoint* insertionPoint = shadowRoot->insertionPoint()) {
m_node = insertionPoint;
m_isVisitingInsertionPointInReprojection = true;
return;
diff --git a/Source/core/dom/FullscreenController.cpp b/Source/core/dom/FullscreenController.cpp
index ed63fee..c365872 100644
--- a/Source/core/dom/FullscreenController.cpp
+++ b/Source/core/dom/FullscreenController.cpp
@@ -431,7 +431,7 @@
m_fullScreenRenderer->unwrapRenderer();
m_fullScreenElement = 0;
- document()->scheduleForcedStyleRecalc();
+ document()->setNeedsStyleRecalc();
// When webkitCancelFullScreen is called, we call webkitExitFullScreen on the topDocument(). That
// means that the events will be queued there. So if we have no events here, start the timer on
diff --git a/Source/core/dom/IdTargetObserverRegistry.h b/Source/core/dom/IdTargetObserverRegistry.h
index fb04ff5..4af563a 100644
--- a/Source/core/dom/IdTargetObserverRegistry.h
+++ b/Source/core/dom/IdTargetObserverRegistry.h
@@ -30,7 +30,7 @@
#include "wtf/HashMap.h"
#include "wtf/HashSet.h"
#include "wtf/PassOwnPtr.h"
-#include "wtf/text/AtomicString.h"
+#include "wtf/text/StringHash.h"
namespace WebCore {
@@ -50,7 +50,7 @@
void notifyObserversInternal(const AtomicString& id);
typedef HashSet<IdTargetObserver*> ObserverSet;
- typedef HashMap<AtomicStringImpl*, OwnPtr<ObserverSet> > IdToObserverSetMap;
+ typedef HashMap<StringImpl*, OwnPtr<ObserverSet> > IdToObserverSetMap;
IdToObserverSetMap m_registry;
ObserverSet* m_notifyingObserversInSet;
};
diff --git a/Source/core/dom/MessagePort.cpp b/Source/core/dom/MessagePort.cpp
index 07b4eb1..be7ab66 100644
--- a/Source/core/dom/MessagePort.cpp
+++ b/Source/core/dom/MessagePort.cpp
@@ -68,7 +68,7 @@
for (unsigned int i = 0; i < ports->size(); ++i) {
MessagePort* dataPort = (*ports)[i].get();
if (dataPort == this || m_entangledChannel->isConnectedTo(dataPort)) {
- es.throwDOMException(InvalidStateError);
+ es.throwDOMException(DataCloneError);
return;
}
}
diff --git a/Source/core/dom/Node.cpp b/Source/core/dom/Node.cpp
index 8f63f06..4cdd942 100644
--- a/Source/core/dom/Node.cpp
+++ b/Source/core/dom/Node.cpp
@@ -55,7 +55,7 @@
#include "core/dom/MutationEvent.h"
#include "core/dom/NameNodeList.h"
#include "core/dom/NodeRareData.h"
-#include "core/dom/NodeRenderingContext.h"
+#include "core/dom/NodeRenderingTraversal.h"
#include "core/dom/NodeTraversal.h"
#include "core/dom/ProcessingInstruction.h"
#include "core/dom/SelectorQuery.h"
@@ -650,10 +650,14 @@
for (const Node* node = this; node; node = node->parentNode()) {
if ((node->isHTMLElement() || node->isDocumentNode()) && node->renderer()) {
+#if ENABLE(USERSELECT_ALL)
// Elements with user-select: all style are considered atomic
// therefore non editable.
if (node->renderer()->style()->userSelect() == SELECT_ALL && treatment == UserSelectAllIsAlwaysNonEditable)
return false;
+#else
+ UNUSED_PARAM(treatment);
+#endif
switch (node->renderer()->style()->userModify()) {
case READ_ONLY:
return false;
@@ -770,7 +774,7 @@
for (ContainerNode* p = parentOrShadowHostNode(); p && !p->childNeedsStyleRecalc(); p = p->parentOrShadowHostNode())
p->setChildNeedsStyleRecalc();
- if (document()->childNeedsStyleRecalc())
+ if (document()->needsStyleRecalc() || document()->childNeedsStyleRecalc())
document()->scheduleStyleRecalc();
}
@@ -1140,11 +1144,6 @@
return 0;
}
-ContainerNode* Node::parentNodeForRenderingAndStyle()
-{
- return NodeRenderingContext(this).parentNodeForRenderingAndStyle();
-}
-
RenderStyle* Node::virtualComputedStyle(PseudoId pseudoElementSpecifier)
{
return parentOrShadowHostNode() ? parentOrShadowHostNode()->computedStyle(pseudoElementSpecifier) : 0;
@@ -1656,7 +1655,7 @@
ChildListMutationScope mutation(this);
container->removeChildren();
if (!text.isEmpty())
- container->appendChild(document()->createTextNode(text), ec);
+ container->appendChild(document()->createTextNode(text), ec, AttachLazily);
return;
}
case DOCUMENT_NODE:
diff --git a/Source/core/dom/Node.h b/Source/core/dom/Node.h
index f71a14a..45db9bc 100644
--- a/Source/core/dom/Node.h
+++ b/Source/core/dom/Node.h
@@ -570,10 +570,10 @@
void reattach(const AttachContext& = AttachContext());
void lazyReattachIfAttached();
- ContainerNode* parentNodeForRenderingAndStyle();
// Wrapper for nodes that don't have a renderer, but still cache the style (like HTMLOptionElement).
RenderStyle* renderStyle() const;
+ RenderStyle* parentRenderStyle() const;
RenderStyle* computedStyle(PseudoId pseudoElementSpecifier = NOPSEUDO) { return virtualComputedStyle(pseudoElementSpecifier); }
@@ -931,9 +931,7 @@
lazyAttach(shouldSetAttached);
}
-// Need a template since ElementShadow is not a Node, but has the style recalc methods.
-template<class T>
-inline bool shouldRecalcStyle(Node::StyleChange change, const T* node)
+inline bool shouldRecalcStyle(Node::StyleChange change, const Node* node)
{
return change >= Node::Inherit || node->childNeedsStyleRecalc() || node->needsStyleRecalc();
}
diff --git a/Source/core/dom/NodeRenderStyle.h b/Source/core/dom/NodeRenderStyle.h
index 2ab78c3..a9487ab 100644
--- a/Source/core/dom/NodeRenderStyle.h
+++ b/Source/core/dom/NodeRenderStyle.h
@@ -26,6 +26,7 @@
#define NodeRenderStyle_h
#include "core/dom/Node.h"
+#include "core/dom/NodeRenderingTraversal.h"
#include "core/rendering/RenderObject.h"
#include "core/rendering/style/RenderStyle.h"
@@ -40,5 +41,11 @@
return nonRendererStyle();
}
+inline RenderStyle* Node::parentRenderStyle() const
+{
+ ContainerNode* parent = NodeRenderingTraversal::parent(this);
+ return parent ? parent->renderStyle() : 0;
+}
+
}
#endif
diff --git a/Source/core/dom/NodeRenderingContext.cpp b/Source/core/dom/NodeRenderingContext.cpp
index f403465..2677c13 100644
--- a/Source/core/dom/NodeRenderingContext.cpp
+++ b/Source/core/dom/NodeRenderingContext.cpp
@@ -27,13 +27,12 @@
#include "core/dom/NodeRenderingContext.h"
#include "RuntimeEnabledFeatures.h"
-#include "SVGNames.h"
#include "core/css/resolver/StyleResolver.h"
#include "core/dom/ContainerNode.h"
#include "core/dom/FullscreenController.h"
#include "core/dom/Node.h"
#include "core/dom/Text.h"
-#include "core/html/shadow/HTMLShadowElement.h"
+#include "core/dom/shadow/InsertionPoint.h"
#include "core/rendering/FlowThreadController.h"
#include "core/rendering/RenderFullScreen.h"
#include "core/rendering/RenderNamedFlowThread.h"
@@ -43,33 +42,15 @@
namespace WebCore {
-NodeRenderingContext::NodeRenderingContext(Node* node)
- : m_node(node)
- , m_parentFlowRenderer(0)
-{
- m_renderingParent = NodeRenderingTraversal::parent(node, &m_parentDetails);
-}
-
NodeRenderingContext::NodeRenderingContext(Node* node, RenderStyle* style)
: m_node(node)
, m_renderingParent(0)
, m_style(style)
, m_parentFlowRenderer(0)
{
-}
-
-NodeRenderingContext::NodeRenderingContext(Node* node, const Node::AttachContext& context)
-: m_node(node)
-, m_style(context.resolvedStyle)
-, m_parentFlowRenderer(0)
-{
m_renderingParent = NodeRenderingTraversal::parent(node, &m_parentDetails);
}
-NodeRenderingContext::~NodeRenderingContext()
-{
-}
-
static bool isRendererReparented(const RenderObject* renderer)
{
if (!renderer->node()->isElementNode())
@@ -175,7 +156,6 @@
{
if (!m_renderingParent)
return false;
-
RenderObject* parentRenderer = this->parentRenderer();
if (!parentRenderer)
return false;
@@ -224,16 +204,6 @@
flowThreadController->registerNamedFlowContentNode(m_node, m_parentFlowRenderer);
}
-bool NodeRenderingContext::isOnEncapsulationBoundary() const
-{
- return isOnUpperEncapsulationBoundary() || isLowerEncapsulationBoundary(m_parentDetails.insertionPoint()) || isLowerEncapsulationBoundary(m_node->parentNode());
-}
-
-bool NodeRenderingContext::isOnUpperEncapsulationBoundary() const
-{
- return m_node->parentNode() && m_node->parentNode()->isShadowRoot();
-}
-
void NodeRenderingContext::createRendererForElementIfNeeded()
{
ASSERT(!m_node->renderer());
@@ -254,14 +224,12 @@
if (!element->rendererIsNeeded(*this))
return;
- RenderObject* parentRenderer = this->parentRenderer();
- RenderObject* nextRenderer = this->nextRenderer();
-
- Document* document = element->document();
RenderObject* newRenderer = element->createRenderer(m_style.get());
if (!newRenderer)
return;
+ RenderObject* parentRenderer = this->parentRenderer();
+
if (!parentRenderer->isChildAllowed(newRenderer, m_style.get())) {
newRenderer->destroy();
return;
@@ -271,11 +239,12 @@
// for the first time. Otherwise code using inRenderFlowThread() in the styleWillChange and styleDidChange will fail.
newRenderer->setFlowThreadState(parentRenderer->flowThreadState());
+ RenderObject* nextRenderer = this->nextRenderer();
element->setRenderer(newRenderer);
newRenderer->setAnimatableStyle(m_style.release()); // setAnimatableStyle() can depend on renderer() already being set.
if (FullscreenController::isActiveFullScreenElement(element)) {
- newRenderer = RenderFullScreen::wrapRenderer(newRenderer, parentRenderer, document);
+ newRenderer = RenderFullScreen::wrapRenderer(newRenderer, parentRenderer, element->document());
if (!newRenderer)
return;
}
@@ -294,19 +263,16 @@
return;
RenderObject* parentRenderer = this->parentRenderer();
- ASSERT(parentRenderer);
- Document* document = textNode->document();
if (resetStyleInheritance())
- m_style = document->styleResolver()->defaultStyleForElement();
+ m_style = textNode->document()->styleResolver()->defaultStyleForElement();
else
m_style = parentRenderer->style();
if (!textNode->textRendererIsNeeded(*this))
return;
+
RenderText* newRenderer = textNode->createTextRenderer(m_style.get());
- if (!newRenderer)
- return;
if (!parentRenderer->isChildAllowed(newRenderer, m_style.get())) {
newRenderer->destroy();
return;
diff --git a/Source/core/dom/NodeRenderingContext.h b/Source/core/dom/NodeRenderingContext.h
index 3bacbf4..9e448a8 100644
--- a/Source/core/dom/NodeRenderingContext.h
+++ b/Source/core/dom/NodeRenderingContext.h
@@ -44,10 +44,7 @@
class NodeRenderingContext {
public:
- explicit NodeRenderingContext(Node*);
- NodeRenderingContext(Node*, RenderStyle*);
- NodeRenderingContext(Node*, const Node::AttachContext&);
- ~NodeRenderingContext();
+ NodeRenderingContext(Node*, RenderStyle* = 0);
void createRendererForTextIfNeeded();
void createRendererForElementIfNeeded();
@@ -62,9 +59,6 @@
const RenderStyle* style() const;
- bool isOnUpperEncapsulationBoundary() const;
- bool isOnEncapsulationBoundary() const;
-
private:
bool shouldCreateRenderer() const;
void moveToFlowThreadIfNeeded();
diff --git a/Source/core/dom/Position.cpp b/Source/core/dom/Position.cpp
index b1d7f07..c917fb5 100644
--- a/Source/core/dom/Position.cpp
+++ b/Source/core/dom/Position.cpp
@@ -852,6 +852,7 @@
return node->parentNode();
}
+#if ENABLE(USERSELECT_ALL)
bool Position::nodeIsUserSelectAll(const Node* node)
{
return node && node->renderer() && node->renderer()->style()->userSelect() == SELECT_ALL;
@@ -878,6 +879,7 @@
}
return candidateRoot;
}
+#endif
bool Position::isCandidate() const
{
diff --git a/Source/core/dom/Position.h b/Source/core/dom/Position.h
index 5d4fd32..c3ad406 100644
--- a/Source/core/dom/Position.h
+++ b/Source/core/dom/Position.h
@@ -189,8 +189,10 @@
static bool hasRenderedNonAnonymousDescendantsWithHeight(RenderObject*);
static bool nodeIsUserSelectNone(Node*);
+#if ENABLE(USERSELECT_ALL)
static bool nodeIsUserSelectAll(const Node*);
static Node* rootUserSelectAllForNode(Node*);
+#endif
static ContainerNode* findParent(const Node*);
void debugPosition(const char* msg = "") const;
diff --git a/Source/core/dom/Text.cpp b/Source/core/dom/Text.cpp
index 9886613..826f282 100644
--- a/Source/core/dom/Text.cpp
+++ b/Source/core/dom/Text.cpp
@@ -207,13 +207,11 @@
if (context.style()->display() == NONE)
return false;
- bool onlyWS = containsOnlyWhitespace();
- if (!onlyWS)
+ if (!containsOnlyWhitespace())
return true;
RenderObject* parent = context.parentRenderer();
- if (parent->isTable() || parent->isTableRow() || parent->isTableSection() || parent->isRenderTableCol() || parent->isFrameSet()
- || parent->isFlexibleBox() || parent->isRenderGrid())
+ if (!parent->canHaveWhitespaceChildren())
return false;
if (context.style()->preserveNewline()) // pre/pre-wrap/pre-line always make renderers.
@@ -230,17 +228,19 @@
} else {
if (parent->isRenderBlock() && !parent->childrenInline() && (!prev || !prev->isInline()))
return false;
-
+
+ // Avoiding creation of a Renderer for the text node is a non-essential memory optimization.
+ // So to avoid blowing up on very wide DOMs, we limit the number of siblings to visit.
+ unsigned maxSiblingsToVisit = 50;
+
RenderObject* first = parent->firstChild();
- while (first && first->isFloatingOrOutOfFlowPositioned())
+ while (first && first->isFloatingOrOutOfFlowPositioned() && maxSiblingsToVisit--)
first = first->nextSibling();
- RenderObject* next = context.nextRenderer();
- if (!first || next == first)
+ if (!first || context.nextRenderer() == first)
// Whitespace at the start of a block just goes away. Don't even
// make a render object for this text.
return false;
}
-
return true;
}
@@ -298,10 +298,7 @@
bool Text::needsWhitespaceRenderer()
{
ASSERT(!renderer());
- ContainerNode* parent = parentNodeForRenderingAndStyle();
- if (!parent)
- return false;
- if (RenderStyle* style = parent->renderStyle())
+ if (RenderStyle* style = parentRenderStyle())
return style->preserveNewline();
return false;
}
diff --git a/Source/core/dom/TextLinkColors.cpp b/Source/core/dom/TextLinkColors.cpp
index f6e1fd8..59589a5 100644
--- a/Source/core/dom/TextLinkColors.cpp
+++ b/Source/core/dom/TextLinkColors.cpp
@@ -44,17 +44,17 @@
void TextLinkColors::resetLinkColor()
{
- m_linkColor = Color(0, 0, 238);
+ m_linkColor = StyleColor(0, 0, 238);
}
void TextLinkColors::resetVisitedLinkColor()
{
- m_visitedLinkColor = Color(85, 26, 139);
+ m_visitedLinkColor = StyleColor(85, 26, 139);
}
void TextLinkColors::resetActiveLinkColor()
{
- m_activeLinkColor.setNamedColor("red");
+ m_activeLinkColor = StyleColor(255, 0, 0);
}
static Color colorForCSSValue(CSSValueID cssValueId)
@@ -94,10 +94,10 @@
return RenderTheme::defaultTheme()->systemColor(cssValueId);
}
-Color TextLinkColors::colorFromPrimitiveValue(const CSSPrimitiveValue* value, Color currentColor, bool forVisitedLink) const
+StyleColor TextLinkColors::colorFromPrimitiveValue(const CSSPrimitiveValue* value, bool forVisitedLink) const
{
if (value->isRGBColor())
- return Color(value->getRGBA32Value());
+ return StyleColor(value->getRGBA32Value());
CSSValueID valueID = value->getValueID();
switch (valueID) {
@@ -112,7 +112,7 @@
case CSSValueWebkitFocusRingColor:
return RenderTheme::focusRingColor();
case CSSValueCurrentcolor:
- return currentColor;
+ return StyleColor::currentColor();
default:
return colorForCSSValue(valueID);
}
diff --git a/Source/core/dom/TextLinkColors.h b/Source/core/dom/TextLinkColors.h
index 6d2728c..fb223e8 100644
--- a/Source/core/dom/TextLinkColors.h
+++ b/Source/core/dom/TextLinkColors.h
@@ -28,7 +28,7 @@
#ifndef TextLinkColors_h
#define TextLinkColors_h
-#include "core/platform/graphics/Color.h"
+#include "core/css/StyleColor.h"
#include "wtf/Noncopyable.h"
namespace WebCore {
@@ -41,25 +41,25 @@
public:
TextLinkColors();
- void setTextColor(const Color& color) { m_textColor = color; }
- Color textColor() const { return m_textColor; }
+ void setTextColor(const StyleColor& color) { m_textColor = color; }
+ StyleColor textColor() const { return m_textColor; }
- const Color& linkColor() const { return m_linkColor; }
- const Color& visitedLinkColor() const { return m_visitedLinkColor; }
- const Color& activeLinkColor() const { return m_activeLinkColor; }
+ const StyleColor& linkColor() const { return m_linkColor; }
+ const StyleColor& visitedLinkColor() const { return m_visitedLinkColor; }
+ const StyleColor& activeLinkColor() const { return m_activeLinkColor; }
void setLinkColor(const Color& color) { m_linkColor = color; }
void setVisitedLinkColor(const Color& color) { m_visitedLinkColor = color; }
void setActiveLinkColor(const Color& color) { m_activeLinkColor = color; }
void resetLinkColor();
void resetVisitedLinkColor();
void resetActiveLinkColor();
- Color colorFromPrimitiveValue(const CSSPrimitiveValue*, Color currentColor, bool forVisitedLink = false) const;
+ StyleColor colorFromPrimitiveValue(const CSSPrimitiveValue*, bool forVisitedLink = false) const;
private:
- Color m_textColor;
- Color m_linkColor;
- Color m_visitedLinkColor;
- Color m_activeLinkColor;
+ StyleColor m_textColor;
+ StyleColor m_linkColor;
+ StyleColor m_visitedLinkColor;
+ StyleColor m_activeLinkColor;
};
}
diff --git a/Source/core/dom/TouchEvent.idl b/Source/core/dom/TouchEvent.idl
index b054441..c3b7a81 100644
--- a/Source/core/dom/TouchEvent.idl
+++ b/Source/core/dom/TouchEvent.idl
@@ -22,9 +22,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-[
- AllowJSCreationOnlyIfFeatureEnabled
-] interface TouchEvent : UIEvent {
+interface TouchEvent : UIEvent {
readonly attribute TouchList touches;
readonly attribute TouchList targetTouches;
readonly attribute TouchList changedTouches;
diff --git a/Source/core/dom/TreeScope.cpp b/Source/core/dom/TreeScope.cpp
index a5f47dd..6afde25 100644
--- a/Source/core/dom/TreeScope.cpp
+++ b/Source/core/dom/TreeScope.cpp
@@ -178,7 +178,7 @@
void TreeScope::addImageMap(HTMLMapElement* imageMap)
{
- AtomicStringImpl* name = imageMap->getName().impl();
+ StringImpl* name = imageMap->getName().impl();
if (!name)
return;
if (!m_imageMapsByName)
@@ -190,7 +190,7 @@
{
if (!m_imageMapsByName)
return;
- AtomicStringImpl* name = imageMap->getName().impl();
+ StringImpl* name = imageMap->getName().impl();
if (!name)
return;
m_imageMapsByName->remove(name, imageMap);
diff --git a/Source/core/dom/TreeScope.h b/Source/core/dom/TreeScope.h
index 6f4b3ee..54144ab 100644
--- a/Source/core/dom/TreeScope.h
+++ b/Source/core/dom/TreeScope.h
@@ -56,7 +56,7 @@
Element* adjustedFocusedElement();
Element* getElementById(const AtomicString&) const;
- bool hasElementWithId(AtomicStringImpl* id) const;
+ bool hasElementWithId(StringImpl* id) const;
bool containsMultipleElementsWithId(const AtomicString& id) const;
void addElementById(const AtomicString& elementId, Element*);
void removeElementById(const AtomicString& elementId, Element*);
@@ -174,7 +174,7 @@
mutable RefPtr<DOMSelection> m_selection;
};
-inline bool TreeScope::hasElementWithId(AtomicStringImpl* id) const
+inline bool TreeScope::hasElementWithId(StringImpl* id) const
{
ASSERT(id);
return m_elementsById && m_elementsById->contains(id);
diff --git a/Source/core/dom/shadow/ComposedShadowTreeWalker.cpp b/Source/core/dom/shadow/ComposedShadowTreeWalker.cpp
index e647b33..84b2fd2 100644
--- a/Source/core/dom/shadow/ComposedShadowTreeWalker.cpp
+++ b/Source/core/dom/shadow/ComposedShadowTreeWalker.cpp
@@ -50,7 +50,7 @@
return false;
if (ShadowRoot* shadowRoot = parent->isShadowRoot() ? toShadowRoot(parent) : 0)
- return ScopeContentDistribution::assignedTo(shadowRoot);
+ return shadowRoot->insertionPoint();
if (parent->isElementNode() && toElement(parent)->shadow())
return true;
@@ -185,7 +185,7 @@
if (node->parentNode() && node->parentNode()->isShadowRoot()) {
ShadowRoot* parentShadowRoot = toShadowRoot(node->parentNode());
if (!parentShadowRoot->isYoungest()) {
- InsertionPoint* assignedInsertionPoint = ScopeContentDistribution::assignedTo(parentShadowRoot);
+ InsertionPoint* assignedInsertionPoint = parentShadowRoot->insertionPoint();
ASSERT(assignedInsertionPoint);
return traverseSiblingInCurrentTree(assignedInsertionPoint, direction);
}
@@ -254,7 +254,7 @@
Node* ComposedShadowTreeWalker::traverseParentBackToYoungerShadowRootOrHost(const ShadowRoot* shadowRoot, ParentTraversalDetails* details) const
{
ASSERT(shadowRoot);
- ASSERT(!ScopeContentDistribution::assignedTo(shadowRoot));
+ ASSERT(!shadowRoot->insertionPoint());
if (shadowRoot->isYoungest()) {
if (canCrossUpperBoundary()) {
diff --git a/Source/core/dom/shadow/ContentDistributor.cpp b/Source/core/dom/shadow/ContentDistributor.cpp
index 5b3a68b..e7ae775 100644
--- a/Source/core/dom/shadow/ContentDistributor.cpp
+++ b/Source/core/dom/shadow/ContentDistributor.cpp
@@ -99,7 +99,7 @@
m_insertionPointListIsValid = true;
ASSERT(m_insertionPointList.isEmpty());
- if (!hasInsertionPoint(shadowRoot))
+ if (!shadowRoot->containsInsertionPoints())
return m_insertionPointList;
for (Element* element = ElementTraversal::firstWithin(shadowRoot); element; element = ElementTraversal::next(element, shadowRoot)) {
@@ -140,43 +140,6 @@
invalidateInsertionPointList();
}
-bool ScopeContentDistribution::hasShadowElement(const ShadowRoot* holder)
-{
- if (!holder->scopeDistribution())
- return false;
-
- return holder->scopeDistribution()->hasShadowElementChildren();
-}
-
-bool ScopeContentDistribution::hasContentElement(const ShadowRoot* holder)
-{
- if (!holder->scopeDistribution())
- return false;
-
- return holder->scopeDistribution()->hasContentElementChildren();
-}
-
-unsigned ScopeContentDistribution::countElementShadow(const ShadowRoot* holder)
-{
- if (!holder->scopeDistribution())
- return 0;
-
- return holder->scopeDistribution()->numberOfElementShadowChildren();
-}
-
-bool ScopeContentDistribution::hasInsertionPoint(const ShadowRoot* holder)
-{
- return hasShadowElement(holder) || hasContentElement(holder);
-}
-
-InsertionPoint* ScopeContentDistribution::assignedTo(const ShadowRoot* holder)
-{
- if (!holder->scopeDistribution())
- return 0;
-
- return holder->scopeDistribution()->insertionPointAssignedTo();
-}
-
ContentDistributor::ContentDistributor()
: m_needsSelectFeatureSet(false)
, m_validity(Undetermined)
@@ -395,14 +358,14 @@
void ContentDistributor::collectSelectFeatureSetFrom(ShadowRoot* root)
{
- if (ScopeContentDistribution::hasElementShadow(root)) {
+ if (root->containsShadowRoots()) {
for (Element* element = ElementTraversal::firstWithin(root); element; element = ElementTraversal::next(element)) {
if (ElementShadow* elementShadow = element->shadow())
m_selectFeatures.add(elementShadow->distributor().ensureSelectFeatureSet(elementShadow));
}
}
- if (ScopeContentDistribution::hasContentElement(root)) {
+ if (root->containsContentElements()) {
for (Element* element = ElementTraversal::firstWithin(root); element; element = ElementTraversal::next(element)) {
if (!isHTMLContentElement(element))
continue;
diff --git a/Source/core/dom/shadow/ContentDistributor.h b/Source/core/dom/shadow/ContentDistributor.h
index 442dc41..ba8707f 100644
--- a/Source/core/dom/shadow/ContentDistributor.h
+++ b/Source/core/dom/shadow/ContentDistributor.h
@@ -92,13 +92,6 @@
bool isUsedForRendering() const;
- static bool hasShadowElement(const ShadowRoot*);
- static bool hasContentElement(const ShadowRoot*);
- static bool hasInsertionPoint(const ShadowRoot*);
- static bool hasElementShadow(const ShadowRoot* holder) { return countElementShadow(holder); }
- static unsigned countElementShadow(const ShadowRoot*);
- static InsertionPoint* assignedTo(const ShadowRoot*);
-
private:
InsertionPoint* m_insertionPointAssignedTo;
unsigned m_numberOfShadowElementChildren;
diff --git a/Source/core/dom/shadow/ElementShadow.cpp b/Source/core/dom/shadow/ElementShadow.cpp
index b767737..e1983e5 100644
--- a/Source/core/dom/shadow/ElementShadow.cpp
+++ b/Source/core/dom/shadow/ElementShadow.cpp
@@ -96,32 +96,6 @@
}
}
-bool ElementShadow::childNeedsStyleRecalc() const
-{
- ASSERT(youngestShadowRoot());
- for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot())
- if (root->childNeedsStyleRecalc())
- return true;
-
- return false;
-}
-
-bool ElementShadow::needsStyleRecalc() const
-{
- ASSERT(youngestShadowRoot());
- for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot())
- if (root->needsStyleRecalc())
- return true;
-
- return false;
-}
-
-void ElementShadow::recalcStyle(Node::StyleChange change)
-{
- for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot())
- root->recalcStyle(change);
-}
-
void ElementShadow::removeAllEventListeners()
{
for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot()) {
diff --git a/Source/core/dom/shadow/ElementShadow.h b/Source/core/dom/shadow/ElementShadow.h
index a1f645d..084d7c1 100644
--- a/Source/core/dom/shadow/ElementShadow.h
+++ b/Source/core/dom/shadow/ElementShadow.h
@@ -59,9 +59,6 @@
void attach(const Node::AttachContext&);
void detach(const Node::AttachContext&);
- bool childNeedsStyleRecalc() const;
- bool needsStyleRecalc() const;
- void recalcStyle(Node::StyleChange);
void removeAllEventListeners();
void invalidateDistribution() { m_distributor.invalidateDistribution(host()); }
diff --git a/Source/core/dom/shadow/InsertionPoint.cpp b/Source/core/dom/shadow/InsertionPoint.cpp
index e0ef0b2..0fe52d9 100644
--- a/Source/core/dom/shadow/InsertionPoint.cpp
+++ b/Source/core/dom/shadow/InsertionPoint.cpp
@@ -90,11 +90,6 @@
return isActive() && !hasDistribution();
}
-bool InsertionPoint::isShadowBoundary() const
-{
- return treeScope()->rootNode()->isShadowRoot() && isActive();
-}
-
bool InsertionPoint::isActive() const
{
if (!containingShadowRoot())
@@ -124,7 +119,7 @@
bool InsertionPoint::rendererIsNeeded(const NodeRenderingContext& context)
{
- return !isShadowBoundary() && HTMLElement::rendererIsNeeded(context);
+ return !isActive() && HTMLElement::rendererIsNeeded(context);
}
void InsertionPoint::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
@@ -201,7 +196,7 @@
bool InsertionPoint::contains(const Node* node) const
{
- return m_distribution.contains(const_cast<Node*>(node)) || (node->isShadowRoot() && ScopeContentDistribution::assignedTo(toShadowRoot(node)) == this);
+ return m_distribution.contains(const_cast<Node*>(node)) || (node->isShadowRoot() && toShadowRoot(node)->insertionPoint() == this);
}
const CSSSelectorList& InsertionPoint::emptySelectorList()
@@ -228,7 +223,7 @@
}
if (Node* parent = parentNodeForDistribution(current)) {
- if (InsertionPoint* insertedTo = parent->isShadowRoot() ? ScopeContentDistribution::assignedTo(toShadowRoot(parent)) : 0) {
+ if (InsertionPoint* insertedTo = parent->isShadowRoot() ? toShadowRoot(parent)->insertionPoint() : 0) {
current = insertedTo;
insertionPoint = insertedTo;
continue;
@@ -255,7 +250,7 @@
}
}
if (Node* parent = parentNodeForDistribution(current)) {
- if (InsertionPoint* insertedTo = parent->isShadowRoot() ? ScopeContentDistribution::assignedTo(toShadowRoot(parent)) : 0) {
+ if (InsertionPoint* insertedTo = parent->isShadowRoot() ? toShadowRoot(parent)->insertionPoint() : 0) {
current = insertedTo;
results.append(insertedTo);
continue;
diff --git a/Source/core/dom/shadow/InsertionPoint.h b/Source/core/dom/shadow/InsertionPoint.h
index 44cd1f9..0f1d486 100644
--- a/Source/core/dom/shadow/InsertionPoint.h
+++ b/Source/core/dom/shadow/InsertionPoint.h
@@ -57,7 +57,6 @@
bool hasDistribution() const { return !m_distribution.isEmpty(); }
void setDistribution(ContentDistribution& distribution) { m_distribution.swap(distribution); }
void clearDistribution() { m_distribution.clear(); }
- bool isShadowBoundary() const;
bool isActive() const;
PassRefPtr<NodeList> getDistributedNodes() const;
@@ -118,13 +117,6 @@
return node->isInsertionPoint() && toInsertionPoint(node)->isActive();
}
-inline bool isLowerEncapsulationBoundary(Node* node)
-{
- if (!node || !node->isInsertionPoint())
- return false;
- return toInsertionPoint(node)->isShadowBoundary();
-}
-
inline Node* parentNodeForDistribution(const Node* node)
{
ASSERT(node);
diff --git a/Source/core/dom/shadow/SelectRuleFeatureSet.h b/Source/core/dom/shadow/SelectRuleFeatureSet.h
index 7292b12..429d277 100644
--- a/Source/core/dom/shadow/SelectRuleFeatureSet.h
+++ b/Source/core/dom/shadow/SelectRuleFeatureSet.h
@@ -68,19 +68,19 @@
inline bool SelectRuleFeatureSet::hasSelectorForId(const AtomicString& idValue) const
{
ASSERT(!idValue.isEmpty());
- return m_cssRuleFeatureSet.idsInRules.contains(idValue.impl());
+ return m_cssRuleFeatureSet.idsInRules.contains(idValue);
}
inline bool SelectRuleFeatureSet::hasSelectorForClass(const AtomicString& classValue) const
{
ASSERT(!classValue.isEmpty());
- return m_cssRuleFeatureSet.classesInRules.contains(classValue.impl());
+ return m_cssRuleFeatureSet.classesInRules.contains(classValue);
}
inline bool SelectRuleFeatureSet::hasSelectorForAttribute(const AtomicString& attributeName) const
{
ASSERT(!attributeName.isEmpty());
- return m_cssRuleFeatureSet.attrsInRules.contains(attributeName.impl());
+ return m_cssRuleFeatureSet.attrsInRules.contains(attributeName);
}
}
diff --git a/Source/core/dom/shadow/ShadowRoot.cpp b/Source/core/dom/shadow/ShadowRoot.cpp
index 2fc2f26..a897eb9 100644
--- a/Source/core/dom/shadow/ShadowRoot.cpp
+++ b/Source/core/dom/shadow/ShadowRoot.cpp
@@ -192,7 +192,7 @@
bool ShadowRoot::isActive() const
{
for (ShadowRoot* shadowRoot = youngerShadowRoot(); shadowRoot; shadowRoot = shadowRoot->youngerShadowRoot())
- if (!ScopeContentDistribution::hasShadowElement(shadowRoot))
+ if (!shadowRoot->containsShadowElements())
return false;
return true;
}
@@ -302,4 +302,24 @@
return m_scopeDistribution.get();
}
+bool ShadowRoot::containsShadowElements() const
+{
+ return m_scopeDistribution ? m_scopeDistribution->hasShadowElementChildren() : 0;
+}
+
+bool ShadowRoot::containsContentElements() const
+{
+ return m_scopeDistribution ? m_scopeDistribution->hasContentElementChildren() : 0;
+}
+
+bool ShadowRoot::containsShadowRoots() const
+{
+ return m_scopeDistribution ? m_scopeDistribution->numberOfElementShadowChildren() : 0;
+}
+
+InsertionPoint* ShadowRoot::insertionPoint() const
+{
+ return m_scopeDistribution ? m_scopeDistribution->insertionPointAssignedTo() : 0;
+}
+
}
diff --git a/Source/core/dom/shadow/ShadowRoot.h b/Source/core/dom/shadow/ShadowRoot.h
index 4e9c5e5..3759557 100644
--- a/Source/core/dom/shadow/ShadowRoot.h
+++ b/Source/core/dom/shadow/ShadowRoot.h
@@ -38,6 +38,7 @@
namespace WebCore {
class ElementShadow;
+class InsertionPoint;
class ScopeContentDistribution;
class ShadowRoot FINAL : public DocumentFragment, public TreeScope, public DoublyLinkedListNode<ShadowRoot> {
@@ -93,6 +94,12 @@
const ScopeContentDistribution* scopeDistribution() const { return m_scopeDistribution.get(); }
ScopeContentDistribution* ensureScopeDistribution();
+ bool containsShadowElements() const;
+ bool containsContentElements() const;
+ bool containsInsertionPoints() const { return containsShadowElements() || containsContentElements(); }
+ bool containsShadowRoots() const;
+ InsertionPoint* insertionPoint() const;
+
ShadowRootType type() const { return static_cast<ShadowRootType>(m_type); }
PassRefPtr<Node> cloneNode(bool, ExceptionCode&);