diff options
Diffstat (limited to 'Source/WebCore/dom')
98 files changed, 1951 insertions, 1404 deletions
diff --git a/Source/WebCore/dom/ActiveDOMObject.cpp b/Source/WebCore/dom/ActiveDOMObject.cpp index 39a4c4c6b..bb2ec2209 100644 --- a/Source/WebCore/dom/ActiveDOMObject.cpp +++ b/Source/WebCore/dom/ActiveDOMObject.cpp @@ -60,6 +60,9 @@ void ContextDestructionObserver::contextDestroyed() ActiveDOMObject::ActiveDOMObject(ScriptExecutionContext* scriptExecutionContext, void* upcastPointer) : ContextDestructionObserver(scriptExecutionContext) , m_pendingActivityCount(0) +#if !ASSERT_DISABLED + , m_suspendIfNeededCalled(false) +#endif { if (!m_scriptExecutionContext) return; @@ -73,10 +76,23 @@ ActiveDOMObject::~ActiveDOMObject() if (!m_scriptExecutionContext) return; + ASSERT(m_suspendIfNeededCalled); ASSERT(m_scriptExecutionContext->isContextThread()); m_scriptExecutionContext->willDestroyActiveDOMObject(this); } +void ActiveDOMObject::suspendIfNeeded() +{ +#if !ASSERT_DISABLED + ASSERT(!m_suspendIfNeededCalled); + m_suspendIfNeededCalled = true; +#endif + if (!m_scriptExecutionContext) + return; + + m_scriptExecutionContext->suspendActiveDOMObjectIfNeeded(this); +} + bool ActiveDOMObject::hasPendingActivity() const { return m_pendingActivityCount; diff --git a/Source/WebCore/dom/ActiveDOMObject.h b/Source/WebCore/dom/ActiveDOMObject.h index db7ca66c0..dce6b56dd 100644 --- a/Source/WebCore/dom/ActiveDOMObject.h +++ b/Source/WebCore/dom/ActiveDOMObject.h @@ -51,6 +51,13 @@ namespace WebCore { public: ActiveDOMObject(ScriptExecutionContext*, void* upcastPointer); + // suspendIfNeeded() should be called exactly once after object construction to synchronize + // the suspend state with that in ScriptExecutionContext. + void suspendIfNeeded(); +#if !ASSERT_DISABLED + bool suspendIfNeededCalled() const { return m_suspendIfNeededCalled; } +#endif + virtual bool hasPendingActivity() const; // canSuspend() is used by the caller if there is a choice between suspending and stopping. @@ -88,6 +95,9 @@ namespace WebCore { private: unsigned m_pendingActivityCount; +#if !ASSERT_DISABLED + bool m_suspendIfNeededCalled; +#endif }; } // namespace WebCore diff --git a/Source/WebCore/dom/Attr.cpp b/Source/WebCore/dom/Attr.cpp index 6930fa1dc..e54c8d0df 100644 --- a/Source/WebCore/dom/Attr.cpp +++ b/Source/WebCore/dom/Attr.cpp @@ -181,7 +181,7 @@ void Attr::childrenChanged(bool changedByParser, Node* beforeChange, Node* after StringBuilder valueBuilder; for (Node *n = firstChild(); n; n = n->nextSibling()) { if (n->isTextNode()) - valueBuilder.append(static_cast<Text*>(n)->data()); + valueBuilder.append(toText(n)->data()); } AtomicString newValue = valueBuilder.toString(); diff --git a/Source/WebCore/dom/Attr.h b/Source/WebCore/dom/Attr.h index 0209f9041..b70357495 100644 --- a/Source/WebCore/dom/Attr.h +++ b/Source/WebCore/dom/Attr.h @@ -39,6 +39,7 @@ class CSSStyleDeclaration; // destruction. however, this is not yet implemented. class Attr : public ContainerNode { + friend class ElementAttributeData; friend class NamedNodeMap; public: static PassRefPtr<Attr> create(Element*, Document*, PassRefPtr<Attribute>); diff --git a/Source/WebCore/dom/Attr.idl b/Source/WebCore/dom/Attr.idl index e3a802cf2..300896723 100644 --- a/Source/WebCore/dom/Attr.idl +++ b/Source/WebCore/dom/Attr.idl @@ -27,11 +27,11 @@ module core { // DOM Level 1 - readonly attribute [ConvertNullStringTo=Null] DOMString name; + readonly attribute [TreatReturnedNullStringAs=Null] DOMString name; readonly attribute boolean specified; - attribute [ConvertNullStringTo=Null, TreatNullAs=NullString] DOMString value + attribute [TreatReturnedNullStringAs=Null, TreatNullAs=NullString] DOMString value setter raises(DOMException); // DOM Level 2 diff --git a/Source/WebCore/dom/CharacterData.idl b/Source/WebCore/dom/CharacterData.idl index dcf796ae5..2bb3d4e49 100644 --- a/Source/WebCore/dom/CharacterData.idl +++ b/Source/WebCore/dom/CharacterData.idl @@ -26,24 +26,24 @@ module core { readonly attribute unsigned long length; - [ConvertNullStringTo=Null, ObjCLegacyUnnamedParameters] DOMString substringData(in [IsIndex,Optional=CallWithDefaultValue] unsigned long offset, - in [IsIndex,Optional=CallWithDefaultValue] unsigned long length) + [TreatReturnedNullStringAs=Null, ObjCLegacyUnnamedParameters] DOMString substringData(in [IsIndex,Optional=DefaultIsUndefined] unsigned long offset, + in [IsIndex,Optional=DefaultIsUndefined] unsigned long length) raises(DOMException); - void appendData(in [Optional=CallWithDefaultValue] DOMString data) + void appendData(in [Optional=DefaultIsUndefined] DOMString data) raises(DOMException); - [ObjCLegacyUnnamedParameters] void insertData(in [IsIndex,Optional=CallWithDefaultValue] unsigned long offset, - in [Optional=CallWithDefaultValue] DOMString data) + [ObjCLegacyUnnamedParameters] void insertData(in [IsIndex,Optional=DefaultIsUndefined] unsigned long offset, + in [Optional=DefaultIsUndefined] DOMString data) raises(DOMException); - [ObjCLegacyUnnamedParameters] void deleteData(in [IsIndex,Optional=CallWithDefaultValue] unsigned long offset, - in [IsIndex,Optional=CallWithDefaultValue] unsigned long length) + [ObjCLegacyUnnamedParameters] void deleteData(in [IsIndex,Optional=DefaultIsUndefined] unsigned long offset, + in [IsIndex,Optional=DefaultIsUndefined] unsigned long length) raises(DOMException); - [ObjCLegacyUnnamedParameters] void replaceData(in [IsIndex,Optional=CallWithDefaultValue] unsigned long offset, - in [IsIndex,Optional=CallWithDefaultValue] unsigned long length, - in [Optional=CallWithDefaultValue] DOMString data) + [ObjCLegacyUnnamedParameters] void replaceData(in [IsIndex,Optional=DefaultIsUndefined] unsigned long offset, + in [IsIndex,Optional=DefaultIsUndefined] unsigned long length, + in [Optional=DefaultIsUndefined] DOMString data) raises(DOMException); }; diff --git a/Source/WebCore/dom/ClientRectList.idl b/Source/WebCore/dom/ClientRectList.idl index 45d6f485f..02f055e6e 100644 --- a/Source/WebCore/dom/ClientRectList.idl +++ b/Source/WebCore/dom/ClientRectList.idl @@ -30,7 +30,7 @@ module view { IndexedGetter ] ClientRectList { readonly attribute unsigned long length; - ClientRect item(in [IsIndex,Optional=CallWithDefaultValue] unsigned long index); + ClientRect item(in [IsIndex,Optional=DefaultIsUndefined] unsigned long index); // FIXME: Fix list behavior to allow custom exceptions to be thrown. }; diff --git a/Source/WebCore/dom/Clipboard.cpp b/Source/WebCore/dom/Clipboard.cpp index 027992515..2053292a1 100644 --- a/Source/WebCore/dom/Clipboard.cpp +++ b/Source/WebCore/dom/Clipboard.cpp @@ -27,6 +27,7 @@ #include "Clipboard.h" #include "CachedImage.h" +#include "DOMStringList.h" #include "FileList.h" #include "Frame.h" #include "FrameLoader.h" @@ -147,7 +148,7 @@ bool Clipboard::hasStringOfType(const String& type) const if (m_policy != ClipboardReadable && m_policy != ClipboardTypesReadable) return false; - return types().contains(type); + return types()->contains(type); } void Clipboard::setDropEffect(const String &effect) diff --git a/Source/WebCore/dom/Clipboard.h b/Source/WebCore/dom/Clipboard.h index a07ae9fc5..d33829a6c 100644 --- a/Source/WebCore/dom/Clipboard.h +++ b/Source/WebCore/dom/Clipboard.h @@ -33,6 +33,7 @@ namespace WebCore { + class DOMStringList; class DataTransferItemList; class DragData; class FileList; @@ -66,7 +67,7 @@ namespace WebCore { virtual bool setData(const String& type, const String& data) = 0; // extensions beyond IE's API - virtual HashSet<String> types() const = 0; + virtual PassRefPtr<DOMStringList> types() const = 0; virtual PassRefPtr<FileList> files() const = 0; IntPoint dragLocation() const { return m_dragLoc; } diff --git a/Source/WebCore/dom/Clipboard.idl b/Source/WebCore/dom/Clipboard.idl index dc453f298..c1c5850ec 100644 --- a/Source/WebCore/dom/Clipboard.idl +++ b/Source/WebCore/dom/Clipboard.idl @@ -29,9 +29,9 @@ module core { interface Clipboard { - attribute [ConvertNullStringTo=Undefined] DOMString dropEffect; - attribute [ConvertNullStringTo=Undefined] DOMString effectAllowed; - readonly attribute [CustomGetter] Array types; + attribute [TreatReturnedNullStringAs=Undefined] DOMString dropEffect; + attribute [TreatReturnedNullStringAs=Undefined] DOMString effectAllowed; + readonly attribute DOMStringList types; readonly attribute FileList files; [Custom] void clearData(in [Optional] DOMString type) diff --git a/Source/WebCore/dom/CompositionEvent.idl b/Source/WebCore/dom/CompositionEvent.idl index a28292c36..f66ed5ae4 100644 --- a/Source/WebCore/dom/CompositionEvent.idl +++ b/Source/WebCore/dom/CompositionEvent.idl @@ -30,11 +30,11 @@ module events { readonly attribute DOMString data; - void initCompositionEvent(in [Optional=CallWithDefaultValue] DOMString typeArg, - in [Optional=CallWithDefaultValue] boolean canBubbleArg, - in [Optional=CallWithDefaultValue] boolean cancelableArg, - in [Optional=CallWithDefaultValue] DOMWindow viewArg, - in [Optional=CallWithDefaultValue] DOMString dataArg); + void initCompositionEvent(in [Optional=DefaultIsUndefined] DOMString typeArg, + in [Optional=DefaultIsUndefined] boolean canBubbleArg, + in [Optional=DefaultIsUndefined] boolean cancelableArg, + in [Optional=DefaultIsUndefined] DOMWindow viewArg, + in [Optional=DefaultIsUndefined] DOMString dataArg); }; diff --git a/Source/WebCore/dom/ContainerNode.cpp b/Source/WebCore/dom/ContainerNode.cpp index dbd2b7259..0a81c6dea 100644 --- a/Source/WebCore/dom/ContainerNode.cpp +++ b/Source/WebCore/dom/ContainerNode.cpp @@ -69,7 +69,7 @@ static inline void collectNodes(Node* node, NodeVector& nodes) static void collectTargetNodes(Node* node, NodeVector& nodes) { - if (node->nodeType() != Node::DOCUMENT_FRAGMENT_NODE) { + if (node->nodeType() != Node::DOCUMENT_FRAGMENT_NODE || node->isShadowRoot()) { nodes.append(node); return; } @@ -158,11 +158,6 @@ bool ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, Exce if (ec) return false; - // FIXME: After sending the mutation events, "this" could be destroyed. - // We can prevent that by doing a "ref", but first we have to make sure - // that no callers call with ref count == 0 and parent = 0 (as of this - // writing, there are definitely callers who call that way). - // Due to arbitrary code running in response to a DOM mutation event it's // possible that "next" is no longer a child of "this". // It's also possible that "child" has been inserted elsewhere. @@ -293,12 +288,7 @@ bool ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, Exce if (ec) return false; - // FIXME: After sending the mutation events, "this" could be destroyed. - // We can prevent that by doing a "ref", but first we have to make sure - // that no callers call with ref count == 0 and parent = 0 (as of this - // writing, there are definitely callers who call that way). - - bool isFragment = newChild->nodeType() == DOCUMENT_FRAGMENT_NODE; + bool isFragment = newChild->nodeType() == DOCUMENT_FRAGMENT_NODE && !newChild->isShadowRoot(); // Add the new child(ren) RefPtr<Node> child = isFragment ? newChild->firstChild() : newChild; @@ -469,24 +459,19 @@ bool ContainerNode::removeChild(Node* oldChild, ExceptionCode& ec) return false; } - // FIXME: After sending the mutation events, "this" could be destroyed. - // We can prevent that by doing a "ref", but first we have to make sure - // that no callers call with ref count == 0 and parent = 0 (as of this - // writing, there are definitely callers who call that way). - Node* prev = child->previousSibling(); Node* next = child->nextSibling(); removeBetween(prev, next, child.get()); - // Dispatch post-removal mutation events childrenChanged(false, prev, next, -1); - dispatchSubtreeModifiedEvent(); if (child->inDocument()) child->removedFromDocument(); else child->removedFromTree(true); + dispatchSubtreeModifiedEvent(); + return child; } @@ -592,11 +577,10 @@ void ContainerNode::removeChildren() removedChild->detach(); } + // FIXME: This should be just above dispatchSubtreeModifiedEvent(); allowEventDispatch(); - // Dispatch a single post-removal mutation event denoting a modified subtree. childrenChanged(false, 0, 0, -static_cast<int>(removedChildrenCount)); - dispatchSubtreeModifiedEvent(); for (i = 0; i < removedChildrenCount; ++i) { Node* removedChild = removedChildren[i].get(); @@ -606,6 +590,8 @@ void ContainerNode::removeChildren() // document. There is no explanation for this discrepancy between removeChild() // and its optimized version removeChildren(). } + + dispatchSubtreeModifiedEvent(); } bool ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec, bool shouldLazyAttach) diff --git a/Source/WebCore/dom/ContainerNodeAlgorithms.h b/Source/WebCore/dom/ContainerNodeAlgorithms.h index 55095a72e..ee69afd16 100644 --- a/Source/WebCore/dom/ContainerNodeAlgorithms.h +++ b/Source/WebCore/dom/ContainerNodeAlgorithms.h @@ -135,8 +135,10 @@ namespace Private { head = n; tail = n; - } else + } else { + RefPtr<GenericNode> protect(n); // removedFromDocument may remove remove all references to this node. NodeRemovalDispatcher<GenericNode, ShouldDispatchRemovalNotification<GenericNode>::value>::dispatch(n); + } } container->setFirstChild(0); diff --git a/Source/WebCore/dom/CustomEvent.idl b/Source/WebCore/dom/CustomEvent.idl index 53a1ffca8..9158d58a2 100644 --- a/Source/WebCore/dom/CustomEvent.idl +++ b/Source/WebCore/dom/CustomEvent.idl @@ -32,10 +32,10 @@ module events { ] CustomEvent : Event { readonly attribute [InitializedByEventConstructor] DOMObject detail; - void initCustomEvent(in [Optional=CallWithDefaultValue] DOMString typeArg, - in [Optional=CallWithDefaultValue] boolean canBubbleArg, - in [Optional=CallWithDefaultValue] boolean cancelableArg, - in [Optional=CallWithDefaultValue] DOMObject detailArg); + void initCustomEvent(in [Optional=DefaultIsUndefined] DOMString typeArg, + in [Optional=DefaultIsUndefined] boolean canBubbleArg, + in [Optional=DefaultIsUndefined] boolean cancelableArg, + in [Optional=DefaultIsUndefined] DOMObject detailArg); }; #endif diff --git a/Source/WebCore/dom/DOMAllInOne.cpp b/Source/WebCore/dom/DOMAllInOne.cpp index 8b1ebbb88..8ec4bfb6b 100644 --- a/Source/WebCore/dom/DOMAllInOne.cpp +++ b/Source/WebCore/dom/DOMAllInOne.cpp @@ -33,6 +33,7 @@ #include "CDATASection.cpp" #include "CharacterData.cpp" #include "CheckedRadioButtons.cpp" +#include "ChildListMutationScope.cpp" #include "ChildNodeList.cpp" #include "ClassNodeList.cpp" #include "ClientRect.cpp" @@ -88,6 +89,9 @@ #include "MouseEvent.cpp" #include "MouseRelatedEvent.cpp" #include "MutationEvent.cpp" +#include "MutationObserverInterestGroup.cpp" +#include "MutationObserverRegistration.cpp" +#include "MutationRecord.cpp" #include "NameNodeList.cpp" #include "NodeFilter.cpp" #include "NodeFilterCondition.cpp" @@ -113,6 +117,7 @@ #include "SecurityContext.cpp" #include "SelectorQuery.cpp" #include "ShadowRoot.cpp" +#include "ShadowRootList.cpp" #include "SpaceSplitString.cpp" #include "StaticHashSetNodeList.cpp" #include "StaticNodeList.cpp" @@ -135,6 +140,7 @@ #include "UserTypingGestureIndicator.cpp" #include "ViewportArguments.cpp" #include "WebKitAnimationEvent.cpp" +#include "WebKitMutationObserver.cpp" #include "WebKitNamedFlow.cpp" #include "WebKitTransitionEvent.cpp" #include "WheelEvent.cpp" diff --git a/Source/WebCore/dom/DOMCoreException.idl b/Source/WebCore/dom/DOMCoreException.idl index 3f25b021a..add5bd9a1 100644 --- a/Source/WebCore/dom/DOMCoreException.idl +++ b/Source/WebCore/dom/DOMCoreException.idl @@ -30,7 +30,8 @@ module core { interface [ JSNoStaticTables, - DoNotCheckConstants + DoNotCheckConstants, + InterfaceName=DOMException ] DOMCoreException { readonly attribute unsigned short code; diff --git a/Source/WebCore/dom/DOMImplementation.cpp b/Source/WebCore/dom/DOMImplementation.cpp index 33104097e..ae6d3665c 100644 --- a/Source/WebCore/dom/DOMImplementation.cpp +++ b/Source/WebCore/dom/DOMImplementation.cpp @@ -364,46 +364,37 @@ PassRefPtr<Document> DOMImplementation::createDocument(const String& type, Frame // Plugins cannot take HTML and XHTML from us, and we don't even need to initialize the plugin database for those. if (type == "text/html") return HTMLDocument::create(frame, url); - - // Plugins cannot take text/plain from us either. - if (type == "text/plain") - return TextDocument::create(frame, url); - if (type == "application/xhtml+xml") return Document::createXHTML(frame, url); #if ENABLE(FTPDIR) - // Plugins cannot take FTP from us either. + // Plugins cannot take FTP from us either if (type == "application/x-ftp-directory") return FTPDirectoryDocument::create(frame, url); #endif - // PDF is the only image type for which a plugin can override built-in support. - if (Image::supportsType(type) && type != "application/pdf" && type != "text/pdf") - return ImageDocument::create(frame, url); - -#if ENABLE(VIDEO) - // Check to see if the type can be played by our MediaPlayer, if so create a MediaDocument as - // this can not be taken by plugins either. - if (MediaPlayer::supportsType(ContentType(type))) - return MediaDocument::create(frame, url); -#endif - - // The plugin database is initialized at this point if plugins are enabled - // which is non-zero overhead. PluginData* pluginData = 0; if (frame && frame->page() && frame->loader()->subframeLoader()->allowPlugins(NotAboutToInstantiatePlugin)) pluginData = frame->page()->pluginData(); - // At this point anything that can be supported can be overridden by plugins. - if (pluginData && pluginData->supportsMimeType(type)) + // PDF is one image type for which a plugin can override built-in support. + // We do not want QuickTime to take over all image types, obviously. + if ((type == "application/pdf" || type == "text/pdf") && pluginData && pluginData->supportsMimeType(type)) return PluginDocument::create(frame, url); - - // Handle PDF for instance if it was not handled by a plugin. if (Image::supportsType(type)) return ImageDocument::create(frame, url); - // Handle a text document was not handled by a plugin. +#if ENABLE(VIDEO) + // Check to see if the type can be played by our MediaPlayer, if so create a MediaDocument + if (MediaPlayer::supportsType(ContentType(type))) + return MediaDocument::create(frame, url); +#endif + + // Everything else except text/plain can be overridden by plugins. In particular, Adobe SVG Viewer should be used for SVG, if installed. + // Disallowing plug-ins to use text/plain prevents plug-ins from hijacking a fundamental type that the browser is expected to handle, + // and also serves as an optimization to prevent loading the plug-in database in the common case. + if (type != "text/plain" && pluginData && pluginData->supportsMimeType(type)) + return PluginDocument::create(frame, url); if (isTextMIMEType(type)) return TextDocument::create(frame, url); diff --git a/Source/WebCore/dom/DOMImplementation.idl b/Source/WebCore/dom/DOMImplementation.idl index 0a2368e52..cd5709906 100644 --- a/Source/WebCore/dom/DOMImplementation.idl +++ b/Source/WebCore/dom/DOMImplementation.idl @@ -27,29 +27,29 @@ module core { // DOM Level 1 - [ObjCLegacyUnnamedParameters] boolean hasFeature(in [Optional=CallWithDefaultValue] DOMString feature, - in [TreatNullAs=NullString,Optional=CallWithDefaultValue] DOMString version); + [ObjCLegacyUnnamedParameters] boolean hasFeature(in [Optional=DefaultIsUndefined] DOMString feature, + in [TreatNullAs=NullString,Optional=DefaultIsUndefined] DOMString version); // DOM Level 2 - [ObjCLegacyUnnamedParameters] DocumentType createDocumentType(in [TreatNullAs=NullString, TreatUndefinedAs=NullString,Optional=CallWithDefaultValue] DOMString qualifiedName, - in [TreatNullAs=NullString, TreatUndefinedAs=NullString,Optional=CallWithDefaultValue] DOMString publicId, - in [TreatNullAs=NullString, TreatUndefinedAs=NullString,Optional=CallWithDefaultValue] DOMString systemId) + [ObjCLegacyUnnamedParameters] DocumentType createDocumentType(in [TreatNullAs=NullString, TreatUndefinedAs=NullString,Optional=DefaultIsUndefined] DOMString qualifiedName, + in [TreatNullAs=NullString, TreatUndefinedAs=NullString,Optional=DefaultIsUndefined] DOMString publicId, + in [TreatNullAs=NullString, TreatUndefinedAs=NullString,Optional=DefaultIsUndefined] DOMString systemId) raises(DOMException); - [ObjCLegacyUnnamedParameters] Document createDocument(in [TreatNullAs=NullString,Optional=CallWithDefaultValue] DOMString namespaceURI, - in [TreatNullAs=NullString,Optional=CallWithDefaultValue] DOMString qualifiedName, - in [TreatNullAs=NullString,Optional=CallWithDefaultValue] DocumentType doctype) + [ObjCLegacyUnnamedParameters] Document createDocument(in [TreatNullAs=NullString,Optional=DefaultIsUndefined] DOMString namespaceURI, + in [TreatNullAs=NullString,Optional=DefaultIsUndefined] DOMString qualifiedName, + in [TreatNullAs=NullString,Optional=DefaultIsUndefined] DocumentType doctype) raises(DOMException); // DOMImplementationCSS interface from DOM Level 2 CSS - [ObjCLegacyUnnamedParameters] CSSStyleSheet createCSSStyleSheet(in [Optional=CallWithDefaultValue] DOMString title, - in [Optional=CallWithDefaultValue] DOMString media) + [ObjCLegacyUnnamedParameters] CSSStyleSheet createCSSStyleSheet(in [Optional=DefaultIsUndefined] DOMString title, + in [Optional=DefaultIsUndefined] DOMString media) raises(DOMException); // HTMLDOMImplementation interface from DOM Level 2 HTML - HTMLDocument createHTMLDocument(in [Optional=CallWithDefaultValue] DOMString title); + HTMLDocument createHTMLDocument(in [Optional=DefaultIsUndefined] DOMString title); }; } diff --git a/Source/WebCore/dom/DOMStringList.idl b/Source/WebCore/dom/DOMStringList.idl index 8238575c6..8f059ae2b 100644 --- a/Source/WebCore/dom/DOMStringList.idl +++ b/Source/WebCore/dom/DOMStringList.idl @@ -29,8 +29,8 @@ module core { IndexedGetter ] DOMStringList { readonly attribute unsigned long length; - [ConvertNullStringTo=Null] DOMString item(in [IsIndex,Optional=CallWithDefaultValue] unsigned long index); - boolean contains(in [Optional=CallWithDefaultValue] DOMString string); + [TreatReturnedNullStringAs=Null] DOMString item(in [IsIndex,Optional=DefaultIsUndefined] unsigned long index); + boolean contains(in [Optional=DefaultIsUndefined] DOMString string); }; } diff --git a/Source/WebCore/dom/DOMStringMap.idl b/Source/WebCore/dom/DOMStringMap.idl index dbda74dba..980d044cd 100644 --- a/Source/WebCore/dom/DOMStringMap.idl +++ b/Source/WebCore/dom/DOMStringMap.idl @@ -29,8 +29,9 @@ module core { JSGenerateIsReachable=ImplElementRoot, NamedGetter, CustomDeleteProperty, - CustomGetPropertyNames, + CustomEnumerateProperty, CustomNamedSetter, + V8CustomToJSObject ] DOMStringMap { }; diff --git a/Source/WebCore/dom/DataTransferItem.idl b/Source/WebCore/dom/DataTransferItem.idl index befd7e2b1..0dad33822 100644 --- a/Source/WebCore/dom/DataTransferItem.idl +++ b/Source/WebCore/dom/DataTransferItem.idl @@ -36,7 +36,7 @@ module core { readonly attribute DOMString kind; readonly attribute DOMString type; - void getAsString(in [Callback,Optional=CallWithDefaultValue] StringCallback callback); + void getAsString(in [Callback,Optional=DefaultIsUndefined] StringCallback callback); Blob getAsFile(); }; diff --git a/Source/WebCore/dom/DataTransferItemList.idl b/Source/WebCore/dom/DataTransferItemList.idl index 8fcc47ded..d1de50e79 100644 --- a/Source/WebCore/dom/DataTransferItemList.idl +++ b/Source/WebCore/dom/DataTransferItemList.idl @@ -39,12 +39,12 @@ module core { #endif ] DataTransferItemList { readonly attribute long length; - DataTransferItem item(in [Optional=CallWithDefaultValue] unsigned long index); + DataTransferItem item(in [Optional=DefaultIsUndefined] unsigned long index); void clear(); void add(in File file); - void add(in [Optional=CallWithDefaultValue] DOMString data, - in [Optional=CallWithDefaultValue] DOMString type) raises(DOMException); + void add(in [Optional=DefaultIsUndefined] DOMString data, + in [Optional=DefaultIsUndefined] DOMString type) raises(DOMException); }; } diff --git a/Source/WebCore/dom/DeviceMotionClient.h b/Source/WebCore/dom/DeviceMotionClient.h index 45bf11aea..34e28e2b2 100644 --- a/Source/WebCore/dom/DeviceMotionClient.h +++ b/Source/WebCore/dom/DeviceMotionClient.h @@ -30,6 +30,7 @@ namespace WebCore { class DeviceMotionController; class DeviceMotionData; +class Page; class DeviceMotionClient { public: @@ -41,6 +42,8 @@ public: virtual void deviceMotionControllerDestroyed() = 0; }; +void provideDeviceMotionTo(Page*, DeviceMotionClient*); + } // namespace WebCore #endif // DeviceMotionClient_h diff --git a/Source/WebCore/dom/DeviceMotionController.cpp b/Source/WebCore/dom/DeviceMotionController.cpp index d7ac3059f..79eacc5e9 100644 --- a/Source/WebCore/dom/DeviceMotionController.cpp +++ b/Source/WebCore/dom/DeviceMotionController.cpp @@ -135,4 +135,22 @@ void DeviceMotionController::didChangeDeviceMotion(DeviceMotionData* deviceMotio listenersVector[i]->dispatchEvent(event); } +const AtomicString& DeviceMotionController::supplementName() +{ + DEFINE_STATIC_LOCAL(AtomicString, name, ("DeviceMotionController")); + return name; +} + +bool DeviceMotionController::isActiveAt(Page* page) +{ + if (DeviceMotionController* self = DeviceMotionController::from(page)) + return self->isActive(); + return false; +} + +void provideDeviceMotionTo(Page* page, DeviceMotionClient* client) +{ + PageSupplement::provideTo(page, DeviceMotionController::supplementName(), DeviceMotionController::create(client)); +} + } // namespace WebCore diff --git a/Source/WebCore/dom/DeviceMotionController.h b/Source/WebCore/dom/DeviceMotionController.h index bb8cca961..996c98861 100644 --- a/Source/WebCore/dom/DeviceMotionController.h +++ b/Source/WebCore/dom/DeviceMotionController.h @@ -27,6 +27,7 @@ #define DeviceMotionController_h #include "DOMWindow.h" +#include "PageSupplement.h" #include "Timer.h" #include <wtf/HashCountedSet.h> @@ -35,7 +36,7 @@ namespace WebCore { class DeviceMotionData; class DeviceMotionClient; -class DeviceMotionController { +class DeviceMotionController : public PageSupplement { public: ~DeviceMotionController(); @@ -52,6 +53,11 @@ public: bool isActive() { return !m_listeners.isEmpty(); } + static const AtomicString& supplementName(); + static DeviceMotionController* from(Frame* frame) { return static_cast<DeviceMotionController*>(PageSupplement::from(frame, supplementName())); } + static DeviceMotionController* from(Page* page) { return static_cast<DeviceMotionController*>(PageSupplement::from(page, supplementName())); } + static bool isActiveAt(Page*); + private: DeviceMotionController(DeviceMotionClient*); diff --git a/Source/WebCore/dom/DeviceMotionEvent.idl b/Source/WebCore/dom/DeviceMotionEvent.idl index fe1b7503e..bb55f7cce 100644 --- a/Source/WebCore/dom/DeviceMotionEvent.idl +++ b/Source/WebCore/dom/DeviceMotionEvent.idl @@ -32,13 +32,13 @@ module core { readonly attribute [Custom] Acceleration accelerationIncludingGravity; readonly attribute [Custom] RotationRate rotationRate; readonly attribute [Custom] double interval; - [Custom] void initDeviceMotionEvent(in [Optional=CallWithDefaultValue] DOMString type, - in [Optional=CallWithDefaultValue] boolean bubbles, - in [Optional=CallWithDefaultValue] boolean cancelable, - in [Optional=CallWithDefaultValue] Acceleration acceleration, - in [Optional=CallWithDefaultValue] Acceleration accelerationIncludingGravity, - in [Optional=CallWithDefaultValue] RotationRate rotationRate, - in [Optional=CallWithDefaultValue] double interval); + [Custom] void initDeviceMotionEvent(in [Optional=DefaultIsUndefined] DOMString type, + in [Optional=DefaultIsUndefined] boolean bubbles, + in [Optional=DefaultIsUndefined] boolean cancelable, + in [Optional=DefaultIsUndefined] Acceleration acceleration, + in [Optional=DefaultIsUndefined] Acceleration accelerationIncludingGravity, + in [Optional=DefaultIsUndefined] RotationRate rotationRate, + in [Optional=DefaultIsUndefined] double interval); }; } diff --git a/Source/WebCore/dom/DeviceOrientationClient.h b/Source/WebCore/dom/DeviceOrientationClient.h index 347c3b399..2c16b0cd8 100644 --- a/Source/WebCore/dom/DeviceOrientationClient.h +++ b/Source/WebCore/dom/DeviceOrientationClient.h @@ -30,6 +30,7 @@ namespace WebCore { class DeviceOrientation; class DeviceOrientationController; +class Page; class DeviceOrientationClient { public: @@ -42,6 +43,8 @@ public: virtual void deviceOrientationControllerDestroyed() = 0; }; +void provideDeviceOrientationTo(Page*, DeviceOrientationClient*); + } // namespace WebCore #endif // DeviceOrientationClient_h diff --git a/Source/WebCore/dom/DeviceOrientationController.cpp b/Source/WebCore/dom/DeviceOrientationController.cpp index 68683fd05..d298b3f44 100644 --- a/Source/WebCore/dom/DeviceOrientationController.cpp +++ b/Source/WebCore/dom/DeviceOrientationController.cpp @@ -137,4 +137,22 @@ void DeviceOrientationController::didChangeDeviceOrientation(DeviceOrientation* listenersVector[i]->dispatchEvent(event); } +const AtomicString& DeviceOrientationController::supplementName() +{ + DEFINE_STATIC_LOCAL(AtomicString, name, ("DeviceOrientationController")); + return name; +} + +bool DeviceOrientationController::isActiveAt(Page* page) +{ + if (DeviceOrientationController* self = DeviceOrientationController::from(page)) + return self->isActive(); + return false; +} + +void provideDeviceOrientationTo(Page* page, DeviceOrientationClient* client) +{ + PageSupplement::provideTo(page, DeviceOrientationController::supplementName(), DeviceOrientationController::create(page, client)); +} + } // namespace WebCore diff --git a/Source/WebCore/dom/DeviceOrientationController.h b/Source/WebCore/dom/DeviceOrientationController.h index 1b87998d9..d8efaca39 100644 --- a/Source/WebCore/dom/DeviceOrientationController.h +++ b/Source/WebCore/dom/DeviceOrientationController.h @@ -27,6 +27,7 @@ #define DeviceOrientationController_h #include "DOMWindow.h" +#include "PageSupplement.h" #include "Timer.h" #include <wtf/HashCountedSet.h> @@ -37,7 +38,7 @@ class DeviceOrientation; class DeviceOrientationClient; class Page; -class DeviceOrientationController { +class DeviceOrientationController : public PageSupplement { public: ~DeviceOrientationController(); @@ -56,6 +57,11 @@ public: DeviceOrientationClient* client() const { return m_client; } + static const AtomicString& supplementName(); + static DeviceOrientationController* from(Frame* frame) { return static_cast<DeviceOrientationController*>(PageSupplement::from(frame, supplementName())); } + static DeviceOrientationController* from(Page* page) { return static_cast<DeviceOrientationController*>(PageSupplement::from(page, supplementName())); } + static bool isActiveAt(Page*); + private: DeviceOrientationController(Page*, DeviceOrientationClient*); diff --git a/Source/WebCore/dom/DeviceOrientationEvent.idl b/Source/WebCore/dom/DeviceOrientationEvent.idl index 11833be92..aed38ffe3 100644 --- a/Source/WebCore/dom/DeviceOrientationEvent.idl +++ b/Source/WebCore/dom/DeviceOrientationEvent.idl @@ -32,13 +32,13 @@ module core { readonly attribute [Custom] double beta; readonly attribute [Custom] double gamma; readonly attribute [Custom] boolean absolute; - [Custom] void initDeviceOrientationEvent(in [Optional=CallWithDefaultValue] DOMString type, - in [Optional=CallWithDefaultValue] boolean bubbles, - in [Optional=CallWithDefaultValue] boolean cancelable, - in [Optional=CallWithDefaultValue] double alpha, - in [Optional=CallWithDefaultValue] double beta, - in [Optional=CallWithDefaultValue] double gamma, - in [Optional=CallWithDefaultValue] boolean absolute); + [Custom] void initDeviceOrientationEvent(in [Optional=DefaultIsUndefined] DOMString type, + in [Optional=DefaultIsUndefined] boolean bubbles, + in [Optional=DefaultIsUndefined] boolean cancelable, + in [Optional=DefaultIsUndefined] double alpha, + in [Optional=DefaultIsUndefined] double beta, + in [Optional=DefaultIsUndefined] double gamma, + in [Optional=DefaultIsUndefined] boolean absolute); }; } diff --git a/Source/WebCore/dom/Document.cpp b/Source/WebCore/dom/Document.cpp index 7e9293672..e85d22f2c 100644 --- a/Source/WebCore/dom/Document.cpp +++ b/Source/WebCore/dom/Document.cpp @@ -33,6 +33,7 @@ #include "Attr.h" #include "Attribute.h" #include "CDATASection.h" +#include "CSSStyleDeclaration.h" #include "CSSStyleSelector.h" #include "CSSStyleSheet.h" #include "CSSValueKeywords.h" @@ -78,6 +79,7 @@ #include "GeolocationController.h" #include "HashChangeEvent.h" #include "HistogramSupport.h" +#include "History.h" #include "HTMLAllCollection.h" #include "HTMLAnchorElement.h" #include "HTMLBodyElement.h" @@ -100,6 +102,7 @@ #include "HitTestRequest.h" #include "HitTestResult.h" #include "ImageLoader.h" +#include "InspectorCounters.h" #include "InspectorInstrumentation.h" #include "Logging.h" #include "MediaQueryList.h" @@ -132,11 +135,13 @@ #include "ScriptElement.h" #include "ScriptEventListener.h" #include "ScriptRunner.h" +#include "ScrollingCoordinator.h" #include "SecurityOrigin.h" #include "SecurityPolicy.h" #include "SegmentedString.h" #include "Settings.h" #include "ShadowRoot.h" +#include "ShadowRootList.h" #include "StaticHashSetNodeList.h" #include "StyleSheetList.h" #include "TextResourceDecoder.h" @@ -201,10 +206,6 @@ #include "NodeRareData.h" #endif -#if ENABLE(THREADED_SCROLLING) -#include "ScrollingCoordinator.h" -#endif - using namespace std; using namespace WTF; using namespace Unicode; @@ -436,6 +437,7 @@ Document::Document(Frame* frame, const KURL& url, bool isXHTML, bool isHTML) , m_writeRecursionIsTooDeep(false) , m_writeRecursionDepth(0) , m_wheelEventHandlerCount(0) + , m_touchEventHandlerCount(0) , m_pendingTasksTimer(this, &Document::pendingTasksTimerFired) { m_document = this; @@ -508,6 +510,7 @@ Document::Document(Frame* frame, const KURL& url, bool isXHTML, bool isHTML) #ifndef NDEBUG m_updatingStyleSelector = false; #endif + InspectorCounters::incrementCounter(InspectorCounters::DocumentCounter); } static void histogramMutationEventUsage(const unsigned short& listenerTypes) @@ -545,7 +548,6 @@ Document::~Document() ASSERT(!m_parser || m_parser->refCount() == 1); detachParser(); m_document = 0; - m_cachedResourceLoader.clear(); m_renderArena.clear(); @@ -578,10 +580,15 @@ Document::~Document() if (m_mediaQueryMatcher) m_mediaQueryMatcher->documentDestroyed(); + clearStyleSelector(); // We need to destory CSSFontSelector before destroying m_cachedResourceLoader. + m_cachedResourceLoader.clear(); + // We must call clearRareData() here since a Document class inherits TreeScope // as well as Node. See a comment on TreeScope.h for the reason. if (hasRareData()) clearRareData(); + + InspectorCounters::decrementCounter(InspectorCounters::DocumentCounter); } void Document::removedLastRef() @@ -664,8 +671,11 @@ void Document::buildAccessKeyMap(TreeScope* scope) const AtomicString& accessKey = element->getAttribute(accesskeyAttr); if (!accessKey.isEmpty()) m_elementsByAccessKey.set(accessKey.impl(), element); - if (ShadowRoot* shadowRoot = element->shadowRoot()) - buildAccessKeyMap(shadowRoot); + + if (element->hasShadowRoot()) { + for (ShadowRoot* root = element->shadowRootList()->youngestShadowRoot(); root; root = root->olderShadowRoot()) + buildAccessKeyMap(root); + } } } @@ -874,6 +884,11 @@ PassRefPtr<Node> Document::importNode(Node* importedNode, bool deep, ExceptionCo case ATTRIBUTE_NODE: return Attr::create(0, this, static_cast<Attr*>(importedNode)->attr()->clone()); case DOCUMENT_FRAGMENT_NODE: { + if (importedNode->isShadowRoot()) { + // ShadowRoot nodes should not be explicitly importable. + // Either they are imported along with their host node, or created implicitly. + break; + } DocumentFragment* oldFragment = static_cast<DocumentFragment*>(importedNode); RefPtr<DocumentFragment> newFragment = createDocumentFragment(); if (deep) { @@ -896,9 +911,6 @@ PassRefPtr<Node> Document::importNode(Node* importedNode, bool deep, ExceptionCo case DOCUMENT_NODE: case DOCUMENT_TYPE_NODE: case XPATH_NAMESPACE_NODE: - case SHADOW_ROOT_NODE: - // ShadowRoot nodes should not be explicitly importable. - // Either they are imported along with their host node, or created implicitly. break; } ec = NOT_SUPPORTED_ERR; @@ -1011,8 +1023,15 @@ PassRefPtr<Element> Document::createElement(const QualifiedName& qName, bool cre return e.release(); } +bool Document::cssRegionsEnabled() const +{ + return settings() && settings()->cssRegionsEnabled(); +} + PassRefPtr<WebKitNamedFlow> Document::webkitGetFlowByName(const String& flowName) { + if (!cssRegionsEnabled()) + return 0; if (!renderer()) return 0; if (RenderView* view = renderer()->view()) @@ -1944,10 +1963,11 @@ void Document::suspendActiveDOMObjects(ActiveDOMObject::ReasonForSuspension why) if (!page()) return; - if (page()->deviceMotionController()) - page()->deviceMotionController()->suspendEventsForAllListeners(domWindow()); - if (page()->deviceOrientationController()) - page()->deviceOrientationController()->suspendEventsForAllListeners(domWindow()); + if (DeviceMotionController* controller = DeviceMotionController::from(page())) + controller->suspendEventsForAllListeners(domWindow()); + if (DeviceOrientationController* controller = DeviceOrientationController::from(page())) + controller->suspendEventsForAllListeners(domWindow()); + #endif } @@ -1959,10 +1979,10 @@ void Document::resumeActiveDOMObjects() if (!page()) return; - if (page()->deviceMotionController()) - page()->deviceMotionController()->resumeEventsForAllListeners(domWindow()); - if (page()->deviceOrientationController()) - page()->deviceOrientationController()->resumeEventsForAllListeners(domWindow()); + if (DeviceMotionController* controller = DeviceMotionController::from(page())) + controller->resumeEventsForAllListeners(domWindow()); + if (DeviceOrientationController* controller = DeviceOrientationController::from(page())) + controller->resumeEventsForAllListeners(domWindow()); #endif } @@ -2311,7 +2331,7 @@ void Document::implicitClose() } // If painting and compositing layer updates were suppressed pending the load event, do these actions now. - if (renderer() && settings() && settings()->suppressIncrementalRendering()) { + if (renderer() && settings() && settings()->suppressesIncrementalRendering()) { #if USE(ACCELERATED_COMPOSITING) view()->updateCompositingLayers(); #endif @@ -2853,7 +2873,6 @@ bool Document::childTypeAllowed(NodeType type) const case NOTATION_NODE: case TEXT_NODE: case XPATH_NAMESPACE_NODE: - case SHADOW_ROOT_NODE: return false; case COMMENT_NODE: case PROCESSING_INSTRUCTION_NODE: @@ -2923,9 +2942,6 @@ bool Document::canReplaceChild(Node* newChild, Node* oldChild) case ELEMENT_NODE: numElements++; break; - case SHADOW_ROOT_NODE: - ASSERT_NOT_REACHED(); - return false; } } } else { @@ -2939,7 +2955,6 @@ bool Document::canReplaceChild(Node* newChild, Node* oldChild) case NOTATION_NODE: case TEXT_NODE: case XPATH_NAMESPACE_NODE: - case SHADOW_ROOT_NODE: return false; case COMMENT_NODE: case PROCESSING_INSTRUCTION_NODE: @@ -5013,7 +5028,7 @@ void Document::enqueueHashchangeEvent(const String& oldURL, const String& newURL void Document::enqueuePopstateEvent(PassRefPtr<SerializedScriptValue> stateObject) { // FIXME: https://bugs.webkit.org/show_bug.cgi?id=36202 Popstate event needs to fire asynchronously - dispatchWindowEvent(PopStateEvent::create(stateObject)); + dispatchWindowEvent(PopStateEvent::create(stateObject, domWindow() ? domWindow()->history() : 0)); } void Document::addMediaCanStartListener(MediaCanStartListener* listener) @@ -5366,7 +5381,6 @@ PassRefPtr<TouchList> Document::createTouchList(ExceptionCode&) const static void wheelEventHandlerCountChanged(Document* document) { -#if ENABLE(THREADED_SCROLLING) Page* page = document->page(); if (!page) return; @@ -5380,9 +5394,6 @@ static void wheelEventHandlerCountChanged(Document* document) return; scrollingCoordinator->frameViewWheelEventHandlerCountChanged(frameView); -#else - UNUSED_PARAM(document); -#endif } void Document::didAddWheelEventHandler() @@ -5406,10 +5417,27 @@ void Document::didRemoveWheelEventHandler() wheelEventHandlerCountChanged(this); } +void Document::didAddTouchEventHandler() +{ + ++m_touchEventHandlerCount; + Frame* mainFrame = page() ? page()->mainFrame() : 0; + if (mainFrame) + mainFrame->notifyChromeClientTouchEventHandlerCountChanged(); +} + +void Document::didRemoveTouchEventHandler() +{ + ASSERT(m_touchEventHandlerCount > 0); + --m_touchEventHandlerCount; + Frame* mainFrame = page() ? page()->mainFrame() : 0; + if (mainFrame) + mainFrame->notifyChromeClientTouchEventHandlerCountChanged(); +} + bool Document::visualUpdatesAllowed() const { return !settings() - || !settings()->suppressIncrementalRendering() + || !settings()->suppressesIncrementalRendering() || loadEventFinished(); } diff --git a/Source/WebCore/dom/Document.h b/Source/WebCore/dom/Document.h index a4bdad685..772e4cd6b 100644 --- a/Source/WebCore/dom/Document.h +++ b/Source/WebCore/dom/Document.h @@ -36,6 +36,7 @@ #include "DocumentEventQueue.h" #include "DocumentTiming.h" #include "IconURL.h" +#include "InspectorCounters.h" #include "IntRect.h" #include "LayoutTypes.h" #include "PageVisibilityState.h" @@ -350,6 +351,7 @@ public: virtual PassRefPtr<Element> createElementNS(const String& namespaceURI, const String& qualifiedName, ExceptionCode&); PassRefPtr<Element> createElement(const QualifiedName&, bool createdByParser); + bool cssRegionsEnabled() const; PassRefPtr<WebKitNamedFlow> webkitGetFlowByName(const String&); /** @@ -1113,6 +1115,10 @@ public: void didAddWheelEventHandler(); void didRemoveWheelEventHandler(); + unsigned touchEventHandlerCount() const { return m_touchEventHandlerCount; } + void didAddTouchEventHandler(); + void didRemoveTouchEventHandler(); + bool visualUpdatesAllowed() const; #if ENABLE(MICRODATA) @@ -1449,6 +1455,7 @@ private: unsigned m_writeRecursionDepth; unsigned m_wheelEventHandlerCount; + unsigned m_touchEventHandlerCount; #if ENABLE(REQUEST_ANIMATION_FRAME) RefPtr<ScriptedAnimationController> m_scriptedAnimationController; @@ -1481,6 +1488,7 @@ inline Node::Node(Document* document, ConstructionType type) #if !defined(NDEBUG) || (defined(DUMP_NODE_STATISTICS) && DUMP_NODE_STATISTICS) trackForDebugging(); #endif + InspectorCounters::incrementCounter(InspectorCounters::NodeCounter); } } // namespace WebCore diff --git a/Source/WebCore/dom/Document.idl b/Source/WebCore/dom/Document.idl index de7b04df1..b3e0aa3a0 100644 --- a/Source/WebCore/dom/Document.idl +++ b/Source/WebCore/dom/Document.idl @@ -21,7 +21,7 @@ module core { interface [ - JSCustomToJS, + CustomToJSObject, JSGenerateToNativeObject, JSInlineGetOwnPropertySlot ] Document : Node { @@ -31,55 +31,55 @@ module core { readonly attribute DOMImplementation implementation; readonly attribute Element documentElement; - [ReturnNewObject] Element createElement(in [TreatNullAs=NullString,Optional=CallWithDefaultValue] DOMString tagName) + [ReturnNewObject] Element createElement(in [TreatNullAs=NullString,Optional=DefaultIsUndefined] DOMString tagName) raises (DOMException); DocumentFragment createDocumentFragment(); - [ReturnNewObject] Text createTextNode(in [Optional=CallWithDefaultValue] DOMString data); - [ReturnNewObject] Comment createComment(in [Optional=CallWithDefaultValue] DOMString data); - [ReturnNewObject] CDATASection createCDATASection(in [Optional=CallWithDefaultValue] DOMString data) + [ReturnNewObject] Text createTextNode(in [Optional=DefaultIsUndefined] DOMString data); + [ReturnNewObject] Comment createComment(in [Optional=DefaultIsUndefined] DOMString data); + [ReturnNewObject] CDATASection createCDATASection(in [Optional=DefaultIsUndefined] DOMString data) raises(DOMException); - [ObjCLegacyUnnamedParameters, ReturnNewObject] ProcessingInstruction createProcessingInstruction(in [Optional=CallWithDefaultValue] DOMString target, - in [Optional=CallWithDefaultValue] DOMString data) + [ObjCLegacyUnnamedParameters, ReturnNewObject] ProcessingInstruction createProcessingInstruction(in [Optional=DefaultIsUndefined] DOMString target, + in [Optional=DefaultIsUndefined] DOMString data) raises (DOMException); - [ReturnNewObject] Attr createAttribute(in [Optional=CallWithDefaultValue] DOMString name) + [ReturnNewObject] Attr createAttribute(in [Optional=DefaultIsUndefined] DOMString name) raises (DOMException); - [ReturnNewObject] EntityReference createEntityReference(in [Optional=CallWithDefaultValue] DOMString name) + [ReturnNewObject] EntityReference createEntityReference(in [Optional=DefaultIsUndefined] DOMString name) raises(DOMException); - NodeList getElementsByTagName(in [Optional=CallWithDefaultValue] DOMString tagname); + NodeList getElementsByTagName(in [Optional=DefaultIsUndefined] DOMString tagname); // Introduced in DOM Level 2: - [ObjCLegacyUnnamedParameters, ReturnNewObject] Node importNode(in [Optional=CallWithDefaultValue] Node importedNode, + [ObjCLegacyUnnamedParameters, ReturnNewObject] Node importNode(in [Optional=DefaultIsUndefined] Node importedNode, in [Optional] boolean deep) raises (DOMException); - [ObjCLegacyUnnamedParameters, ReturnNewObject] Element createElementNS(in [TreatNullAs=NullString,Optional=CallWithDefaultValue] DOMString namespaceURI, - in [TreatNullAs=NullString,Optional=CallWithDefaultValue] DOMString qualifiedName) + [ObjCLegacyUnnamedParameters, ReturnNewObject] Element createElementNS(in [TreatNullAs=NullString,Optional=DefaultIsUndefined] DOMString namespaceURI, + in [TreatNullAs=NullString,Optional=DefaultIsUndefined] DOMString qualifiedName) raises (DOMException); - [ObjCLegacyUnnamedParameters, ReturnNewObject] Attr createAttributeNS(in [TreatNullAs=NullString,Optional=CallWithDefaultValue] DOMString namespaceURI, - in [TreatNullAs=NullString,Optional=CallWithDefaultValue] DOMString qualifiedName) + [ObjCLegacyUnnamedParameters, ReturnNewObject] Attr createAttributeNS(in [TreatNullAs=NullString,Optional=DefaultIsUndefined] DOMString namespaceURI, + in [TreatNullAs=NullString,Optional=DefaultIsUndefined] DOMString qualifiedName) raises (DOMException); - [ObjCLegacyUnnamedParameters] NodeList getElementsByTagNameNS(in [TreatNullAs=NullString,Optional=CallWithDefaultValue] DOMString namespaceURI, - in [Optional=CallWithDefaultValue] DOMString localName); - Element getElementById(in [Optional=CallWithDefaultValue] DOMString elementId); + [ObjCLegacyUnnamedParameters] NodeList getElementsByTagNameNS(in [TreatNullAs=NullString,Optional=DefaultIsUndefined] DOMString namespaceURI, + in [Optional=DefaultIsUndefined] DOMString localName); + Element getElementById(in [Optional=DefaultIsUndefined] DOMString elementId); // DOM Level 3 Core - readonly attribute [ConvertNullStringTo=Null] DOMString inputEncoding; + readonly attribute [TreatReturnedNullStringAs=Null] DOMString inputEncoding; - readonly attribute [ConvertNullStringTo=Null] DOMString xmlEncoding; - attribute [ConvertNullStringTo=Null, TreatNullAs=NullString] DOMString xmlVersion + readonly attribute [TreatReturnedNullStringAs=Null] DOMString xmlEncoding; + attribute [TreatReturnedNullStringAs=Null, TreatNullAs=NullString] DOMString xmlVersion setter raises (DOMException); attribute boolean xmlStandalone setter raises (DOMException); - Node adoptNode(in [Optional=CallWithDefaultValue] Node source) + Node adoptNode(in [Optional=DefaultIsUndefined] Node source) raises (DOMException); - attribute [ConvertNullStringTo=Null, TreatNullAs=NullString] DOMString documentURI; + attribute [TreatReturnedNullStringAs=Null, TreatNullAs=NullString] DOMString documentURI; // DOM Level 2 Events (DocumentEvents interface) - Event createEvent(in [Optional=CallWithDefaultValue] DOMString eventType) + Event createEvent(in [Optional=DefaultIsUndefined] DOMString eventType) raises(DOMException); // DOM Level 2 Tranversal and Range (DocumentRange interface) @@ -88,15 +88,15 @@ module core { // DOM Level 2 Tranversal and Range (DocumentTraversal interface) - [ObjCLegacyUnnamedParameters] NodeIterator createNodeIterator(in [Optional=CallWithDefaultValue] Node root, - in [Optional=CallWithDefaultValue] unsigned long whatToShow, - in [Optional=CallWithDefaultValue] NodeFilter filter, - in [Optional=CallWithDefaultValue] boolean expandEntityReferences) + [ObjCLegacyUnnamedParameters] NodeIterator createNodeIterator(in [Optional=DefaultIsUndefined] Node root, + in [Optional=DefaultIsUndefined] unsigned long whatToShow, + in [Optional=DefaultIsUndefined] NodeFilter filter, + in [Optional=DefaultIsUndefined] boolean expandEntityReferences) raises(DOMException); - [ObjCLegacyUnnamedParameters] TreeWalker createTreeWalker(in [Optional=CallWithDefaultValue] Node root, - in [Optional=CallWithDefaultValue] unsigned long whatToShow, - in [Optional=CallWithDefaultValue] NodeFilter filter, - in [Optional=CallWithDefaultValue] boolean expandEntityReferences) + [ObjCLegacyUnnamedParameters] TreeWalker createTreeWalker(in [Optional=DefaultIsUndefined] Node root, + in [Optional=DefaultIsUndefined] unsigned long whatToShow, + in [Optional=DefaultIsUndefined] NodeFilter filter, + in [Optional=DefaultIsUndefined] boolean expandEntityReferences) raises(DOMException); // DOM Level 2 Abstract Views (DocumentView interface) @@ -109,26 +109,26 @@ module core { // DOM Level 2 Style (DocumentCSS interface) - [ObjCLegacyUnnamedParameters] CSSStyleDeclaration getOverrideStyle(in [Optional=CallWithDefaultValue] Element element, - in [Optional=CallWithDefaultValue] DOMString pseudoElement); + [ObjCLegacyUnnamedParameters] CSSStyleDeclaration getOverrideStyle(in [Optional=DefaultIsUndefined] Element element, + in [Optional=DefaultIsUndefined] DOMString pseudoElement); // DOM Level 3 XPath (XPathEvaluator interface) - [ObjCLegacyUnnamedParameters] XPathExpression createExpression(in [Optional=CallWithDefaultValue] DOMString expression, - in [Optional=CallWithDefaultValue] XPathNSResolver resolver) + [ObjCLegacyUnnamedParameters] XPathExpression createExpression(in [Optional=DefaultIsUndefined] DOMString expression, + in [Optional=DefaultIsUndefined] XPathNSResolver resolver) raises(DOMException); XPathNSResolver createNSResolver(in Node nodeResolver); - [ObjCLegacyUnnamedParameters, V8Custom] XPathResult evaluate(in [Optional=CallWithDefaultValue] DOMString expression, - in [Optional=CallWithDefaultValue] Node contextNode, - in [Optional=CallWithDefaultValue] XPathNSResolver resolver, - in [Optional=CallWithDefaultValue] unsigned short type, - in [Optional=CallWithDefaultValue] XPathResult inResult) + [ObjCLegacyUnnamedParameters, V8Custom] XPathResult evaluate(in [Optional=DefaultIsUndefined] DOMString expression, + in [Optional=DefaultIsUndefined] Node contextNode, + in [Optional=DefaultIsUndefined] XPathNSResolver resolver, + in [Optional=DefaultIsUndefined] unsigned short type, + in [Optional=DefaultIsUndefined] XPathResult inResult) raises(DOMException); // Common extensions - boolean execCommand(in [Optional=CallWithDefaultValue] DOMString command, - in [Optional=CallWithDefaultValue] boolean userInterface, - in [TreatNullAs=NullString, TreatUndefinedAs=NullString,Optional=CallWithDefaultValue] DOMString value); + boolean execCommand(in [Optional=DefaultIsUndefined] DOMString command, + in [Optional=DefaultIsUndefined] boolean userInterface, + in [TreatNullAs=NullString, TreatUndefinedAs=NullString,Optional=DefaultIsUndefined] DOMString value); #if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C // FIXME: remove the these two versions once [Optional] is implemented for Objective-C. @@ -137,11 +137,11 @@ module core { boolean execCommand(in DOMString command); #endif - boolean queryCommandEnabled(in [Optional=CallWithDefaultValue] DOMString command); - boolean queryCommandIndeterm(in [Optional=CallWithDefaultValue] DOMString command); - boolean queryCommandState(in [Optional=CallWithDefaultValue] DOMString command); - boolean queryCommandSupported(in [Optional=CallWithDefaultValue] DOMString command); - [ConvertNullStringTo=False] DOMString queryCommandValue(in [Optional=CallWithDefaultValue] DOMString command); + boolean queryCommandEnabled(in [Optional=DefaultIsUndefined] DOMString command); + boolean queryCommandIndeterm(in [Optional=DefaultIsUndefined] DOMString command); + boolean queryCommandState(in [Optional=DefaultIsUndefined] DOMString command); + boolean queryCommandSupported(in [Optional=DefaultIsUndefined] DOMString command); + [TreatReturnedNullStringAs=False] DOMString queryCommandValue(in [Optional=DefaultIsUndefined] DOMString command); // Moved down from HTMLDocument @@ -172,10 +172,10 @@ module core { readonly attribute HTMLCollection anchors; readonly attribute DOMString lastModified; - NodeList getElementsByName(in [Optional=CallWithDefaultValue] DOMString elementName); + NodeList getElementsByName(in [Optional=DefaultIsUndefined] DOMString elementName); #if defined(ENABLE_MICRODATA) && ENABLE_MICRODATA - NodeList getItems(in [TreatNullAs=NullString, TreatUndefinedAs=NullString, Optional=CallWithDefaultValue] DOMString typeNames); + NodeList getItems(in [TreatNullAs=NullString, TreatUndefinedAs=NullString, Optional=DefaultIsUndefined] DOMString typeNames); #endif #if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT @@ -184,25 +184,25 @@ module core { // IE extensions - attribute [ConvertNullStringTo=Undefined, TreatNullAs=NullString] DOMString charset; - readonly attribute [ConvertNullStringTo=Undefined] DOMString defaultCharset; - readonly attribute [ConvertNullStringTo=Undefined] DOMString readyState; + attribute [TreatReturnedNullStringAs=Undefined, TreatNullAs=NullString] DOMString charset; + readonly attribute [TreatReturnedNullStringAs=Undefined] DOMString defaultCharset; + readonly attribute [TreatReturnedNullStringAs=Undefined] DOMString readyState; - Element elementFromPoint(in [Optional=CallWithDefaultValue] long x, - in [Optional=CallWithDefaultValue] long y); - Range caretRangeFromPoint(in [Optional=CallWithDefaultValue] long x, - in [Optional=CallWithDefaultValue] long y); + Element elementFromPoint(in [Optional=DefaultIsUndefined] long x, + in [Optional=DefaultIsUndefined] long y); + Range caretRangeFromPoint(in [Optional=DefaultIsUndefined] long x, + in [Optional=DefaultIsUndefined] long y); // Mozilla extensions #if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT DOMSelection getSelection(); #endif - readonly attribute [ConvertNullStringTo=Null] DOMString characterSet; + readonly attribute [TreatReturnedNullStringAs=Null] DOMString characterSet; // WebKit extensions - readonly attribute [ConvertNullStringTo=Null] DOMString preferredStylesheetSet; - attribute [ConvertNullStringTo=Null, TreatNullAs=NullString] DOMString selectedStylesheetSet; + readonly attribute [TreatReturnedNullStringAs=Null] DOMString preferredStylesheetSet; + attribute [TreatReturnedNullStringAs=Null, TreatNullAs=NullString] DOMString selectedStylesheetSet; #if !defined(LANGUAGE_JAVASCRIPT) || !LANGUAGE_JAVASCRIPT CSSStyleDeclaration createCSSStyleDeclaration(); @@ -230,7 +230,7 @@ module core { #endif // HTML 5 - NodeList getElementsByClassName(in [Optional=CallWithDefaultValue] DOMString tagname); + NodeList getElementsByClassName(in [Optional=DefaultIsUndefined] DOMString tagname); readonly attribute DOMString compatMode; @@ -325,17 +325,17 @@ module core { #endif #if defined(ENABLE_TOUCH_EVENTS) && ENABLE_TOUCH_EVENTS - [ReturnNewObject, V8EnabledAtRuntime] Touch createTouch(in [Optional=CallWithDefaultValue] DOMWindow window, - in [Optional=CallWithDefaultValue] EventTarget target, - in [Optional=CallWithDefaultValue] long identifier, - in [Optional=CallWithDefaultValue] long pageX, - in [Optional=CallWithDefaultValue] long pageY, - in [Optional=CallWithDefaultValue] long screenX, - in [Optional=CallWithDefaultValue] long screenY, - in [Optional=CallWithDefaultValue] long webkitRadiusX, - in [Optional=CallWithDefaultValue] long webkitRadiusY, - in [Optional=CallWithDefaultValue] float webkitRotationAngle, - in [Optional=CallWithDefaultValue] float webkitForce) + [ReturnNewObject, V8EnabledAtRuntime] Touch createTouch(in [Optional=DefaultIsUndefined] DOMWindow window, + in [Optional=DefaultIsUndefined] EventTarget target, + in [Optional=DefaultIsUndefined] long identifier, + in [Optional=DefaultIsUndefined] long pageX, + in [Optional=DefaultIsUndefined] long pageY, + in [Optional=DefaultIsUndefined] long screenX, + in [Optional=DefaultIsUndefined] long screenY, + in [Optional=DefaultIsUndefined] long webkitRadiusX, + in [Optional=DefaultIsUndefined] long webkitRadiusY, + in [Optional=DefaultIsUndefined] float webkitRotationAngle, + in [Optional=DefaultIsUndefined] float webkitForce) raises (DOMException); [ReturnNewObject, V8EnabledAtRuntime, Custom] TouchList createTouchList() raises (DOMException); diff --git a/Source/WebCore/dom/DocumentEventQueue.cpp b/Source/WebCore/dom/DocumentEventQueue.cpp index 31023e28d..5b899b3f5 100644 --- a/Source/WebCore/dom/DocumentEventQueue.cpp +++ b/Source/WebCore/dom/DocumentEventQueue.cpp @@ -64,6 +64,7 @@ DocumentEventQueue::DocumentEventQueue(ScriptExecutionContext* context) : m_pendingEventTimer(adoptPtr(new DocumentEventQueueTimer(this, context))) , m_isClosed(false) { + m_pendingEventTimer->suspendIfNeeded(); } DocumentEventQueue::~DocumentEventQueue() diff --git a/Source/WebCore/dom/DocumentOrderedMap.cpp b/Source/WebCore/dom/DocumentOrderedMap.cpp index 886b8bf08..bcb23b496 100644 --- a/Source/WebCore/dom/DocumentOrderedMap.cpp +++ b/Source/WebCore/dom/DocumentOrderedMap.cpp @@ -42,7 +42,7 @@ using namespace HTMLNames; inline bool keyMatchesId(AtomicStringImpl* key, Element* element) { - return element->hasID() && element->getIdAttribute().impl() == key; + return element->getIdAttribute().impl() == key; } inline bool keyMatchesMapName(AtomicStringImpl* key, Element* element) diff --git a/Source/WebCore/dom/DocumentType.idl b/Source/WebCore/dom/DocumentType.idl index ed146fa4f..729023271 100644 --- a/Source/WebCore/dom/DocumentType.idl +++ b/Source/WebCore/dom/DocumentType.idl @@ -31,9 +31,9 @@ module core { // DOM Level 2 - readonly attribute [ConvertNullStringTo=Null] DOMString publicId; - readonly attribute [ConvertNullStringTo=Null] DOMString systemId; - readonly attribute [ConvertNullStringTo=Null] DOMString internalSubset; + readonly attribute [TreatReturnedNullStringAs=Null] DOMString publicId; + readonly attribute [TreatReturnedNullStringAs=Null] DOMString systemId; + readonly attribute [TreatReturnedNullStringAs=Null] DOMString internalSubset; }; diff --git a/Source/WebCore/dom/Element.cpp b/Source/WebCore/dom/Element.cpp index 355f38adb..1b4d839db 100644 --- a/Source/WebCore/dom/Element.cpp +++ b/Source/WebCore/dom/Element.cpp @@ -57,6 +57,7 @@ #include "NodeRenderingContext.h" #include "Page.h" #include "RenderLayer.h" +#include "RenderRegion.h" #include "RenderView.h" #include "RenderWidget.h" #include "Settings.h" @@ -616,27 +617,28 @@ void Element::setAttribute(const AtomicString& name, const AtomicString& value, const AtomicString& localName = shouldIgnoreAttributeCase(this) ? name.lower() : name; - size_t index = ensureUpdatedAttributes()->getAttributeItemIndex(localName, false); - const QualifiedName& qName = index != notFound ? m_attributeMap->attributeItem(index)->name() : QualifiedName(nullAtom, localName, nullAtom); + size_t index = ensureUpdatedAttributeData()->getAttributeItemIndex(localName, false); + const QualifiedName& qName = index != notFound ? attributeItem(index)->name() : QualifiedName(nullAtom, localName, nullAtom); setAttributeInternal(index, qName, value); } void Element::setAttribute(const QualifiedName& name, const AtomicString& value) { - setAttributeInternal(ensureUpdatedAttributes()->getAttributeItemIndex(name), name, value); + setAttributeInternal(ensureUpdatedAttributeData()->getAttributeItemIndex(name), name, value); } inline void Element::setAttributeInternal(size_t index, const QualifiedName& name, const AtomicString& value) { - Attribute* old = index != notFound ? m_attributeMap->attributeItem(index) : 0; + ElementAttributeData* attributeData = &m_attributeMap->m_attributeData; + Attribute* old = index != notFound ? attributeData->attributeItem(index) : 0; if (value.isNull()) { if (old) - m_attributeMap->removeAttribute(index); + attributeData->removeAttribute(index, this); return; } if (!old) { - m_attributeMap->addAttribute(createAttribute(name, value)); + attributeData->addAttribute(Attribute::create(name, value), this); return; } @@ -650,11 +652,6 @@ inline void Element::setAttributeInternal(size_t index, const QualifiedName& nam didModifyAttribute(old); } -PassRefPtr<Attribute> Element::createAttribute(const QualifiedName& name, const AtomicString& value) -{ - return Attribute::create(name, value); -} - void Element::attributeChanged(Attribute* attr) { if (isIdAttributeName(attr->name())) @@ -662,12 +659,12 @@ void Element::attributeChanged(Attribute* attr) else if (attr->name() == HTMLNames::nameAttr) setHasName(!attr->isNull()); - recalcStyleIfNeededAfterAttributeChanged(attr); - updateAfterAttributeChanged(attr); -} + if (!needsStyleRecalc() && document()->attached()) { + CSSStyleSelector* styleSelector = document()->styleSelectorIfExists(); + if (!styleSelector || styleSelector->hasSelectorForAttribute(attr->name().localName())) + setNeedsStyleRecalc(); + } -void Element::updateAfterAttributeChanged(Attribute* attr) -{ invalidateNodeListsCacheAfterAttributeChanged(attr->name()); if (!AXObjectCache::accessibilityEnabled()) @@ -697,22 +694,9 @@ void Element::updateAfterAttributeChanged(Attribute* attr) else if (attrName == aria_invalidAttr) document()->axObjectCache()->postNotification(renderer(), AXObjectCache::AXInvalidStatusChanged, true); } - -void Element::recalcStyleIfNeededAfterAttributeChanged(Attribute* attr) -{ - if (needsStyleRecalc()) - return; - if (!document()->attached()) - return; - CSSStyleSelector* styleSelector = document()->styleSelectorIfExists(); - if (styleSelector && !styleSelector->hasSelectorForAttribute(attr->name().localName())) - return; - setNeedsStyleRecalc(); -} void Element::idAttributeChanged(Attribute* attr) { - setHasID(!attr->isNull()); if (attributeData()) { if (attr->isNull()) attributeData()->setIdForStyleResolution(nullAtom); @@ -750,27 +734,28 @@ void Element::parserSetAttributeMap(PassOwnPtr<NamedNodeMap> list, FragmentScrip m_attributeMap = list; if (m_attributeMap) { + ElementAttributeData* attributeData = &m_attributeMap->m_attributeData; m_attributeMap->m_element = this; // If the element is created as result of a paste or drag-n-drop operation // we want to remove all the script and event handlers. if (scriptingPermission == FragmentScriptingNotAllowed) { unsigned i = 0; while (i < m_attributeMap->length()) { - const QualifiedName& attributeName = m_attributeMap->m_attributes[i]->name(); + const QualifiedName& attributeName = attributeData->m_attributes[i]->name(); if (isEventHandlerAttribute(attributeName)) { - m_attributeMap->m_attributes.remove(i); + attributeData->m_attributes.remove(i); continue; } - if (isAttributeToRemove(attributeName, m_attributeMap->m_attributes[i]->value())) - m_attributeMap->m_attributes[i]->setValue(nullAtom); + if (isAttributeToRemove(attributeName, attributeData->m_attributes[i]->value())) + attributeData->m_attributes[i]->setValue(nullAtom); i++; } } // Store the set of attributes that changed on the stack in case // attributeChanged mutates m_attributeMap. Vector<RefPtr<Attribute> > attributes; - m_attributeMap->copyAttributesToVector(attributes); + attributeData->copyAttributesToVector(attributes); for (Vector<RefPtr<Attribute> >::iterator iter = attributes.begin(); iter != attributes.end(); ++iter) attributeChanged(iter->get()); } @@ -862,6 +847,8 @@ void Element::willRemove() if (containsFullScreenElement()) setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(false); #endif + if (ShadowRootList* shadowRoots = shadowRootList()) + shadowRoots->willRemove(); ContainerNode::willRemove(); } @@ -870,8 +857,8 @@ void Element::insertedIntoDocument() // need to do superclass processing first so inDocument() is true // by the time we reach updateId ContainerNode::insertedIntoDocument(); - if (ShadowRoot* shadow = shadowRoot()) - shadow->insertedIntoDocument(); + if (ShadowRootList* shadowRoots = shadowRootList()) + shadowRoots->insertedIntoDocument(); if (m_attributeMap) { if (hasID()) { @@ -903,8 +890,8 @@ void Element::removedFromDocument() } ContainerNode::removedFromDocument(); - if (ShadowRoot* shadow = shadowRoot()) - shadow->removedFromDocument(); + if (ShadowRootList* shadowRoots = shadowRootList()) + shadowRoots->removedFromDocument(); } void Element::insertedIntoTree(bool deep) @@ -912,8 +899,8 @@ void Element::insertedIntoTree(bool deep) ContainerNode::insertedIntoTree(deep); if (!deep) return; - if (ShadowRoot* shadow = shadowRoot()) - shadow->insertedIntoTree(true); + if (ShadowRootList* shadowRoots = shadowRootList()) + shadowRoots->insertedIntoTree(true); #if ENABLE(FULLSCREEN_API) if (containsFullScreenElement() && parentElement() && !parentElement()->containsFullScreenElement()) @@ -926,8 +913,8 @@ void Element::removedFromTree(bool deep) ContainerNode::removedFromTree(deep); if (!deep) return; - if (ShadowRoot* shadow = shadowRoot()) - shadow->removedFromTree(true); + if (ShadowRootList* shadowRoots = shadowRootList()) + shadowRoots->removedFromTree(true); } void Element::attach() @@ -939,10 +926,9 @@ void Element::attach() StyleSelectorParentPusher parentPusher(this); // When a shadow root exists, it does the work of attaching the children. - if (ShadowRoot* shadow = shadowRoot()) { + if (hasShadowRoot()) { parentPusher.push(); - Node::attach(); - shadow->attach(); + shadowRootList()->attach(); // In a shadow tree, some of light children may be attached by 'content' element. // However, when there is no content element or content element does not select @@ -951,6 +937,7 @@ void Element::attach() if (!child->attached()) child->attach(); } + Node::attach(); } else { if (firstChild()) parentPusher.push(); @@ -978,8 +965,8 @@ void Element::detach() if (hasRareData()) rareData()->resetComputedStyle(); ContainerNode::detach(); - if (ShadowRoot* shadow = shadowRoot()) - shadow->detach(); + if (ShadowRootList* shadowRoots = shadowRootList()) + shadowRoots->detach(); RenderWidget::resumeWidgetHierarchyUpdates(); } @@ -1121,7 +1108,7 @@ void Element::recalcStyle(StyleChange change) bool forceCheckOfAnyElementSibling = false; for (Node *n = firstChild(); n; n = n->nextSibling()) { if (n->isTextNode()) { - static_cast<Text*>(n)->recalcTextStyle(change); + toText(n)->recalcTextStyle(change); continue; } if (!n->isElementNode()) @@ -1138,10 +1125,11 @@ void Element::recalcStyle(StyleChange change) forceCheckOfAnyElementSibling = forceCheckOfAnyElementSibling || (childRulesChanged && hasIndirectAdjacentRules); } // FIXME: This does not care about sibling combinators. Will be necessary in XBL2 world. - if (ShadowRoot* shadow = shadowRoot()) { - if (change >= Inherit || shadow->childNeedsStyleRecalc() || shadow->needsStyleRecalc()) { + if (hasShadowRoot()) { + ShadowRootList* list = shadowRootList(); + if (change >= Inherit || list->childNeedsStyleRecalc() || list->needsStyleRecalc()) { parentPusher.push(); - shadow->recalcShadowTreeStyle(change); + list->recalcShadowTreeStyle(change); } } @@ -1152,9 +1140,19 @@ void Element::recalcStyle(StyleChange change) didRecalcStyle(change); } -ShadowRoot* Element::shadowRoot() const +bool Element::hasShadowRoot() const { - return hasRareData() ? rareData()->m_shadowRoot : 0; + if (ShadowRootList* list = shadowRootList()) + return list->hasShadowRoot(); + return false; +} + +ShadowRootList* Element::shadowRootList() const +{ + if (!hasRareData()) + return 0; + + return &rareData()->m_shadowRootList; } static bool validateShadowRoot(Document* document, ShadowRoot* shadowRoot, ExceptionCode& ec) @@ -1175,16 +1173,19 @@ static bool validateShadowRoot(Document* document, ShadowRoot* shadowRoot, Excep return true; } -void Element::setShadowRoot(PassRefPtr<ShadowRoot> prpShadowRoot, ExceptionCode& ec) +void Element::setShadowRoot(PassRefPtr<ShadowRoot> shadowRoot, ExceptionCode& ec) { - RefPtr<ShadowRoot> shadowRoot = prpShadowRoot; if (!validateShadowRoot(document(), shadowRoot.get(), ec)) return; + if (!hasRareData()) + ensureRareData(); + removeShadowRoot(); - ensureRareData()->m_shadowRoot = shadowRoot.get(); shadowRoot->setShadowHost(this); + shadowRootList()->pushShadowRoot(shadowRoot.get()); + if (inDocument()) shadowRoot->insertedIntoDocument(); if (attached()) { @@ -1196,23 +1197,20 @@ void Element::setShadowRoot(PassRefPtr<ShadowRoot> prpShadowRoot, ExceptionCode& ShadowRoot* Element::ensureShadowRoot() { - if (ShadowRoot* existingRoot = shadowRoot()) - return existingRoot; + if (hasShadowRoot()) + return shadowRootList()->oldestShadowRoot(); return ShadowRoot::create(this, ShadowRoot::CreatingUserAgentShadowRoot).get(); } void Element::removeShadowRoot() { - if (!hasRareData()) + if (!hasShadowRoot()) return; - ElementRareData* data = rareData(); - if (RefPtr<ShadowRoot> oldRoot = data->m_shadowRoot) { - data->m_shadowRoot = 0; + while (RefPtr<ShadowRoot> oldRoot = shadowRootList()->popShadowRoot()) { document()->removeFocusedNodeOfSubtree(oldRoot.get()); - // Remove from rendering tree if (oldRoot->attached()) oldRoot->detach(); @@ -1223,9 +1221,10 @@ void Element::removeShadowRoot() else oldRoot->removedFromTree(true); if (attached()) { - for (Node* child = firstChild(); child; child = child->nextSibling()) + for (Node* child = firstChild(); child; child = child->nextSibling()) { if (!child->attached()) child->lazyAttach(); + } } } } @@ -1361,8 +1360,8 @@ void Element::childrenChanged(bool changedByParser, Node* beforeChange, Node* af checkForSiblingStyleChanges(this, renderStyle(), false, beforeChange, afterChange, childCountDelta); if (hasRareData()) { - if (ShadowRoot* root = shadowRoot()) - root->hostChildrenChanged(); + if (hasShadowRoot()) + shadowRootList()->hostChildrenChanged(); } } @@ -1473,15 +1472,16 @@ void Element::setAttributeNS(const AtomicString& namespaceURI, const AtomicStrin void Element::removeAttribute(const String& name) { - if (!m_attributeMap) + ElementAttributeData* attributeData = this->attributeData(); + if (!attributeData) return; String localName = shouldIgnoreAttributeCase(this) ? name.lower() : name; - size_t index = m_attributeMap->getAttributeItemIndex(localName, false); + size_t index = attributeData->getAttributeItemIndex(localName, false); if (index == notFound) return; - m_attributeMap->removeAttribute(index); + attributeData->removeAttribute(index, this); } void Element::removeAttributeNS(const String& namespaceURI, const String& localName) @@ -1508,22 +1508,22 @@ PassRefPtr<Attr> Element::getAttributeNodeNS(const String& namespaceURI, const S bool Element::hasAttribute(const String& name) const { - NamedNodeMap* attrs = updatedAttributes(); - if (!attrs) + ElementAttributeData* attributeData = updatedAttributeData(); + if (!attributeData) return false; // This call to String::lower() seems to be required but // there may be a way to remove it. String localName = shouldIgnoreAttributeCase(this) ? name.lower() : name; - return attrs->getAttributeItem(localName, false); + return attributeData->getAttributeItem(localName, false); } bool Element::hasAttributeNS(const String& namespaceURI, const String& localName) const { - NamedNodeMap* attrs = updatedAttributes(); - if (!attrs) + ElementAttributeData* attributeData = updatedAttributeData(); + if (!attributeData) return false; - return attrs->getAttributeItem(QualifiedName(nullAtom, localName, namespaceURI)); + return attributeData->getAttributeItem(QualifiedName(nullAtom, localName, namespaceURI)); } CSSStyleDeclaration *Element::style() @@ -1558,7 +1558,7 @@ void Element::focus(bool restorePreviousSelection) // If a focus event handler changes the focus to a different node it // does not make sense to continue and update appearence. protect = this; - if (shadowRoot() && page->focusController()->transferFocusToElementInShadowRoot(this, restorePreviousSelection)) + if (hasShadowRoot() && page->focusController()->transferFocusToElementInShadowRoot(this, restorePreviousSelection)) return; if (!page->focusController()->setFocusedNode(this, doc->frame())) return; @@ -1710,15 +1710,12 @@ void Element::cancelFocusAppearanceUpdate() void Element::normalizeAttributes() { - NamedNodeMap* attrs = updatedAttributes(); - if (!attrs) - return; - - if (attrs->isEmpty()) + ElementAttributeData* attributeData = updatedAttributeData(); + if (!attributeData || attributeData->isEmpty()) return; Vector<RefPtr<Attribute> > attributeVector; - attrs->copyAttributesToVector(attributeVector); + attributeData->copyAttributesToVector(attributeVector); size_t numAttrs = attributeVector.size(); for (size_t i = 0; i < numAttrs; ++i) { if (Attr* attr = attributeVector[i]->attr()) @@ -1751,30 +1748,6 @@ unsigned Element::childElementCount() const return count; } -#if ENABLE(STYLE_SCOPED) -bool Element::hasScopedHTMLStyleChild() const -{ - return hasRareData() && rareData()->hasScopedHTMLStyleChild(); -} - -size_t Element::numberOfScopedHTMLStyleChildren() const -{ - return hasRareData() ? rareData()->numberOfScopedHTMLStyleChildren() : 0; -} - -void Element::registerScopedHTMLStyleChild() -{ - ensureRareData()->registerScopedHTMLStyleChild(); -} - -void Element::unregisterScopedHTMLStyleChild() -{ - ASSERT(hasRareData()); - if (hasRareData()) - rareData()->unregisterScopedHTMLStyleChild(); -} -#endif - bool Element::webkitMatchesSelector(const String& selector, ExceptionCode& ec) { if (selector.isEmpty()) { @@ -1879,13 +1852,13 @@ void Element::setUnsignedIntegralAttribute(const QualifiedName& attributeName, u } #if ENABLE(SVG) -bool Element::childShouldCreateRenderer(Node* child) const +bool Element::childShouldCreateRenderer(const NodeRenderingContext& childContext) const { // Only create renderers for SVG elements whose parents are SVG elements, or for proper <svg xmlns="svgNS"> subdocuments. - if (child->isSVGElement()) - return child->hasTagName(SVGNames::svgTag) || isSVGElement(); + if (childContext.node()->isSVGElement()) + return childContext.node()->hasTagName(SVGNames::svgTag) || isSVGElement(); - return Node::childShouldCreateRenderer(child); + return Node::childShouldCreateRenderer(childContext); } #endif @@ -1971,6 +1944,33 @@ PassRefPtr<WebKitAnimationList> Element::webkitGetAnimations() const return animController->animationsForRenderer(renderer()); } +const AtomicString& Element::webkitRegionOverflow() const +{ + document()->updateLayoutIgnorePendingStylesheets(); + + if (document()->cssRegionsEnabled() && renderer() && renderer()->isRenderRegion()) { + RenderRegion* region = toRenderRegion(renderer()); + switch (region->regionState()) { + case RenderRegion::RegionFit: { + DEFINE_STATIC_LOCAL(AtomicString, fitState, ("fit")); + return fitState; + } + case RenderRegion::RegionEmpty: { + DEFINE_STATIC_LOCAL(AtomicString, emptyState, ("empty")); + return emptyState; + } + case RenderRegion::RegionOverflow: { + DEFINE_STATIC_LOCAL(AtomicString, overflowState, ("overflow")); + return overflowState; + } + default: + break; + } + } + DEFINE_STATIC_LOCAL(AtomicString, undefinedState, ("undefined")); + return undefinedState; +} + #ifndef NDEBUG bool Element::fastAttributeLookupAllowed(const QualifiedName& name) const { @@ -2004,7 +2004,7 @@ void Element::willModifyAttribute(const QualifiedName& name, const AtomicString& #if ENABLE(INSPECTOR) if (!isSynchronizingStyleAttribute()) - InspectorInstrumentation::willModifyDOMAttr(document(), this); + InspectorInstrumentation::willModifyDOMAttr(document(), this, oldValue, newValue); #endif } diff --git a/Source/WebCore/dom/Element.h b/Source/WebCore/dom/Element.h index 9381e2f58..c9a1139a9 100644 --- a/Source/WebCore/dom/Element.h +++ b/Source/WebCore/dom/Element.h @@ -42,6 +42,7 @@ class DOMTokenList; class ElementRareData; class IntSize; class ShadowRoot; +class ShadowRootList; class WebKitAnimationList; enum SpellcheckAttributeState { @@ -147,6 +148,8 @@ public: const AtomicString& getIdAttribute() const; void setIdAttribute(const AtomicString&); + const AtomicString& getNameAttribute() const; + // Call this to get the value of the id attribute for style resolution purposes. // The value will already be lowercased if the document is in compatibility mode, // so this function is not suitable for non-style uses. @@ -236,14 +239,10 @@ public: // Only called by the parser immediately after element construction. void parserSetAttributeMap(PassOwnPtr<NamedNodeMap>, FragmentScriptingPermission); - NamedNodeMap* attributeMap() const { return m_attributeMap.get(); } - NamedNodeMap* ensureAttributeMap() const; - ElementAttributeData* attributeData() const { return m_attributeMap ? m_attributeMap->attributeData() : 0; } - ElementAttributeData* ensureAttributeData() const { return ensureUpdatedAttributes()->attributeData(); } - - // FIXME: This method should be removed once AttributeData is moved to Element. - ElementAttributeData* ensureAttributeDataWithoutUpdate() const { return ensureAttributeMap()->attributeData(); } + ElementAttributeData* ensureAttributeData() const; + ElementAttributeData* updatedAttributeData() const; + ElementAttributeData* ensureUpdatedAttributeData() const; void setAttributesFromElement(const Element&); @@ -254,7 +253,11 @@ public: virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); void recalcStyle(StyleChange = NoChange); - ShadowRoot* shadowRoot() const; + bool hasShadowRoot() const; + ShadowRootList* shadowRootList() const; + + // FIXME: These API will be moved to ShadowRootList. + // https://bugs.webkit.org/show_bug.cgi?id=78313 void setShadowRoot(PassRefPtr<ShadowRoot>, ExceptionCode&); ShadowRoot* ensureShadowRoot(); void removeShadowRoot(); @@ -323,13 +326,6 @@ public: Element* nextElementSibling() const; unsigned childElementCount() const; -#if ENABLE(STYLE_SCOPED) - void registerScopedHTMLStyleChild(); - void unregisterScopedHTMLStyleChild(); - bool hasScopedHTMLStyleChild() const; - size_t numberOfScopedHTMLStyleChildren() const; -#endif - bool webkitMatchesSelector(const String& selectors, ExceptionCode&); DOMTokenList* classList(); @@ -376,7 +372,7 @@ public: virtual void dispatchFormControlChangeEvent() { } #if ENABLE(SVG) - virtual bool childShouldCreateRenderer(Node*) const; + virtual bool childShouldCreateRenderer(const NodeRenderingContext&) const; #endif #if ENABLE(FULLSCREEN_API) @@ -396,7 +392,10 @@ public: PassRefPtr<RenderStyle> styleForRenderer(); - PassRefPtr<Attribute> createAttribute(const QualifiedName&, const AtomicString& value); + const AtomicString& webkitRegionOverflow() const; + + bool hasID() const; + bool hasClass() const; protected: Element(const QualifiedName& tagName, Document* document, ConstructionType type) @@ -418,11 +417,6 @@ protected: virtual bool shouldRegisterAsNamedItem() const { return false; } virtual bool shouldRegisterAsExtraNamedItem() const { return false; } - // The implementation of Element::attributeChanged() calls the following two functions. - // They are separated to allow a different flow of control in StyledElement::attributeChanged(). - void recalcStyleIfNeededAfterAttributeChanged(Attribute*); - void updateAfterAttributeChanged(Attribute*); - void idAttributeChanged(Attribute*); HTMLCollection* ensureCachedHTMLCollection(CollectionType); @@ -539,7 +533,9 @@ inline Element* Element::nextElementSibling() const inline NamedNodeMap* Element::ensureUpdatedAttributes() const { updateInvalidAttributes(); - return ensureAttributeMap(); + if (!m_attributeMap) + createAttributeMap(); + return m_attributeMap.get(); } inline NamedNodeMap* Element::updatedAttributes() const @@ -548,10 +544,29 @@ inline NamedNodeMap* Element::updatedAttributes() const return m_attributeMap.get(); } +inline ElementAttributeData* Element::ensureAttributeData() const +{ + if (!m_attributeMap) + createAttributeMap(); + return m_attributeMap->attributeData(); +} + +inline ElementAttributeData* Element::updatedAttributeData() const +{ + updateInvalidAttributes(); + return attributeData(); +} + +inline ElementAttributeData* Element::ensureUpdatedAttributeData() const +{ + updateInvalidAttributes(); + return ensureAttributeData(); +} + inline void Element::setAttributesFromElement(const Element& other) { - if (NamedNodeMap* attributeMap = other.updatedAttributes()) - ensureUpdatedAttributes()->setAttributes(*attributeMap); + if (ElementAttributeData* attributeData = other.updatedAttributeData()) + ensureUpdatedAttributeData()->setAttributes(*attributeData, this); } inline void Element::updateName(const AtomicString& oldName, const AtomicString& newName) @@ -628,7 +643,12 @@ inline bool Element::isIdAttributeName(const QualifiedName& attributeName) const inline const AtomicString& Element::getIdAttribute() const { - return fastGetAttribute(document()->idAttributeName()); + return hasID() ? fastGetAttribute(document()->idAttributeName()) : nullAtom; +} + +inline const AtomicString& Element::getNameAttribute() const +{ + return hasName() ? fastGetAttribute(HTMLNames::nameAttr) : nullAtom; } inline void Element::setIdAttribute(const AtomicString& value) @@ -660,13 +680,6 @@ inline void Element::removeAttribute(unsigned index) m_attributeMap->removeAttribute(index); } -inline NamedNodeMap* Element::ensureAttributeMap() const -{ - if (!m_attributeMap) - createAttributeMap(); - return m_attributeMap.get(); -} - inline void Element::updateInvalidAttributes() const { if (!isStyleAttributeValid()) @@ -687,6 +700,27 @@ inline Element* firstElementChild(const ContainerNode* container) return static_cast<Element*>(child); } +inline bool Element::hasID() const +{ + return attributeData() && attributeData()->hasID(); +} + +inline bool Element::hasClass() const +{ + return attributeData() && attributeData()->hasClass(); +} + +// Put here to make them inline. +inline bool Node::hasID() const +{ + return isElementNode() && toElement(this)->hasID(); +} + +inline bool Node::hasClass() const +{ + return isElementNode() && toElement(this)->hasClass(); +} + } // namespace #endif diff --git a/Source/WebCore/dom/Element.idl b/Source/WebCore/dom/Element.idl index 20d4c8e11..c66b14592 100644 --- a/Source/WebCore/dom/Element.idl +++ b/Source/WebCore/dom/Element.idl @@ -22,44 +22,45 @@ module core { interface [ JSGenerateToNativeObject, - JSInlineGetOwnPropertySlot + JSInlineGetOwnPropertySlot, + V8CustomToJSObject ] Element : Node { // DOM Level 1 Core - readonly attribute [ConvertNullStringTo=Null] DOMString tagName; + readonly attribute [TreatReturnedNullStringAs=Null] DOMString tagName; - [ConvertNullStringTo=Null] DOMString getAttribute(in [Optional=CallWithDefaultValue] DOMString name); - [ObjCLegacyUnnamedParameters] void setAttribute(in [Optional=CallWithDefaultValue] DOMString name, - in [Optional=CallWithDefaultValue] DOMString value) + [TreatReturnedNullStringAs=Null] DOMString getAttribute(in [Optional=DefaultIsUndefined] DOMString name); + [ObjCLegacyUnnamedParameters] void setAttribute(in [Optional=DefaultIsUndefined] DOMString name, + in [Optional=DefaultIsUndefined] DOMString value) raises(DOMException); - void removeAttribute(in [Optional=CallWithDefaultValue] DOMString name); - Attr getAttributeNode(in [Optional=CallWithDefaultValue] DOMString name); - Attr setAttributeNode(in [Optional=CallWithDefaultValue] Attr newAttr) + void removeAttribute(in [Optional=DefaultIsUndefined] DOMString name); + Attr getAttributeNode(in [Optional=DefaultIsUndefined] DOMString name); + Attr setAttributeNode(in [Optional=DefaultIsUndefined] Attr newAttr) raises(DOMException); - Attr removeAttributeNode(in [Optional=CallWithDefaultValue] Attr oldAttr) + Attr removeAttributeNode(in [Optional=DefaultIsUndefined] Attr oldAttr) raises(DOMException); - NodeList getElementsByTagName(in [Optional=CallWithDefaultValue] DOMString name); + NodeList getElementsByTagName(in [Optional=DefaultIsUndefined] DOMString name); // DOM Level 2 Core - [ObjCLegacyUnnamedParameters] DOMString getAttributeNS(in [TreatNullAs=NullString,Optional=CallWithDefaultValue] DOMString namespaceURI, - in [Optional=CallWithDefaultValue] DOMString localName); - [ObjCLegacyUnnamedParameters] void setAttributeNS(in [TreatNullAs=NullString,Optional=CallWithDefaultValue] DOMString namespaceURI, - in [Optional=CallWithDefaultValue] DOMString qualifiedName, - in [Optional=CallWithDefaultValue] DOMString value) + [ObjCLegacyUnnamedParameters] DOMString getAttributeNS(in [TreatNullAs=NullString,Optional=DefaultIsUndefined] DOMString namespaceURI, + in [Optional=DefaultIsUndefined] DOMString localName); + [ObjCLegacyUnnamedParameters] void setAttributeNS(in [TreatNullAs=NullString,Optional=DefaultIsUndefined] DOMString namespaceURI, + in [Optional=DefaultIsUndefined] DOMString qualifiedName, + in [Optional=DefaultIsUndefined] DOMString value) raises(DOMException); [ObjCLegacyUnnamedParameters] void removeAttributeNS(in [TreatNullAs=NullString] DOMString namespaceURI, in DOMString localName); - [ObjCLegacyUnnamedParameters] NodeList getElementsByTagNameNS(in [TreatNullAs=NullString,Optional=CallWithDefaultValue] DOMString namespaceURI, - in [Optional=CallWithDefaultValue] DOMString localName); - [ObjCLegacyUnnamedParameters] Attr getAttributeNodeNS(in [TreatNullAs=NullString,Optional=CallWithDefaultValue] DOMString namespaceURI, - in [Optional=CallWithDefaultValue] DOMString localName); - Attr setAttributeNodeNS(in [Optional=CallWithDefaultValue] Attr newAttr) + [ObjCLegacyUnnamedParameters] NodeList getElementsByTagNameNS(in [TreatNullAs=NullString,Optional=DefaultIsUndefined] DOMString namespaceURI, + in [Optional=DefaultIsUndefined] DOMString localName); + [ObjCLegacyUnnamedParameters] Attr getAttributeNodeNS(in [TreatNullAs=NullString,Optional=DefaultIsUndefined] DOMString namespaceURI, + in [Optional=DefaultIsUndefined] DOMString localName); + Attr setAttributeNodeNS(in [Optional=DefaultIsUndefined] Attr newAttr) raises(DOMException); boolean hasAttribute(in DOMString name); - [ObjCLegacyUnnamedParameters] boolean hasAttributeNS(in [TreatNullAs=NullString,Optional=CallWithDefaultValue] DOMString namespaceURI, - in [Optional=CallWithDefaultValue] DOMString localName); + [ObjCLegacyUnnamedParameters] boolean hasAttributeNS(in [TreatNullAs=NullString,Optional=DefaultIsUndefined] DOMString namespaceURI, + in [Optional=DefaultIsUndefined] DOMString localName); readonly attribute CSSStyleDeclaration style; @@ -86,15 +87,15 @@ module core { // WebKit extensions void scrollIntoViewIfNeeded(in [Optional] boolean centerIfNeeded); - void scrollByLines(in [Optional=CallWithDefaultValue] long lines); - void scrollByPages(in [Optional=CallWithDefaultValue] long pages); + void scrollByLines(in [Optional=DefaultIsUndefined] long lines); + void scrollByPages(in [Optional=DefaultIsUndefined] long pages); #if defined(ENABLE_ANIMATION_API) && ENABLE_ANIMATION_API WebKitAnimationList webkitGetAnimations(); #endif // HTML 5 - NodeList getElementsByClassName(in [Optional=CallWithDefaultValue] DOMString name); + NodeList getElementsByClassName(in [Optional=DefaultIsUndefined] DOMString name); #if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT readonly attribute DOMStringMap dataset; @@ -107,7 +108,7 @@ module core { raises(DOMException); // WebKit extension, pending specification. - boolean webkitMatchesSelector(in [Optional=CallWithDefaultValue] DOMString selectors) + boolean webkitMatchesSelector(in [Optional=DefaultIsUndefined] DOMString selectors) raises(DOMException); // ElementTraversal API @@ -130,9 +131,12 @@ module core { #if defined(ENABLE_FULLSCREEN_API) && ENABLE_FULLSCREEN_API const unsigned short ALLOW_KEYBOARD_INPUT = 1; - [V8EnabledAtRuntime] void webkitRequestFullScreen(in [Optional=CallWithDefaultValue] unsigned short flags); + [V8EnabledAtRuntime] void webkitRequestFullScreen(in [Optional=DefaultIsUndefined] unsigned short flags); #endif + // CSS Regions API + readonly attribute DOMString webkitRegionOverflow; + #if !defined(LANGUAGE_OBJECTIVE_C) || !LANGUAGE_OBJECTIVE_C // Event handler DOM attributes attribute [NotEnumerable] EventListener onabort; diff --git a/Source/WebCore/dom/ElementAttributeData.cpp b/Source/WebCore/dom/ElementAttributeData.cpp index cea62f3cf..71457f4b1 100644 --- a/Source/WebCore/dom/ElementAttributeData.cpp +++ b/Source/WebCore/dom/ElementAttributeData.cpp @@ -26,38 +26,159 @@ #include "config.h" #include "ElementAttributeData.h" +#include "Attr.h" #include "StyledElement.h" namespace WebCore { +ElementAttributeData::~ElementAttributeData() +{ + detachAttributesFromElement(); +} + void ElementAttributeData::setClass(const String& className, bool shouldFoldCase) { m_classNames.set(className, shouldFoldCase); } -StylePropertySet* ElementAttributeData::ensureInlineStyleDecl(Element* element) +StylePropertySet* ElementAttributeData::ensureInlineStyleDecl(StyledElement* element) { if (!m_inlineStyleDecl) { ASSERT(element->isStyledElement()); - m_inlineStyleDecl = StylePropertySet::createInline(static_cast<StyledElement*>(element)); + m_inlineStyleDecl = StylePropertySet::create(); m_inlineStyleDecl->setStrictParsing(element->isHTMLElement() && !element->document()->inQuirksMode()); } return m_inlineStyleDecl.get(); } -void ElementAttributeData::destroyInlineStyleDecl() +void ElementAttributeData::destroyInlineStyleDecl(StyledElement* element) { if (!m_inlineStyleDecl) return; - m_inlineStyleDecl->clearParentElement(); + m_inlineStyleDecl->clearParentElement(element); m_inlineStyleDecl = 0; } -StylePropertySet* ElementAttributeData::ensureAttributeStyle(StyledElement* element) +void ElementAttributeData::addAttribute(PassRefPtr<Attribute> prpAttribute, Element* element) +{ + RefPtr<Attribute> attribute = prpAttribute; + + if (element) + element->willModifyAttribute(attribute->name(), nullAtom, attribute->value()); + + m_attributes.append(attribute); + if (Attr* attr = attribute->attr()) + attr->m_element = element; + + if (element) + element->didModifyAttribute(attribute.get()); +} + +void ElementAttributeData::removeAttribute(size_t index, Element* element) +{ + ASSERT(index < length()); + + RefPtr<Attribute> attribute = m_attributes[index]; + + if (element) + element->willRemoveAttribute(attribute->name(), attribute->value()); + + if (Attr* attr = attribute->attr()) + attr->m_element = 0; + m_attributes.remove(index); + + if (element) + element->didRemoveAttribute(attribute.get()); +} + +void ElementAttributeData::detachAttributesFromElement() +{ + size_t size = m_attributes.size(); + for (size_t i = 0; i < size; i++) { + if (Attr* attr = m_attributes[i]->attr()) + attr->m_element = 0; + } +} + +void ElementAttributeData::copyAttributesToVector(Vector<RefPtr<Attribute> >& copy) +{ + copy = m_attributes; +} + +size_t ElementAttributeData::getAttributeItemIndexSlowCase(const String& name, bool shouldIgnoreAttributeCase) const +{ + unsigned len = length(); + + // Continue to checking case-insensitively and/or full namespaced names if necessary: + for (unsigned i = 0; i < len; ++i) { + const QualifiedName& attrName = m_attributes[i]->name(); + if (!attrName.hasPrefix()) { + if (shouldIgnoreAttributeCase && equalIgnoringCase(name, attrName.localName())) + return i; + } else { + // FIXME: Would be faster to do this comparison without calling toString, which + // generates a temporary string by concatenation. But this branch is only reached + // if the attribute name has a prefix, which is rare in HTML. + if (equalPossiblyIgnoringCase(name, attrName.toString(), shouldIgnoreAttributeCase)) + return i; + } + } + return notFound; +} + +void ElementAttributeData::setAttributes(const ElementAttributeData& other, Element* element) +{ + ASSERT(element); + + // If assigning the map changes the id attribute, we need to call + // updateId. + Attribute* oldId = getAttributeItem(element->document()->idAttributeName()); + Attribute* newId = other.getAttributeItem(element->document()->idAttributeName()); + + if (oldId || newId) + element->updateId(oldId ? oldId->value() : nullAtom, newId ? newId->value() : nullAtom); + + Attribute* oldName = getAttributeItem(HTMLNames::nameAttr); + Attribute* newName = other.getAttributeItem(HTMLNames::nameAttr); + + if (oldName || newName) + element->updateName(oldName ? oldName->value() : nullAtom, newName ? newName->value() : nullAtom); + + clearAttributes(); + unsigned newLength = other.length(); + m_attributes.resize(newLength); + + // FIXME: These loops can probably be combined. + for (unsigned i = 0; i < newLength; i++) + m_attributes[i] = other.m_attributes[i]->clone(); + for (unsigned i = 0; i < newLength; i++) + element->attributeChanged(m_attributes[i].get()); +} + +void ElementAttributeData::clearAttributes() { - if (!m_attributeStyle) - m_attributeStyle = StylePropertySet::createAttributeStyle(element); - return m_attributeStyle.get(); + clearClass(); + detachAttributesFromElement(); + m_attributes.clear(); +} + +void ElementAttributeData::replaceAttribute(size_t index, PassRefPtr<Attribute> prpAttribute, Element* element) +{ + ASSERT(element); + ASSERT(index < length()); + + RefPtr<Attribute> attribute = prpAttribute; + Attribute* old = m_attributes[index].get(); + + element->willModifyAttribute(attribute->name(), old->value(), attribute->value()); + + if (Attr* attr = old->attr()) + attr->m_element = 0; + m_attributes[index] = attribute; + if (Attr* attr = attribute->attr()) + attr->m_element = element; + + element->didModifyAttribute(attribute.get()); } } diff --git a/Source/WebCore/dom/ElementAttributeData.h b/Source/WebCore/dom/ElementAttributeData.h index 408065981..be145617c 100644 --- a/Source/WebCore/dom/ElementAttributeData.h +++ b/Source/WebCore/dom/ElementAttributeData.h @@ -26,8 +26,10 @@ #ifndef ElementAttributeData_h #define ElementAttributeData_h +#include "Attribute.h" #include "SpaceSplitString.h" #include "StylePropertySet.h" +#include <wtf/NotFound.h> namespace WebCore { @@ -35,6 +37,8 @@ class Element; class ElementAttributeData { public: + ~ElementAttributeData(); + void clearClass() { m_classNames.clear(); } void setClass(const String& className, bool shouldFoldCase); const SpaceSplitString& classNames() const { return m_classNames; } @@ -43,25 +47,109 @@ public: void setIdForStyleResolution(const AtomicString& newId) { m_idForStyleResolution = newId; } StylePropertySet* inlineStyleDecl() { return m_inlineStyleDecl.get(); } - StylePropertySet* ensureInlineStyleDecl(Element*); - void destroyInlineStyleDecl(); + StylePropertySet* ensureInlineStyleDecl(StyledElement*); + void destroyInlineStyleDecl(StyledElement* element); StylePropertySet* attributeStyle() const { return m_attributeStyle.get(); } - StylePropertySet* ensureAttributeStyle(StyledElement*); + void setAttributeStyle(PassRefPtr<StylePropertySet> style) { m_attributeStyle = style; } + + size_t length() const { return m_attributes.size(); } + bool isEmpty() const { return m_attributes.isEmpty(); } + + // Internal interface. + Attribute* attributeItem(unsigned index) const { return m_attributes[index].get(); } + Attribute* getAttributeItem(const QualifiedName&) const; + size_t getAttributeItemIndex(const QualifiedName&) const; + + // These functions do no error checking. + void addAttribute(PassRefPtr<Attribute>, Element*); + void removeAttribute(const QualifiedName&, Element*); + void removeAttribute(size_t index, Element*); + + bool hasID() const { return !m_idForStyleResolution.isNull(); } + bool hasClass() const { return !m_classNames.isNull(); } private: + friend class Element; friend class NamedNodeMap; ElementAttributeData() { } + void detachAttributesFromElement(); + void copyAttributesToVector(Vector<RefPtr<Attribute> >&); + Attribute* getAttributeItem(const String& name, bool shouldIgnoreAttributeCase) const; + size_t getAttributeItemIndex(const String& name, bool shouldIgnoreAttributeCase) const; + size_t getAttributeItemIndexSlowCase(const String& name, bool shouldIgnoreAttributeCase) const; + void setAttributes(const ElementAttributeData& other, Element*); + void clearAttributes(); + void replaceAttribute(size_t index, PassRefPtr<Attribute>, Element*); + RefPtr<StylePropertySet> m_inlineStyleDecl; RefPtr<StylePropertySet> m_attributeStyle; SpaceSplitString m_classNames; AtomicString m_idForStyleResolution; + Vector<RefPtr<Attribute>, 4> m_attributes; }; +inline void ElementAttributeData::removeAttribute(const QualifiedName& name, Element* element) +{ + size_t index = getAttributeItemIndex(name); + if (index == notFound) + return; + + removeAttribute(index, element); +} + +inline Attribute* ElementAttributeData::getAttributeItem(const String& name, bool shouldIgnoreAttributeCase) const +{ + size_t index = getAttributeItemIndex(name, shouldIgnoreAttributeCase); + if (index != notFound) + return m_attributes[index].get(); + return 0; +} + +inline Attribute* ElementAttributeData::getAttributeItem(const QualifiedName& name) const +{ + size_t index = getAttributeItemIndex(name); + if (index != notFound) + return m_attributes[index].get(); + return 0; +} + +// We use a boolean parameter instead of calling shouldIgnoreAttributeCase so that the caller +// can tune the behavior (hasAttribute is case sensitive whereas getAttribute is not). +inline size_t ElementAttributeData::getAttributeItemIndex(const QualifiedName& name) const +{ + size_t len = length(); + for (unsigned i = 0; i < len; ++i) { + if (m_attributes[i]->name().matches(name)) + return i; + } + return notFound; +} + +inline size_t ElementAttributeData::getAttributeItemIndex(const String& name, bool shouldIgnoreAttributeCase) const +{ + unsigned len = length(); + bool doSlowCheck = shouldIgnoreAttributeCase; + + // Optimize for the case where the attribute exists and its name exactly matches. + for (unsigned i = 0; i < len; ++i) { + const QualifiedName& attrName = m_attributes[i]->name(); + if (!attrName.hasPrefix()) { + if (name == attrName.localName()) + return i; + } else + doSlowCheck = true; + } + + if (doSlowCheck) + return getAttributeItemIndexSlowCase(name, shouldIgnoreAttributeCase); + return notFound; +} + } #endif // ElementAttributeData_h diff --git a/Source/WebCore/dom/ElementRareData.h b/Source/WebCore/dom/ElementRareData.h index ca32115e6..ff45783bd 100644 --- a/Source/WebCore/dom/ElementRareData.h +++ b/Source/WebCore/dom/ElementRareData.h @@ -27,12 +27,11 @@ #include "Element.h" #include "HTMLCollection.h" #include "NodeRareData.h" +#include "ShadowRootList.h" #include <wtf/OwnPtr.h> namespace WebCore { -class ShadowRoot; - class ElementRareData : public NodeRareData { public: ElementRareData(); @@ -40,13 +39,6 @@ public: void resetComputedStyle(); -#if ENABLE(STYLE_SCOPED) - void registerScopedHTMLStyleChild(); - void unregisterScopedHTMLStyleChild(); - bool hasScopedHTMLStyleChild() const; - size_t numberOfScopedHTMLStyleChildren() const; -#endif - using NodeRareData::needsFocusAppearanceUpdateSoonAfterAttach; using NodeRareData::setNeedsFocusAppearanceUpdateSoonAfterAttach; @@ -72,13 +64,9 @@ public: LayoutSize m_minimumSizeForResizing; RefPtr<RenderStyle> m_computedStyle; - ShadowRoot* m_shadowRoot; + ShadowRootList m_shadowRootList; AtomicString m_shadowPseudoId; -#if ENABLE(STYLE_SCOPED) - size_t m_numberOfScopedHTMLStyleChildren; -#endif - OwnPtr<DatasetDOMStringMap> m_datasetDOMStringMap; OwnPtr<ClassList> m_classList; @@ -95,11 +83,8 @@ inline IntSize defaultMinimumSizeForResizing() } inline ElementRareData::ElementRareData() - : m_minimumSizeForResizing(defaultMinimumSizeForResizing()) - , m_shadowRoot(0) -#if ENABLE(STYLE_SCOPED) - , m_numberOfScopedHTMLStyleChildren(0) -#endif + : NodeRareData() + , m_minimumSizeForResizing(defaultMinimumSizeForResizing()) , m_styleAffectedByEmpty(false) #if ENABLE(FULLSCREEN_API) , m_containsFullScreenElement(false) @@ -109,7 +94,7 @@ inline ElementRareData::ElementRareData() inline ElementRareData::~ElementRareData() { - ASSERT(!m_shadowRoot); + ASSERT(!m_shadowRootList.hasShadowRoot()); } inline void ElementRareData::resetComputedStyle() @@ -117,29 +102,5 @@ inline void ElementRareData::resetComputedStyle() m_computedStyle.clear(); } -#if ENABLE(STYLE_SCOPED) -inline void ElementRareData::registerScopedHTMLStyleChild() -{ - ++m_numberOfScopedHTMLStyleChildren; -} - -inline void ElementRareData::unregisterScopedHTMLStyleChild() -{ - ASSERT(m_numberOfScopedHTMLStyleChildren > 0); - if (m_numberOfScopedHTMLStyleChildren > 0) - --m_numberOfScopedHTMLStyleChildren; -} - -inline bool ElementRareData::hasScopedHTMLStyleChild() const -{ - return m_numberOfScopedHTMLStyleChildren; -} - -inline size_t ElementRareData::numberOfScopedHTMLStyleChildren() const -{ - return m_numberOfScopedHTMLStyleChildren; -} -#endif - } #endif // ElementRareData_h diff --git a/Source/WebCore/dom/Entity.idl b/Source/WebCore/dom/Entity.idl index 8dacbe90a..b9ec406b9 100644 --- a/Source/WebCore/dom/Entity.idl +++ b/Source/WebCore/dom/Entity.idl @@ -20,9 +20,9 @@ module core { interface Entity : Node { - readonly attribute [ConvertNullStringTo=Null] DOMString publicId; - readonly attribute [ConvertNullStringTo=Null] DOMString systemId; - readonly attribute [ConvertNullStringTo=Null] DOMString notationName; + readonly attribute [TreatReturnedNullStringAs=Null] DOMString publicId; + readonly attribute [TreatReturnedNullStringAs=Null] DOMString systemId; + readonly attribute [TreatReturnedNullStringAs=Null] DOMString notationName; }; } diff --git a/Source/WebCore/dom/Event.idl b/Source/WebCore/dom/Event.idl index 94d45427e..2abd5a950 100644 --- a/Source/WebCore/dom/Event.idl +++ b/Source/WebCore/dom/Event.idl @@ -22,7 +22,7 @@ module events { // Introduced in DOM Level 2: interface [ - JSCustomToJS, + CustomToJSObject, ConstructorTemplate=Event, JSNoStaticTables, ObjCPolymorphic @@ -63,9 +63,9 @@ module events { void stopPropagation(); void preventDefault(); - [ObjCLegacyUnnamedParameters] void initEvent(in [Optional=CallWithDefaultValue] DOMString eventTypeArg, - in [Optional=CallWithDefaultValue] boolean canBubbleArg, - in [Optional=CallWithDefaultValue] boolean cancelableArg); + [ObjCLegacyUnnamedParameters] void initEvent(in [Optional=DefaultIsUndefined] DOMString eventTypeArg, + in [Optional=DefaultIsUndefined] boolean canBubbleArg, + in [Optional=DefaultIsUndefined] boolean cancelableArg); // DOM Level 3 Additions. readonly attribute boolean defaultPrevented; diff --git a/Source/WebCore/dom/EventDispatcher.cpp b/Source/WebCore/dom/EventDispatcher.cpp index 7573832ba..3ee5285bc 100644 --- a/Source/WebCore/dom/EventDispatcher.cpp +++ b/Source/WebCore/dom/EventDispatcher.cpp @@ -127,7 +127,7 @@ static inline bool isShadowRootOrSVGShadowRoot(const Node* node) static inline bool isShadowHost(Node* node) { - return node->isElementNode() && toElement(node)->shadowRoot(); + return node->isElementNode() && toElement(node)->hasShadowRoot(); } PassRefPtr<EventTarget> EventDispatcher::adjustToShadowBoundaries(PassRefPtr<Node> relatedTarget, const Vector<Node*> relatedTargetAncestors) diff --git a/Source/WebCore/dom/EventSender.h b/Source/WebCore/dom/EventSender.h new file mode 100644 index 000000000..646034c32 --- /dev/null +++ b/Source/WebCore/dom/EventSender.h @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2012 Apple 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. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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 EventSender_h +#define EventSender_h + +#include "Timer.h" +#include <wtf/Vector.h> + +namespace WebCore { + +template<typename T> class EventSender { + WTF_MAKE_NONCOPYABLE(EventSender); WTF_MAKE_FAST_ALLOCATED; +public: + explicit EventSender(const AtomicString& eventType); + + const AtomicString& eventType() const { return m_eventType; } + void dispatchEventSoon(T*); + void cancelEvent(T*); + void dispatchPendingEvents(); + +#ifndef NDEBUG + bool hasPendingEvents(T* sender) const + { + return m_dispatchSoonList.find(sender) != notFound || m_dispatchingList.find(sender) != notFound; + } +#endif + +private: + void timerFired(Timer<EventSender<T> >*) { dispatchPendingEvents(); } + + AtomicString m_eventType; + Timer<EventSender<T> > m_timer; + Vector<T*> m_dispatchSoonList; + Vector<T*> m_dispatchingList; +}; + +template<typename T> EventSender<T>::EventSender(const AtomicString& eventType) + : m_eventType(eventType) + , m_timer(this, &EventSender::timerFired) +{ +} + +template<typename T> void EventSender<T>::dispatchEventSoon(T* sender) +{ + m_dispatchSoonList.append(sender); + if (!m_timer.isActive()) + m_timer.startOneShot(0); +} + +template<typename T> void EventSender<T>::cancelEvent(T* sender) +{ + // Remove instances of this sender from both lists. + // Use loops because we allow multiple instances to get into the lists. + size_t size = m_dispatchSoonList.size(); + for (size_t i = 0; i < size; ++i) { + if (m_dispatchSoonList[i] == sender) + m_dispatchSoonList[i] = 0; + } + size = m_dispatchingList.size(); + for (size_t i = 0; i < size; ++i) { + if (m_dispatchingList[i] == sender) + m_dispatchingList[i] = 0; + } +} + +template<typename T> void EventSender<T>::dispatchPendingEvents() +{ + // Need to avoid re-entering this function; if new dispatches are + // scheduled before the parent finishes processing the list, they + // will set a timer and eventually be processed. + if (!m_dispatchingList.isEmpty()) + return; + + m_timer.stop(); + + m_dispatchSoonList.checkConsistency(); + + m_dispatchingList.swap(m_dispatchSoonList); + size_t size = m_dispatchingList.size(); + for (size_t i = 0; i < size; ++i) { + if (T* sender = m_dispatchingList[i]) { + m_dispatchingList[i] = 0; + sender->dispatchPendingEvent(this); + } + } + m_dispatchingList.clear(); +} + +} // namespace WebCore + +#endif // EventSender_h diff --git a/Source/WebCore/dom/HashChangeEvent.idl b/Source/WebCore/dom/HashChangeEvent.idl index b2b48877b..6c80a957f 100644 --- a/Source/WebCore/dom/HashChangeEvent.idl +++ b/Source/WebCore/dom/HashChangeEvent.idl @@ -23,11 +23,11 @@ module events { interface [ ConstructorTemplate=Event ] HashChangeEvent : Event { - void initHashChangeEvent(in [Optional=CallWithDefaultValue] DOMString type, - in [Optional=CallWithDefaultValue] boolean canBubble, - in [Optional=CallWithDefaultValue] boolean cancelable, - in [Optional=CallWithDefaultValue] DOMString oldURL, - in [Optional=CallWithDefaultValue] DOMString newURL); + void initHashChangeEvent(in [Optional=DefaultIsUndefined] DOMString type, + in [Optional=DefaultIsUndefined] boolean canBubble, + in [Optional=DefaultIsUndefined] boolean cancelable, + in [Optional=DefaultIsUndefined] DOMString oldURL, + in [Optional=DefaultIsUndefined] DOMString newURL); readonly attribute [InitializedByEventConstructor] DOMString oldURL; readonly attribute [InitializedByEventConstructor] DOMString newURL; }; diff --git a/Source/WebCore/dom/KeyboardEvent.idl b/Source/WebCore/dom/KeyboardEvent.idl index e71361f67..2c2b7ba11 100644 --- a/Source/WebCore/dom/KeyboardEvent.idl +++ b/Source/WebCore/dom/KeyboardEvent.idl @@ -40,37 +40,37 @@ module events { readonly attribute boolean altGraphKey; #if !defined(LANGUAGE_JAVASCRIPT) || !LANGUAGE_JAVASCRIPT - boolean getModifierState(in [Optional=CallWithDefaultValue] DOMString keyIdentifierArg); + boolean getModifierState(in [Optional=DefaultIsUndefined] DOMString keyIdentifierArg); #endif // FIXME: this does not match the version in the DOM spec. - void initKeyboardEvent(in [Optional=CallWithDefaultValue] DOMString type, - in [Optional=CallWithDefaultValue] boolean canBubble, - in [Optional=CallWithDefaultValue] boolean cancelable, - in [Optional=CallWithDefaultValue] DOMWindow view, - in [Optional=CallWithDefaultValue] DOMString keyIdentifier, - in [Optional=CallWithDefaultValue] unsigned long keyLocation, - in [Optional=CallWithDefaultValue] boolean ctrlKey, - in [Optional=CallWithDefaultValue] boolean altKey, - in [Optional=CallWithDefaultValue] boolean shiftKey, - in [Optional=CallWithDefaultValue] boolean metaKey, - in [Optional=CallWithDefaultValue] boolean altGraphKey); + void initKeyboardEvent(in [Optional=DefaultIsUndefined] DOMString type, + in [Optional=DefaultIsUndefined] boolean canBubble, + in [Optional=DefaultIsUndefined] boolean cancelable, + in [Optional=DefaultIsUndefined] DOMWindow view, + in [Optional=DefaultIsUndefined] DOMString keyIdentifier, + in [Optional=DefaultIsUndefined] unsigned long keyLocation, + in [Optional=DefaultIsUndefined] boolean ctrlKey, + in [Optional=DefaultIsUndefined] boolean altKey, + in [Optional=DefaultIsUndefined] boolean shiftKey, + in [Optional=DefaultIsUndefined] boolean metaKey, + in [Optional=DefaultIsUndefined] boolean altGraphKey); // WebKit Extensions #if !defined(LANGUAGE_JAVASCRIPT) || !LANGUAGE_JAVASCRIPT readonly attribute long keyCode; readonly attribute long charCode; - void initKeyboardEvent(in [Optional=CallWithDefaultValue] DOMString type, - in [Optional=CallWithDefaultValue] boolean canBubble, - in [Optional=CallWithDefaultValue] boolean cancelable, - in [Optional=CallWithDefaultValue] DOMWindow view, - in [Optional=CallWithDefaultValue] DOMString keyIdentifier, - in [Optional=CallWithDefaultValue] unsigned long keyLocation, - in [Optional=CallWithDefaultValue] boolean ctrlKey, - in [Optional=CallWithDefaultValue] boolean altKey, - in [Optional=CallWithDefaultValue] boolean shiftKey, - in [Optional=CallWithDefaultValue] boolean metaKey); + void initKeyboardEvent(in [Optional=DefaultIsUndefined] DOMString type, + in [Optional=DefaultIsUndefined] boolean canBubble, + in [Optional=DefaultIsUndefined] boolean cancelable, + in [Optional=DefaultIsUndefined] DOMWindow view, + in [Optional=DefaultIsUndefined] DOMString keyIdentifier, + in [Optional=DefaultIsUndefined] unsigned long keyLocation, + in [Optional=DefaultIsUndefined] boolean ctrlKey, + in [Optional=DefaultIsUndefined] boolean altKey, + in [Optional=DefaultIsUndefined] boolean shiftKey, + in [Optional=DefaultIsUndefined] boolean metaKey); #endif }; diff --git a/Source/WebCore/dom/MessageEvent.idl b/Source/WebCore/dom/MessageEvent.idl index 123235929..c8356ed60 100644 --- a/Source/WebCore/dom/MessageEvent.idl +++ b/Source/WebCore/dom/MessageEvent.idl @@ -38,23 +38,23 @@ module events { readonly attribute [InitializedByEventConstructor, CachedAttribute, CustomGetter] DOMObject data; readonly attribute [InitializedByEventConstructor, CustomGetter] Array ports; - [Custom] void initMessageEvent(in [Optional=CallWithDefaultValue] DOMString typeArg, - in [Optional=CallWithDefaultValue] boolean canBubbleArg, - in [Optional=CallWithDefaultValue] boolean cancelableArg, - in [Optional=CallWithDefaultValue] DOMObject dataArg, - in [Optional=CallWithDefaultValue] DOMString originArg, - in [Optional=CallWithDefaultValue] DOMString lastEventIdArg, - in [Optional=CallWithDefaultValue] DOMWindow sourceArg, - in [Optional=CallWithDefaultValue] Array messagePorts); + [Custom] void initMessageEvent(in [Optional=DefaultIsUndefined] DOMString typeArg, + in [Optional=DefaultIsUndefined] boolean canBubbleArg, + in [Optional=DefaultIsUndefined] boolean cancelableArg, + in [Optional=DefaultIsUndefined] DOMObject dataArg, + in [Optional=DefaultIsUndefined] DOMString originArg, + in [Optional=DefaultIsUndefined] DOMString lastEventIdArg, + in [Optional=DefaultIsUndefined] DOMWindow sourceArg, + in [Optional=DefaultIsUndefined] Array messagePorts); - [Custom] void webkitInitMessageEvent(in [Optional=CallWithDefaultValue] DOMString typeArg, - in [Optional=CallWithDefaultValue] boolean canBubbleArg, - in [Optional=CallWithDefaultValue] boolean cancelableArg, - in [Optional=CallWithDefaultValue] DOMObject dataArg, - in [Optional=CallWithDefaultValue] DOMString originArg, - in [Optional=CallWithDefaultValue] DOMString lastEventIdArg, - in [Optional=CallWithDefaultValue] DOMWindow sourceArg, - in [Optional=CallWithDefaultValue] Array transferables); + [Custom] void webkitInitMessageEvent(in [Optional=DefaultIsUndefined] DOMString typeArg, + in [Optional=DefaultIsUndefined] boolean canBubbleArg, + in [Optional=DefaultIsUndefined] boolean cancelableArg, + in [Optional=DefaultIsUndefined] DOMObject dataArg, + in [Optional=DefaultIsUndefined] DOMString originArg, + in [Optional=DefaultIsUndefined] DOMString lastEventIdArg, + in [Optional=DefaultIsUndefined] DOMWindow sourceArg, + in [Optional=DefaultIsUndefined] Array transferables); #else // Code generator for ObjC bindings does not support custom bindings, thus there is no good way to // return a variant value. As workaround, expose the data attribute as SerializedScriptValue. @@ -63,14 +63,14 @@ module events { // There's no good way to expose an array via the ObjC bindings, so for now just expose a single port. readonly attribute MessagePort messagePort; - void initMessageEvent(in [Optional=CallWithDefaultValue] DOMString typeArg, - in [Optional=CallWithDefaultValue] boolean canBubbleArg, - in [Optional=CallWithDefaultValue] boolean cancelableArg, - in [Optional=CallWithDefaultValue] SerializedScriptValue dataArg, - in [Optional=CallWithDefaultValue] DOMString originArg, - in [Optional=CallWithDefaultValue] DOMString lastEventIdArg, - in [Optional=CallWithDefaultValue] DOMWindow sourceArg, - in [Optional=CallWithDefaultValue] MessagePort messagePort); + void initMessageEvent(in [Optional=DefaultIsUndefined] DOMString typeArg, + in [Optional=DefaultIsUndefined] boolean canBubbleArg, + in [Optional=DefaultIsUndefined] boolean cancelableArg, + in [Optional=DefaultIsUndefined] SerializedScriptValue dataArg, + in [Optional=DefaultIsUndefined] DOMString originArg, + in [Optional=DefaultIsUndefined] DOMString lastEventIdArg, + in [Optional=DefaultIsUndefined] DOMWindow sourceArg, + in [Optional=DefaultIsUndefined] MessagePort messagePort); #endif }; diff --git a/Source/WebCore/dom/MouseEvent.idl b/Source/WebCore/dom/MouseEvent.idl index 3ece01c50..48eff1e3e 100644 --- a/Source/WebCore/dom/MouseEvent.idl +++ b/Source/WebCore/dom/MouseEvent.idl @@ -34,21 +34,21 @@ module events { readonly attribute unsigned short button; readonly attribute EventTarget relatedTarget; - [ObjCLegacyUnnamedParameters] void initMouseEvent(in [Optional=CallWithDefaultValue] DOMString type, - in [Optional=CallWithDefaultValue] boolean canBubble, - in [Optional=CallWithDefaultValue] boolean cancelable, - in [Optional=CallWithDefaultValue] DOMWindow view, - in [Optional=CallWithDefaultValue] long detail, - in [Optional=CallWithDefaultValue] long screenX, - in [Optional=CallWithDefaultValue] long screenY, - in [Optional=CallWithDefaultValue] long clientX, - in [Optional=CallWithDefaultValue] long clientY, - in [Optional=CallWithDefaultValue] boolean ctrlKey, - in [Optional=CallWithDefaultValue] boolean altKey, - in [Optional=CallWithDefaultValue] boolean shiftKey, - in [Optional=CallWithDefaultValue] boolean metaKey, - in [Optional=CallWithDefaultValue] unsigned short button, - in [Optional=CallWithDefaultValue] EventTarget relatedTarget); + [ObjCLegacyUnnamedParameters] void initMouseEvent(in [Optional=DefaultIsUndefined] DOMString type, + in [Optional=DefaultIsUndefined] boolean canBubble, + in [Optional=DefaultIsUndefined] boolean cancelable, + in [Optional=DefaultIsUndefined] DOMWindow view, + in [Optional=DefaultIsUndefined] long detail, + in [Optional=DefaultIsUndefined] long screenX, + in [Optional=DefaultIsUndefined] long screenY, + in [Optional=DefaultIsUndefined] long clientX, + in [Optional=DefaultIsUndefined] long clientY, + in [Optional=DefaultIsUndefined] boolean ctrlKey, + in [Optional=DefaultIsUndefined] boolean altKey, + in [Optional=DefaultIsUndefined] boolean shiftKey, + in [Optional=DefaultIsUndefined] boolean metaKey, + in [Optional=DefaultIsUndefined] unsigned short button, + in [Optional=DefaultIsUndefined] EventTarget relatedTarget); // extensions readonly attribute long offsetX; diff --git a/Source/WebCore/dom/MutationEvent.idl b/Source/WebCore/dom/MutationEvent.idl index 5aee2e560..2765dc9c2 100644 --- a/Source/WebCore/dom/MutationEvent.idl +++ b/Source/WebCore/dom/MutationEvent.idl @@ -33,14 +33,14 @@ module events { readonly attribute DOMString attrName; readonly attribute unsigned short attrChange; - [ObjCLegacyUnnamedParameters] void initMutationEvent(in [Optional=CallWithDefaultValue] DOMString type, - in [Optional=CallWithDefaultValue] boolean canBubble, - in [Optional=CallWithDefaultValue] boolean cancelable, - in [Optional=CallWithDefaultValue] Node relatedNode, - in [Optional=CallWithDefaultValue] DOMString prevValue, - in [Optional=CallWithDefaultValue] DOMString newValue, - in [Optional=CallWithDefaultValue] DOMString attrName, - in [Optional=CallWithDefaultValue] unsigned short attrChange); + [ObjCLegacyUnnamedParameters] void initMutationEvent(in [Optional=DefaultIsUndefined] DOMString type, + in [Optional=DefaultIsUndefined] boolean canBubble, + in [Optional=DefaultIsUndefined] boolean cancelable, + in [Optional=DefaultIsUndefined] Node relatedNode, + in [Optional=DefaultIsUndefined] DOMString prevValue, + in [Optional=DefaultIsUndefined] DOMString newValue, + in [Optional=DefaultIsUndefined] DOMString attrName, + in [Optional=DefaultIsUndefined] unsigned short attrChange); }; diff --git a/Source/WebCore/dom/MutationRecord.idl b/Source/WebCore/dom/MutationRecord.idl index c19b41f21..a7883c50f 100644 --- a/Source/WebCore/dom/MutationRecord.idl +++ b/Source/WebCore/dom/MutationRecord.idl @@ -41,8 +41,8 @@ module core { readonly attribute Node nextSibling; readonly attribute DOMString attributeName; - readonly attribute [ConvertNullStringTo=Null] DOMString attributeNamespace; + readonly attribute [TreatReturnedNullStringAs=Null] DOMString attributeNamespace; - readonly attribute [ConvertNullStringTo=Null] DOMString oldValue; + readonly attribute [TreatReturnedNullStringAs=Null] DOMString oldValue; }; } diff --git a/Source/WebCore/dom/NameNodeList.cpp b/Source/WebCore/dom/NameNodeList.cpp index df63a8cfe..47268fe72 100644 --- a/Source/WebCore/dom/NameNodeList.cpp +++ b/Source/WebCore/dom/NameNodeList.cpp @@ -44,7 +44,7 @@ NameNodeList::~NameNodeList() bool NameNodeList::nodeMatches(Element* testNode) const { - return testNode->fastGetAttribute(nameAttr) == m_nodeName; + return testNode->getNameAttribute() == m_nodeName; } } // namespace WebCore diff --git a/Source/WebCore/dom/NamedNodeMap.cpp b/Source/WebCore/dom/NamedNodeMap.cpp index 0a32a66ca..47145970e 100644 --- a/Source/WebCore/dom/NamedNodeMap.cpp +++ b/Source/WebCore/dom/NamedNodeMap.cpp @@ -40,15 +40,6 @@ static inline bool shouldIgnoreAttributeCase(const Element* e) return e && e->document()->isHTMLDocument() && e->isHTMLElement(); } -inline void NamedNodeMap::detachAttributesFromElement() -{ - size_t size = m_attributes.size(); - for (size_t i = 0; i < size; i++) { - if (Attr* attr = m_attributes[i]->attr()) - attr->m_element = 0; - } -} - void NamedNodeMap::ref() { ASSERT(m_element); @@ -61,14 +52,9 @@ void NamedNodeMap::deref() m_element->deref(); } -NamedNodeMap::~NamedNodeMap() -{ - detachAttributesFromElement(); -} - PassRefPtr<Node> NamedNodeMap::getNamedItem(const String& name) const { - Attribute* a = getAttributeItem(name, shouldIgnoreAttributeCase(m_element)); + Attribute* a = m_attributeData.getAttributeItem(name, shouldIgnoreAttributeCase(m_element)); if (!a) return 0; @@ -82,7 +68,7 @@ PassRefPtr<Node> NamedNodeMap::getNamedItemNS(const String& namespaceURI, const PassRefPtr<Node> NamedNodeMap::removeNamedItem(const String& name, ExceptionCode& ec) { - Attribute* a = getAttributeItem(name, shouldIgnoreAttributeCase(m_element)); + Attribute* a = m_attributeData.getAttributeItem(name, shouldIgnoreAttributeCase(m_element)); if (!a) { ec = NOT_FOUND_ERR; return 0; @@ -135,9 +121,9 @@ PassRefPtr<Node> NamedNodeMap::setNamedItem(Node* node, ExceptionCode& ec) RefPtr<Attr> oldAttr; if (oldAttribute) { oldAttr = oldAttribute->createAttrIfNeeded(m_element); - replaceAttribute(index, attribute); + m_attributeData.replaceAttribute(index, attribute, m_element); } else - addAttribute(attribute); + m_attributeData.addAttribute(attribute, m_element); return oldAttr.release(); } @@ -157,7 +143,7 @@ PassRefPtr<Node> NamedNodeMap::removeNamedItem(const QualifiedName& name, Except return 0; } - RefPtr<Attr> attr = m_attributes[index]->createAttrIfNeeded(m_element); + RefPtr<Attr> attr = m_attributeData.m_attributes[index]->createAttrIfNeeded(m_element); removeAttribute(index); @@ -169,40 +155,7 @@ PassRefPtr<Node> NamedNodeMap::item(unsigned index) const if (index >= length()) return 0; - return m_attributes[index]->createAttrIfNeeded(m_element); -} - -void NamedNodeMap::copyAttributesToVector(Vector<RefPtr<Attribute> >& copy) -{ - copy = m_attributes; -} - -size_t NamedNodeMap::getAttributeItemIndexSlowCase(const String& name, bool shouldIgnoreAttributeCase) const -{ - unsigned len = length(); - - // Continue to checking case-insensitively and/or full namespaced names if necessary: - for (unsigned i = 0; i < len; ++i) { - const QualifiedName& attrName = m_attributes[i]->name(); - if (!attrName.hasPrefix()) { - if (shouldIgnoreAttributeCase && equalIgnoringCase(name, attrName.localName())) - return i; - } else { - // FIXME: Would be faster to do this comparison without calling toString, which - // generates a temporary string by concatenation. But this branch is only reached - // if the attribute name has a prefix, which is rare in HTML. - if (equalPossiblyIgnoringCase(name, attrName.toString(), shouldIgnoreAttributeCase)) - return i; - } - } - return notFound; -} - -void NamedNodeMap::clearAttributes() -{ - attributeData()->clearClass(); - detachAttributesFromElement(); - m_attributes.clear(); + return m_attributeData.m_attributes[index]->createAttrIfNeeded(m_element); } void NamedNodeMap::detachFromElement() @@ -212,90 +165,7 @@ void NamedNodeMap::detachFromElement() // of that, we can simply clear all the attributes to avoid accessing stale // pointers to do things like create Attr objects. m_element = 0; - clearAttributes(); -} - -void NamedNodeMap::setAttributes(const NamedNodeMap& other) -{ - // clone all attributes in the other map, but attach to our element - if (!m_element) - return; - - // If assigning the map changes the id attribute, we need to call - // updateId. - Attribute* oldId = getAttributeItem(m_element->document()->idAttributeName()); - Attribute* newId = other.getAttributeItem(m_element->document()->idAttributeName()); - - if (oldId || newId) - m_element->updateId(oldId ? oldId->value() : nullAtom, newId ? newId->value() : nullAtom); - - Attribute* oldName = getAttributeItem(HTMLNames::nameAttr); - Attribute* newName = other.getAttributeItem(HTMLNames::nameAttr); - - if (oldName || newName) - m_element->updateName(oldName ? oldName->value() : nullAtom, newName ? newName->value() : nullAtom); - - clearAttributes(); - unsigned newLength = other.length(); - m_attributes.resize(newLength); - - // FIXME: These loops can probably be combined. - for (unsigned i = 0; i < newLength; i++) - m_attributes[i] = other.m_attributes[i]->clone(); - for (unsigned i = 0; i < newLength; i++) - m_element->attributeChanged(m_attributes[i].get()); -} - -void NamedNodeMap::addAttribute(PassRefPtr<Attribute> prpAttribute) -{ - RefPtr<Attribute> attribute = prpAttribute; - - if (m_element) - m_element->willModifyAttribute(attribute->name(), nullAtom, attribute->value()); - - m_attributes.append(attribute); - if (Attr* attr = attribute->attr()) - attr->m_element = m_element; - - if (m_element) - m_element->didModifyAttribute(attribute.get()); -} - -void NamedNodeMap::removeAttribute(size_t index) -{ - ASSERT(index < length()); - - RefPtr<Attribute> attribute = m_attributes[index]; - - if (m_element) - m_element->willRemoveAttribute(attribute->name(), attribute->value()); - - if (Attr* attr = attribute->attr()) - attr->m_element = 0; - m_attributes.remove(index); - - if (m_element) - m_element->didRemoveAttribute(attribute.get()); -} - -void NamedNodeMap::replaceAttribute(size_t index, PassRefPtr<Attribute> prpAttribute) -{ - ASSERT(index < length()); - - RefPtr<Attribute> attribute = prpAttribute; - Attribute* old = m_attributes[index].get(); - - if (m_element) - m_element->willModifyAttribute(attribute->name(), old->value(), attribute->value()); - - if (Attr* attr = old->attr()) - attr->m_element = 0; - m_attributes[index] = attribute; - if (Attr* attr = attribute->attr()) - attr->m_element = m_element; - - if (m_element) - m_element->didModifyAttribute(attribute.get()); + m_attributeData.clearAttributes(); } bool NamedNodeMap::mapsEquivalent(const NamedNodeMap* otherMap) const diff --git a/Source/WebCore/dom/NamedNodeMap.h b/Source/WebCore/dom/NamedNodeMap.h index 6bdde0fb3..3201fcd08 100644 --- a/Source/WebCore/dom/NamedNodeMap.h +++ b/Source/WebCore/dom/NamedNodeMap.h @@ -25,10 +25,8 @@ #ifndef NamedNodeMap_h #define NamedNodeMap_h -#include "Attribute.h" #include "ElementAttributeData.h" #include "SpaceSplitString.h" -#include <wtf/NotFound.h> namespace WebCore { @@ -44,8 +42,6 @@ public: return adoptPtr(new NamedNodeMap(element)); } - ~NamedNodeMap(); - void ref(); void deref(); @@ -63,19 +59,17 @@ public: PassRefPtr<Node> setNamedItemNS(Node*, ExceptionCode&); PassRefPtr<Node> item(unsigned index) const; - size_t length() const { return m_attributes.size(); } - bool isEmpty() const { return !length(); } + size_t length() const { return m_attributeData.length(); } + bool isEmpty() const { return m_attributeData.isEmpty(); } // Internal interface. - Attribute* attributeItem(unsigned index) const { return m_attributes[index].get(); } - Attribute* getAttributeItem(const QualifiedName&) const; - size_t getAttributeItemIndex(const QualifiedName&) const; - - void copyAttributesToVector(Vector<RefPtr<Attribute> >&); + Attribute* attributeItem(unsigned index) const { return m_attributeData.attributeItem(index); } + Attribute* getAttributeItem(const QualifiedName& name) const { return m_attributeData.getAttributeItem(name); } + size_t getAttributeItemIndex(const QualifiedName& name) const { return m_attributeData.getAttributeItemIndex(name); } - void shrinkToLength() { m_attributes.shrinkCapacity(length()); } - void reserveInitialCapacity(unsigned capacity) { m_attributes.reserveInitialCapacity(capacity); } + void shrinkToLength() { m_attributeData.m_attributes.shrinkCapacity(length()); } + void reserveInitialCapacity(unsigned capacity) { m_attributeData.m_attributes.reserveInitialCapacity(capacity); } // Used during parsing: only inserts if not already there. No error checking! void insertAttribute(PassRefPtr<Attribute> newAttribute, bool allowDuplicates) @@ -88,9 +82,9 @@ public: bool mapsEquivalent(const NamedNodeMap* otherMap) const; // These functions do no error checking. - void addAttribute(PassRefPtr<Attribute>); - void removeAttribute(const QualifiedName&); - void removeAttribute(size_t index); + void addAttribute(PassRefPtr<Attribute> attribute) { m_attributeData.addAttribute(attribute, m_element); } + void removeAttribute(const QualifiedName& name) { m_attributeData.removeAttribute(name, m_element); } + void removeAttribute(size_t index) { m_attributeData.removeAttribute(index, m_element); } Element* element() const { return m_element; } @@ -103,14 +97,8 @@ private: { } - void detachAttributesFromElement(); void detachFromElement(); - Attribute* getAttributeItem(const String& name, bool shouldIgnoreAttributeCase) const; - size_t getAttributeItemIndex(const String& name, bool shouldIgnoreAttributeCase) const; - size_t getAttributeItemIndexSlowCase(const String& name, bool shouldIgnoreAttributeCase) const; - void setAttributes(const NamedNodeMap&); - void clearAttributes(); - void replaceAttribute(size_t index, PassRefPtr<Attribute>); + Attribute* getAttributeItem(const String& name, bool shouldIgnoreAttributeCase) const { return m_attributeData.getAttributeItem(name, shouldIgnoreAttributeCase); } // FIXME: NamedNodeMap is being broken up into two classes, one containing data // for elements with attributes, and one for exposure to the DOM. @@ -118,66 +106,8 @@ private: ElementAttributeData m_attributeData; Element* m_element; - Vector<RefPtr<Attribute>, 4> m_attributes; }; -inline Attribute* NamedNodeMap::getAttributeItem(const QualifiedName& name) const -{ - size_t index = getAttributeItemIndex(name); - if (index != notFound) - return m_attributes[index].get(); - return 0; -} - -inline size_t NamedNodeMap::getAttributeItemIndex(const QualifiedName& name) const -{ - size_t len = length(); - for (unsigned i = 0; i < len; ++i) { - if (m_attributes[i]->name().matches(name)) - return i; - } - return notFound; -} - -inline Attribute* NamedNodeMap::getAttributeItem(const String& name, bool shouldIgnoreAttributeCase) const -{ - size_t index = getAttributeItemIndex(name, shouldIgnoreAttributeCase); - if (index != notFound) - return m_attributes[index].get(); - return 0; -} - -// We use a boolean parameter instead of calling shouldIgnoreAttributeCase so that the caller -// can tune the behavior (hasAttribute is case sensitive whereas getAttribute is not). -inline size_t NamedNodeMap::getAttributeItemIndex(const String& name, bool shouldIgnoreAttributeCase) const -{ - unsigned len = length(); - bool doSlowCheck = shouldIgnoreAttributeCase; - - // Optimize for the case where the attribute exists and its name exactly matches. - for (unsigned i = 0; i < len; ++i) { - const QualifiedName& attrName = m_attributes[i]->name(); - if (!attrName.hasPrefix()) { - if (name == attrName.localName()) - return i; - } else - doSlowCheck = true; - } - - if (doSlowCheck) - return getAttributeItemIndexSlowCase(name, shouldIgnoreAttributeCase); - return notFound; -} - -inline void NamedNodeMap::removeAttribute(const QualifiedName& name) -{ - size_t index = getAttributeItemIndex(name); - if (index == notFound) - return; - - removeAttribute(index); -} - } // namespace WebCore #endif // NamedNodeMap_h diff --git a/Source/WebCore/dom/NamedNodeMap.idl b/Source/WebCore/dom/NamedNodeMap.idl index 3c07a1146..88820c017 100644 --- a/Source/WebCore/dom/NamedNodeMap.idl +++ b/Source/WebCore/dom/NamedNodeMap.idl @@ -24,34 +24,35 @@ module core { JSGenerateIsReachable=ImplElementRoot, JSCustomMarkFunction, IndexedGetter, - NamedGetter + NamedGetter, + V8CustomToJSObject ] NamedNodeMap { - Node getNamedItem(in [Optional=CallWithDefaultValue] DOMString name); + Node getNamedItem(in [Optional=DefaultIsUndefined] DOMString name); - Node setNamedItem(in [Optional=CallWithDefaultValue] Node node) + Node setNamedItem(in [Optional=DefaultIsUndefined] Node node) raises(DOMException); - Node removeNamedItem(in [Optional=CallWithDefaultValue] DOMString name) + Node removeNamedItem(in [Optional=DefaultIsUndefined] DOMString name) raises(DOMException); - Node item(in [Optional=CallWithDefaultValue] unsigned long index); + Node item(in [Optional=DefaultIsUndefined] unsigned long index); readonly attribute unsigned long length; // Introduced in DOM Level 2: - [ObjCLegacyUnnamedParameters] Node getNamedItemNS(in [TreatNullAs=NullString,Optional=CallWithDefaultValue] DOMString namespaceURI, - in [Optional=CallWithDefaultValue] DOMString localName) + [ObjCLegacyUnnamedParameters] Node getNamedItemNS(in [TreatNullAs=NullString,Optional=DefaultIsUndefined] DOMString namespaceURI, + in [Optional=DefaultIsUndefined] DOMString localName) // FIXME: the implementation does take an exceptioncode parameter. /*raises(DOMException)*/; - Node setNamedItemNS(in [Optional=CallWithDefaultValue] Node node) + Node setNamedItemNS(in [Optional=DefaultIsUndefined] Node node) raises(DOMException); - [ObjCLegacyUnnamedParameters] Node removeNamedItemNS(in [TreatNullAs=NullString,Optional=CallWithDefaultValue] DOMString namespaceURI, - in [Optional=CallWithDefaultValue] DOMString localName) + [ObjCLegacyUnnamedParameters] Node removeNamedItemNS(in [TreatNullAs=NullString,Optional=DefaultIsUndefined] DOMString namespaceURI, + in [Optional=DefaultIsUndefined] DOMString localName) raises(DOMException); }; diff --git a/Source/WebCore/dom/Node.cpp b/Source/WebCore/dom/Node.cpp index 39b8fa895..2e9c61a7e 100644 --- a/Source/WebCore/dom/Node.cpp +++ b/Source/WebCore/dom/Node.cpp @@ -63,7 +63,7 @@ #include "HTMLElement.h" #include "HTMLFrameOwnerElement.h" #include "HTMLNames.h" -#include "InspectorInstrumentation.h" +#include "InspectorCounters.h" #include "KeyboardEvent.h" #include "LabelsNodeList.h" #include "Logging.h" @@ -86,6 +86,7 @@ #include "ScopedEventQueue.h" #include "SelectorQuery.h" #include "ShadowRoot.h" +#include "ShadowRootList.h" #include "StaticNodeList.h" #include "StorageEvent.h" #include "TagNodeList.h" @@ -227,7 +228,10 @@ void Node::dumpStatistics() break; } case DOCUMENT_FRAGMENT_NODE: { - ++fragmentNodes; + if (node->isShadowRoot()) + ++shadowRootNodes; + else + ++fragmentNodes; break; } case NOTATION_NODE: { @@ -238,10 +242,6 @@ void Node::dumpStatistics() ++xpathNSNodes; break; } - case SHADOW_ROOT_NODE: { - ++shadowRootNodes; - break; - } } } @@ -352,8 +352,7 @@ Node::StyleChange Node::diff(const RenderStyle* s1, const RenderStyle* s2) if ((s1 && s2) && (s1->flowThread() != s2->flowThread())) ch = Detach; - // When either the region thread or the region index has changed, - // we need to prepare a separate render region object. + // When the region thread has changed, we need to prepare a separate render region object. if ((s1 && s2) && (s1->regionThread() != s2->regionThread())) ch = Detach; @@ -406,6 +405,8 @@ Node::~Node() if (doc) doc->guardDeref(); + + InspectorCounters::decrementCounter(InspectorCounters::NodeCounter); } void Node::setDocument(Document* document) @@ -632,7 +633,7 @@ void Node::normalize() continue; } - RefPtr<Text> text = static_cast<Text*>(node.get()); + RefPtr<Text> text = toText(node.get()); // Remove empty text nodes. if (!text->length()) { @@ -647,7 +648,7 @@ void Node::normalize() while (Node* nextSibling = node->nextSibling()) { if (nextSibling->nodeType() != TEXT_NODE) break; - RefPtr<Text> nextText = static_cast<Text*>(nextSibling); + RefPtr<Text> nextText = toText(nextSibling); // Remove empty text nodes. if (!nextText->length()) { @@ -694,13 +695,13 @@ const AtomicString& Node::virtualNamespaceURI() const bool Node::isContentEditable() { - document()->updateLayoutIgnorePendingStylesheets(); + document()->updateStyleIfNeeded(); return rendererIsEditable(Editable); } bool Node::isContentRichlyEditable() { - document()->updateLayoutIgnorePendingStylesheets(); + document()->updateStyleIfNeeded(); return rendererIsEditable(RichlyEditable); } @@ -808,9 +809,9 @@ bool Node::hasNonEmptyBoundingBox() const return false; } -inline static ShadowRoot* shadowRoot(Node* node) +inline static ShadowRoot* oldestShadowRootFor(const Node* node) { - return node->isElementNode() ? toElement(node)->shadowRoot() : 0; + return node->isElementNode() && toElement(node)->hasShadowRoot() ? toElement(node)->shadowRootList()->oldestShadowRoot() : 0; } inline void Node::setStyleChange(StyleChangeType changeType) @@ -1339,7 +1340,7 @@ void Node::detach() setFlag(InDetachFlag); if (renderer()) - renderer()->destroy(); + renderer()->destroyAndCleanupAnonymousWrappers(); setRenderer(0); Document* doc = document(); @@ -1759,11 +1760,13 @@ bool Node::isEqualNode(Node* other) const NamedNodeMap* attributes = toElement(this)->updatedAttributes(); NamedNodeMap* otherAttributes = toElement(other)->updatedAttributes(); - if (attributes && !attributes->mapsEquivalent(otherAttributes)) - return false; - - if (otherAttributes && !otherAttributes->mapsEquivalent(attributes)) - return false; + if (attributes) { + if (!attributes->mapsEquivalent(otherAttributes)) + return false; + } else if (otherAttributes) { + if (!otherAttributes->mapsEquivalent(attributes)) + return false; + } } Node* child = firstChild(); @@ -1844,7 +1847,6 @@ bool Node::isDefaultNamespace(const AtomicString& namespaceURIMaybeEmpty) const case NOTATION_NODE: case DOCUMENT_TYPE_NODE: case DOCUMENT_FRAGMENT_NODE: - case SHADOW_ROOT_NODE: return false; case ATTRIBUTE_NODE: { const Attr* attr = static_cast<const Attr*>(this); @@ -1878,7 +1880,6 @@ String Node::lookupPrefix(const AtomicString &namespaceURI) const case NOTATION_NODE: case DOCUMENT_FRAGMENT_NODE: case DOCUMENT_TYPE_NODE: - case SHADOW_ROOT_NODE: return String(); case ATTRIBUTE_NODE: { const Attr *attr = static_cast<const Attr *>(this); @@ -1937,7 +1938,6 @@ String Node::lookupNamespaceURI(const String &prefix) const case NOTATION_NODE: case DOCUMENT_TYPE_NODE: case DOCUMENT_FRAGMENT_NODE: - case SHADOW_ROOT_NODE: return String(); case ATTRIBUTE_NODE: { const Attr *attr = static_cast<const Attr *>(this); @@ -2005,7 +2005,6 @@ static void appendTextContent(const Node* node, bool convertBRsToNewlines, bool& case Node::ENTITY_NODE: case Node::ENTITY_REFERENCE_NODE: case Node::DOCUMENT_FRAGMENT_NODE: - case Node::SHADOW_ROOT_NODE: isNullString = false; for (Node* child = node->firstChild(); child; child = child->nextSibling()) { if (child->nodeType() == Node::COMMENT_NODE || child->nodeType() == Node::PROCESSING_INSTRUCTION_NODE) @@ -2043,8 +2042,7 @@ void Node::setTextContent(const String& text, ExceptionCode& ec) case ATTRIBUTE_NODE: case ENTITY_NODE: case ENTITY_REFERENCE_NODE: - case DOCUMENT_FRAGMENT_NODE: - case SHADOW_ROOT_NODE: { + case DOCUMENT_FRAGMENT_NODE: { ContainerNode* container = toContainerNode(this); #if ENABLE(MUTATION_OBSERVERS) ChildListMutationScope mutation(this); @@ -2271,13 +2269,11 @@ static void traverseTreeAndMark(const String& baseIndent, const Node* rootNode, indent += "\t"; fprintf(stderr, "%s", indent.utf8().data()); node->showNode(); - - ContainerNode* rootNode = shadowRoot(const_cast<Node*>(node)); - - if (rootNode) { - indent += "\t"; - traverseTreeAndMark(indent, rootNode, markedNode1, markedLabel1, markedNode2, markedLabel2); - } + if (node->isShadowRoot()) { + if (ShadowRoot* youngerShadowRoot = toShadowRoot(node)->youngerShadowRoot()) + traverseTreeAndMark(indent + "\t", youngerShadowRoot, markedNode1, markedLabel1, markedNode2, markedLabel2); + } else if (ShadowRoot* oldestShadowRoot = oldestShadowRootFor(node)) + traverseTreeAndMark(indent + "\t", oldestShadowRoot, markedNode1, markedLabel1, markedNode2, markedLabel2); } } @@ -2307,7 +2303,7 @@ void Node::formatForDebugger(char* buffer, unsigned length) const strncpy(buffer, result.utf8().data(), length - 1); } -static ContainerNode* parentOrHostOrFrameOwner(Node* node) +static ContainerNode* parentOrHostOrFrameOwner(const Node* node) { ContainerNode* parent = node->parentOrHostNode(); if (!parent && node->document() && node->document()->frame()) @@ -2315,16 +2311,21 @@ static ContainerNode* parentOrHostOrFrameOwner(Node* node) return parent; } -static void showSubTreeAcrossFrame(Node* node, const Node* markedNode, const String& indent) +static void showSubTreeAcrossFrame(const Node* node, const Node* markedNode, const String& indent) { if (node == markedNode) fputs("*", stderr); fputs(indent.utf8().data(), stderr); node->showNode(); - if (node->isFrameOwnerElement()) - showSubTreeAcrossFrame(static_cast<HTMLFrameOwnerElement*>(node)->contentDocument(), markedNode, indent + "\t"); - if (ShadowRoot* shadow = shadowRoot(node)) - showSubTreeAcrossFrame(shadow, markedNode, indent + "\t"); + if (node->isShadowRoot()) { + if (ShadowRoot* youngerShadowRoot = toShadowRoot(node)->youngerShadowRoot()) + showSubTreeAcrossFrame(youngerShadowRoot, markedNode, indent + "\t"); + } else { + if (node->isFrameOwnerElement()) + showSubTreeAcrossFrame(static_cast<const HTMLFrameOwnerElement*>(node)->contentDocument(), markedNode, indent + "\t"); + if (ShadowRoot* oldestShadowRoot = oldestShadowRootFor(node)) + showSubTreeAcrossFrame(oldestShadowRoot, markedNode, indent + "\t"); + } for (Node* child = node->firstChild(); child; child = child->nextSibling()) showSubTreeAcrossFrame(child, markedNode, indent + "\t"); } @@ -2483,6 +2484,11 @@ static inline HashSet<SVGElementInstance*> instancesForSVGElement(Node* node) } #endif +static inline bool isTouchEventType(const AtomicString& eventType) +{ + return eventType == eventNames().touchstartEvent || eventType == eventNames().touchmoveEvent || eventType == eventNames().touchendEvent || eventType == eventNames().touchcancelEvent; +} + static inline bool tryAddEventListener(Node* targetNode, const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture) { if (!targetNode->EventTarget::addEventListener(eventType, listener, useCapture)) @@ -2492,6 +2498,8 @@ static inline bool tryAddEventListener(Node* targetNode, const AtomicString& eve document->addListenerTypeIfNeeded(eventType); if (eventType == eventNames().mousewheelEvent) document->didAddWheelEventHandler(); + else if (isTouchEventType(eventType)) + document->didAddTouchEventHandler(); } return true; @@ -2541,6 +2549,8 @@ static inline bool tryRemoveEventListener(Node* targetNode, const AtomicString& if (Document* document = targetNode->document()) { if (eventType == eventNames().mousewheelEvent) document->didRemoveWheelEventHandler(); + else if (isTouchEventType(eventType)) + document->didRemoveTouchEventHandler(); } return true; @@ -2721,6 +2731,39 @@ void Node::notifyMutationObserversNodeWillDetach() } #endif // ENABLE(MUTATION_OBSERVERS) +#if ENABLE(STYLE_SCOPED) +bool Node::hasScopedHTMLStyleChild() const +{ + return hasRareData() && rareData()->hasScopedHTMLStyleChild(); +} + +size_t Node::numberOfScopedHTMLStyleChildren() const +{ + return hasRareData() ? rareData()->numberOfScopedHTMLStyleChildren() : 0; +} + +void Node::registerScopedHTMLStyleChild() +{ + ensureRareData()->registerScopedHTMLStyleChild(); +} + +void Node::unregisterScopedHTMLStyleChild() +{ + ASSERT(hasRareData()); + if (hasRareData()) + rareData()->unregisterScopedHTMLStyleChild(); +} +#else +bool Node::hasScopedHTMLStyleChild() const +{ + return 0; +} + +size_t Node::numberOfScopedHTMLStyleChildren() const +{ + return 0; +} +#endif void Node::handleLocalEvents(Event* event) { diff --git a/Source/WebCore/dom/Node.h b/Source/WebCore/dom/Node.h index 311bd4117..9ca126498 100644 --- a/Source/WebCore/dom/Node.h +++ b/Source/WebCore/dom/Node.h @@ -90,7 +90,7 @@ class HTMLPropertiesCollection; typedef int ExceptionCode; -const int nodeStyleChangeShift = 25; +const int nodeStyleChangeShift = 23; // SyntheticStyleChange means that we need to go through the entire style change logic even though // no style property has actually changed. It is used to restructure the tree when, for instance, @@ -122,7 +122,6 @@ public: DOCUMENT_FRAGMENT_NODE = 11, NOTATION_NODE = 12, XPATH_NAMESPACE_NODE = 13, - SHADOW_ROOT_NODE = 14 }; enum DocumentPosition { DOCUMENT_POSITION_EQUIVALENT = 0x00, @@ -224,6 +223,9 @@ public: bool isDocumentNode() const; bool isShadowRoot() const { return getFlag(IsShadowRootOrSVGShadowRootFlag) && !isSVGElement(); } virtual bool isContentElement() const { return false; } +#if ENABLE(SHADOW_DOM) + virtual bool isShadowElement() const { return false; } +#endif Node* shadowAncestorNode() const; // Returns 0, a ShadowRoot, or a legacy shadow root. @@ -297,9 +299,11 @@ public: virtual bool sheetLoaded() { return true; } virtual void startLoadingDynamicSheet() { ASSERT_NOT_REACHED(); } + bool attributeStyleDirty() const { return getFlag(AttributeStyleDirtyFlag); } bool hasName() const { return getFlag(HasNameFlag); } - bool hasID() const { return getFlag(HasIDFlag); } - bool hasClass() const { return getFlag(HasClassFlag); } + bool hasID() const; + bool hasClass() const; + bool active() const { return getFlag(IsActiveFlag); } bool inActiveChain() const { return getFlag(InActiveChainFlag); } bool inDetach() const { return getFlag(InDetachFlag); } @@ -312,9 +316,10 @@ public: bool childNeedsStyleRecalc() const { return getFlag(ChildNeedsStyleRecalcFlag); } bool isLink() const { return getFlag(IsLinkFlag); } + void setAttributeStyleDirty() { setFlag(AttributeStyleDirtyFlag); } + void clearAttributeStyleDirty() { clearFlag(AttributeStyleDirtyFlag); } + void setHasName(bool f) { setFlag(f, HasNameFlag); } - void setHasID(bool f) { setFlag(f, HasIDFlag); } - void setHasClass(bool f) { setFlag(f, HasClassFlag); } void setChildNeedsStyleRecalc() { setFlag(ChildNeedsStyleRecalcFlag); } void clearChildNeedsStyleRecalc() { clearFlag(ChildNeedsStyleRecalcFlag); } void setInDocument() { setFlag(InDocumentFlag); } @@ -492,7 +497,7 @@ public: virtual void willRemove(); void createRendererIfNeeded(); virtual bool rendererIsNeeded(const NodeRenderingContext&); - virtual bool childShouldCreateRenderer(Node*) const { return true; } + virtual bool childShouldCreateRenderer(const NodeRenderingContext&) const { return true; } virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); ContainerNode* parentNodeForRenderingAndStyle(); @@ -632,6 +637,13 @@ public: void notifyMutationObserversNodeWillDetach(); #endif // ENABLE(MUTATION_OBSERVERS) +#if ENABLE(STYLE_SCOPED) + void registerScopedHTMLStyleChild(); + void unregisterScopedHTMLStyleChild(); +#endif + bool hasScopedHTMLStyleChild() const; + size_t numberOfScopedHTMLStyleChildren() const; + private: enum NodeFlags { IsTextFlag = 1, @@ -641,37 +653,37 @@ private: IsStyledElementFlag = 1 << 4, IsHTMLFlag = 1 << 5, IsSVGFlag = 1 << 6, - HasIDFlag = 1 << 7, - HasClassFlag = 1 << 8, - IsAttachedFlag = 1 << 9, - ChildNeedsStyleRecalcFlag = 1 << 10, - InDocumentFlag = 1 << 11, - IsLinkFlag = 1 << 12, - IsActiveFlag = 1 << 13, - IsHoveredFlag = 1 << 14, - InActiveChainFlag = 1 << 15, - InDetachFlag = 1 << 16, - HasRareDataFlag = 1 << 17, - IsShadowRootOrSVGShadowRootFlag = 1 << 18, + IsAttachedFlag = 1 << 7, + ChildNeedsStyleRecalcFlag = 1 << 8, + InDocumentFlag = 1 << 9, + IsLinkFlag = 1 << 10, + IsActiveFlag = 1 << 11, + IsHoveredFlag = 1 << 12, + InActiveChainFlag = 1 << 13, + InDetachFlag = 1 << 14, + HasRareDataFlag = 1 << 15, + IsShadowRootOrSVGShadowRootFlag = 1 << 16, // These bits are used by derived classes, pulled up here so they can // be stored in the same memory word as the Node bits above. - IsParsingChildrenFinishedFlag = 1 << 19, // Element - IsStyleAttributeValidFlag = 1 << 20, // StyledElement - IsSynchronizingStyleAttributeFlag = 1 << 21, // StyledElement + IsParsingChildrenFinishedFlag = 1 << 17, // Element + IsStyleAttributeValidFlag = 1 << 18, // StyledElement + IsSynchronizingStyleAttributeFlag = 1 << 19, // StyledElement #if ENABLE(SVG) - AreSVGAttributesValidFlag = 1 << 22, // Element - IsSynchronizingSVGAttributesFlag = 1 << 23, // SVGElement - HasSVGRareDataFlag = 1 << 24, // SVGElement + AreSVGAttributesValidFlag = 1 << 20, // Element + IsSynchronizingSVGAttributesFlag = 1 << 21, // SVGElement + HasSVGRareDataFlag = 1 << 22, // SVGElement #endif StyleChangeMask = 1 << nodeStyleChangeShift | 1 << (nodeStyleChangeShift + 1), - SelfOrAncestorHasDirAutoFlag = 1 << 27, - HasCustomWillOrDidRecalcStyleFlag = 1 << 28, - HasCustomStyleForRendererFlag = 1 << 29, + SelfOrAncestorHasDirAutoFlag = 1 << 25, + HasCustomWillOrDidRecalcStyleFlag = 1 << 26, + HasCustomStyleForRendererFlag = 1 << 27, + + HasNameFlag = 1 << 28, - HasNameFlag = 1 << 30, + AttributeStyleDirtyFlag = 1 << 31, #if ENABLE(SVG) DefaultNodeFlags = IsParsingChildrenFinishedFlag | IsStyleAttributeValidFlag | AreSVGAttributesValidFlag @@ -680,7 +692,7 @@ private: #endif }; - // 1 bit remaining + // 3 bits remaining bool getFlag(NodeFlags mask) const { return m_nodeFlags & mask; } void setFlag(bool f, NodeFlags mask) const { m_nodeFlags = (m_nodeFlags & ~mask) | (-(int32_t)f & mask); } diff --git a/Source/WebCore/dom/Node.idl b/Source/WebCore/dom/Node.idl index b67be68b4..e27a215ca 100644 --- a/Source/WebCore/dom/Node.idl +++ b/Source/WebCore/dom/Node.idl @@ -26,7 +26,7 @@ module core { JSCustomPushEventHandlerScope, JSCustomIsReachable, JSCustomFinalize, - JSCustomToJS, + CustomToJSObject, EventTarget, JSGenerateToNativeObject, JSInlineGetOwnPropertySlot, @@ -51,10 +51,10 @@ module core { const unsigned short DOCUMENT_FRAGMENT_NODE = 11; const unsigned short NOTATION_NODE = 12; - readonly attribute [ConvertNullStringTo=Null] DOMString nodeName; + readonly attribute [TreatReturnedNullStringAs=Null] DOMString nodeName; // FIXME: the spec says this can also raise on retrieval. - attribute [ConvertNullStringTo=Null, TreatNullAs=NullString] DOMString nodeValue + attribute [TreatReturnedNullStringAs=Null, TreatNullAs=NullString] DOMString nodeValue setter raises(DOMException); readonly attribute unsigned short nodeType; @@ -67,46 +67,46 @@ module core { readonly attribute NamedNodeMap attributes; readonly attribute Document ownerDocument; - [ObjCLegacyUnnamedParameters, Custom] Node insertBefore(in [Return] Node newChild, - in Node refChild) + [ObjCLegacyUnnamedParameters, Custom] Node insertBefore(in [CustomReturn] Node newChild, + in Node refChild) raises(DOMException); [ObjCLegacyUnnamedParameters, Custom] Node replaceChild(in Node newChild, - in [Return] Node oldChild) - raises(DOMExceptionJSC); - [Custom] Node removeChild(in [Return] Node oldChild) + in [CustomReturn] Node oldChild) raises(DOMException); - [Custom] Node appendChild(in [Return] Node newChild) + [Custom] Node removeChild(in [CustomReturn] Node oldChild) + raises(DOMException); + [Custom] Node appendChild(in [CustomReturn] Node newChild) raises(DOMException); boolean hasChildNodes(); - Node cloneNode(in [Optional=CallWithDefaultValue] boolean deep); + Node cloneNode(in [Optional=DefaultIsUndefined] boolean deep); void normalize(); // Introduced in DOM Level 2: - [ObjCLegacyUnnamedParameters] boolean isSupported(in [Optional=CallWithDefaultValue] DOMString feature, - in [TreatNullAs=NullString,Optional=CallWithDefaultValue] DOMString version); + [ObjCLegacyUnnamedParameters] boolean isSupported(in [Optional=DefaultIsUndefined] DOMString feature, + in [TreatNullAs=NullString,Optional=DefaultIsUndefined] DOMString version); - readonly attribute [ConvertNullStringTo=Null] DOMString namespaceURI; - attribute [ConvertNullStringTo=Null, TreatNullAs=NullString] DOMString prefix + readonly attribute [TreatReturnedNullStringAs=Null] DOMString namespaceURI; + attribute [TreatReturnedNullStringAs=Null, TreatNullAs=NullString] DOMString prefix setter raises(DOMException); - readonly attribute [ConvertNullStringTo=Null] DOMString localName; + readonly attribute [TreatReturnedNullStringAs=Null] DOMString localName; boolean hasAttributes(); // Introduced in DOM Level 3: - readonly attribute [ConvertNullStringTo=Null] DOMString baseURI; + readonly attribute [TreatReturnedNullStringAs=Null] DOMString baseURI; // FIXME: the spec says this can also raise on retrieval. - attribute [ConvertNullStringTo=Null, TreatNullAs=NullString] DOMString textContent + attribute [TreatReturnedNullStringAs=Null, TreatNullAs=NullString] DOMString textContent setter raises(DOMException); - boolean isSameNode(in [Optional=CallWithDefaultValue] Node other); - boolean isEqualNode(in [Optional=CallWithDefaultValue] Node other); - [ConvertNullStringTo=Null] DOMString lookupPrefix(in [TreatNullAs=NullString,Optional=CallWithDefaultValue] DOMString namespaceURI); - boolean isDefaultNamespace(in [TreatNullAs=NullString,Optional=CallWithDefaultValue] DOMString namespaceURI); - [ConvertNullStringTo=Null] DOMString lookupNamespaceURI(in [TreatNullAs=NullString,Optional=CallWithDefaultValue] DOMString prefix); + boolean isSameNode(in [Optional=DefaultIsUndefined] Node other); + boolean isEqualNode(in [Optional=DefaultIsUndefined] Node other); + [TreatReturnedNullStringAs=Null] DOMString lookupPrefix(in [TreatNullAs=NullString,Optional=DefaultIsUndefined] DOMString namespaceURI); + boolean isDefaultNamespace(in [TreatNullAs=NullString,Optional=DefaultIsUndefined] DOMString namespaceURI); + [TreatReturnedNullStringAs=Null] DOMString lookupNamespaceURI(in [TreatNullAs=NullString,Optional=DefaultIsUndefined] DOMString prefix); // DocumentPosition const unsigned short DOCUMENT_POSITION_DISCONNECTED = 0x01; @@ -116,10 +116,10 @@ module core { const unsigned short DOCUMENT_POSITION_CONTAINED_BY = 0x10; const unsigned short DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20; - unsigned short compareDocumentPosition(in [Optional=CallWithDefaultValue] Node other); + unsigned short compareDocumentPosition(in [Optional=DefaultIsUndefined] Node other); // Introduced in DOM4 - boolean contains(in [Optional=CallWithDefaultValue] Node other); + boolean contains(in [Optional=DefaultIsUndefined] Node other); #if 0 DOMObject getFeature(in DOMString feature, diff --git a/Source/WebCore/dom/NodeFilter.idl b/Source/WebCore/dom/NodeFilter.idl index 8edef0e03..5caa5ff03 100644 --- a/Source/WebCore/dom/NodeFilter.idl +++ b/Source/WebCore/dom/NodeFilter.idl @@ -47,7 +47,7 @@ module traversal { const unsigned long SHOW_DOCUMENT_FRAGMENT = 0x00000400; const unsigned long SHOW_NOTATION = 0x00000800; - [CallWith=ScriptState] short acceptNode(in [Optional=CallWithDefaultValue] Node n); + [CallWith=ScriptState] short acceptNode(in [Optional=DefaultIsUndefined] Node n); }; diff --git a/Source/WebCore/dom/NodeList.idl b/Source/WebCore/dom/NodeList.idl index ebe813f83..71544d16b 100644 --- a/Source/WebCore/dom/NodeList.idl +++ b/Source/WebCore/dom/NodeList.idl @@ -26,7 +26,7 @@ module core { NamedGetter ] NodeList { - Node item(in [IsIndex,Optional=CallWithDefaultValue] unsigned long index); + Node item(in [IsIndex,Optional=DefaultIsUndefined] unsigned long index); readonly attribute unsigned long length; diff --git a/Source/WebCore/dom/NodeRareData.h b/Source/WebCore/dom/NodeRareData.h index 77b920d1b..0864b2626 100644 --- a/Source/WebCore/dom/NodeRareData.h +++ b/Source/WebCore/dom/NodeRareData.h @@ -100,6 +100,9 @@ public: , m_tabIndexWasSetExplicitly(false) , m_isFocused(false) , m_needsFocusAppearanceUpdateSoonAfterAttach(false) +#if ENABLE(STYLE_SCOPED) + , m_numberOfScopedHTMLStyleChildren(0) +#endif { } @@ -226,6 +229,30 @@ public: } #endif +#if ENABLE(STYLE_SCOPED) + void registerScopedHTMLStyleChild() + { + ++m_numberOfScopedHTMLStyleChildren; + } + + void unregisterScopedHTMLStyleChild() + { + ASSERT(m_numberOfScopedHTMLStyleChildren > 0); + if (m_numberOfScopedHTMLStyleChildren > 0) + --m_numberOfScopedHTMLStyleChildren; + } + + bool hasScopedHTMLStyleChild() const + { + return m_numberOfScopedHTMLStyleChildren; + } + + size_t numberOfScopedHTMLStyleChildren() const + { + return m_numberOfScopedHTMLStyleChildren; + } +#endif + bool isFocused() const { return m_isFocused; } void setFocused(bool focused) { m_isFocused = focused; } @@ -257,6 +284,10 @@ private: mutable RefPtr<DOMSettableTokenList> m_itemType; mutable OwnPtr<HTMLPropertiesCollection> m_properties; #endif + +#if ENABLE(STYLE_SCOPED) + size_t m_numberOfScopedHTMLStyleChildren; +#endif }; } // namespace WebCore diff --git a/Source/WebCore/dom/NodeRenderingContext.cpp b/Source/WebCore/dom/NodeRenderingContext.cpp index 4a9709a0d..cdcb102d8 100644 --- a/Source/WebCore/dom/NodeRenderingContext.cpp +++ b/Source/WebCore/dom/NodeRenderingContext.cpp @@ -27,14 +27,15 @@ #include "NodeRenderingContext.h" #include "ContainerNode.h" -#include "ContentInclusionSelector.h" #include "HTMLContentElement.h" +#include "HTMLContentSelector.h" #include "Node.h" #include "RenderFlowThread.h" #include "RenderFullScreen.h" #include "RenderObject.h" #include "RenderView.h" #include "ShadowRoot.h" +#include "ShadowRootList.h" #if ENABLE(SVG) #include "SVGNames.h" @@ -43,12 +44,11 @@ namespace WebCore { NodeRenderingContext::NodeRenderingContext(Node* node) - : m_location(LocationNotInTree) - , m_phase(AttachStraight) + : m_phase(AttachingNotInTree) , m_node(node) , m_parentNodeForRenderingAndStyle(0) - , m_visualParentShadowRoot(0) - , m_includer(0) + , m_visualParentShadowRootList(0) + , m_insertionPoint(0) , m_style(0) , m_parentFlowRenderer(0) { @@ -57,49 +57,46 @@ NodeRenderingContext::NodeRenderingContext(Node* node) return; if (parent->isShadowRoot()) { - m_location = LocationShadowChild; + m_phase = AttachingShadowChild; m_parentNodeForRenderingAndStyle = parent->shadowHost(); return; } - m_location = LocationLightChild; - if (parent->isElementNode()) { - m_visualParentShadowRoot = toElement(parent)->shadowRoot(); - - if (m_visualParentShadowRoot) { - if ((m_includer = m_visualParentShadowRoot->includerFor(m_node)) - && m_visualParentShadowRoot->isInclusionSelectorActive()) { - m_phase = AttachContentForwarded; - m_parentNodeForRenderingAndStyle = NodeRenderingContext(m_includer).parentNodeForRenderingAndStyle(); + if (toElement(parent)->hasShadowRoot()) { + m_visualParentShadowRootList = toElement(parent)->shadowRootList(); + if ((m_insertionPoint = m_visualParentShadowRootList->insertionPointFor(m_node)) + && m_visualParentShadowRootList->isSelectorActive()) { + m_phase = AttachingDistributed; + m_parentNodeForRenderingAndStyle = NodeRenderingContext(m_insertionPoint).parentNodeForRenderingAndStyle(); return; } - m_phase = AttachContentLight; + m_phase = AttachingNotDistributed; m_parentNodeForRenderingAndStyle = parent; return; } - if (parent->isContentElement()) { - HTMLContentElement* shadowContentElement = toHTMLContentElement(parent); - if (!shadowContentElement->hasInclusion()) { - m_phase = AttachContentFallback; - m_parentNodeForRenderingAndStyle = NodeRenderingContext(parent).parentNodeForRenderingAndStyle(); - return; - } + if (isInsertionPoint(parent)) { + if (toInsertionPoint(parent)->hasSelection()) + m_phase = AttachingNotFallbacked; + else + m_phase = AttachingFallbacked; + m_parentNodeForRenderingAndStyle = NodeRenderingContext(parent).parentNodeForRenderingAndStyle(); + return; } } + m_phase = AttachingStraight; m_parentNodeForRenderingAndStyle = parent; } NodeRenderingContext::NodeRenderingContext(Node* node, RenderStyle* style) - : m_location(LocationUndetermined) - , m_phase(AttachStraight) + : m_phase(Calculating) , m_node(node) , m_parentNodeForRenderingAndStyle(0) - , m_visualParentShadowRoot(0) - , m_includer(0) + , m_visualParentShadowRootList(0) + , m_insertionPoint(0) , m_style(style) , m_parentFlowRenderer(0) { @@ -120,72 +117,80 @@ PassRefPtr<RenderStyle> NodeRenderingContext::releaseStyle() return m_style.release(); } -static RenderObject* nextRendererOf(HTMLContentElement* parent, Node* current) +static RenderObject* nextRendererOf(InsertionPoint* parent, Node* current) { - ShadowInclusion* currentInclusion = parent->inclusions()->find(current); - if (!currentInclusion) + HTMLContentSelection* currentSelection = parent->selections()->find(current); + if (!currentSelection) return 0; - for (ShadowInclusion* inclusion = currentInclusion->next(); inclusion; inclusion = inclusion->next()) { - if (RenderObject* renderer = inclusion->content()->renderer()) + for (HTMLContentSelection* selection = currentSelection->next(); selection; selection = selection->next()) { + if (RenderObject* renderer = selection->node()->renderer()) return renderer; } return 0; } -static RenderObject* previousRendererOf(HTMLContentElement* parent, Node* current) +static RenderObject* previousRendererOf(InsertionPoint* parent, Node* current) { RenderObject* lastRenderer = 0; - for (ShadowInclusion* inclusion = parent->inclusions()->first(); inclusion; inclusion = inclusion->next()) { - if (inclusion->content() == current) + for (HTMLContentSelection* selection = parent->selections()->first(); selection; selection = selection->next()) { + if (selection->node() == current) break; - if (RenderObject* renderer = inclusion->content()->renderer()) + if (RenderObject* renderer = selection->node()->renderer()) lastRenderer = renderer; } return lastRenderer; } -static RenderObject* firstRendererOf(HTMLContentElement* parent) +static RenderObject* firstRendererOf(InsertionPoint* parent) { - for (ShadowInclusion* inclusion = parent->inclusions()->first(); inclusion; inclusion = inclusion->next()) { - if (RenderObject* renderer = inclusion->content()->renderer()) - return renderer; + if (parent->hasSelection()) { + for (HTMLContentSelection* selection = parent->selections()->first(); selection; selection = selection->next()) { + if (RenderObject* renderer = selection->node()->renderer()) + return renderer; + } + + return 0; } - return 0; + return NodeRenderingContext(parent).nextRenderer(); } -static RenderObject* lastRendererOf(HTMLContentElement* parent) +static RenderObject* lastRendererOf(InsertionPoint* parent) { - for (ShadowInclusion* inclusion = parent->inclusions()->last(); inclusion; inclusion = inclusion->previous()) { - if (RenderObject* renderer = inclusion->content()->renderer()) - return renderer; + if (parent->hasSelection()) { + for (HTMLContentSelection* selection = parent->selections()->last(); selection; selection = selection->previous()) { + if (RenderObject* renderer = selection->node()->renderer()) + return renderer; + } + + return 0; } - return 0; + return NodeRenderingContext(parent).previousRenderer(); } RenderObject* NodeRenderingContext::nextRenderer() const { - ASSERT(m_node->renderer() || m_location != LocationUndetermined); + ASSERT(m_node->renderer() || m_phase != Calculating); if (RenderObject* renderer = m_node->renderer()) return renderer->nextSibling(); if (m_parentFlowRenderer) return m_parentFlowRenderer->nextRendererForNode(m_node); - if (m_phase == AttachContentForwarded) { - if (RenderObject* found = nextRendererOf(m_includer, m_node)) + if (m_phase == AttachingDistributed) { + if (RenderObject* found = nextRendererOf(m_insertionPoint, m_node)) return found; - return NodeRenderingContext(m_includer).nextRenderer(); + return NodeRenderingContext(m_insertionPoint).nextRenderer(); } - // Avoid an O(n^2) problem with this function by not checking for + // Avoid an O(N^2) problem with this function by not checking for // nextRenderer() when the parent element hasn't attached yet. - if (m_node->parentOrHostNode() && !m_node->parentOrHostNode()->attached() && m_phase != AttachContentFallback) + if (m_node->parentOrHostNode() && !m_node->parentOrHostNode()->attached()) return 0; for (Node* node = m_node->nextSibling(); node; node = node->nextSibling()) { @@ -195,31 +200,30 @@ RenderObject* NodeRenderingContext::nextRenderer() const continue; return node->renderer(); } - if (node->isContentElement()) { - if (RenderObject* first = firstRendererOf(toHTMLContentElement(node))) + + if (isInsertionPoint(node)) { + if (RenderObject* first = firstRendererOf(toInsertionPoint(node))) return first; } } - if (m_phase == AttachContentFallback) - return NodeRenderingContext(m_node->parentNode()).nextRenderer(); - return 0; } RenderObject* NodeRenderingContext::previousRenderer() const { - ASSERT(m_node->renderer() || m_location != LocationUndetermined); + ASSERT(m_node->renderer() || m_phase != Calculating); + if (RenderObject* renderer = m_node->renderer()) return renderer->previousSibling(); if (m_parentFlowRenderer) return m_parentFlowRenderer->previousRendererForNode(m_node); - if (m_phase == AttachContentForwarded) { - if (RenderObject* found = previousRendererOf(m_includer, m_node)) + if (m_phase == AttachingDistributed) { + if (RenderObject* found = previousRendererOf(m_insertionPoint, m_node)) return found; - return NodeRenderingContext(m_includer).previousRenderer(); + return NodeRenderingContext(m_insertionPoint).previousRenderer(); } // FIXME: We should have the same O(N^2) avoidance as nextRenderer does @@ -231,68 +235,57 @@ RenderObject* NodeRenderingContext::previousRenderer() const continue; return node->renderer(); } - if (node->isContentElement()) { - if (RenderObject* last = lastRendererOf(toHTMLContentElement(node))) + if (isInsertionPoint(node)) { + if (RenderObject* last = lastRendererOf(toInsertionPoint(node))) return last; } } - if (m_phase == AttachContentFallback) - return NodeRenderingContext(m_node->parentNode()).previousRenderer(); - return 0; } RenderObject* NodeRenderingContext::parentRenderer() const { if (RenderObject* renderer = m_node->renderer()) { - ASSERT(m_location == LocationUndetermined); + ASSERT(m_phase == Calculating); return renderer->parent(); } if (m_parentFlowRenderer) return m_parentFlowRenderer; - ASSERT(m_location != LocationUndetermined); + ASSERT(m_phase != Calculating); return m_parentNodeForRenderingAndStyle ? m_parentNodeForRenderingAndStyle->renderer() : 0; } void NodeRenderingContext::hostChildrenChanged() { - if (m_phase == AttachContentLight) - m_visualParentShadowRoot->hostChildrenChanged(); + if (m_phase == AttachingNotDistributed) + m_visualParentShadowRootList->hostChildrenChanged(); } bool NodeRenderingContext::shouldCreateRenderer() const { - ASSERT(m_location != LocationUndetermined); + ASSERT(m_phase != Calculating); ASSERT(parentNodeForRenderingAndStyle()); - if (m_location == LocationNotInTree || m_phase == AttachContentLight) + if (m_phase == AttachingNotInTree || m_phase == AttachingNotDistributed || m_phase == AttachingNotFallbacked) return false; - RenderObject* parentRenderer = this->parentRenderer(); if (!parentRenderer) return false; - - if (m_location == LocationLightChild && m_phase == AttachStraight) { - // FIXME: Ignoring canHaveChildren() in a case of shadow children might be wrong. - // See https://bugs.webkit.org/show_bug.cgi?id=52423 - if (!parentRenderer->canHaveChildren()) - return false; - - if (m_visualParentShadowRoot) - return false; - } - - if (!m_parentNodeForRenderingAndStyle->childShouldCreateRenderer(m_node)) + if (!parentRenderer->canHaveChildren()) + return false; + if (!m_parentNodeForRenderingAndStyle->childShouldCreateRenderer(*this)) return false; - return true; } void NodeRenderingContext::moveToFlowThreadIfNeeded() { + if (!m_node->document()->cssRegionsEnabled()) + return; + if (!m_node->isElementNode() || !m_style || m_style->flowThread().isEmpty()) return; diff --git a/Source/WebCore/dom/NodeRenderingContext.h b/Source/WebCore/dom/NodeRenderingContext.h index 610420d37..ca20d525c 100644 --- a/Source/WebCore/dom/NodeRenderingContext.h +++ b/Source/WebCore/dom/NodeRenderingContext.h @@ -34,12 +34,12 @@ namespace WebCore { class ContainerNode; class Document; +class InsertionPoint; class Node; class RenderFlowThread; class RenderObject; class RenderStyle; -class HTMLContentElement; -class ShadowRoot; +class ShadowRootList; class NodeRenderingContext { public: @@ -52,7 +52,7 @@ public: RenderObject* parentRenderer() const; RenderObject* nextRenderer() const; RenderObject* previousRenderer() const; - HTMLContentElement* includer() const; + InsertionPoint* insertionPoint() const; RenderStyle* style() const; void setStyle(PassRefPtr<RenderStyle>); @@ -62,32 +62,28 @@ public: void hostChildrenChanged(); + bool isOnEncapsulationBoundary() const; bool hasFlowThreadParent() const { return m_parentFlowRenderer; } RenderFlowThread* parentFlowRenderer() const { return m_parentFlowRenderer; } void moveToFlowThreadIfNeeded(); private: - - enum TreeLocation { - LocationUndetermined, - LocationNotInTree, - LocationLightChild, - LocationShadowChild, - }; - - enum AttachPhase { - AttachStraight, - AttachContentLight, - AttachContentForwarded, - AttachContentFallback, + enum AttachingPhase { + Calculating, + AttachingStraight, + AttachingNotInTree, + AttachingDistributed, + AttachingNotDistributed, + AttachingFallbacked, + AttachingNotFallbacked, + AttachingShadowChild, }; - TreeLocation m_location; - AttachPhase m_phase; + AttachingPhase m_phase; Node* m_node; ContainerNode* m_parentNodeForRenderingAndStyle; - ShadowRoot* m_visualParentShadowRoot; - HTMLContentElement* m_includer; + ShadowRootList* m_visualParentShadowRootList; + InsertionPoint* m_insertionPoint; RefPtr<RenderStyle> m_style; RenderFlowThread* m_parentFlowRenderer; AtomicString m_flowThread; @@ -100,7 +96,7 @@ inline Node* NodeRenderingContext::node() const inline ContainerNode* NodeRenderingContext::parentNodeForRenderingAndStyle() const { - ASSERT(m_location != LocationUndetermined); + ASSERT(m_phase != Calculating); return m_parentNodeForRenderingAndStyle; } @@ -109,9 +105,16 @@ inline RenderStyle* NodeRenderingContext::style() const return m_style.get(); } -inline HTMLContentElement* NodeRenderingContext::includer() const +inline InsertionPoint* NodeRenderingContext::insertionPoint() const +{ + return m_insertionPoint; +} + +inline bool NodeRenderingContext::isOnEncapsulationBoundary() const { - return m_includer; + return (m_phase == AttachingDistributed + || m_phase == AttachingShadowChild + || m_phase == AttachingFallbacked); } class NodeRendererFactory { diff --git a/Source/WebCore/dom/Notation.idl b/Source/WebCore/dom/Notation.idl index 96351d253..2917cb26f 100644 --- a/Source/WebCore/dom/Notation.idl +++ b/Source/WebCore/dom/Notation.idl @@ -20,8 +20,8 @@ module core { interface Notation : Node { - readonly attribute [ConvertNullStringTo=Null] DOMString publicId; - readonly attribute [ConvertNullStringTo=Null] DOMString systemId; + readonly attribute [TreatReturnedNullStringAs=Null] DOMString publicId; + readonly attribute [TreatReturnedNullStringAs=Null] DOMString systemId; }; } diff --git a/Source/WebCore/dom/OverflowEvent.idl b/Source/WebCore/dom/OverflowEvent.idl index a1ecc4179..10b9504f4 100644 --- a/Source/WebCore/dom/OverflowEvent.idl +++ b/Source/WebCore/dom/OverflowEvent.idl @@ -37,9 +37,9 @@ module events { readonly attribute [InitializedByEventConstructor] boolean verticalOverflow; #if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C - void initOverflowEvent(in [Optional=CallWithDefaultValue] unsigned short orient, - in [Optional=CallWithDefaultValue] boolean horizontalOverflow, - in [Optional=CallWithDefaultValue] boolean verticalOverflow); + void initOverflowEvent(in [Optional=DefaultIsUndefined] unsigned short orient, + in [Optional=DefaultIsUndefined] boolean horizontalOverflow, + in [Optional=DefaultIsUndefined] boolean verticalOverflow); #endif }; diff --git a/Source/WebCore/dom/PopStateEvent.cpp b/Source/WebCore/dom/PopStateEvent.cpp index 8d0cb7292..d1e0c758a 100644 --- a/Source/WebCore/dom/PopStateEvent.cpp +++ b/Source/WebCore/dom/PopStateEvent.cpp @@ -28,6 +28,8 @@ #include "PopStateEvent.h" #include "EventNames.h" +#include "History.h" +#include "SerializedScriptValue.h" namespace WebCore { @@ -38,6 +40,7 @@ PopStateEventInit::PopStateEventInit() PopStateEvent::PopStateEvent() : Event(eventNames().popstateEvent, false, true) , m_serializedState(0) + , m_history(0) { } @@ -45,19 +48,14 @@ PopStateEvent::PopStateEvent(const AtomicString& type, const PopStateEventInit& : Event(type, initializer) , m_state(initializer.state) , m_serializedState(0) + , m_history(0) { } -PopStateEvent::PopStateEvent(const ScriptValue& state) - : Event(eventNames().popstateEvent, false, true) - , m_state(state) - , m_serializedState(0) -{ -} - -PopStateEvent::PopStateEvent(PassRefPtr<SerializedScriptValue> serializedState) +PopStateEvent::PopStateEvent(PassRefPtr<SerializedScriptValue> serializedState, PassRefPtr<History> history) : Event(eventNames().popstateEvent, false, true) , m_serializedState(serializedState) + , m_history(history) { } @@ -70,14 +68,9 @@ PassRefPtr<PopStateEvent> PopStateEvent::create() return adoptRef(new PopStateEvent); } -PassRefPtr<PopStateEvent> PopStateEvent::create(const ScriptValue& state) -{ - return adoptRef(new PopStateEvent(state)); -} - -PassRefPtr<PopStateEvent> PopStateEvent::create(PassRefPtr<SerializedScriptValue> serializedState) +PassRefPtr<PopStateEvent> PopStateEvent::create(PassRefPtr<SerializedScriptValue> serializedState, PassRefPtr<History> history) { - return adoptRef(new PopStateEvent(serializedState)); + return adoptRef(new PopStateEvent(serializedState, history)); } PassRefPtr<PopStateEvent> PopStateEvent::create(const AtomicString& type, const PopStateEventInit& initializer) diff --git a/Source/WebCore/dom/PopStateEvent.h b/Source/WebCore/dom/PopStateEvent.h index 5125fc1ca..8de0ae6d1 100644 --- a/Source/WebCore/dom/PopStateEvent.h +++ b/Source/WebCore/dom/PopStateEvent.h @@ -29,7 +29,6 @@ #include "Event.h" #include "ScriptValue.h" -#include "SerializedScriptValue.h" namespace WebCore { @@ -39,27 +38,30 @@ struct PopStateEventInit : public EventInit { ScriptValue state; }; +class History; +class SerializedScriptValue; + class PopStateEvent : public Event { public: virtual ~PopStateEvent(); static PassRefPtr<PopStateEvent> create(); - static PassRefPtr<PopStateEvent> create(const ScriptValue&); - static PassRefPtr<PopStateEvent> create(PassRefPtr<SerializedScriptValue>); + static PassRefPtr<PopStateEvent> create(PassRefPtr<SerializedScriptValue>, PassRefPtr<History>); static PassRefPtr<PopStateEvent> create(const AtomicString&, const PopStateEventInit&); SerializedScriptValue* serializedState() const { return m_serializedState.get(); } ScriptValue state() const { return m_state; } + History* history() const { return m_history.get(); } virtual const AtomicString& interfaceName() const; private: PopStateEvent(); PopStateEvent(const AtomicString&, const PopStateEventInit&); - explicit PopStateEvent(const ScriptValue&); - explicit PopStateEvent(PassRefPtr<SerializedScriptValue>); + explicit PopStateEvent(PassRefPtr<SerializedScriptValue>, PassRefPtr<History>); ScriptValue m_state; RefPtr<SerializedScriptValue> m_serializedState; + RefPtr<History> m_history; }; } // namespace WebCore diff --git a/Source/WebCore/dom/PopStateEvent.idl b/Source/WebCore/dom/PopStateEvent.idl index 6326a9d7a..c9343ca80 100644 --- a/Source/WebCore/dom/PopStateEvent.idl +++ b/Source/WebCore/dom/PopStateEvent.idl @@ -30,7 +30,7 @@ module events { interface [ ConstructorTemplate=Event ] PopStateEvent : Event { - readonly attribute [InitializedByEventConstructor, CustomGetter] DOMObject state; + readonly attribute [InitializedByEventConstructor, CachedAttribute, CustomGetter] DOMObject state; }; #endif diff --git a/Source/WebCore/dom/Position.cpp b/Source/WebCore/dom/Position.cpp index fed04947a..74b16ab60 100644 --- a/Source/WebCore/dom/Position.cpp +++ b/Source/WebCore/dom/Position.cpp @@ -153,7 +153,7 @@ Text* Position::containerText() const { switch (anchorType()) { case PositionIsOffsetInAnchor: - return m_anchorNode && m_anchorNode->isTextNode() ? static_cast<Text*>(m_anchorNode.get()) : 0; + return m_anchorNode && m_anchorNode->isTextNode() ? toText(m_anchorNode.get()) : 0; case PositionIsBeforeAnchor: case PositionIsAfterAnchor: return 0; @@ -283,7 +283,7 @@ PassRefPtr<CSSComputedStyleDeclaration> Position::computedStyle() const Element* elem = element(); if (!elem) return 0; - return WebCore::computedStyle(elem); + return CSSComputedStyleDeclaration::create(elem); } Position Position::previous(PositionMoveType moveType) const @@ -1018,7 +1018,7 @@ Position Position::leadingWhitespacePosition(EAffinity affinity, bool considerNo Position prev = previousCharacterPosition(affinity); if (prev != *this && prev.deprecatedNode()->inSameContainingBlockFlowElement(deprecatedNode()) && prev.deprecatedNode()->isTextNode()) { - String string = static_cast<Text *>(prev.deprecatedNode())->data(); + String string = toText(prev.deprecatedNode())->data(); UChar c = string[prev.deprecatedEditingOffset()]; if (considerNonCollapsibleWhitespace ? (isSpaceOrNewline(c) || c == noBreakSpace) : isCollapsibleWhitespace(c)) if (isEditablePosition(prev)) diff --git a/Source/WebCore/dom/ProcessingInstruction.idl b/Source/WebCore/dom/ProcessingInstruction.idl index 9c673fdcb..02499a2f1 100644 --- a/Source/WebCore/dom/ProcessingInstruction.idl +++ b/Source/WebCore/dom/ProcessingInstruction.idl @@ -24,8 +24,8 @@ module core { // DOM Level 1 - readonly attribute [ConvertNullStringTo=Null] DOMString target; - attribute [ConvertNullStringTo=Null, TreatNullAs=NullString] DOMString data + readonly attribute [TreatReturnedNullStringAs=Null] DOMString target; + attribute [TreatReturnedNullStringAs=Null, TreatNullAs=NullString] DOMString data setter raises(DOMException); // interface LinkStyle from DOM Level 2 Style Sheets diff --git a/Source/WebCore/dom/Range.cpp b/Source/WebCore/dom/Range.cpp index 9b569b3e0..0c00cfda9 100644 --- a/Source/WebCore/dom/Range.cpp +++ b/Source/WebCore/dom/Range.cpp @@ -677,7 +677,6 @@ static inline unsigned lengthOfContentsInNode(Node* node) case Node::DOCUMENT_FRAGMENT_NODE: case Node::NOTATION_NODE: case Node::XPATH_NAMESPACE_NODE: - case Node::SHADOW_ROOT_NODE: return node->childNodeCount(); } ASSERT_NOT_REACHED(); @@ -840,7 +839,6 @@ PassRefPtr<Node> Range::processContentsBetweenOffsets(ActionType action, PassRef case Node::DOCUMENT_FRAGMENT_NODE: case Node::NOTATION_NODE: case Node::XPATH_NAMESPACE_NODE: - case Node::SHADOW_ROOT_NODE: // FIXME: Should we assert that some nodes never appear here? if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) { if (fragment) @@ -997,7 +995,7 @@ void Range::insertNode(PassRefPtr<Node> prpNewNode, ExceptionCode& ec) Node::NodeType newNodeType = newNode->nodeType(); int numNewChildren; - if (newNodeType == Node::DOCUMENT_FRAGMENT_NODE) { + if (newNodeType == Node::DOCUMENT_FRAGMENT_NODE && !newNode->isShadowRoot()) { // check each child node, not the DocumentFragment itself numNewChildren = 0; for (Node* c = newNode->firstChild(); c; c = c->nextSibling()) { @@ -1028,16 +1026,19 @@ void Range::insertNode(PassRefPtr<Node> prpNewNode, ExceptionCode& ec) case Node::ENTITY_NODE: case Node::NOTATION_NODE: case Node::DOCUMENT_NODE: - case Node::SHADOW_ROOT_NODE: ec = RangeException::INVALID_NODE_TYPE_ERR; return; default: + if (newNode->isShadowRoot()) { + ec = RangeException::INVALID_NODE_TYPE_ERR; + return; + } break; } bool collapsed = m_start == m_end; if (startIsText) { - RefPtr<Text> newText = static_cast<Text*>(m_start.container())->splitText(m_start.offset(), ec); + RefPtr<Text> newText = toText(m_start.container())->splitText(m_start.offset(), ec); if (ec) return; m_start.container()->parentNode()->insertBefore(newNode.release(), newText.get(), ec); @@ -1217,8 +1218,7 @@ Node* Range::checkNodeWOffset(Node* n, int offset, ExceptionCode& ec) const case Node::DOCUMENT_NODE: case Node::ELEMENT_NODE: case Node::ENTITY_REFERENCE_NODE: - case Node::XPATH_NAMESPACE_NODE: - case Node::SHADOW_ROOT_NODE: { + case Node::XPATH_NAMESPACE_NODE: { if (!offset) return 0; Node* childBefore = n->childNode(offset - 1); @@ -1243,7 +1243,6 @@ void Range::checkNodeBA(Node* n, ExceptionCode& ec) const case Node::DOCUMENT_NODE: case Node::ENTITY_NODE: case Node::NOTATION_NODE: - case Node::SHADOW_ROOT_NODE: ec = RangeException::INVALID_NODE_TYPE_ERR; return; case Node::CDATA_SECTION_NODE: @@ -1265,7 +1264,6 @@ void Range::checkNodeBA(Node* n, ExceptionCode& ec) const case Node::ATTRIBUTE_NODE: case Node::DOCUMENT_NODE: case Node::DOCUMENT_FRAGMENT_NODE: - case Node::SHADOW_ROOT_NODE: break; case Node::CDATA_SECTION_NODE: case Node::COMMENT_NODE: @@ -1397,7 +1395,6 @@ void Range::selectNode(Node* refNode, ExceptionCode& ec) case Node::PROCESSING_INSTRUCTION_NODE: case Node::TEXT_NODE: case Node::XPATH_NAMESPACE_NODE: - case Node::SHADOW_ROOT_NODE: break; case Node::DOCUMENT_TYPE_NODE: case Node::ENTITY_NODE: @@ -1422,7 +1419,6 @@ void Range::selectNode(Node* refNode, ExceptionCode& ec) case Node::DOCUMENT_NODE: case Node::ENTITY_NODE: case Node::NOTATION_NODE: - case Node::SHADOW_ROOT_NODE: ec = RangeException::INVALID_NODE_TYPE_ERR; return; } @@ -1463,7 +1459,6 @@ void Range::selectNodeContents(Node* refNode, ExceptionCode& ec) case Node::PROCESSING_INSTRUCTION_NODE: case Node::TEXT_NODE: case Node::XPATH_NAMESPACE_NODE: - case Node::SHADOW_ROOT_NODE: break; case Node::DOCUMENT_TYPE_NODE: case Node::ENTITY_NODE: @@ -1512,7 +1507,6 @@ void Range::surroundContents(PassRefPtr<Node> passNewParent, ExceptionCode& ec) case Node::PROCESSING_INSTRUCTION_NODE: case Node::TEXT_NODE: case Node::XPATH_NAMESPACE_NODE: - case Node::SHADOW_ROOT_NODE: break; } @@ -1678,7 +1672,7 @@ IntRect Range::boundingBox() const size_t n = rects.size(); for (size_t i = 0; i < n; ++i) result.unite(rects[i]); - return result; + return pixelSnappedIntRect(result); } void Range::textRects(Vector<IntRect>& rects, bool useSelectionHeight, RangeInFixedPosition* inFixed) @@ -2040,7 +2034,7 @@ void Range::getBorderAndTextQuads(Vector<FloatQuad>& quads) const } } } else if (node->isTextNode()) { - if (RenderObject* renderer = static_cast<Text*>(node)->renderer()) { + if (RenderObject* renderer = toText(node)->renderer()) { RenderText* renderText = toRenderText(renderer); int startOffset = (node == startContainer) ? m_start.offset() : 0; int endOffset = (node == endContainer) ? m_end.offset() : INT_MAX; diff --git a/Source/WebCore/dom/Range.idl b/Source/WebCore/dom/Range.idl index eb7168fa6..67f4aee07 100644 --- a/Source/WebCore/dom/Range.idl +++ b/Source/WebCore/dom/Range.idl @@ -36,25 +36,25 @@ module ranges { readonly attribute Node commonAncestorContainer getter raises(DOMException); - [ObjCLegacyUnnamedParameters] void setStart(in [Optional=CallWithDefaultValue] Node refNode, - in [Optional=CallWithDefaultValue] long offset) + [ObjCLegacyUnnamedParameters] void setStart(in [Optional=DefaultIsUndefined] Node refNode, + in [Optional=DefaultIsUndefined] long offset) raises(RangeException, DOMException); - [ObjCLegacyUnnamedParameters] void setEnd(in [Optional=CallWithDefaultValue] Node refNode, - in [Optional=CallWithDefaultValue] long offset) + [ObjCLegacyUnnamedParameters] void setEnd(in [Optional=DefaultIsUndefined] Node refNode, + in [Optional=DefaultIsUndefined] long offset) raises(RangeException, DOMException); - void setStartBefore(in [Optional=CallWithDefaultValue] Node refNode) + void setStartBefore(in [Optional=DefaultIsUndefined] Node refNode) raises(RangeException, DOMException); - void setStartAfter(in [Optional=CallWithDefaultValue] Node refNode) + void setStartAfter(in [Optional=DefaultIsUndefined] Node refNode) raises(RangeException, DOMException); - void setEndBefore(in [Optional=CallWithDefaultValue] Node refNode) + void setEndBefore(in [Optional=DefaultIsUndefined] Node refNode) raises(RangeException, DOMException); - void setEndAfter(in [Optional=CallWithDefaultValue] Node refNode) + void setEndAfter(in [Optional=DefaultIsUndefined] Node refNode) raises(RangeException, DOMException); - void collapse(in [Optional=CallWithDefaultValue] boolean toStart) + void collapse(in [Optional=DefaultIsUndefined] boolean toStart) raises(DOMException); - void selectNode(in [Optional=CallWithDefaultValue] Node refNode) + void selectNode(in [Optional=DefaultIsUndefined] Node refNode) raises(RangeException, DOMException); - void selectNodeContents(in [Optional=CallWithDefaultValue] Node refNode) + void selectNodeContents(in [Optional=DefaultIsUndefined] Node refNode) raises(RangeException, DOMException); // CompareHow @@ -63,8 +63,8 @@ module ranges { const unsigned short END_TO_END = 2; const unsigned short END_TO_START = 3; - [ObjCLegacyUnnamedParameters] short compareBoundaryPoints(in [Optional=CallWithDefaultValue] CompareHow how, - in [Optional=CallWithDefaultValue] Range sourceRange) + [ObjCLegacyUnnamedParameters] short compareBoundaryPoints(in [Optional=DefaultIsUndefined] CompareHow how, + in [Optional=DefaultIsUndefined] Range sourceRange) raises(DOMException); void deleteContents() @@ -73,9 +73,9 @@ module ranges { raises(DOMException); DocumentFragment cloneContents() raises(DOMException); - void insertNode(in [Optional=CallWithDefaultValue] Node newNode) + void insertNode(in [Optional=DefaultIsUndefined] Node newNode) raises(DOMException, RangeException); - void surroundContents(in [Optional=CallWithDefaultValue] Node newParent) + void surroundContents(in [Optional=DefaultIsUndefined] Node newParent) raises(DOMException, RangeException); Range cloneRange() raises(DOMException); @@ -94,15 +94,15 @@ module ranges { // extensions - DocumentFragment createContextualFragment(in [Optional=CallWithDefaultValue] DOMString html) + DocumentFragment createContextualFragment(in [Optional=DefaultIsUndefined] DOMString html) raises(DOMException); // WebKit extensions - boolean intersectsNode(in [Optional=CallWithDefaultValue] Node refNode) + boolean intersectsNode(in [Optional=DefaultIsUndefined] Node refNode) raises(RangeException, DOMException); - short compareNode(in [Optional=CallWithDefaultValue] Node refNode) + short compareNode(in [Optional=DefaultIsUndefined] Node refNode) raises(RangeException, DOMException); // CompareResults @@ -111,15 +111,15 @@ module ranges { const unsigned short NODE_BEFORE_AND_AFTER = 2; const unsigned short NODE_INSIDE = 3; - short comparePoint(in [Optional=CallWithDefaultValue] Node refNode, - in [Optional=CallWithDefaultValue] long offset) + short comparePoint(in [Optional=DefaultIsUndefined] Node refNode, + in [Optional=DefaultIsUndefined] long offset) raises(RangeException, DOMException); - boolean isPointInRange(in [Optional=CallWithDefaultValue] Node refNode, - in [Optional=CallWithDefaultValue] long offset) + boolean isPointInRange(in [Optional=DefaultIsUndefined] Node refNode, + in [Optional=DefaultIsUndefined] long offset) raises(RangeException, DOMException); - void expand(in [Optional=CallWithDefaultValue] DOMString unit) + void expand(in [Optional=DefaultIsUndefined] DOMString unit) raises(RangeException, DOMException); #if !defined(LANGUAGE_JAVASCRIPT) || !LANGUAGE_JAVASCRIPT diff --git a/Source/WebCore/dom/RequestAnimationFrameCallback.idl b/Source/WebCore/dom/RequestAnimationFrameCallback.idl index b850c4776..4da682083 100644 --- a/Source/WebCore/dom/RequestAnimationFrameCallback.idl +++ b/Source/WebCore/dom/RequestAnimationFrameCallback.idl @@ -30,7 +30,7 @@ module core { interface [ - Callback=FunctionOnly, + Callback, Conditional=REQUEST_ANIMATION_FRAME, ] RequestAnimationFrameCallback{ #if defined(V8_BINDING) && V8_BINDING diff --git a/Source/WebCore/dom/ScriptElement.cpp b/Source/WebCore/dom/ScriptElement.cpp index 71c1fce42..895e8337d 100644 --- a/Source/WebCore/dom/ScriptElement.cpp +++ b/Source/WebCore/dom/ScriptElement.cpp @@ -355,7 +355,7 @@ String ScriptElement::scriptContent() const if (!n->isTextNode()) continue; - Text* t = static_cast<Text*>(n); + Text* t = toText(n); if (foundMultipleTextNodes) content.append(t->data()); else if (firstTextNode) { diff --git a/Source/WebCore/dom/ScriptExecutionContext.cpp b/Source/WebCore/dom/ScriptExecutionContext.cpp index 5670fe8ef..9a5682d7f 100644 --- a/Source/WebCore/dom/ScriptExecutionContext.cpp +++ b/Source/WebCore/dom/ScriptExecutionContext.cpp @@ -93,6 +93,7 @@ ScriptExecutionContext::ScriptExecutionContext() : m_iteratingActiveDOMObjects(false) , m_inDestructor(false) , m_inDispatchErrorEvent(false) + , m_activeDOMObjectsAreSuspended(false) #if ENABLE(SQL_DATABASE) , m_hasOpenDatabases(false) #endif @@ -102,7 +103,6 @@ ScriptExecutionContext::ScriptExecutionContext() ScriptExecutionContext::~ScriptExecutionContext() { m_inDestructor = true; - for (HashSet<ContextDestructionObserver*>::iterator iter = m_destructionObservers.begin(); iter != m_destructionObservers.end(); iter = m_destructionObservers.begin()) { ContextDestructionObserver* observer = *iter; m_destructionObservers.remove(observer); @@ -211,11 +211,12 @@ bool ScriptExecutionContext::canSuspendActiveDOMObjects() HashMap<ActiveDOMObject*, void*>::iterator activeObjectsEnd = m_activeDOMObjects.end(); for (HashMap<ActiveDOMObject*, void*>::iterator iter = m_activeDOMObjects.begin(); iter != activeObjectsEnd; ++iter) { ASSERT(iter->first->scriptExecutionContext() == this); + ASSERT(iter->first->suspendIfNeededCalled()); if (!iter->first->canSuspend()) { m_iteratingActiveDOMObjects = false; return false; } - } + } m_iteratingActiveDOMObjects = false; return true; } @@ -227,18 +228,23 @@ void ScriptExecutionContext::suspendActiveDOMObjects(ActiveDOMObject::ReasonForS HashMap<ActiveDOMObject*, void*>::iterator activeObjectsEnd = m_activeDOMObjects.end(); for (HashMap<ActiveDOMObject*, void*>::iterator iter = m_activeDOMObjects.begin(); iter != activeObjectsEnd; ++iter) { ASSERT(iter->first->scriptExecutionContext() == this); + ASSERT(iter->first->suspendIfNeededCalled()); iter->first->suspend(why); } m_iteratingActiveDOMObjects = false; + m_activeDOMObjectsAreSuspended = true; + m_reasonForSuspendingActiveDOMObjects = why; } void ScriptExecutionContext::resumeActiveDOMObjects() { + m_activeDOMObjectsAreSuspended = false; // No protection against m_activeDOMObjects changing during iteration: resume() shouldn't execute arbitrary JS. m_iteratingActiveDOMObjects = true; HashMap<ActiveDOMObject*, void*>::iterator activeObjectsEnd = m_activeDOMObjects.end(); for (HashMap<ActiveDOMObject*, void*>::iterator iter = m_activeDOMObjects.begin(); iter != activeObjectsEnd; ++iter) { ASSERT(iter->first->scriptExecutionContext() == this); + ASSERT(iter->first->suspendIfNeededCalled()); iter->first->resume(); } m_iteratingActiveDOMObjects = false; @@ -251,6 +257,7 @@ void ScriptExecutionContext::stopActiveDOMObjects() HashMap<ActiveDOMObject*, void*>::iterator activeObjectsEnd = m_activeDOMObjects.end(); for (HashMap<ActiveDOMObject*, void*>::iterator iter = m_activeDOMObjects.begin(); iter != activeObjectsEnd; ++iter) { ASSERT(iter->first->scriptExecutionContext() == this); + ASSERT(iter->first->suspendIfNeededCalled()); iter->first->stop(); } m_iteratingActiveDOMObjects = false; @@ -259,6 +266,14 @@ void ScriptExecutionContext::stopActiveDOMObjects() closeMessagePorts(); } +void ScriptExecutionContext::suspendActiveDOMObjectIfNeeded(ActiveDOMObject* object) +{ + ASSERT(m_activeDOMObjects.contains(object)); + // Ensure all ActiveDOMObjects are suspended also newly created ones. + if (m_activeDOMObjectsAreSuspended) + object->suspend(m_reasonForSuspendingActiveDOMObjects); +} + void ScriptExecutionContext::didCreateActiveDOMObject(ActiveDOMObject* object, void* upcastPointer) { ASSERT(object); diff --git a/Source/WebCore/dom/ScriptExecutionContext.h b/Source/WebCore/dom/ScriptExecutionContext.h index 6cbdd0265..15ceb42ee 100644 --- a/Source/WebCore/dom/ScriptExecutionContext.h +++ b/Source/WebCore/dom/ScriptExecutionContext.h @@ -98,6 +98,9 @@ public: void addConsoleMessage(MessageSource, MessageType, MessageLevel, const String& message, const String& sourceURL = String(), unsigned lineNumber = 0, PassRefPtr<ScriptCallStack> = 0); void addConsoleMessage(MessageSource, MessageType, MessageLevel, const String& message, PassRefPtr<ScriptCallStack>); +#if ENABLE(BLOB) + PublicURLManager& publicURLManager(); +#endif // Active objects are not garbage collected even if inaccessible, e.g. because their activity may result in callbacks being invoked. bool canSuspendActiveDOMObjects(); // Active objects can be asked to suspend even if canSuspendActiveDOMObjects() returns 'false' - @@ -106,12 +109,15 @@ public: virtual void resumeActiveDOMObjects(); virtual void stopActiveDOMObjects(); -#if ENABLE(BLOB) - PublicURLManager& publicURLManager(); -#endif + bool activeDOMObjectsAreSuspended() const { return m_activeDOMObjectsAreSuspended; } + + // Called from the constructor and destructors of ActiveDOMObject. void didCreateActiveDOMObject(ActiveDOMObject*, void* upcastPointer); void willDestroyActiveDOMObject(ActiveDOMObject*); + // Called after the construction of an ActiveDOMObject to synchronize suspend state. + void suspendActiveDOMObjectIfNeeded(ActiveDOMObject*); + typedef const HashMap<ActiveDOMObject*, void*> ActiveDOMObjectsMap; ActiveDOMObjectsMap& activeDOMObjects() const { return m_activeDOMObjects; } @@ -215,6 +221,9 @@ private: OwnPtr<PublicURLManager> m_publicURLManager; #endif + bool m_activeDOMObjectsAreSuspended; + ActiveDOMObject::ReasonForSuspension m_reasonForSuspendingActiveDOMObjects; + #if ENABLE(SQL_DATABASE) RefPtr<DatabaseThread> m_databaseThread; bool m_hasOpenDatabases; // This never changes back to false, even after the database thread is closed. diff --git a/Source/WebCore/dom/ScriptedAnimationController.cpp b/Source/WebCore/dom/ScriptedAnimationController.cpp index 8875f5568..099bc5cbd 100644 --- a/Source/WebCore/dom/ScriptedAnimationController.cpp +++ b/Source/WebCore/dom/ScriptedAnimationController.cpp @@ -85,7 +85,7 @@ ScriptedAnimationController::CallbackId ScriptedAnimationController::registerCal callback->m_element = animationElement; m_callbacks.append(callback); - InspectorInstrumentation::didRegisterAnimationFrameCallback(m_document, id); + InspectorInstrumentation::didRequestAnimationFrame(m_document, id); if (!m_suspendCount) scheduleAnimation(); @@ -97,7 +97,7 @@ void ScriptedAnimationController::cancelCallback(CallbackId id) for (size_t i = 0; i < m_callbacks.size(); ++i) { if (m_callbacks[i]->m_id == id) { m_callbacks[i]->m_firedOrCancelled = true; - InspectorInstrumentation::didCancelAnimationFrameCallback(m_document, id); + InspectorInstrumentation::didCancelAnimationFrame(m_document, id); m_callbacks.remove(i); return; } @@ -141,9 +141,9 @@ void ScriptedAnimationController::serviceScriptedAnimations(DOMTimeStamp time) RequestAnimationFrameCallback* callback = callbacks[i].get(); if (!callback->m_firedOrCancelled && (!callback->m_element || callback->m_element->renderer())) { callback->m_firedOrCancelled = true; - InspectorInstrumentationCookie cookie = InspectorInstrumentation::willFireAnimationFrameEvent(m_document, callback->m_id); + InspectorInstrumentationCookie cookie = InspectorInstrumentation::willFireAnimationFrame(m_document, callback->m_id); callback->handleEvent(time); - InspectorInstrumentation::didFireAnimationFrameEvent(cookie); + InspectorInstrumentation::didFireAnimationFrame(cookie); firedCallback = true; callbacks.remove(i); break; diff --git a/Source/WebCore/dom/ShadowRoot.cpp b/Source/WebCore/dom/ShadowRoot.cpp index 290be3f6d..6cf50acb9 100644 --- a/Source/WebCore/dom/ShadowRoot.cpp +++ b/Source/WebCore/dom/ShadowRoot.cpp @@ -27,22 +27,28 @@ #include "config.h" #include "ShadowRoot.h" -#include "ContentInclusionSelector.h" #include "Document.h" #include "Element.h" #include "HTMLContentElement.h" +#include "HTMLContentSelector.h" #include "HTMLNames.h" +#include "InsertionPoint.h" #include "NodeRareData.h" +#include "ShadowRootList.h" #include "SVGNames.h" -#include "Text.h" + +#if ENABLE(SHADOW_DOM) +#include "RuntimeEnabledFeatures.h" +#endif namespace WebCore { ShadowRoot::ShadowRoot(Document* document) : DocumentFragment(document, CreateShadowRoot) , TreeScope(this) + , m_prev(0) + , m_next(0) , m_applyAuthorSheets(false) - , m_needsRecalculateContent(false) { ASSERT(document); @@ -55,6 +61,9 @@ ShadowRoot::ShadowRoot(Document* document) ShadowRoot::~ShadowRoot() { + ASSERT(!m_prev); + ASSERT(!m_next); + // We must call clearRareData() here since a ShadowRoot class inherits TreeScope // as well as Node. See a comment on TreeScope.h for the reason. if (hasRareData()) @@ -92,7 +101,13 @@ PassRefPtr<ShadowRoot> ShadowRoot::create(Element* element, ExceptionCode& ec) PassRefPtr<ShadowRoot> ShadowRoot::create(Element* element, ShadowRootCreationPurpose purpose, ExceptionCode& ec) { - if (!element || element->shadowRoot()) { +#if ENABLE(SHADOW_DOM) + bool isMultipleShadowSubtreesEnabled = RuntimeEnabledFeatures::multipleShadowSubtreesEnabled(); +#else + bool isMultipleShadowSubtreesEnabled = false; +#endif + + if (!element || (!isMultipleShadowSubtreesEnabled && element->hasShadowRoot())) { ec = HIERARCHY_REQUEST_ERR; return 0; } @@ -104,14 +119,15 @@ PassRefPtr<ShadowRoot> ShadowRoot::create(Element* element, ShadowRootCreationPu return 0; } - ASSERT(purpose != CreatingUserAgentShadowRoot || !element->shadowRoot()); - RefPtr<ShadowRoot> shadowRoot = create(element->document()); + ASSERT(purpose != CreatingUserAgentShadowRoot || !element->hasShadowRoot()); + RefPtr<ShadowRoot> shadowRoot = adoptRef(new ShadowRoot(element->document())); ec = 0; element->setShadowRoot(shadowRoot, ec); if (ec) return 0; - + ASSERT(element == shadowRoot->host()); + ASSERT(element->hasShadowRoot()); return shadowRoot.release(); } @@ -120,11 +136,6 @@ String ShadowRoot::nodeName() const return "#shadow-root"; } -Node::NodeType ShadowRoot::nodeType() const -{ - return SHADOW_ROOT_NODE; -} - PassRefPtr<Node> ShadowRoot::cloneNode(bool) { // ShadowRoot should not be arbitrarily cloned. @@ -146,53 +157,11 @@ bool ShadowRoot::childTypeAllowed(NodeType type) const } } -void ShadowRoot::recalcShadowTreeStyle(StyleChange change) -{ - if (needsReattachHostChildrenAndShadow()) - reattachHostChildrenAndShadow(); - else { - for (Node* n = firstChild(); n; n = n->nextSibling()) { - if (n->isElementNode()) - static_cast<Element*>(n)->recalcStyle(change); - else if (n->isTextNode()) - static_cast<Text*>(n)->recalcTextStyle(change); - } - } - - clearNeedsReattachHostChildrenAndShadow(); - clearNeedsStyleRecalc(); - clearChildNeedsStyleRecalc(); -} - -void ShadowRoot::setNeedsReattachHostChildrenAndShadow() -{ - m_needsRecalculateContent = true; - if (shadowHost()) - shadowHost()->setNeedsStyleRecalc(); -} - -HTMLContentElement* ShadowRoot::includerFor(Node* node) const -{ - if (!m_inclusions) - return 0; - ShadowInclusion* found = m_inclusions->findFor(node); - if (!found) - return 0; - return found->includer(); -} - -void ShadowRoot::hostChildrenChanged() +ShadowRootList* ShadowRoot::list() const { - if (!hasContentElement()) - return; - - // This results in forced detaching/attaching of the shadow render tree. See ShadowRoot::recalcStyle(). - setNeedsReattachHostChildrenAndShadow(); -} - -bool ShadowRoot::isInclusionSelectorActive() const -{ - return m_inclusions && m_inclusions->hasCandidates(); + if (host()) + return host()->shadowRootList(); + return 0; } bool ShadowRoot::hasContentElement() const @@ -217,46 +186,15 @@ void ShadowRoot::setApplyAuthorSheets(bool value) void ShadowRoot::attach() { - // Children of m_inclusions is populated lazily in - // ensureInclusions(), and here we just ensure that + // Children of m_selector is populated lazily in + // ensureSelector(), and here we just ensure that // it is in clean state. - ASSERT(!m_inclusions || !m_inclusions->hasCandidates()); + // FIXME: This assertion breaks if multiple shadow roots are being attached. + // ShadowRootList should have responsibility of side effect of selector in attaching/detaching. + ASSERT(!host()->shadowRootList()->selector() || !host()->shadowRootList()->selector()->hasCandidates()); DocumentFragment::attach(); - if (m_inclusions) - m_inclusions->didSelect(); -} - -void ShadowRoot::reattachHostChildrenAndShadow() -{ - Node* hostNode = host(); - if (!hostNode) - return; - - for (Node* child = hostNode->firstChild(); child; child = child->nextSibling()) { - if (child->attached()) - child->detach(); - } - - reattach(); - - for (Node* child = hostNode->firstChild(); child; child = child->nextSibling()) { - if (!child->attached()) - child->attach(); - } -} - -ContentInclusionSelector* ShadowRoot::inclusions() const -{ - return m_inclusions.get(); + if (HTMLContentSelector* selector = host()->shadowRootList()->selector()) + selector->didSelect(); } -ContentInclusionSelector* ShadowRoot::ensureInclusions() -{ - if (!m_inclusions) - m_inclusions = adoptPtr(new ContentInclusionSelector()); - m_inclusions->willSelectOver(this); - return m_inclusions.get(); -} - - } diff --git a/Source/WebCore/dom/ShadowRoot.h b/Source/WebCore/dom/ShadowRoot.h index 401ee5e9d..312116749 100644 --- a/Source/WebCore/dom/ShadowRoot.h +++ b/Source/WebCore/dom/ShadowRoot.h @@ -30,16 +30,19 @@ #include "DocumentFragment.h" #include "ExceptionCode.h" #include "TreeScope.h" +#include <wtf/DoublyLinkedList.h> namespace WebCore { -class ContentInclusionSelector; class Document; class HTMLContentElement; +class HTMLContentSelector; +class InsertionPoint; +class ShadowRootList; -class ShadowRoot : public DocumentFragment, public TreeScope { +class ShadowRoot : public DocumentFragment, public TreeScope, public DoublyLinkedListNode<ShadowRoot> { + friend class WTF::DoublyLinkedListNode<ShadowRoot>; public: - static PassRefPtr<ShadowRoot> create(Document*); static PassRefPtr<ShadowRoot> create(Element*, ExceptionCode&); // FIXME: We will support multiple shadow subtrees, however current implementation does not work well @@ -58,56 +61,44 @@ public: void clearNeedsReattachHostChildrenAndShadow(); bool needsReattachHostChildrenAndShadow(); - HTMLContentElement* includerFor(Node*) const; + InsertionPoint* insertionPointFor(Node*) const; void hostChildrenChanged(); - bool isInclusionSelectorActive() const; virtual void attach(); - void reattachHostChildrenAndShadow(); virtual bool applyAuthorSheets() const; void setApplyAuthorSheets(bool); Element* host() const { return shadowHost(); } + ShadowRootList* list() const; - ContentInclusionSelector* inclusions() const; - ContentInclusionSelector* ensureInclusions(); + ShadowRoot* youngerShadowRoot() const { return prev(); } + ShadowRoot* olderShadowRoot() const { return next(); } + + bool hasContentElement() const; private: ShadowRoot(Document*); virtual ~ShadowRoot(); virtual String nodeName() const; - virtual NodeType nodeType() const; virtual PassRefPtr<Node> cloneNode(bool deep); virtual bool childTypeAllowed(NodeType) const; - bool hasContentElement() const; - + ShadowRoot* m_prev; + ShadowRoot* m_next; bool m_applyAuthorSheets : 1; - bool m_needsRecalculateContent : 1; - OwnPtr<ContentInclusionSelector> m_inclusions; }; -inline PassRefPtr<ShadowRoot> ShadowRoot::create(Document* document) -{ - return adoptRef(new ShadowRoot(document)); -} - -inline void ShadowRoot::clearNeedsReattachHostChildrenAndShadow() -{ - m_needsRecalculateContent = false; -} - -inline bool ShadowRoot::needsReattachHostChildrenAndShadow() +inline const ShadowRoot* toShadowRoot(const Node* node) { - return m_needsRecalculateContent || hasContentElement(); + ASSERT(!node || node->isShadowRoot()); + return static_cast<const ShadowRoot*>(node); } inline ShadowRoot* toShadowRoot(Node* node) { - ASSERT(!node || node->nodeType() == Node::SHADOW_ROOT_NODE); - return static_cast<ShadowRoot*>(node); + return const_cast<ShadowRoot*>(toShadowRoot(static_cast<const Node*>(node))); } } // namespace diff --git a/Source/WebCore/dom/ShadowRoot.idl b/Source/WebCore/dom/ShadowRoot.idl index 011d6795f..ffa3b03b4 100644 --- a/Source/WebCore/dom/ShadowRoot.idl +++ b/Source/WebCore/dom/ShadowRoot.idl @@ -33,11 +33,11 @@ module core { ConstructorRaisesException ] ShadowRoot : DocumentFragment { readonly attribute Element host; - Element getElementById(in [Optional=CallWithDefaultValue] DOMString elementId); - NodeList getElementsByClassName(in [Optional=CallWithDefaultValue] DOMString className); - NodeList getElementsByTagName(in [Optional=CallWithDefaultValue] DOMString tagName); - NodeList getElementsByTagNameNS(in [TreatNullAs=NullString,Optional=CallWithDefaultValue] DOMString namespaceURI, - in [Optional=CallWithDefaultValue] DOMString localName); + Element getElementById(in [Optional=DefaultIsUndefined] DOMString elementId); + NodeList getElementsByClassName(in [Optional=DefaultIsUndefined] DOMString className); + NodeList getElementsByTagName(in [Optional=DefaultIsUndefined] DOMString tagName); + NodeList getElementsByTagNameNS(in [TreatNullAs=NullString,Optional=DefaultIsUndefined] DOMString namespaceURI, + in [Optional=DefaultIsUndefined] DOMString localName); }; } diff --git a/Source/WebCore/dom/ShadowRootList.cpp b/Source/WebCore/dom/ShadowRootList.cpp new file mode 100644 index 000000000..3adee6370 --- /dev/null +++ b/Source/WebCore/dom/ShadowRootList.cpp @@ -0,0 +1,238 @@ +/* + * Copyright (C) 2012 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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 "ShadowRootList.h" + +#include "Document.h" +#include "Element.h" +#include "HTMLContentSelector.h" +#include "RuntimeEnabledFeatures.h" +#include "ShadowRoot.h" +#include "Text.h" + +namespace WebCore { + +ShadowRootList::ShadowRootList() + : m_needsRecalculateContent(false) +{ +} + +ShadowRootList::~ShadowRootList() +{ + ASSERT(!hasShadowRoot()); +} + +void ShadowRootList::pushShadowRoot(ShadowRoot* shadowRoot) +{ +#if ENABLE(SHADOW_DOM) + if (!RuntimeEnabledFeatures::multipleShadowSubtreesEnabled()) + ASSERT(!hasShadowRoot()); +#else + ASSERT(!hasShadowRoot()); +#endif + + m_shadowRoots.push(shadowRoot); +} + +ShadowRoot* ShadowRootList::popShadowRoot() +{ + if (!hasShadowRoot()) + return 0; + + return m_shadowRoots.removeHead(); +} + +void ShadowRootList::insertedIntoDocument() +{ + for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot()) + root->insertedIntoDocument(); +} + +void ShadowRootList::removedFromDocument() +{ + for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot()) + root->removedFromDocument(); +} + +void ShadowRootList::insertedIntoTree(bool deep) +{ + for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot()) + root->insertedIntoTree(deep); +} + +void ShadowRootList::removedFromTree(bool deep) +{ + for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot()) + root->removedFromTree(deep); +} + +void ShadowRootList::willRemove() +{ + for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot()) + root->willRemove(); +} + +void ShadowRootList::attach() +{ + // FIXME: Currently we only support the case that the shadow root list has at most one shadow root. + // See also https://bugs.webkit.org/show_bug.cgi?id=77503 and its dependent bugs. + ASSERT(m_shadowRoots.size() <= 1); + + for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot()) { + if (!root->attached()) + root->attach(); + } +} + +void ShadowRootList::detach() +{ + // FIXME: Currently we only support the case that the shadow root list has at most one shadow root. + // See also https://bugs.webkit.org/show_bug.cgi?id=77503 and its dependent bugs. + ASSERT(m_shadowRoots.size() <= 1); + + for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot()) { + if (root->attached()) + root->detach(); + } +} + +InsertionPoint* ShadowRootList::insertionPointFor(Node* node) const +{ + if (!m_selector) + return 0; + HTMLContentSelection* found = m_selector->findFor(node); + if (!found) + return 0; + return found->insertionPoint(); +} + +bool ShadowRootList::isSelectorActive() const +{ + return m_selector && m_selector->hasCandidates(); +} + +void ShadowRootList::reattach() +{ + detach(); + attach(); +} + +bool ShadowRootList::childNeedsStyleRecalc() +{ + ASSERT(youngestShadowRoot()); + if (!youngestShadowRoot()) + return false; + + return youngestShadowRoot()->childNeedsStyleRecalc(); +} + +bool ShadowRootList::needsStyleRecalc() +{ + ASSERT(youngestShadowRoot()); + if (!youngestShadowRoot()) + return false; + + return youngestShadowRoot()->needsStyleRecalc(); +} + +void ShadowRootList::recalcShadowTreeStyle(Node::StyleChange change) +{ + ShadowRoot* youngest = youngestShadowRoot(); + if (!youngest) + return; + + if (needsReattachHostChildrenAndShadow()) + reattachHostChildrenAndShadow(); + else { + for (Node* n = youngest->firstChild(); n; n = n->nextSibling()) { + if (n->isElementNode()) + static_cast<Element*>(n)->recalcStyle(change); + else if (n->isTextNode()) + toText(n)->recalcTextStyle(change); + } + } + + clearNeedsReattachHostChildrenAndShadow(); + for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot()) { + root->clearNeedsStyleRecalc(); + root->clearChildNeedsStyleRecalc(); + } +} + +bool ShadowRootList::needsReattachHostChildrenAndShadow() +{ + return m_needsRecalculateContent || (youngestShadowRoot() && youngestShadowRoot()->hasContentElement()); +} + +void ShadowRootList::hostChildrenChanged() +{ + ASSERT(youngestShadowRoot()); + + if (!youngestShadowRoot()->hasContentElement()) + return; + + // This results in forced detaching/attaching of the shadow render tree. See ShadowRoot::recalcStyle(). + setNeedsReattachHostChildrenAndShadow(); +} + +void ShadowRootList::setNeedsReattachHostChildrenAndShadow() +{ + m_needsRecalculateContent = true; + + host()->setNeedsStyleRecalc(); +} + +void ShadowRootList::reattachHostChildrenAndShadow() +{ + ASSERT(youngestShadowRoot()); + + Node* hostNode = youngestShadowRoot()->host(); + if (!hostNode) + return; + + for (Node* child = hostNode->firstChild(); child; child = child->nextSibling()) { + if (child->attached()) + child->detach(); + } + + reattach(); + + for (Node* child = hostNode->firstChild(); child; child = child->nextSibling()) { + if (!child->attached()) + child->attach(); + } +} + +HTMLContentSelector* ShadowRootList::ensureSelector() +{ + if (!m_selector) + m_selector = adoptPtr(new HTMLContentSelector()); + m_selector->willSelectOver(host()); + return m_selector.get(); +} + +} // namespace diff --git a/Source/WebCore/dom/ShadowRootList.h b/Source/WebCore/dom/ShadowRootList.h new file mode 100644 index 000000000..db3170a6d --- /dev/null +++ b/Source/WebCore/dom/ShadowRootList.h @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2012 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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 ShadowRootList_h +#define ShadowRootList_h + +#include "ShadowRoot.h" +#include <wtf/DoublyLinkedList.h> +#include <wtf/Noncopyable.h> +#include <wtf/OwnPtr.h> +#include <wtf/PassRefPtr.h> + +namespace WebCore { + +class Node; +class Element; +class HTMLContentSelector; +class InsertionPoint; + +class ShadowRootList { +public: + ShadowRootList(); + ~ShadowRootList(); + + bool hasShadowRoot() const; + ShadowRoot* youngestShadowRoot() const; + ShadowRoot* oldestShadowRoot() const; + + void pushShadowRoot(ShadowRoot*); + ShadowRoot* popShadowRoot(); + + void insertedIntoDocument(); + void removedFromDocument(); + void insertedIntoTree(bool deep); + void removedFromTree(bool deep); + void willRemove(); + + void attach(); + void detach(); + void reattach(); + + bool childNeedsStyleRecalc(); + bool needsStyleRecalc(); + void recalcShadowTreeStyle(Node::StyleChange); + void setNeedsReattachHostChildrenAndShadow(); + void clearNeedsReattachHostChildrenAndShadow(); + bool needsReattachHostChildrenAndShadow(); + void reattachHostChildrenAndShadow(); + void hostChildrenChanged(); + + InsertionPoint* insertionPointFor(Node*) const; + + HTMLContentSelector* selector() const; + HTMLContentSelector* ensureSelector(); + + bool isSelectorActive() const; + +private: + Element* host() const; + + DoublyLinkedList<ShadowRoot> m_shadowRoots; + OwnPtr<HTMLContentSelector> m_selector; + bool m_needsRecalculateContent : 1; + WTF_MAKE_NONCOPYABLE(ShadowRootList); +}; + +inline bool ShadowRootList::hasShadowRoot() const +{ + return !m_shadowRoots.isEmpty(); +} + +inline ShadowRoot* ShadowRootList::youngestShadowRoot() const +{ + return m_shadowRoots.head(); +} + +inline ShadowRoot* ShadowRootList::oldestShadowRoot() const +{ + return m_shadowRoots.tail(); +} + +inline HTMLContentSelector* ShadowRootList::selector() const +{ + return m_selector.get(); +} + +inline void ShadowRootList::clearNeedsReattachHostChildrenAndShadow() +{ + m_needsRecalculateContent = false; +} + +inline Element* ShadowRootList::host() const +{ + ASSERT(hasShadowRoot()); + return youngestShadowRoot()->host(); +} + +} // namespace + +#endif diff --git a/Source/WebCore/dom/StaticHashSetNodeList.cpp b/Source/WebCore/dom/StaticHashSetNodeList.cpp index 6c8c2db97..3d6b5c38f 100644 --- a/Source/WebCore/dom/StaticHashSetNodeList.cpp +++ b/Source/WebCore/dom/StaticHashSetNodeList.cpp @@ -69,7 +69,7 @@ Node* StaticHashSetNodeList::itemWithName(const AtomicString& elementId) const ListHashSet<RefPtr<Node> >::const_iterator end = m_nodes.end(); for ( ; it != end ; ++it) { Node* node = (*it).get(); - if (node->hasID() && static_cast<Element*>(node)->getIdAttribute() == elementId) + if (static_cast<Element*>(node)->getIdAttribute() == elementId) return node; } diff --git a/Source/WebCore/dom/StaticNodeList.cpp b/Source/WebCore/dom/StaticNodeList.cpp index 0a19a0582..fe1d1cbe4 100644 --- a/Source/WebCore/dom/StaticNodeList.cpp +++ b/Source/WebCore/dom/StaticNodeList.cpp @@ -50,8 +50,7 @@ Node* StaticNodeList::itemWithName(const AtomicString& elementId) const size_t length = m_nodes.size(); for (size_t i = 0; i < length; ++i) { Node* node = m_nodes[i].get(); - // FIXME: This should probably be using getIdAttribute instead of idForStyleResolution. - if (node->hasID() && static_cast<Element*>(node)->getIdAttribute() == elementId) + if (static_cast<Element*>(node)->getIdAttribute() == elementId) return node; } diff --git a/Source/WebCore/dom/StyledElement.cpp b/Source/WebCore/dom/StyledElement.cpp index 526052647..99e7f3523 100644 --- a/Source/WebCore/dom/StyledElement.cpp +++ b/Source/WebCore/dom/StyledElement.cpp @@ -66,6 +66,11 @@ void StyledElement::attributeChanged(Attribute* attr) if (!(attr->name() == styleAttr && isSynchronizingStyleAttribute())) parseAttribute(attr); + if (isPresentationAttribute(attr)) { + setAttributeStyleDirty(); + setNeedsStyleRecalc(InlineStyleChange); + } + Element::attributeChanged(attr); } @@ -79,7 +84,6 @@ void StyledElement::classAttributeChanged(const AtomicString& newClassString) break; } bool hasClass = i < length; - setHasClass(hasClass); if (hasClass) { const bool shouldFoldCase = document()->inQuirksMode(); ensureAttributeData()->setClass(newClassString, shouldFoldCase); @@ -88,7 +92,6 @@ void StyledElement::classAttributeChanged(const AtomicString& newClassString) } else if (attributeData()) attributeData()->clearClass(); setNeedsStyleRecalc(); - dispatchSubtreeModifiedEvent(); } void StyledElement::parseAttribute(Attribute* attr) @@ -99,198 +102,81 @@ void StyledElement::parseAttribute(Attribute* attr) if (attr->isNull()) destroyInlineStyleDecl(); else if (document()->contentSecurityPolicy()->allowInlineStyle()) - ensureInlineStyleDecl()->parseDeclaration(attr->value()); + ensureInlineStyleDecl()->parseDeclaration(attr->value(), document()->elementSheet()); setIsStyleAttributeValid(); setNeedsStyleRecalc(); + InspectorInstrumentation::didInvalidateStyleAttr(document(), this); } } -void StyledElement::removeCSSProperties(int id1, int id2, int id3, int id4, int id5, int id6, int id7, int id8) +void StyledElement::inlineStyleChanged() { - StylePropertySet* style = attributeStyle(); - if (!style) - return; - - ASSERT(id1 != CSSPropertyInvalid); - style->removeProperty(id1); - - if (id2 == CSSPropertyInvalid) - return; - style->removeProperty(id2); - if (id3 == CSSPropertyInvalid) - return; - style->removeProperty(id3); - if (id4 == CSSPropertyInvalid) - return; - style->removeProperty(id4); - if (id5 == CSSPropertyInvalid) - return; - style->removeProperty(id5); - if (id6 == CSSPropertyInvalid) - return; - style->removeProperty(id6); - if (id7 == CSSPropertyInvalid) - return; - style->removeProperty(id7); - if (id8 == CSSPropertyInvalid) - return; - style->removeProperty(id8); + setNeedsStyleRecalc(InlineStyleChange); + setIsStyleAttributeValid(false); + InspectorInstrumentation::didInvalidateStyleAttr(document(), this); } - -void StyledElement::addCSSProperty(int id, const String &value) + +bool StyledElement::setInlineStyleProperty(int propertyID, int identifier, bool important) { - if (!ensureAttributeStyle()->setProperty(id, value)) - removeCSSProperty(id); + ensureInlineStyleDecl()->setProperty(propertyID, document()->cssValuePool()->createIdentifierValue(identifier), important); + inlineStyleChanged(); + return true; } -void StyledElement::addCSSProperty(int propertyID, int identifier) +bool StyledElement::setInlineStyleProperty(int propertyID, double value, CSSPrimitiveValue::UnitTypes unit, bool important) { - ensureAttributeStyle()->setProperty(CSSProperty(propertyID, document()->cssValuePool()->createIdentifierValue(identifier))); - setNeedsStyleRecalc(); + ensureInlineStyleDecl()->setProperty(propertyID, document()->cssValuePool()->createValue(value, unit), important); + inlineStyleChanged(); + return true; } -void StyledElement::addCSSImageProperty(int id, const String& url) +bool StyledElement::setInlineStyleProperty(int propertyID, const String& value, bool important) { - ensureAttributeStyle()->setProperty(CSSProperty(id, CSSImageValue::create(url))); - setNeedsStyleRecalc(); + bool changes = ensureInlineStyleDecl()->setProperty(propertyID, value, important, document()->elementSheet()); + if (changes) + inlineStyleChanged(); + return changes; } -void StyledElement::addCSSLength(int id, const String &value) +bool StyledElement::removeInlineStyleProperty(int propertyID) { - // FIXME: This function should not spin up the CSS parser, but should instead just figure out the correct - // length unit and make the appropriate parsed value. - - // strip attribute garbage.. - StringImpl* v = value.impl(); - if (v) { - unsigned int l = 0; - - while (l < v->length() && (*v)[l] <= ' ') - l++; - - for (; l < v->length(); l++) { - UChar cc = (*v)[l]; - if (cc > '9') - break; - if (cc < '0') { - if (cc == '%' || cc == '*') - l++; - if (cc != '.') - break; - } - } - - if (l != v->length()) { - addCSSProperty(id, v->substring(0, l)); - return; - } - } - - addCSSProperty(id, value); + bool changes = ensureInlineStyleDecl()->removeProperty(propertyID); + if (changes) + inlineStyleChanged(); + return changes; } -static String parseColorStringWithCrazyLegacyRules(const String& colorString) +void StyledElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const { - // Per spec, only look at the first 128 digits of the string. - const size_t maxColorLength = 128; - // We'll pad the buffer with two extra 0s later, so reserve two more than the max. - Vector<char, maxColorLength+2> digitBuffer; - - size_t i = 0; - // Skip a leading #. - if (colorString[0] == '#') - i = 1; - - // Grab the first 128 characters, replacing non-hex characters with 0. - // Non-BMP characters are replaced with "00" due to them appearing as two "characters" in the String. - for (; i < colorString.length() && digitBuffer.size() < maxColorLength; i++) { - if (!isASCIIHexDigit(colorString[i])) - digitBuffer.append('0'); - else - digitBuffer.append(colorString[i]); - } - - if (!digitBuffer.size()) - return "#000000"; - - // Pad the buffer out to at least the next multiple of three in size. - digitBuffer.append('0'); - digitBuffer.append('0'); - - if (digitBuffer.size() < 6) - return String::format("#0%c0%c0%c", digitBuffer[0], digitBuffer[1], digitBuffer[2]); - - // Split the digits into three components, then search the last 8 digits of each component. - ASSERT(digitBuffer.size() >= 6); - size_t componentLength = digitBuffer.size() / 3; - size_t componentSearchWindowLength = min<size_t>(componentLength, 8); - size_t redIndex = componentLength - componentSearchWindowLength; - size_t greenIndex = componentLength * 2 - componentSearchWindowLength; - size_t blueIndex = componentLength * 3 - componentSearchWindowLength; - // Skip digits until one of them is non-zero, or we've only got two digits left in the component. - while (digitBuffer[redIndex] == '0' && digitBuffer[greenIndex] == '0' && digitBuffer[blueIndex] == '0' && (componentLength - redIndex) > 2) { - redIndex++; - greenIndex++; - blueIndex++; - } - ASSERT(redIndex + 1 < componentLength); - ASSERT(greenIndex >= componentLength); - ASSERT(greenIndex + 1 < componentLength * 2); - ASSERT(blueIndex >= componentLength * 2); - ASSERT(blueIndex + 1 < digitBuffer.size()); - return String::format("#%c%c%c%c%c%c", digitBuffer[redIndex], digitBuffer[redIndex + 1], digitBuffer[greenIndex], digitBuffer[greenIndex + 1], digitBuffer[blueIndex], digitBuffer[blueIndex + 1]); + if (StylePropertySet* inlineStyle = inlineStyleDecl()) + inlineStyle->addSubresourceStyleURLs(urls, document()->elementSheet()); } -// Color parsing that matches HTML's "rules for parsing a legacy color value" -void StyledElement::addCSSColor(int id, const String& attributeValue) +void StyledElement::updateAttributeStyle() { - // An empty string doesn't apply a color. (One containing only whitespace does, which is why this check occurs before stripping.) - if (attributeValue.isEmpty()) { - removeCSSProperty(id); - return; - } - - String colorString = attributeValue.stripWhiteSpace(); - - // "transparent" doesn't apply a color either. - if (equalIgnoringCase(colorString, "transparent")) { - removeCSSProperty(id); - return; + RefPtr<StylePropertySet> style = StylePropertySet::create(); + for (unsigned i = 0; i < attributeCount(); ++i) { + Attribute* attribute = attributeItem(i); + collectStyleForAttribute(attribute, style.get()); } + clearAttributeStyleDirty(); - // If the string is a named CSS color or a 3/6-digit hex color, use that. - Color parsedColor(colorString); - if (parsedColor.isValid()) { - addCSSProperty(id, colorString); - return; + if (style->isEmpty()) + attributeData()->setAttributeStyle(0); + else { + style->shrinkToFit(); + attributeData()->setAttributeStyle(style.release()); } - - addCSSProperty(id, parseColorStringWithCrazyLegacyRules(colorString)); } -void StyledElement::copyNonAttributeProperties(const Element* sourceElement) +void StyledElement::addPropertyToAttributeStyle(StylePropertySet* style, int propertyID, int identifier) { - ASSERT(sourceElement); - ASSERT(sourceElement->isStyledElement()); - - const StyledElement* source = static_cast<const StyledElement*>(sourceElement); - if (!source->inlineStyleDecl()) - return; - - StylePropertySet* inlineStyle = ensureInlineStyleDecl(); - inlineStyle->copyPropertiesFrom(*source->inlineStyleDecl()); - inlineStyle->setStrictParsing(source->inlineStyleDecl()->useStrictParsing()); - - setIsStyleAttributeValid(source->isStyleAttributeValid()); - setIsSynchronizingStyleAttribute(source->isSynchronizingStyleAttribute()); - - Element::copyNonAttributeProperties(sourceElement); + style->setProperty(propertyID, document()->cssValuePool()->createIdentifierValue(identifier)); } -void StyledElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const +void StyledElement::addPropertyToAttributeStyle(StylePropertySet* style, int propertyID, double value, CSSPrimitiveValue::UnitTypes unit) { - if (StylePropertySet* inlineStyle = inlineStyleDecl()) - inlineStyle->addSubresourceStyleURLs(urls); + style->setProperty(propertyID, document()->cssValuePool()->createValue(value, unit)); } } diff --git a/Source/WebCore/dom/StyledElement.h b/Source/WebCore/dom/StyledElement.h index 2a6d392cf..2773e41c3 100644 --- a/Source/WebCore/dom/StyledElement.h +++ b/Source/WebCore/dom/StyledElement.h @@ -36,23 +36,21 @@ class StyledElement : public Element { public: virtual ~StyledElement(); - void addCSSLength(int id, const String& value); - void addCSSProperty(int id, const String& value); - void addCSSProperty(int id, int value); - void addCSSImageProperty(int propertyID, const String& url); - void addCSSColor(int id, const String& color); - void removeCSSProperties(int id1, int id2 = CSSPropertyInvalid, int id3 = CSSPropertyInvalid, int id4 = CSSPropertyInvalid, int id5 = CSSPropertyInvalid, int id6 = CSSPropertyInvalid, int id7 = CSSPropertyInvalid, int id8 = CSSPropertyInvalid); - void removeCSSProperty(int id) { removeCSSProperties(id); } - virtual StylePropertySet* additionalAttributeStyle() { return 0; } void invalidateStyleAttribute(); StylePropertySet* inlineStyleDecl() const { return attributeData() ? attributeData()->inlineStyleDecl() : 0; } - StylePropertySet* ensureInlineStyleDecl() { return ensureAttributeDataWithoutUpdate()->ensureInlineStyleDecl(this); } - virtual CSSStyleDeclaration* style() OVERRIDE { return ensureInlineStyleDecl()->ensureCSSStyleDeclaration(); } - - StylePropertySet* attributeStyle() const { return attributeData() ? attributeData()->attributeStyle() : 0; } - StylePropertySet* ensureAttributeStyle() { return ensureAttributeDataWithoutUpdate()->ensureAttributeStyle(this); } + StylePropertySet* ensureInlineStyleDecl() { return ensureAttributeData()->ensureInlineStyleDecl(this); } + + // Unlike StylePropertySet setters, these implement invalidation. + bool setInlineStyleProperty(int propertyID, int identifier, bool important = false); + bool setInlineStyleProperty(int propertyID, double value, CSSPrimitiveValue::UnitTypes, bool important = false); + bool setInlineStyleProperty(int propertyID, const String& value, bool important = false); + bool removeInlineStyleProperty(int propertyID); + + virtual CSSStyleDeclaration* style() OVERRIDE { return ensureInlineStyleDecl()->ensureInlineCSSStyleDeclaration(this); } + + StylePropertySet* attributeStyle(); const SpaceSplitString& classNames() const; @@ -66,6 +64,13 @@ protected: virtual void parseAttribute(Attribute*); virtual void copyNonAttributeProperties(const Element*); + virtual bool isPresentationAttribute(Attribute*) const { return false; } + virtual void collectStyleForAttribute(Attribute*, StylePropertySet*) { } + + void addPropertyToAttributeStyle(StylePropertySet*, int propertyID, int identifier); + void addPropertyToAttributeStyle(StylePropertySet*, int propertyID, double value, CSSPrimitiveValue::UnitTypes); + void addPropertyToAttributeStyle(StylePropertySet*, int propertyID, const String& value); + virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const; // classAttributeChanged() exists to share code between @@ -75,11 +80,14 @@ protected: private: virtual void updateStyleAttribute() const; + void inlineStyleChanged(); + + void updateAttributeStyle(); void destroyInlineStyleDecl() { if (attributeData()) - attributeData()->destroyInlineStyleDecl(); + attributeData()->destroyInlineStyleDecl(this); } }; @@ -95,6 +103,18 @@ inline void StyledElement::invalidateStyleAttribute() clearIsStyleAttributeValid(); } +inline StylePropertySet* StyledElement::attributeStyle() +{ + if (attributeStyleDirty()) + updateAttributeStyle(); + return attributeData() ? attributeData()->attributeStyle() : 0; +} + +inline void StyledElement::addPropertyToAttributeStyle(StylePropertySet* style, int propertyID, const String& value) +{ + style->setProperty(propertyID, value, false, document()->elementSheet()); +} + } //namespace #endif diff --git a/Source/WebCore/dom/Text.h b/Source/WebCore/dom/Text.h index 7629b7dab..deb18a5ea 100644 --- a/Source/WebCore/dom/Text.h +++ b/Source/WebCore/dom/Text.h @@ -70,6 +70,12 @@ private: #endif }; +inline Text* toText(Node* node) +{ + ASSERT(!node || node->isTextNode()); + return static_cast<Text*>(node); +} + } // namespace WebCore #endif // Text_h diff --git a/Source/WebCore/dom/Text.idl b/Source/WebCore/dom/Text.idl index d781677f5..4736e22fe 100644 --- a/Source/WebCore/dom/Text.idl +++ b/Source/WebCore/dom/Text.idl @@ -23,12 +23,12 @@ module core { // DOM Level 1 - Text splitText(in [IsIndex,Optional=CallWithDefaultValue] unsigned long offset) + Text splitText(in [IsIndex,Optional=DefaultIsUndefined] unsigned long offset) raises (DOMException); // Introduced in DOM Level 3: readonly attribute DOMString wholeText; - Text replaceWholeText(in [Optional=CallWithDefaultValue] DOMString content) + Text replaceWholeText(in [Optional=DefaultIsUndefined] DOMString content) raises(DOMException); }; diff --git a/Source/WebCore/dom/TextEvent.idl b/Source/WebCore/dom/TextEvent.idl index 2421b65ad..36f507c06 100644 --- a/Source/WebCore/dom/TextEvent.idl +++ b/Source/WebCore/dom/TextEvent.idl @@ -30,11 +30,11 @@ module events { readonly attribute DOMString data; - void initTextEvent(in [Optional=CallWithDefaultValue] DOMString typeArg, - in [Optional=CallWithDefaultValue] boolean canBubbleArg, - in [Optional=CallWithDefaultValue] boolean cancelableArg, - in [Optional=CallWithDefaultValue] DOMWindow viewArg, - in [Optional=CallWithDefaultValue] DOMString dataArg); + void initTextEvent(in [Optional=DefaultIsUndefined] DOMString typeArg, + in [Optional=DefaultIsUndefined] boolean canBubbleArg, + in [Optional=DefaultIsUndefined] boolean cancelableArg, + in [Optional=DefaultIsUndefined] DOMWindow viewArg, + in [Optional=DefaultIsUndefined] DOMString dataArg); }; diff --git a/Source/WebCore/dom/TouchEvent.idl b/Source/WebCore/dom/TouchEvent.idl index 39edfc87e..4b79757f5 100644 --- a/Source/WebCore/dom/TouchEvent.idl +++ b/Source/WebCore/dom/TouchEvent.idl @@ -36,18 +36,18 @@ module events { readonly attribute boolean altKey; readonly attribute boolean metaKey; - void initTouchEvent(in [Optional=CallWithDefaultValue] TouchList touches, - in [Optional=CallWithDefaultValue] TouchList targetTouches, - in [Optional=CallWithDefaultValue] TouchList changedTouches, - in [Optional=CallWithDefaultValue] DOMString type, - in [Optional=CallWithDefaultValue] DOMWindow view, - in [Optional=CallWithDefaultValue] long screenX, - in [Optional=CallWithDefaultValue] long screenY, - in [Optional=CallWithDefaultValue] long clientX, - in [Optional=CallWithDefaultValue] long clientY, - in [Optional=CallWithDefaultValue] boolean ctrlKey, - in [Optional=CallWithDefaultValue] boolean altKey, - in [Optional=CallWithDefaultValue] boolean shiftKey, - in [Optional=CallWithDefaultValue] boolean metaKey); + void initTouchEvent(in [Optional=DefaultIsUndefined] TouchList touches, + in [Optional=DefaultIsUndefined] TouchList targetTouches, + in [Optional=DefaultIsUndefined] TouchList changedTouches, + in [Optional=DefaultIsUndefined] DOMString type, + in [Optional=DefaultIsUndefined] DOMWindow view, + in [Optional=DefaultIsUndefined] long screenX, + in [Optional=DefaultIsUndefined] long screenY, + in [Optional=DefaultIsUndefined] long clientX, + in [Optional=DefaultIsUndefined] long clientY, + in [Optional=DefaultIsUndefined] boolean ctrlKey, + in [Optional=DefaultIsUndefined] boolean altKey, + in [Optional=DefaultIsUndefined] boolean shiftKey, + in [Optional=DefaultIsUndefined] boolean metaKey); }; } diff --git a/Source/WebCore/dom/TreeScopeAdopter.cpp b/Source/WebCore/dom/TreeScopeAdopter.cpp index 727df2f12..e76209cc8 100644 --- a/Source/WebCore/dom/TreeScopeAdopter.cpp +++ b/Source/WebCore/dom/TreeScopeAdopter.cpp @@ -28,12 +28,13 @@ #include "Document.h" #include "NodeRareData.h" #include "ShadowRoot.h" +#include "ShadowRootList.h" namespace WebCore { static inline ShadowRoot* shadowRootFor(Node* node) { - return node->isElementNode() ? toElement(node)->shadowRoot() : 0; + return node->isElementNode() && toElement(node)->hasShadowRoot() ? toElement(node)->shadowRootList()->youngestShadowRoot() : 0; } void TreeScopeAdopter::moveTreeToNewScope(Node* root) const @@ -96,10 +97,8 @@ inline void TreeScopeAdopter::moveNodeToNewDocument(Node* node, Document* oldDoc ASSERT(!node->inDocument() || oldDocument != newDocument); newDocument->guardRef(); - if (oldDocument) { + if (oldDocument) oldDocument->moveNodeIteratorsToNewDocument(node, newDocument); - oldDocument->guardDeref(); - } node->setDocument(newDocument); @@ -110,6 +109,9 @@ inline void TreeScopeAdopter::moveNodeToNewDocument(Node* node, Document* oldDoc node->didMoveToNewDocument(oldDocument); ASSERT(didMoveToNewDocumentWasCalled); + + if (oldDocument) + oldDocument->guardDeref(); } } diff --git a/Source/WebCore/dom/UIEvent.idl b/Source/WebCore/dom/UIEvent.idl index 83dcdc95a..39a2caf83 100644 --- a/Source/WebCore/dom/UIEvent.idl +++ b/Source/WebCore/dom/UIEvent.idl @@ -24,11 +24,11 @@ module events { readonly attribute DOMWindow view; readonly attribute long detail; - [ObjCLegacyUnnamedParameters] void initUIEvent(in [Optional=CallWithDefaultValue] DOMString type, - in [Optional=CallWithDefaultValue] boolean canBubble, - in [Optional=CallWithDefaultValue] boolean cancelable, - in [Optional=CallWithDefaultValue] DOMWindow view, - in [Optional=CallWithDefaultValue] long detail); + [ObjCLegacyUnnamedParameters] void initUIEvent(in [Optional=DefaultIsUndefined] DOMString type, + in [Optional=DefaultIsUndefined] boolean canBubble, + in [Optional=DefaultIsUndefined] boolean cancelable, + in [Optional=DefaultIsUndefined] DOMWindow view, + in [Optional=DefaultIsUndefined] long detail); // extensions readonly attribute long keyCode; diff --git a/Source/WebCore/dom/ViewportArguments.cpp b/Source/WebCore/dom/ViewportArguments.cpp index 636804b97..b5dc48c10 100644 --- a/Source/WebCore/dom/ViewportArguments.cpp +++ b/Source/WebCore/dom/ViewportArguments.cpp @@ -212,10 +212,14 @@ static float numericPrefix(const String& keyString, const String& valueString, D // and we should check if the valueString prefix was a number. bool didReadNumber; - float value = valueString.toFloat(ok, &didReadNumber); + float value; + if (valueString.is8Bit()) + value = WTF::charactersToFloatIgnoringJunk(valueString.characters8(), valueString.length(), ok, &didReadNumber); + else + value = WTF::charactersToFloatIgnoringJunk(valueString.characters16(), valueString.length(), ok, &didReadNumber); if (!*ok) { if (!didReadNumber) { - ASSERT(!value); + ASSERT(isnan(value) || !value); reportViewportWarning(document, UnrecognizedViewportArgumentValueError, valueString, keyString); return value; } diff --git a/Source/WebCore/dom/WebKitNamedFlow.cpp b/Source/WebCore/dom/WebKitNamedFlow.cpp index e00263698..bced96576 100644 --- a/Source/WebCore/dom/WebKitNamedFlow.cpp +++ b/Source/WebCore/dom/WebKitNamedFlow.cpp @@ -30,9 +30,12 @@ #include "config.h" #include "WebKitNamedFlow.h" +#include "RenderFlowThread.h" + namespace WebCore { -WebKitNamedFlow::WebKitNamedFlow() +WebKitNamedFlow::WebKitNamedFlow(RenderFlowThread* parentFlowThread) +: m_parentFlowThread(parentFlowThread) { } @@ -40,4 +43,10 @@ WebKitNamedFlow::~WebKitNamedFlow() { } +bool WebKitNamedFlow::overflow() const +{ + m_parentFlowThread->document()->updateLayoutIgnorePendingStylesheets(); + return m_parentFlowThread->overflow(); +} + } // namespace WebCore diff --git a/Source/WebCore/dom/WebKitNamedFlow.h b/Source/WebCore/dom/WebKitNamedFlow.h index 276796121..e815f03f4 100644 --- a/Source/WebCore/dom/WebKitNamedFlow.h +++ b/Source/WebCore/dom/WebKitNamedFlow.h @@ -35,17 +35,22 @@ namespace WebCore { +class RenderFlowThread; + class WebKitNamedFlow : public RefCounted<WebKitNamedFlow> { public: - static PassRefPtr<WebKitNamedFlow> create() + static PassRefPtr<WebKitNamedFlow> create(RenderFlowThread* parentFlowThread) { - return adoptRef(new WebKitNamedFlow); + return adoptRef(new WebKitNamedFlow(parentFlowThread)); } ~WebKitNamedFlow(); + bool overflow() const; private: - WebKitNamedFlow(); + WebKitNamedFlow(RenderFlowThread*); + + RenderFlowThread* m_parentFlowThread; }; } diff --git a/Source/WebCore/dom/WebKitNamedFlow.idl b/Source/WebCore/dom/WebKitNamedFlow.idl index 06d85529e..2a065dd17 100644 --- a/Source/WebCore/dom/WebKitNamedFlow.idl +++ b/Source/WebCore/dom/WebKitNamedFlow.idl @@ -29,7 +29,8 @@ module core { interface [ - JSGenerateToJS + JSGenerateToJSObject ] WebKitNamedFlow { + readonly attribute boolean overflow; }; } diff --git a/Source/WebCore/dom/WheelEvent.idl b/Source/WebCore/dom/WheelEvent.idl index e0fd563ba..0282525fb 100644 --- a/Source/WebCore/dom/WheelEvent.idl +++ b/Source/WebCore/dom/WheelEvent.idl @@ -46,31 +46,31 @@ module events { #endif /* defined(LANGUAGE_OBJECTIVE_C) */ #if !defined(LANGUAGE_JAVASCRIPT) || !LANGUAGE_JAVASCRIPT - void initWheelEvent(in [Optional=CallWithDefaultValue] long wheelDeltaX, - in [Optional=CallWithDefaultValue] long wheelDeltaY, - in [Optional=CallWithDefaultValue] DOMWindow view, - in [Optional=CallWithDefaultValue] long screenX, - in [Optional=CallWithDefaultValue] long screenY, - in [Optional=CallWithDefaultValue] long clientX, - in [Optional=CallWithDefaultValue] long clientY, - in [Optional=CallWithDefaultValue] boolean ctrlKey, - in [Optional=CallWithDefaultValue] boolean altKey, - in [Optional=CallWithDefaultValue] boolean shiftKey, - in [Optional=CallWithDefaultValue] boolean metaKey); + void initWheelEvent(in [Optional=DefaultIsUndefined] long wheelDeltaX, + in [Optional=DefaultIsUndefined] long wheelDeltaY, + in [Optional=DefaultIsUndefined] DOMWindow view, + in [Optional=DefaultIsUndefined] long screenX, + in [Optional=DefaultIsUndefined] long screenY, + in [Optional=DefaultIsUndefined] long clientX, + in [Optional=DefaultIsUndefined] long clientY, + in [Optional=DefaultIsUndefined] boolean ctrlKey, + in [Optional=DefaultIsUndefined] boolean altKey, + in [Optional=DefaultIsUndefined] boolean shiftKey, + in [Optional=DefaultIsUndefined] boolean metaKey); #endif /* !defined(LANGUAGE_JAVASCRIPT) */ #if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT - void initWebKitWheelEvent(in [Optional=CallWithDefaultValue] long wheelDeltaX, - in [Optional=CallWithDefaultValue] long wheelDeltaY, - in [Optional=CallWithDefaultValue] DOMWindow view, - in [Optional=CallWithDefaultValue] long screenX, - in [Optional=CallWithDefaultValue] long screenY, - in [Optional=CallWithDefaultValue] long clientX, - in [Optional=CallWithDefaultValue] long clientY, - in [Optional=CallWithDefaultValue] boolean ctrlKey, - in [Optional=CallWithDefaultValue] boolean altKey, - in [Optional=CallWithDefaultValue] boolean shiftKey, - in [Optional=CallWithDefaultValue] boolean metaKey); + void initWebKitWheelEvent(in [Optional=DefaultIsUndefined] long wheelDeltaX, + in [Optional=DefaultIsUndefined] long wheelDeltaY, + in [Optional=DefaultIsUndefined] DOMWindow view, + in [Optional=DefaultIsUndefined] long screenX, + in [Optional=DefaultIsUndefined] long screenY, + in [Optional=DefaultIsUndefined] long clientX, + in [Optional=DefaultIsUndefined] long clientY, + in [Optional=DefaultIsUndefined] boolean ctrlKey, + in [Optional=DefaultIsUndefined] boolean altKey, + in [Optional=DefaultIsUndefined] boolean shiftKey, + in [Optional=DefaultIsUndefined] boolean metaKey); #endif /* defined(LANGUAGE_JAVASCRIPT) */ }; } |