diff options
Diffstat (limited to 'WebCore/dom')
40 files changed, 1040 insertions, 211 deletions
diff --git a/WebCore/dom/BeforeProcessEvent.cpp b/WebCore/dom/BeforeProcessEvent.cpp new file mode 100644 index 0000000..7314481 --- /dev/null +++ b/WebCore/dom/BeforeProcessEvent.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2010 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. ``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 COMPUTER, INC. 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 "BeforeProcessEvent.h" + +namespace WebCore { + +String BeforeProcessEvent::text() const +{ + // FIXME - Return innerText for <style> elements and inline <script> elements, or the resource text for remote <script> elements + return String(); +} + +void BeforeProcessEvent::setText(const String&) +{ + // FIXME - Replace innerText for <style> elements and inline <script> elements, and remove the src attribute on + // remote <script> elements, replacing it with an innerText property. +} + +} // namespace WebCore diff --git a/WebCore/dom/BeforeProcessEvent.h b/WebCore/dom/BeforeProcessEvent.h new file mode 100644 index 0000000..035d2da --- /dev/null +++ b/WebCore/dom/BeforeProcessEvent.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2010 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. ``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 COMPUTER, INC. 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 BeforeProcessEvent_h +#define BeforeProcessEvent_h + +#include "Event.h" +#include "EventNames.h" + +namespace WebCore { + +class BeforeProcessEvent : public Event { +public: + static PassRefPtr<BeforeProcessEvent> create() + { + return adoptRef(new BeforeProcessEvent); + } + + void initBeforeProcessEvent(const AtomicString& type, bool canBubble, bool cancelable) + { + initEvent(type, canBubble, cancelable); + } + + String text() const; + void setText(const String&); + +private: + BeforeProcessEvent() + : Event(eventNames().beforeprocessEvent, false, true) + { + } + +}; + +} // namespace WebCore + +#endif // BeforeProcessEvent_h diff --git a/WebCore/dom/BeforeProcessEvent.idl b/WebCore/dom/BeforeProcessEvent.idl new file mode 100644 index 0000000..28b1a81 --- /dev/null +++ b/WebCore/dom/BeforeProcessEvent.idl @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2010 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. ``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 COMPUTER, INC. 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. + * + */ + +module events { + + interface BeforeProcessEvent : Event { + void initBeforeProcessEvent(in DOMString type, in boolean canBubble, in boolean cancelable); + attribute DOMString text; + }; + +} diff --git a/WebCore/dom/CharacterData.cpp b/WebCore/dom/CharacterData.cpp index 9670988..075df47 100644 --- a/WebCore/dom/CharacterData.cpp +++ b/WebCore/dom/CharacterData.cpp @@ -38,15 +38,15 @@ void CharacterData::setData(const String& data, ExceptionCode&) int oldLength = length(); RefPtr<StringImpl> oldStr = m_data; m_data = dataImpl; - + if ((!renderer() || !rendererIsNeeded(renderer()->style())) && attached()) { detach(); attach(); } else if (renderer()) - toRenderText(renderer())->setText(m_data); - + toRenderText(renderer())->setTextWithOffset(m_data, 0, oldLength); + dispatchModifiedEvent(oldStr.get()); - + document()->textRemoved(this, 0, oldLength); } diff --git a/WebCore/dom/ContainerNode.cpp b/WebCore/dom/ContainerNode.cpp index fddccdd..6539e5b 100644 --- a/WebCore/dom/ContainerNode.cpp +++ b/WebCore/dom/ContainerNode.cpp @@ -537,7 +537,31 @@ bool ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec, bo return true; } -ContainerNode* ContainerNode::addChild(PassRefPtr<Node> newChild) +void ContainerNode::addChildCommon(Node* newChild) +{ + ASSERT(!newChild->parent()); // Use appendChild if you need to handle reparenting. + forbidEventDispatch(); + Node* last = m_lastChild; + // FIXME: This method should take a PassRefPtr. + appendChildToContainer<Node, ContainerNode>(newChild, this); + allowEventDispatch(); + + document()->incDOMTreeVersion(); + if (inDocument()) + newChild->insertedIntoDocument(); + childrenChanged(true, last, 0, 1); +} + +void ContainerNode::parserAddChild(PassRefPtr<Node> newChild) +{ + ASSERT(newChild); + // This function is only used during parsing. + // It does not send any DOM mutation events or handle reparenting. + + addChildCommon(newChild.get()); +} + +ContainerNode* ContainerNode::legacyParserAddChild(PassRefPtr<Node> newChild) { ASSERT(newChild); // This function is only used during parsing. @@ -547,16 +571,8 @@ ContainerNode* ContainerNode::addChild(PassRefPtr<Node> newChild) if (document()->isHTMLDocument() && !childAllowed(newChild.get())) return 0; - forbidEventDispatch(); - Node* last = m_lastChild; - appendChildToContainer<Node, ContainerNode>(newChild.get(), this); - allowEventDispatch(); + addChildCommon(newChild.get()); - document()->incDOMTreeVersion(); - if (inDocument()) - newChild->insertedIntoDocument(); - childrenChanged(true, last, 0, 1); - if (newChild->isElementNode()) return static_cast<ContainerNode*>(newChild.get()); return this; diff --git a/WebCore/dom/ContainerNode.h b/WebCore/dom/ContainerNode.h index 9789f1f..36e6ac5 100644 --- a/WebCore/dom/ContainerNode.h +++ b/WebCore/dom/ContainerNode.h @@ -48,7 +48,9 @@ public: virtual bool removeChild(Node* child, ExceptionCode&); virtual bool appendChild(PassRefPtr<Node> newChild, ExceptionCode&, bool shouldLazyAttach = false); - virtual ContainerNode* addChild(PassRefPtr<Node>); + virtual ContainerNode* legacyParserAddChild(PassRefPtr<Node>); + virtual void parserAddChild(PassRefPtr<Node>); + bool hasChildNodes() const { return m_firstChild; } virtual void attach(); virtual void detach(); @@ -89,10 +91,13 @@ protected: void setFirstChild(Node* child) { m_firstChild = child; } void setLastChild(Node* child) { m_lastChild = child; } - + private: + // FIXME: This should take a PassRefPtr. + void addChildCommon(Node*); + static void dispatchPostAttachCallbacks(); - + bool getUpperLeftCorner(FloatPoint&) const; bool getLowerRightCorner(FloatPoint&) const; diff --git a/WebCore/dom/DOMImplementation.cpp b/WebCore/dom/DOMImplementation.cpp index 3483b23..467f1fc 100644 --- a/WebCore/dom/DOMImplementation.cpp +++ b/WebCore/dom/DOMImplementation.cpp @@ -256,10 +256,11 @@ PassRefPtr<Document> DOMImplementation::createDocument(const String& namespaceUR return 0; } + // FIXME: Shouldn't this call appendChild instead? if (doctype) - doc->addChild(doctype); + doc->legacyParserAddChild(doctype); if (documentElement) - doc->addChild(documentElement.release()); + doc->legacyParserAddChild(documentElement.release()); return doc.release(); } diff --git a/WebCore/dom/DOMStringMap.cpp b/WebCore/dom/DOMStringMap.cpp new file mode 100644 index 0000000..e63dabe --- /dev/null +++ b/WebCore/dom/DOMStringMap.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2010 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. + */ + +#include "config.h" +#include "DOMStringMap.h" + +namespace WebCore { + +DOMStringMap::~DOMStringMap() +{ +} + +} // namespace WebCore diff --git a/WebCore/dom/DOMStringMap.h b/WebCore/dom/DOMStringMap.h new file mode 100644 index 0000000..c0bc07d --- /dev/null +++ b/WebCore/dom/DOMStringMap.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2010 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 DOMStringMap_h +#define DOMStringMap_h + +#include "PlatformString.h" +#include <wtf/Noncopyable.h> +#include <wtf/PassRefPtr.h> +#include <wtf/Vector.h> + +namespace WebCore { + +typedef int ExceptionCode; + +class DOMStringMap : public Noncopyable { +public: + virtual ~DOMStringMap(); + + virtual void ref() = 0; + virtual void deref() = 0; + + virtual void getNames(Vector<String>&) = 0; + virtual String item(const String& name) = 0; + virtual bool contains(const String& name) = 0; + virtual void setItem(const String& name, const String& value, ExceptionCode&) = 0; + virtual void deleteItem(const String& name, ExceptionCode&) = 0; + +protected: + DOMStringMap() + { + } +}; + +} // namespace WebCore + +#endif // DOMStringMap_h diff --git a/WebCore/dom/DOMStringMap.idl b/WebCore/dom/DOMStringMap.idl new file mode 100644 index 0000000..0320b3b --- /dev/null +++ b/WebCore/dom/DOMStringMap.idl @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2010 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. + */ + +module core { + + interface [ + HasNameGetter, + CustomDeleteProperty, + CustomGetPropertyNames, + DelegatingPutFunction, + ] DOMStringMap { + }; + +} diff --git a/WebCore/dom/DatasetDOMStringMap.cpp b/WebCore/dom/DatasetDOMStringMap.cpp new file mode 100644 index 0000000..6359d55 --- /dev/null +++ b/WebCore/dom/DatasetDOMStringMap.cpp @@ -0,0 +1,192 @@ +/* + * Copyright (C) 2010 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. + */ + +#include "config.h" +#include "DatasetDOMStringMap.h" + +#include "Attribute.h" +#include "Element.h" +#include "ExceptionCode.h" +#include "NamedNodeMap.h" +#include <wtf/ASCIICType.h> + +namespace WebCore { + +static bool isValidAttributeName(const String& name) +{ + if (!name.startsWith("data-")) + return false; + + const UChar* characters = name.characters(); + unsigned length = name.length(); + for (unsigned i = 5; i < length; ++i) { + if (isASCIIUpper(characters[i])) + return false; + } + + return true; +} + +static String convertAttributeNameToPropertyName(const String& name) +{ + Vector<UChar> newStringBuffer; + + const UChar* characters = name.characters(); + unsigned length = name.length(); + for (unsigned i = 5; i < length; ++i) { + if (characters[i] != '-') + newStringBuffer.append(characters[i]); + else { + if ((i + 1 < length) && isASCIILower(characters[i + 1])) { + newStringBuffer.append(toASCIIUpper(characters[i + 1])); + ++i; + } else + newStringBuffer.append(characters[i]); + } + } + + return String::adopt(newStringBuffer); +} + +static bool propertyNameMatchesAttributeName(const String& propertyName, const String& attributeName) +{ + // FIXME: This should be able to match without creating a new string. + + if (!isValidAttributeName(attributeName)) + return false; + + String convertedName = convertAttributeNameToPropertyName(attributeName); + return (convertedName == propertyName); +} + +static bool isValidPropertyName(const String& name) +{ + const UChar* characters = name.characters(); + unsigned length = name.length(); + for (unsigned i = 0; i < length; ++i) { + if (characters[i] == '-' && (i + 1 < length) && isASCIILower(characters[i + 1])) + return false; + } + return true; +} + +static String convertPropertyNameToAttributeName(const String& name) +{ + Vector<UChar> newStringBuffer; + + newStringBuffer.append('d'); + newStringBuffer.append('a'); + newStringBuffer.append('t'); + newStringBuffer.append('a'); + newStringBuffer.append('-'); + + const UChar* characters = name.characters(); + unsigned length = name.length(); + for (unsigned i = 0; i < length; ++i) { + if (isASCIIUpper(characters[i])) { + newStringBuffer.append('-'); + newStringBuffer.append(toASCIILower(characters[i])); + } else + newStringBuffer.append(characters[i]); + } + + return String::adopt(newStringBuffer); +} + + +void DatasetDOMStringMap::ref() +{ + m_element->ref(); +} + +void DatasetDOMStringMap::deref() +{ + m_element->deref(); +} + +void DatasetDOMStringMap::getNames(Vector<String>& names) +{ + NamedNodeMap* attributeMap = m_element->attributes(true); + if (attributeMap) { + unsigned length = attributeMap->length(); + for (unsigned i = 0; i < length; i++) { + Attribute* attribute = attributeMap->attributeItem(i); + if (isValidAttributeName(attribute->localName())) + names.append(convertAttributeNameToPropertyName(attribute->localName())); + } + } +} + +String DatasetDOMStringMap::item(const String& name) +{ + NamedNodeMap* attributeMap = m_element->attributes(true); + if (attributeMap) { + unsigned length = attributeMap->length(); + for (unsigned i = 0; i < length; i++) { + Attribute* attribute = attributeMap->attributeItem(i); + if (propertyNameMatchesAttributeName(name, attribute->localName())) + return attribute->value(); + } + } + + return String(); +} + +bool DatasetDOMStringMap::contains(const String& name) +{ + NamedNodeMap* attributeMap = m_element->attributes(true); + if (attributeMap) { + unsigned length = attributeMap->length(); + for (unsigned i = 0; i < length; i++) { + Attribute* attribute = attributeMap->attributeItem(i); + if (propertyNameMatchesAttributeName(name, attribute->localName())) + return true; + } + } + return false; +} + +void DatasetDOMStringMap::setItem(const String& name, const String& value, ExceptionCode& ec) +{ + if (!isValidPropertyName(name)) { + ec = SYNTAX_ERR; + return; + } + + m_element->setAttribute(convertPropertyNameToAttributeName(name), value, ec); +} + +void DatasetDOMStringMap::deleteItem(const String& name, ExceptionCode& ec) +{ + if (!isValidPropertyName(name)) { + ec = SYNTAX_ERR; + return; + } + + ExceptionCode dummy; + m_element->removeAttribute(convertPropertyNameToAttributeName(name), dummy); +} + +} // namespace WebCore diff --git a/WebCore/dom/DatasetDOMStringMap.h b/WebCore/dom/DatasetDOMStringMap.h new file mode 100644 index 0000000..f82eaa5 --- /dev/null +++ b/WebCore/dom/DatasetDOMStringMap.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2010 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 DatasetDOMStringMap_h +#define DatasetDOMStringMap_h + +#include "DOMStringMap.h" +#include <wtf/PassOwnPtr.h> + +namespace WebCore { + +class Element; + +class DatasetDOMStringMap : public DOMStringMap { +public: + static PassOwnPtr<DatasetDOMStringMap> create(Element* element) + { + return new DatasetDOMStringMap(element); + } + + virtual void ref(); + virtual void deref(); + + virtual void getNames(Vector<String>&); + virtual String item(const String& name); + virtual bool contains(const String& name); + virtual void setItem(const String& name, const String& value, ExceptionCode&); + virtual void deleteItem(const String& name, ExceptionCode&); + +private: + DatasetDOMStringMap(Element* element) + : m_element(element) + { + } + + Element* m_element; +}; + +} // namespace WebCore + +#endif // DatasetDOMStringMap_h diff --git a/WebCore/dom/DecodedDataDocumentParser.cpp b/WebCore/dom/DecodedDataDocumentParser.cpp new file mode 100644 index 0000000..51cc847 --- /dev/null +++ b/WebCore/dom/DecodedDataDocumentParser.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2010 Google, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 + * 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 "DecodedDataDocumentParser.h" + +#include "DocumentWriter.h" +#include "SegmentedString.h" +#include "TextResourceDecoder.h" + +namespace WebCore { + +DecodedDataDocumentParser::DecodedDataDocumentParser(Document* document, bool viewSourceMode) + : DocumentParser(document) + , m_inViewSourceMode(viewSourceMode) +{ +} + +void DecodedDataDocumentParser::appendBytes(DocumentWriter* writer , const char* data, int length, bool shouldFlush) +{ + if (!length && !shouldFlush) + return; + + TextResourceDecoder* decoder = writer->createDecoderIfNeeded(); + String decoded = decoder->decode(data, length); + if (shouldFlush) + decoded += decoder->flush(); + if (decoded.isEmpty()) + return; + + writer->reportDataRecieved(); + + append(decoded); +} + +}; + diff --git a/WebCore/dom/DecodedDataDocumentParser.h b/WebCore/dom/DecodedDataDocumentParser.h new file mode 100644 index 0000000..f45bb68 --- /dev/null +++ b/WebCore/dom/DecodedDataDocumentParser.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2010 Google, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 + * 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 DecodedDataDocumentParser_h +#define DecodedDataDocumentParser_h + +#include "DocumentParser.h" + +namespace WebCore { + +class DecodedDataDocumentParser : public DocumentParser { +public: + // Only used by the XMLDocumentParser to communicate back to + // XMLHttpRequest if the responseXML was well formed. + virtual bool wellFormed() const { return true; } + + bool inViewSourceMode() const { return m_inViewSourceMode; } + void setInViewSourceMode(bool mode) { m_inViewSourceMode = mode; } + +protected: + DecodedDataDocumentParser(Document*, bool viewSourceMode = false); + +private: + // append is used by DocumentWriter::replaceDocument + virtual void append(const SegmentedString&) = 0; + + // appendBytes is used by DocumentWriter (the loader) + virtual void appendBytes(DocumentWriter*, const char* bytes, int length, bool flush); + + bool m_inViewSourceMode; +}; + +} + +#endif // DecodedDataDocumentParser_h diff --git a/WebCore/dom/Document.cpp b/WebCore/dom/Document.cpp index 99ec33e..be2bb4c 100644 --- a/WebCore/dom/Document.cpp +++ b/WebCore/dom/Document.cpp @@ -1549,29 +1549,42 @@ bool Document::isPageBoxVisible(int pageIndex) return style->visibility() != HIDDEN; // display property doesn't apply to @page. } -IntRect Document::pageAreaRectInPixels(int pageIndex) +void Document::pageSizeAndMarginsInPixels(int pageIndex, IntSize& pageSize, int& marginTop, int& marginRight, int& marginBottom, int& marginLeft) { RefPtr<RenderStyle> style = styleForPage(pageIndex); - IntSize pageSize = preferredPageSizeInPixels(pageIndex); - // 100% value for margin-{left,right,top,bottom}. This is used also for top and bottom. http://www.w3.org/TR/CSS2/box.html#value-def-margin-width - int maxValue = pageSize.width(); - int surroundLeft = style->marginLeft().calcValue(maxValue) + style->borderLeft().width() + style->paddingLeft().calcValue(maxValue); - int surroundRight = style->marginRight().calcValue(maxValue) + style->borderRight().width() + style->paddingRight().calcValue(maxValue); - int surroundTop = style->marginTop().calcValue(maxValue) + style->borderTop().width() + style->paddingTop().calcValue(maxValue); - int surroundBottom = style->marginBottom().calcValue(maxValue) + style->borderBottom().width() + style->paddingBottom().calcValue(maxValue); - int width = pageSize.width() - surroundLeft - surroundRight; - int height = pageSize.height() - surroundTop - surroundBottom; - return IntRect(surroundLeft, surroundTop, width, height); -} + int width = pageSize.width(); + int height = pageSize.height(); + switch (style->pageSizeType()) { + case PAGE_SIZE_AUTO: + break; + case PAGE_SIZE_AUTO_LANDSCAPE: + if (width < height) + std::swap(width, height); + break; + case PAGE_SIZE_AUTO_PORTRAIT: + if (width > height) + std::swap(width, height); + break; + case PAGE_SIZE_RESOLVED: { + LengthSize size = style->pageSize(); + ASSERT(size.width().isFixed()); + ASSERT(size.height().isFixed()); + width = size.width().calcValue(0); + height = size.height().calcValue(0); + break; + } + default: + ASSERT_NOT_REACHED(); + } + pageSize = IntSize(width, height); -IntSize Document::preferredPageSizeInPixels(int pageIndex) -{ - RefPtr<RenderStyle> style = styleForPage(pageIndex); - LengthSize size = style->pageSize(); - ASSERT(size.width().isFixed()); - ASSERT(size.height().isFixed()); - return IntSize(size.width().calcValue(0), size.height().calcValue(0)); + // The percentage is calculated with respect to the width even for margin top and bottom. + // http://www.w3.org/TR/CSS2/box.html#margin-properties + marginTop = style->marginTop().isAuto() ? marginTop : style->marginTop().calcValue(width); + marginRight = style->marginRight().isAuto() ? marginRight : style->marginRight().calcValue(width); + marginBottom = style->marginBottom().isAuto() ? marginBottom : style->marginBottom().calcValue(width); + marginLeft = style->marginLeft().isAuto() ? marginLeft : style->marginLeft().calcValue(width); } void Document::createStyleSelector() @@ -1754,6 +1767,11 @@ DocumentParser* Document::createParser() return new XMLDocumentParser(this, view()); } +ScriptableDocumentParser* Document::scriptableDocumentParser() const +{ + return parser() ? parser()->asScriptableDocumentParser() : 0; +} + void Document::open(Document* ownerDocument) { if (ownerDocument) { @@ -1763,9 +1781,10 @@ void Document::open(Document* ownerDocument) } if (m_frame) { - if (m_frame->loader()->isLoadingMainResource() || (parser() && parser()->isExecutingScript())) + ScriptableDocumentParser* parser = scriptableDocumentParser(); + if (m_frame->loader()->isLoadingMainResource() || (parser && parser->isExecutingScript())) return; - + if (m_frame->loader()->state() == FrameStateProvisional) m_frame->loader()->stopAllLoaders(); } @@ -1802,8 +1821,9 @@ void Document::implicitOpen() m_parser = createParser(); setParsing(true); - if (m_frame) - m_parser->setXSSAuditor(m_frame->script()->xssAuditor()); + ScriptableDocumentParser* parser = scriptableDocumentParser(); + if (m_frame && parser) + parser->setXSSAuditor(m_frame->script()->xssAuditor()); // If we reload, the animation controller sticks around and has // a stale animation time. We need to update it here. @@ -1888,7 +1908,8 @@ void Document::implicitClose() m_processingLoadEvent = true; - m_wellFormed = m_parser && m_parser->wellFormed(); + ScriptableDocumentParser* parser = scriptableDocumentParser(); + m_wellFormed = parser && parser->wellFormed(); // We have to clear the parser, in case someone document.write()s from the // onLoad event handler, as in Radar 3206524. @@ -2044,21 +2065,7 @@ void Document::write(const SegmentedString& text, Document* ownerDocument) open(ownerDocument); ASSERT(m_parser); - // FIXME: forceSynchronous should always be the same as the bool passed to - // write(). However LegacyHTMLDocumentParser uses write("", false) to pump - // the parser (after running external scripts, etc.) thus necessitating a - // separate state for forceSynchronous. - bool wasForcedSynchronous = false; - LegacyHTMLDocumentParser* parser = m_parser->asHTMLDocumentParser(); - if (parser) { - wasForcedSynchronous = parser->forceSynchronous(); - parser->setForceSynchronous(true); - } - - m_parser->write(text, false); - - if (m_parser && parser && m_parser->asHTMLDocumentParser() == parser) - parser->setForceSynchronous(wasForcedSynchronous); + m_parser->insert(text); #ifdef INSTRUMENT_LAYOUT_SCHEDULING if (!ownerElement()) @@ -2667,9 +2674,10 @@ void Document::removePendingSheet() #endif updateStyleSelector(); - - if (!m_pendingStylesheets && m_parser) - m_parser->executeScriptsWaitingForStylesheets(); + + ScriptableDocumentParser* parser = scriptableDocumentParser(); + if (!m_pendingStylesheets && parser) + parser->executeScriptsWaitingForStylesheets(); if (!m_pendingStylesheets && m_gotoAnchorNeededAfterStylesheetsLoad && view()) view()->scrollToFragment(m_frame->loader()->url()); @@ -3348,6 +3356,8 @@ void Document::addListenerTypeIfNeeded(const AtomicString& eventType) addListenerType(TRANSITIONEND_LISTENER); else if (eventType == eventNames().beforeloadEvent) addListenerType(BEFORELOAD_LISTENER); + else if (eventType == eventNames().beforeprocessEvent) + addListenerType(BEFOREPROCESS_LISTENER); #if ENABLE(TOUCH_EVENTS) else if (eventType == eventNames().touchstartEvent || eventType == eventNames().touchmoveEvent @@ -4900,8 +4910,10 @@ HTMLCanvasElement* Document::getCSSCanvasElement(const String& name) void Document::initDNSPrefetch() { + Settings* settings = this->settings(); + m_haveExplicitlyDisabledDNSPrefetch = false; - m_isDNSPrefetchEnabled = securityOrigin()->protocol() == "http"; + m_isDNSPrefetchEnabled = settings && settings->dnsPrefetchingEnabled() && securityOrigin()->protocol() == "http"; // Inherit DNS prefetch opt-out from parent frame if (Document* parent = parentDocument()) { diff --git a/WebCore/dom/Document.h b/WebCore/dom/Document.h index dc4b6ba..3d9cf48 100644 --- a/WebCore/dom/Document.h +++ b/WebCore/dom/Document.h @@ -37,6 +37,7 @@ #include "QualifiedName.h" #include "ScriptExecutionContext.h" #include "Timer.h" +#include <wtf/FixedArray.h> #include <wtf/HashCountedSet.h> #include <wtf/OwnPtr.h> #include <wtf/PassOwnPtr.h> @@ -100,6 +101,7 @@ namespace WebCore { class RegisteredEventListener; class RenderArena; class RenderView; + class ScriptableDocumentParser; class ScriptElementData; class SecurityOrigin; class SerializedScriptValue; @@ -483,9 +485,16 @@ public: void updateLayoutIgnorePendingStylesheets(); PassRefPtr<RenderStyle> styleForElementIgnoringPendingStylesheets(Element*); PassRefPtr<RenderStyle> styleForPage(int pageIndex); + + // Returns true if page box (margin boxes and page borders) is visible. bool isPageBoxVisible(int pageIndex); - IntRect pageAreaRectInPixels(int pageIndex); - IntSize preferredPageSizeInPixels(int pageIndex); + + // Returns the preferred page size and margins in pixels, assuming 96 + // pixels per inch. pageSize, marginTop, marginRight, marginBottom, + // marginLeft must be initialized to the default values that are used if + // auto is specified. + void pageSizeAndMarginsInPixels(int pageIndex, IntSize& pageSize, int& marginTop, int& marginRight, int& marginBottom, int& marginLeft); + static void updateStyleForAllDocuments(); // FIXME: Try to reduce the # of calls to this function. DocLoader* docLoader() { return m_docLoader.get(); } @@ -541,7 +550,8 @@ public: CSSStyleSheet* mappedElementSheet(); virtual DocumentParser* createParser(); - DocumentParser* parser() { return m_parser.get(); } + DocumentParser* parser() const { return m_parser.get(); } + ScriptableDocumentParser* scriptableDocumentParser() const; bool printing() const { return m_printing; } void setPrinting(bool p) { m_printing = p; } @@ -663,7 +673,8 @@ public: ANIMATIONITERATION_LISTENER = 0x400, TRANSITIONEND_LISTENER = 0x800, BEFORELOAD_LISTENER = 0x1000, - TOUCH_LISTENER = 0x2000 + TOUCH_LISTENER = 0x2000, + BEFOREPROCESS_LISTENER = 0x4000 }; bool hasListenerType(ListenerType listenerType) const { return (m_listenerTypes & listenerType); } @@ -1226,8 +1237,8 @@ private: CheckedRadioButtons m_checkedRadioButtons; typedef HashMap<AtomicStringImpl*, CollectionCache*> NamedCollectionMap; - CollectionCache m_collectionInfo[NumUnnamedDocumentCachedTypes]; - NamedCollectionMap m_nameCollectionInfo[NumNamedDocumentCachedTypes]; + FixedArray<CollectionCache, NumUnnamedDocumentCachedTypes> m_collectionInfo; + FixedArray<NamedCollectionMap, NumNamedDocumentCachedTypes> m_nameCollectionInfo; #if ENABLE(XPATH) RefPtr<XPathEvaluator> m_xpathEvaluator; diff --git a/WebCore/dom/DocumentFragment.cpp b/WebCore/dom/DocumentFragment.cpp index 7287439..ecc5725 100644 --- a/WebCore/dom/DocumentFragment.cpp +++ b/WebCore/dom/DocumentFragment.cpp @@ -91,7 +91,7 @@ void DocumentFragment::parseHTML(const String& source, FragmentScriptingPermissi bool DocumentFragment::parseXML(const String& source, Element* parent, FragmentScriptingPermission scriptingPermission) { - return parseXMLDocumentFragment(source, this, parent, scriptingPermission); + return XMLDocumentParser::parseDocumentFragment(source, this, parent, scriptingPermission); } } diff --git a/WebCore/dom/DocumentParser.cpp b/WebCore/dom/DocumentParser.cpp new file mode 100644 index 0000000..b80927c --- /dev/null +++ b/WebCore/dom/DocumentParser.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2010 Google, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 + * 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 "DocumentParser.h" + +#include <wtf/Assertions.h> + +namespace WebCore { + +DocumentParser::DocumentParser(Document* document) + : m_parserStopped(false) + , m_document(document) +{ + ASSERT(document); +} + +}; + diff --git a/WebCore/dom/DocumentParser.h b/WebCore/dom/DocumentParser.h index 881136c..7e47a87 100644 --- a/WebCore/dom/DocumentParser.h +++ b/WebCore/dom/DocumentParser.h @@ -24,29 +24,34 @@ #ifndef DocumentParser_h #define DocumentParser_h -#include <wtf/Assertions.h> +#include <wtf/Noncopyable.h> namespace WebCore { class Document; +class DocumentWriter; class LegacyHTMLTreeBuilder; -class LegacyHTMLDocumentParser; class SegmentedString; -class XSSAuditor; +class ScriptableDocumentParser; class DocumentParser : public Noncopyable { public: virtual ~DocumentParser() { } - // Script output must be prepended, while new data - // received during executing a script must be appended, hence the - // extra bool to be able to distinguish between both cases. - // document.write() always uses false, while the loader uses true. - virtual void write(const SegmentedString&, bool isFromNetwork) = 0; + virtual ScriptableDocumentParser* asScriptableDocumentParser() { return 0; } + + // insert is used by document.write + virtual void insert(const SegmentedString&) = 0; + + // appendBytes is used by DocumentWriter (the loader) + virtual void appendBytes(DocumentWriter*, const char* bytes, int length, bool flush) = 0; + + // FIXME: append() should be private, but DocumentWriter::replaceDocument + // uses it for now. + virtual void append(const SegmentedString&) = 0; + virtual void finish() = 0; virtual bool finishWasCalled() = 0; - virtual bool isWaitingForScripts() const = 0; - virtual bool isExecutingScript() const { return false; } virtual void stopParsing() { m_parserStopped = true; } // FIXME: processingData() is only used by DocumentLoader::isLoadingInAPISense @@ -54,53 +59,22 @@ public: // actually implements it. virtual bool processingData() const { return false; } - virtual bool wantsRawData() const { return false; } - virtual bool writeRawData(const char* /*data*/, int /*length*/) - { - ASSERT_NOT_REACHED(); - return false; - } - - virtual bool wellFormed() const { return true; } - - virtual int lineNumber() const { return -1; } - virtual int columnNumber() const { return -1; } - - virtual void executeScriptsWaitingForStylesheets() {} - + // FIXME: Exposed for HTMLFormControlElement::removedFromTree. HTML DOM + // code should not need to reach into implementation details of the parser. virtual LegacyHTMLTreeBuilder* htmlTreeBuilder() const { return 0; } - virtual LegacyHTMLDocumentParser* asHTMLDocumentParser() { return 0; } - - // FIXME: view source mode is only used by the HTML and Text - // DocumentParsers and may not belong on the base-class. - bool inViewSourceMode() const { return m_inViewSourceMode; } - void setInViewSourceMode(bool mode) { m_inViewSourceMode = mode; } Document* document() const { return m_document; } - XSSAuditor* xssAuditor() const { return m_XSSAuditor; } - void setXSSAuditor(XSSAuditor* auditor) { m_XSSAuditor = auditor; } - protected: - DocumentParser(Document* document, bool viewSourceMode = false) - : m_parserStopped(false) - , m_inViewSourceMode(viewSourceMode) - , m_document(document) - , m_XSSAuditor(0) - { - ASSERT(document); - } + DocumentParser(Document*); // The parser has buffers, so parsing may continue even after // it stops receiving data. We use m_parserStopped to stop the parser // even when it has buffered data. bool m_parserStopped; - bool m_inViewSourceMode; // Every DocumentParser needs a pointer back to the document. Document* m_document; - // The XSSAuditor associated with this document parser. - XSSAuditor* m_XSSAuditor; }; } // namespace WebCore diff --git a/WebCore/dom/Element.cpp b/WebCore/dom/Element.cpp index adbb720..3dbd880 100644 --- a/WebCore/dom/Element.cpp +++ b/WebCore/dom/Element.cpp @@ -33,6 +33,7 @@ #include "CSSStyleSelector.h" #include "ClientRect.h" #include "ClientRectList.h" +#include "DatasetDOMStringMap.h" #include "Document.h" #include "DocumentFragment.h" #include "ElementRareData.h" @@ -153,10 +154,10 @@ PassRefPtr<Element> Element::cloneElementWithoutChildren() // This is a sanity check as HTML overloads some of the DOM methods. ASSERT(isHTMLElement() == clone->isHTMLElement()); - // Clone attributes. - if (namedAttrMap) - clone->attributes()->setAttributes(*attributes(true)); // Call attributes(true) to force attribute synchronization to occur (for svg and style) before cloning happens. - + // Call attributes(true) to force attribute synchronization to occur for SVG and style attributes. + if (NamedNodeMap* attributeMap = attributes(true)) + clone->attributes()->setAttributes(*attributeMap); + clone->copyNonAttributeProperties(this); return clone.release(); @@ -1520,6 +1521,14 @@ bool Element::webkitMatchesSelector(const String& selector, ExceptionCode& ec) return false; } +DOMStringMap* Element::dataset() +{ + ElementRareData* data = ensureRareData(); + if (!data->m_datasetDOMStringMap) + data->m_datasetDOMStringMap = DatasetDOMStringMap::create(this); + return data->m_datasetDOMStringMap.get(); +} + KURL Element::getURLAttribute(const QualifiedName& name) const { #if !ASSERT_DISABLED diff --git a/WebCore/dom/Element.h b/WebCore/dom/Element.h index a0cf7b1..7dd7d80 100644 --- a/WebCore/dom/Element.h +++ b/WebCore/dom/Element.h @@ -35,6 +35,7 @@ namespace WebCore { class Attribute; class ClientRect; class ClientRectList; +class DOMStringMap; class ElementRareData; class IntSize; @@ -262,6 +263,8 @@ public: bool webkitMatchesSelector(const String& selectors, ExceptionCode&); + DOMStringMap* dataset(); + virtual bool isFormControlElement() const { return false; } virtual bool isEnabledFormControl() const { return true; } virtual bool isReadOnlyFormControl() const { return false; } diff --git a/WebCore/dom/Element.idl b/WebCore/dom/Element.idl index 6bb0687..0ad3184 100644 --- a/WebCore/dom/Element.idl +++ b/WebCore/dom/Element.idl @@ -99,6 +99,12 @@ module core { // HTML 5 NodeList getElementsByClassName(in DOMString name); +#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT +#if !defined(V8_BINDING) || !V8_BINDING + readonly attribute DOMStringMap dataset; +#endif +#endif + // NodeSelector - Selector API Element querySelector(in DOMString selectors) raises(DOMException); diff --git a/WebCore/dom/ElementRareData.h b/WebCore/dom/ElementRareData.h index b444d99..8e338ab 100644 --- a/WebCore/dom/ElementRareData.h +++ b/WebCore/dom/ElementRareData.h @@ -22,8 +22,10 @@ #ifndef ElementRareData_h #define ElementRareData_h +#include "DatasetDOMStringMap.h" #include "Element.h" #include "NodeRareData.h" +#include <wtf/OwnPtr.h> namespace WebCore { @@ -38,6 +40,8 @@ public: IntSize m_minimumSizeForResizing; RefPtr<RenderStyle> m_computedStyle; + + OwnPtr<DatasetDOMStringMap> m_datasetDOMStringMap; }; inline IntSize defaultMinimumSizeForResizing() diff --git a/WebCore/dom/EventNames.h b/WebCore/dom/EventNames.h index 0491d02..65abfbf 100644 --- a/WebCore/dom/EventNames.h +++ b/WebCore/dom/EventNames.h @@ -34,6 +34,7 @@ namespace WebCore { macro(beforecut) \ macro(beforeload) \ macro(beforepaste) \ + macro(beforeprocess) \ macro(beforeunload) \ macro(blur) \ macro(cached) \ diff --git a/WebCore/dom/Node.cpp b/WebCore/dom/Node.cpp index 4b25d9a..77a88e7 100644 --- a/WebCore/dom/Node.cpp +++ b/WebCore/dom/Node.cpp @@ -644,11 +644,16 @@ const AtomicString& Node::virtualNamespaceURI() const return nullAtom; } -ContainerNode* Node::addChild(PassRefPtr<Node>) +ContainerNode* Node::legacyParserAddChild(PassRefPtr<Node>) { return 0; } +void Node::parserAddChild(PassRefPtr<Node>) +{ + ASSERT_NOT_REACHED(); +} + bool Node::isContentEditable() const { return parent() && parent()->isContentEditable(); diff --git a/WebCore/dom/Node.h b/WebCore/dom/Node.h index 6e99cd7..a839c0e 100644 --- a/WebCore/dom/Node.h +++ b/WebCore/dom/Node.h @@ -264,7 +264,10 @@ public: // Used by the parser. Checks against the DTD, unlike DOM operations like appendChild(). // Also does not dispatch DOM mutation events. // Returns the appropriate container node for future insertions as you parse, or 0 for failure. - virtual ContainerNode* addChild(PassRefPtr<Node>); + virtual ContainerNode* legacyParserAddChild(PassRefPtr<Node>); + // addChild is tied into the logic of the LegacyHTMLTreeBuilder. We need + // a "clean" version to use for the HTML5 version of the HTMLTreeBuilder. + virtual void parserAddChild(PassRefPtr<Node>); // Called by the parser when this element's close tag is reached, // signaling that all child tags have been parsed and added. diff --git a/WebCore/dom/Node.idl b/WebCore/dom/Node.idl index dec6b19..07046d1 100644 --- a/WebCore/dom/Node.idl +++ b/WebCore/dom/Node.idl @@ -134,7 +134,6 @@ module core { #if !defined(LANGUAGE_CPP) || !LANGUAGE_CPP #if !defined(LANGUAGE_OBJECTIVE_C) || !LANGUAGE_OBJECTIVE_C -#if !defined(LANGUAGE_GOBJECT) || !LANGUAGE_GOBJECT void addEventListener(in DOMString type, in EventListener listener, in boolean useCapture); @@ -145,7 +144,6 @@ module core { raises(EventException); #endif #endif -#endif #if defined(LANGUAGE_CPP) && LANGUAGE_CPP [Custom] void addEventListener(in DOMString type, diff --git a/WebCore/dom/RawDataDocumentParser.h b/WebCore/dom/RawDataDocumentParser.h index 77d148d..2eb3d0a 100644 --- a/WebCore/dom/RawDataDocumentParser.h +++ b/WebCore/dom/RawDataDocumentParser.h @@ -30,12 +30,6 @@ namespace WebCore { -// FIXME: It seems wrong that RawDataDocumentParser is a subclass of -// DocumentParser. RawDataDocumentParser, just wants to override an earlier -// version of write() before the data is decoded. Seems the decoding could -// move into the base-class DocumentParser, and then RawDataDocumentParser -// would just be short-circuting. That could simplify some of the -// DocumentWriter logic. class RawDataDocumentParser : public DocumentParser { public: RawDataDocumentParser(Document* document) @@ -51,23 +45,23 @@ protected: } private: - virtual void write(const SegmentedString&, bool) + virtual void insert(const SegmentedString&) { // <https://bugs.webkit.org/show_bug.cgi?id=25397>: JS code can always call document.write, we need to handle it. ASSERT_NOT_REACHED(); } + virtual void append(const SegmentedString&) + { + ASSERT_NOT_REACHED(); + } + virtual bool finishWasCalled() { // finish() always calls document()->finishedParsing() so we will be // deleted after finish(). return false; } - - virtual bool isWaitingForScripts() const { return false; } - - virtual bool wantsRawData() const { return true; } - virtual bool writeRawData(const char*, int) { return false; } }; }; diff --git a/WebCore/dom/ScriptExecutionContext.cpp b/WebCore/dom/ScriptExecutionContext.cpp index 226aad8..291243d 100644 --- a/WebCore/dom/ScriptExecutionContext.cpp +++ b/WebCore/dom/ScriptExecutionContext.cpp @@ -109,38 +109,9 @@ DatabaseThread* ScriptExecutionContext::databaseThread() return m_databaseThread.get(); } -void ScriptExecutionContext::addOpenDatabase(Database* database) -{ - ASSERT(isContextThread()); - if (!m_openDatabaseSet) - m_openDatabaseSet.set(new DatabaseSet()); - - ASSERT(!m_openDatabaseSet->contains(database)); - m_openDatabaseSet->add(database); -} - -void ScriptExecutionContext::removeOpenDatabase(Database* database) -{ - ASSERT(isContextThread()); - ASSERT(m_openDatabaseSet && m_openDatabaseSet->contains(database)); - if (!m_openDatabaseSet) - return; - m_openDatabaseSet->remove(database); -} - void ScriptExecutionContext::stopDatabases(DatabaseTaskSynchronizer* cleanupSync) { ASSERT(isContextThread()); - if (m_openDatabaseSet) { - DatabaseSet::iterator i = m_openDatabaseSet->begin(); - DatabaseSet::iterator end = m_openDatabaseSet->end(); - for (; i != end; ++i) { - (*i)->stop(); - if (m_databaseThread) - m_databaseThread->unscheduleDatabaseTasks(*i); - } - } - if (m_databaseThread) m_databaseThread->requestTermination(cleanupSync); else if (cleanupSync) diff --git a/WebCore/dom/ScriptExecutionContext.h b/WebCore/dom/ScriptExecutionContext.h index 18e2cd0..4cd483a 100644 --- a/WebCore/dom/ScriptExecutionContext.h +++ b/WebCore/dom/ScriptExecutionContext.h @@ -70,8 +70,6 @@ namespace WebCore { DatabaseThread* databaseThread(); void setHasOpenDatabases() { m_hasOpenDatabases = true; } bool hasOpenDatabases() const { return m_hasOpenDatabases; } - void addOpenDatabase(Database*); - void removeOpenDatabase(Database*); // When the database cleanup is done, cleanupSync will be signalled. void stopDatabases(DatabaseTaskSynchronizer*); #endif @@ -160,8 +158,6 @@ namespace WebCore { #if ENABLE(DATABASE) RefPtr<DatabaseThread> m_databaseThread; bool m_hasOpenDatabases; // This never changes back to false, even after the database thread is closed. - typedef HashSet<Database* > DatabaseSet; - OwnPtr<DatabaseSet> m_openDatabaseSet; #endif #if ENABLE(FILE_READER) || ENABLE(FILE_WRITER) diff --git a/WebCore/dom/ScriptableDocumentParser.cpp b/WebCore/dom/ScriptableDocumentParser.cpp new file mode 100644 index 0000000..43b3417 --- /dev/null +++ b/WebCore/dom/ScriptableDocumentParser.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2010 Google, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 + * 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 "ScriptableDocumentParser.h" + +namespace WebCore { + +ScriptableDocumentParser::ScriptableDocumentParser(Document* document, bool viewSourceMode) + : DecodedDataDocumentParser(document, viewSourceMode) + , m_xssAuditor(0) +{ +} + +}; diff --git a/WebCore/dom/ScriptableDocumentParser.h b/WebCore/dom/ScriptableDocumentParser.h new file mode 100644 index 0000000..f5f2e42 --- /dev/null +++ b/WebCore/dom/ScriptableDocumentParser.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2010 Google, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 + * 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 ScriptableDocumentParser_h +#define ScriptableDocumentParser_h + +#include "DecodedDataDocumentParser.h" + +namespace WebCore { + +class SegmentedString; +class XSSAuditor; + +class ScriptableDocumentParser : public DecodedDataDocumentParser { +public: + // Only used by Document::open for deciding if its safe to act on a + // JavaScript document.open() call right now, or it should be ignored. + virtual bool isExecutingScript() const { return false; } + + // FIXME: Only the HTMLDocumentParser ever blocks script execution on + // stylesheet load, which is likely a bug in the XMLDocumentParser. + virtual void executeScriptsWaitingForStylesheets() { } + + virtual bool isWaitingForScripts() const = 0; + + // These are used to expose the current line/column to the scripting system. + virtual int lineNumber() const = 0; + virtual int columnNumber() const = 0; + + XSSAuditor* xssAuditor() const { return m_xssAuditor; } + void setXSSAuditor(XSSAuditor* auditor) { m_xssAuditor = auditor; } + + // Exposed for LegacyHTMLTreeBuilder::reportErrorToConsole + virtual bool processingContentWrittenByScript() const { return false; } + +protected: + ScriptableDocumentParser(Document*, bool viewSourceMode = false); + +private: + virtual ScriptableDocumentParser* asScriptableDocumentParser() { return this; } + + // The XSSAuditor associated with this document parser. + XSSAuditor* m_xssAuditor; +}; + +} + +#endif // ScriptableDocumentParser_h diff --git a/WebCore/dom/SelectElement.cpp b/WebCore/dom/SelectElement.cpp index 43e6e28..e9958a2 100644 --- a/WebCore/dom/SelectElement.cpp +++ b/WebCore/dom/SelectElement.cpp @@ -534,7 +534,7 @@ static int nextValidIndex(const Vector<Element*>& listItems, int listIndex, Skip } #endif -void SelectElement::menuListDefaultEventHandler(SelectElementData& data, Element* element, Event* event) +void SelectElement::menuListDefaultEventHandler(SelectElementData& data, Element* element, Event* event, HTMLFormElement* htmlForm) { if (event->type() == eventNames().keydownEvent) { if (!element->renderer() || !event->isKeyboardEvent()) @@ -613,6 +613,8 @@ void SelectElement::menuListDefaultEventHandler(SelectElementData& data, Element menuList->showPopup(); handled = true; } else if (keyCode == '\r') { + if (htmlForm) + htmlForm->submitImplicitly(event, false); menuListOnChange(data, element); handled = true; } @@ -692,7 +694,7 @@ void SelectElement::updateSelectedState(SelectElementData& data, Element* elemen updateListBoxSelection(data, element, !multiSelect); } -void SelectElement::listBoxDefaultEventHandler(SelectElementData& data, Element* element, Event* event) +void SelectElement::listBoxDefaultEventHandler(SelectElementData& data, Element* element, Event* event, HTMLFormElement* htmlForm) { const Vector<Element*>& listItems = data.listItems(element); @@ -758,18 +760,29 @@ void SelectElement::listBoxDefaultEventHandler(SelectElementData& data, Element* listBoxOnChange(data, element); event->setDefaultHandled(); } + } else if (event->type() == eventNames().keypressEvent) { + if (!event->isKeyboardEvent()) + return; + int keyCode = static_cast<KeyboardEvent*>(event)->keyCode(); + + if (keyCode == '\r') { + if (htmlForm) + htmlForm->submitImplicitly(event, false); + event->setDefaultHandled(); + return; + } } } -void SelectElement::defaultEventHandler(SelectElementData& data, Element* element, Event* event) +void SelectElement::defaultEventHandler(SelectElementData& data, Element* element, Event* event, HTMLFormElement* htmlForm) { if (!element->renderer()) return; if (data.usesMenuList()) - menuListDefaultEventHandler(data, element, event); + menuListDefaultEventHandler(data, element, event, htmlForm); else - listBoxDefaultEventHandler(data, element, event); + listBoxDefaultEventHandler(data, element, event, htmlForm); if (event->defaultHandled()) return; diff --git a/WebCore/dom/SelectElement.h b/WebCore/dom/SelectElement.h index 493bee5..3831ac4 100644 --- a/WebCore/dom/SelectElement.h +++ b/WebCore/dom/SelectElement.h @@ -92,7 +92,7 @@ protected: static void parseMultipleAttribute(SelectElementData&, Element*, Attribute*); static bool appendFormData(SelectElementData&, Element*, FormDataList&); static void reset(SelectElementData&, Element*); - static void defaultEventHandler(SelectElementData&, Element*, Event*); + static void defaultEventHandler(SelectElementData&, Element*, Event*, HTMLFormElement*); static int lastSelectedListIndex(const SelectElementData&, const Element*); static void typeAheadFind(SelectElementData&, Element*, KeyboardEvent*); static void insertedIntoTree(SelectElementData&, Element*); @@ -103,8 +103,8 @@ protected: bool multi, bool shift); private: - static void menuListDefaultEventHandler(SelectElementData&, Element*, Event*); - static void listBoxDefaultEventHandler(SelectElementData&, Element*, Event*); + static void menuListDefaultEventHandler(SelectElementData&, Element*, Event*, HTMLFormElement*); + static void listBoxDefaultEventHandler(SelectElementData&, Element*, Event*, HTMLFormElement*); static void setOptionsChangedOnRenderer(SelectElementData&, Element*); }; diff --git a/WebCore/dom/Text.cpp b/WebCore/dom/Text.cpp index 14da1a4..1589b11 100644 --- a/WebCore/dom/Text.cpp +++ b/WebCore/dom/Text.cpp @@ -72,7 +72,7 @@ PassRefPtr<Text> Text::splitText(unsigned offset, ExceptionCode& ec) document()->textNodeSplit(this); if (renderer()) - toRenderText(renderer())->setText(dataImpl()); + toRenderText(renderer())->setTextWithOffset(dataImpl(), 0, oldStr->length()); return newText.release(); } diff --git a/WebCore/dom/ViewportArguments.cpp b/WebCore/dom/ViewportArguments.cpp index 23d0297..c507032 100644 --- a/WebCore/dom/ViewportArguments.cpp +++ b/WebCore/dom/ViewportArguments.cpp @@ -33,7 +33,7 @@ #include "Frame.h" #include "Page.h" #include "PlatformString.h" -#include "DocumentParser.h" +#include "ScriptableDocumentParser.h" namespace WebCore { @@ -103,10 +103,20 @@ static MessageLevel viewportErrorMessageLevel(ViewportErrorCode errorCode) return errorCode == UnrecognizedViewportArgumentError || errorCode == MaximumScaleTooLargeError ? ErrorMessageLevel : TipMessageLevel; } -void reportViewportWarning(Document* document, ViewportErrorCode errorCode, const String& replacement) +// FIXME: Why is this different from SVGDocumentExtensions parserLineNumber? +// FIXME: Callers should probably use ScriptController::eventHandlerLineNumber() +static int parserLineNumber(Document* document) { - DocumentParser* parser = document->parser(); + if (!document) + return 0; + ScriptableDocumentParser* parser = document->scriptableDocumentParser(); + if (!parser) + return 0; + return parser->lineNumber() + 1; +} +void reportViewportWarning(Document* document, ViewportErrorCode errorCode, const String& replacement) +{ Frame* frame = document->frame(); if (!frame) return; @@ -114,7 +124,7 @@ void reportViewportWarning(Document* document, ViewportErrorCode errorCode, cons String message = viewportErrorMessageTemplate(errorCode); message.replace("%replacement", replacement); - frame->domWindow()->console()->addMessage(HTMLMessageSource, LogMessageType, viewportErrorMessageLevel(errorCode), message, parser ? parser->lineNumber() + 1 : 0, document->url().string()); + frame->domWindow()->console()->addMessage(HTMLMessageSource, LogMessageType, viewportErrorMessageLevel(errorCode), message, parserLineNumber(document), document->url().string()); } } // namespace WebCore diff --git a/WebCore/dom/XMLDocumentParser.cpp b/WebCore/dom/XMLDocumentParser.cpp index ab02bb3..3d2f324 100644 --- a/WebCore/dom/XMLDocumentParser.cpp +++ b/WebCore/dom/XMLDocumentParser.cpp @@ -116,7 +116,16 @@ void XMLDocumentParser::clearCurrentNodeStack() } } -void XMLDocumentParser::write(const SegmentedString& s, bool /*appendData*/) +void XMLDocumentParser::insert(const SegmentedString& source) +{ + // FIXME: This is a hack to work around the fact that XMLHttpRequest + // responseXML() calls Document::write() which in turn calls insert(). In + // HTML, that's correct, as insert() implies a synchronous parse. For XML, + // all parsing is synchronous but document.write shouldn't be supported. + append(source); +} + +void XMLDocumentParser::append(const SegmentedString& s) { String parseString = s.toString(); @@ -167,7 +176,7 @@ bool XMLDocumentParser::enterText() ASSERT(m_bufferedText.size() == 0); #endif RefPtr<Node> newNode = Text::create(document(), ""); - if (!m_currentNode->addChild(newNode.get())) + if (!m_currentNode->legacyParserAddChild(newNode.get())) return false; pushCurrentNode(newNode.get()); return true; diff --git a/WebCore/dom/XMLDocumentParser.h b/WebCore/dom/XMLDocumentParser.h index 7553cea..a6cc9a0 100644 --- a/WebCore/dom/XMLDocumentParser.h +++ b/WebCore/dom/XMLDocumentParser.h @@ -136,10 +136,10 @@ bool parseXMLDocumentFragment(const String&, DocumentFragment*, Element* parent #include "CachedResourceClient.h" #include "CachedResourceHandle.h" +#include "FragmentScriptingPermission.h" +#include "ScriptableDocumentParser.h" #include "SegmentedString.h" #include "StringHash.h" -#include "DocumentParser.h" -#include "FragmentScriptingPermission.h" #include <wtf/HashMap.h> #include <wtf/OwnPtr.h> @@ -179,7 +179,7 @@ namespace WebCore { }; #endif - class XMLDocumentParser : public DocumentParser, public CachedResourceClient { + class XMLDocumentParser : public ScriptableDocumentParser, public CachedResourceClient { public: XMLDocumentParser(Document*, FrameView* = 0); XMLDocumentParser(DocumentFragment*, Element*, FragmentScriptingPermission); @@ -199,9 +199,12 @@ namespace WebCore { bool isWMLDocument() const; #endif + static bool parseDocumentFragment(const String&, DocumentFragment*, Element* parent = 0, FragmentScriptingPermission = FragmentScriptingAllowed); + private: // From DocumentParser - virtual void write(const SegmentedString&, bool appendData); + virtual void insert(const SegmentedString&); + virtual void append(const SegmentedString&); virtual void finish(); virtual bool finishWasCalled(); virtual bool isWaitingForScripts() const; @@ -247,8 +250,6 @@ public: void endDocument(); #endif private: - friend bool parseXMLDocumentFragment(const String&, DocumentFragment*, Element*, FragmentScriptingPermission); - void initializeParserContext(const char* chunk = 0); void pushCurrentNode(Node*); @@ -315,7 +316,6 @@ void* xmlDocPtrForString(DocLoader*, const String& source, const String& url); #endif HashMap<String, String> parseAttributes(const String&, bool& attrsOK); -bool parseXMLDocumentFragment(const String&, DocumentFragment*, Element* parent = 0, FragmentScriptingPermission = FragmentScriptingAllowed); } // namespace WebCore diff --git a/WebCore/dom/XMLDocumentParserLibxml2.cpp b/WebCore/dom/XMLDocumentParserLibxml2.cpp index 33b0a09..a6e9cd0 100644 --- a/WebCore/dom/XMLDocumentParserLibxml2.cpp +++ b/WebCore/dom/XMLDocumentParserLibxml2.cpp @@ -523,7 +523,7 @@ PassRefPtr<XMLParserContext> XMLParserContext::createMemoryParser(xmlSAXHandlerP // -------------------------------- XMLDocumentParser::XMLDocumentParser(Document* document, FrameView* frameView) - : DocumentParser(document) + : ScriptableDocumentParser(document) , m_view(frameView) , m_context(0) , m_pendingCallbacks(new PendingCallbacks) @@ -550,7 +550,7 @@ XMLDocumentParser::XMLDocumentParser(Document* document, FrameView* frameView) } XMLDocumentParser::XMLDocumentParser(DocumentFragment* fragment, Element* parentElement, FragmentScriptingPermission scriptingPermission) - : DocumentParser(fragment->document()) + : ScriptableDocumentParser(fragment->document()) , m_view(0) , m_context(0) , m_pendingCallbacks(new PendingCallbacks) @@ -790,7 +790,7 @@ void XMLDocumentParser::startElementNs(const xmlChar* xmlLocalName, const xmlCha if (scriptElement) m_scriptStartLine = lineNumber(); - if (!m_currentNode->addChild(newElement.get())) { + if (!m_currentNode->legacyParserAddChild(newElement.get())) { stopParsing(); return; } @@ -935,7 +935,7 @@ void XMLDocumentParser::processingInstruction(const xmlChar* target, const xmlCh pi->setCreatedByParser(true); - if (!m_currentNode->addChild(pi.get())) + if (!m_currentNode->legacyParserAddChild(pi.get())) return; if (m_view && !pi->attached()) pi->attach(); @@ -962,7 +962,7 @@ void XMLDocumentParser::cdataBlock(const xmlChar* s, int len) exitText(); RefPtr<Node> newNode = CDATASection::create(document(), toString(s, len)); - if (!m_currentNode->addChild(newNode.get())) + if (!m_currentNode->legacyParserAddChild(newNode.get())) return; if (m_view && !newNode->attached()) newNode->attach(); @@ -981,7 +981,7 @@ void XMLDocumentParser::comment(const xmlChar* s) exitText(); RefPtr<Node> newNode = Comment::create(document(), toString(s)); - m_currentNode->addChild(newNode.get()); + m_currentNode->legacyParserAddChild(newNode.get()); if (m_view && !newNode->attached()) newNode->attach(); } @@ -1045,7 +1045,7 @@ void XMLDocumentParser::internalSubset(const xmlChar* name, const xmlChar* exter } #endif - document()->addChild(DocumentType::create(document(), toString(name), toString(externalID), toString(systemID))); + document()->legacyParserAddChild(DocumentType::create(document(), toString(name), toString(externalID), toString(systemID))); } } @@ -1363,7 +1363,7 @@ void XMLDocumentParser::resumeParsing() // Then, write any pending data SegmentedString rest = m_pendingSrc; m_pendingSrc.clear(); - write(rest, false); + append(rest); // Finally, if finish() has been called and write() didn't result // in any further callbacks being queued, call end() @@ -1373,7 +1373,7 @@ void XMLDocumentParser::resumeParsing() // FIXME: This method should be possible to implement using the DocumentParser // API, instead of needing to grab at libxml2 state directly. -bool parseXMLDocumentFragment(const String& chunk, DocumentFragment* fragment, Element* parent, FragmentScriptingPermission scriptingPermission) +bool XMLDocumentParser::parseDocumentFragment(const String& chunk, DocumentFragment* fragment, Element* parent, FragmentScriptingPermission scriptingPermission) { if (!chunk.length()) return true; diff --git a/WebCore/dom/XMLDocumentParserQt.cpp b/WebCore/dom/XMLDocumentParserQt.cpp index 3b657f1..c702c09 100644 --- a/WebCore/dom/XMLDocumentParserQt.cpp +++ b/WebCore/dom/XMLDocumentParserQt.cpp @@ -44,6 +44,7 @@ #include "ResourceHandle.h" #include "ResourceRequest.h" #include "ResourceResponse.h" +#include "ScriptableDocumentParser.h" #include "ScriptController.h" #include "ScriptElement.h" #include "ScriptSourceCode.h" @@ -78,7 +79,7 @@ QString EntityResolver::resolveUndeclaredEntity(const QString &name) // -------------------------------- XMLDocumentParser::XMLDocumentParser(Document* document, FrameView* frameView) - : DocumentParser(document) + : ScriptableDocumentParser(document) , m_view(frameView) , m_wroteText(false) , m_currentNode(document) @@ -105,7 +106,7 @@ XMLDocumentParser::XMLDocumentParser(Document* document, FrameView* frameView) } XMLDocumentParser::XMLDocumentParser(DocumentFragment* fragment, Element* parentElement, FragmentScriptingPermission permission) - : DocumentParser(fragment->document()) + : ScriptableDocumentParser(fragment->document()) , m_view(0) , m_wroteText(false) , m_currentNode(fragment) @@ -228,7 +229,7 @@ int XMLDocumentParser::columnNumber() const void XMLDocumentParser::stopParsing() { - DocumentParser::stopParsing(); + ScriptableDocumentParser::stopParsing(); } void XMLDocumentParser::resumeParsing() @@ -245,24 +246,24 @@ void XMLDocumentParser::resumeParsing() // Then, write any pending data SegmentedString rest = m_pendingSrc; m_pendingSrc.clear(); - write(rest, false); + append(rest); - // Finally, if finish() has been called and write() didn't result + // Finally, if finish() has been called and append() didn't result // in any further callbacks being queued, call end() if (m_finishCalled && !m_parserPaused && !m_pendingScript) end(); } -bool parseXMLDocumentFragment(const String& chunk, DocumentFragment* fragment, Element* parent, FragmentScriptingPermission scriptingPermission) +bool XMLDocumentParser::parseDocumentFragment(const String& chunk, DocumentFragment* fragment, Element* parent, FragmentScriptingPermission scriptingPermission) { if (!chunk.length()) return true; XMLDocumentParser parser(fragment, parent, scriptingPermission); - parser.write(String("<qxmlstreamdummyelement>"), false); - parser.write(chunk, false); - parser.write(String("</qxmlstreamdummyelement>"), false); + parser.append(String("<qxmlstreamdummyelement>")); + parser.append(chunk); + parser.append(String("</qxmlstreamdummyelement>")); parser.finish(); return !parser.hasError(); } @@ -516,7 +517,7 @@ void XMLDocumentParser::parseStartElement() if (scriptElement) m_scriptStartLine = lineNumber(); - if (!m_currentNode->addChild(newElement.get())) { + if (!m_currentNode->legacyParserAddChild(newElement.get())) { stopParsing(); return; } @@ -617,7 +618,7 @@ void XMLDocumentParser::parseProcessingInstruction() pi->setCreatedByParser(true); - if (!m_currentNode->addChild(pi.get())) + if (!m_currentNode->legacyParserAddChild(pi.get())) return; if (m_view && !pi->attached()) pi->attach(); @@ -636,7 +637,7 @@ void XMLDocumentParser::parseCdata() exitText(); RefPtr<Node> newNode = CDATASection::create(document(), m_stream.text()); - if (!m_currentNode->addChild(newNode.get())) + if (!m_currentNode->legacyParserAddChild(newNode.get())) return; if (m_view && !newNode->attached()) newNode->attach(); @@ -647,7 +648,7 @@ void XMLDocumentParser::parseComment() exitText(); RefPtr<Node> newNode = Comment::create(document(), m_stream.text()); - m_currentNode->addChild(newNode.get()); + m_currentNode->legacyParserAddChild(newNode.get()); if (m_view && !newNode->attached()) newNode->attach(); } @@ -706,7 +707,7 @@ void XMLDocumentParser::parseDtd() handleError(fatal, "Invalid DTD Public ID", lineNumber(), columnNumber()); #endif if (!m_parsingFragment) - document()->addChild(DocumentType::create(document(), name, publicId, systemId)); + document()->legacyParserAddChild(DocumentType::create(document(), name, publicId, systemId)); } } |