diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-07-23 09:28:44 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-07-23 09:28:44 +0200 |
commit | 815f1ed417bd26fbe2abbdf20ac5d3423b30796c (patch) | |
tree | 923c9a9e2834ccab60f5caecfb8f0ac410c1dd9e /Source/WebCore/html | |
parent | b4ad5d9d2b96baacd0180ead50de5195ca78af2d (diff) | |
download | qtwebkit-815f1ed417bd26fbe2abbdf20ac5d3423b30796c.tar.gz |
Imported WebKit commit e65cbc5b6ac32627c797e7fc7f46eb7794410c92 (http://svn.webkit.org/repository/webkit/trunk@123308)
New snapshot with better configure tests
Diffstat (limited to 'Source/WebCore/html')
70 files changed, 592 insertions, 338 deletions
diff --git a/Source/WebCore/html/CollectionType.h b/Source/WebCore/html/CollectionType.h index 9cd70cea0..ab03ce646 100644 --- a/Source/WebCore/html/CollectionType.h +++ b/Source/WebCore/html/CollectionType.h @@ -61,7 +61,7 @@ enum CollectionType { #endif FormControls, - InvalidCollectionType + NodeListCollectionType }; static const CollectionType FirstUnnamedDocumentCachedType = DocImages; diff --git a/Source/WebCore/html/ColorInputType.cpp b/Source/WebCore/html/ColorInputType.cpp index 1ececc2b6..ea2151c1e 100644 --- a/Source/WebCore/html/ColorInputType.cpp +++ b/Source/WebCore/html/ColorInputType.cpp @@ -38,6 +38,8 @@ #include "HTMLDivElement.h" #include "HTMLInputElement.h" #include "MouseEvent.h" +#include "RenderObject.h" +#include "RenderView.h" #include "ScriptController.h" #include "ShadowRoot.h" @@ -117,7 +119,7 @@ void ColorInputType::createShadowSubtree() ExceptionCode ec = 0; wrapperElement->appendChild(colorSwatch.release(), ec); ASSERT(!ec); - element()->shadow()->oldestShadowRoot()->appendChild(wrapperElement.release(), ec); + element()->userAgentShadowRoot()->appendChild(wrapperElement.release(), ec); ASSERT(!ec); updateColorSwatch(); @@ -191,10 +193,17 @@ void ColorInputType::updateColorSwatch() HTMLElement* ColorInputType::shadowColorSwatch() const { - ShadowRoot* shadow = element()->shadow()->oldestShadowRoot(); + ShadowRoot* shadow = element()->userAgentShadowRoot(); return shadow ? toHTMLElement(shadow->firstChild()->firstChild()) : 0; } +IntRect ColorInputType::elementRectRelativeToWindow() const +{ + RenderObject* renderer = element()->renderer(); + ASSERT(renderer); + return pixelSnappedIntRect(renderer->view()->frameView()->contentsToWindow(renderer->absoluteBoundingBoxRect())); +} + } // namespace WebCore #endif // ENABLE(INPUT_TYPE_COLOR) diff --git a/Source/WebCore/html/ColorInputType.h b/Source/WebCore/html/ColorInputType.h index 779cd976e..e03cb2242 100644 --- a/Source/WebCore/html/ColorInputType.h +++ b/Source/WebCore/html/ColorInputType.h @@ -46,6 +46,7 @@ public: // ColorChooserClient implementation. virtual void didChooseColor(const Color&) OVERRIDE; virtual void didEndChooser() OVERRIDE; + virtual IntRect elementRectRelativeToWindow() const OVERRIDE; private: ColorInputType(HTMLInputElement* element) : BaseClickableWithKeyInputType(element) { } diff --git a/Source/WebCore/html/FTPDirectoryDocument.cpp b/Source/WebCore/html/FTPDirectoryDocument.cpp index 412a1fe65..18689c97f 100644 --- a/Source/WebCore/html/FTPDirectoryDocument.cpp +++ b/Source/WebCore/html/FTPDirectoryDocument.cpp @@ -88,7 +88,6 @@ private: RefPtr<HTMLTableElement> m_tableElement; bool m_skipLF; - bool m_parsedTemplate; int m_size; UChar* m_buffer; @@ -101,7 +100,6 @@ private: FTPDirectoryDocumentParser::FTPDirectoryDocumentParser(HTMLDocument* document) : HTMLDocumentParser(document, false) , m_skipLF(false) - , m_parsedTemplate(false) , m_size(254) , m_buffer(static_cast<UChar*>(fastMalloc(sizeof(UChar) * m_size))) , m_dest(m_buffer) diff --git a/Source/WebCore/html/FileInputType.cpp b/Source/WebCore/html/FileInputType.cpp index f39733d15..7a75e13c1 100644 --- a/Source/WebCore/html/FileInputType.cpp +++ b/Source/WebCore/html/FileInputType.cpp @@ -297,13 +297,13 @@ void FileInputType::createShadowSubtree() { ASSERT(element()->shadow()); ExceptionCode ec = 0; - element()->shadow()->oldestShadowRoot()->appendChild(element()->multiple() ? UploadButtonElement::createForMultiple(element()->document()): UploadButtonElement::create(element()->document()), ec); + element()->userAgentShadowRoot()->appendChild(element()->multiple() ? UploadButtonElement::createForMultiple(element()->document()): UploadButtonElement::create(element()->document()), ec); } void FileInputType::multipleAttributeChanged() { ASSERT(element()->shadow()); - UploadButtonElement* button = static_cast<UploadButtonElement*>(element()->shadow()->oldestShadowRoot()->firstChild()); + UploadButtonElement* button = static_cast<UploadButtonElement*>(element()->userAgentShadowRoot()->firstChild()); if (button) button->setValue(element()->multiple() ? fileButtonChooseMultipleFilesLabel() : fileButtonChooseFileLabel()); } diff --git a/Source/WebCore/html/FormController.cpp b/Source/WebCore/html/FormController.cpp index 46241be1a..5e39fe229 100644 --- a/Source/WebCore/html/FormController.cpp +++ b/Source/WebCore/html/FormController.cpp @@ -79,14 +79,13 @@ FormControlState FormControlState::deserialize(const Vector<String>& stateVector class FormElementKey { public: - FormElementKey(AtomicStringImpl* = 0, AtomicStringImpl* = 0, AtomicStringImpl* = 0); + FormElementKey(AtomicStringImpl* = 0, AtomicStringImpl* = 0); ~FormElementKey(); FormElementKey(const FormElementKey&); FormElementKey& operator=(const FormElementKey&); AtomicStringImpl* name() const { return m_name; } AtomicStringImpl* type() const { return m_type; } - AtomicStringImpl* formKey() const { return m_formKey; } // Hash table deleted values, which are only constructed and never copied or destroyed. FormElementKey(WTF::HashTableDeletedValueType) : m_name(hashTableDeletedValue()) { } @@ -100,13 +99,11 @@ private: AtomicStringImpl* m_name; AtomicStringImpl* m_type; - AtomicStringImpl* m_formKey; }; -FormElementKey::FormElementKey(AtomicStringImpl* name, AtomicStringImpl* type, AtomicStringImpl* formKey) +FormElementKey::FormElementKey(AtomicStringImpl* name, AtomicStringImpl* type) : m_name(name) , m_type(type) - , m_formKey(formKey) { ref(); } @@ -119,7 +116,6 @@ FormElementKey::~FormElementKey() FormElementKey::FormElementKey(const FormElementKey& other) : m_name(other.name()) , m_type(other.type()) - , m_formKey(other.formKey()) { ref(); } @@ -130,7 +126,6 @@ FormElementKey& FormElementKey::operator=(const FormElementKey& other) deref(); m_name = other.name(); m_type = other.type(); - m_formKey = other.formKey(); return *this; } @@ -140,8 +135,6 @@ void FormElementKey::ref() const name()->ref(); if (type()) type()->ref(); - if (formKey()) - formKey()->ref(); } void FormElementKey::deref() const @@ -150,13 +143,11 @@ void FormElementKey::deref() const name()->deref(); if (type()) type()->deref(); - if (formKey()) - formKey()->deref(); } inline bool operator==(const FormElementKey& a, const FormElementKey& b) { - return a.name() == b.name() && a.type() == b.type() && a.formKey() == b.formKey(); + return a.name() == b.name() && a.type() == b.type(); } struct FormElementKeyHash { @@ -178,17 +169,23 @@ struct FormElementKeyHashTraits : WTF::GenericHashTraits<FormElementKey> { // ---------------------------------------------------------------------------- class SavedFormState { + WTF_MAKE_NONCOPYABLE(SavedFormState); + WTF_MAKE_FAST_ALLOCATED; + public: static PassOwnPtr<SavedFormState> create(); + static PassOwnPtr<SavedFormState> deserialize(const Vector<String>&, size_t& index); + void serializeTo(Vector<String>&) const; bool isEmpty() const { return m_stateForNewFormElements.isEmpty(); } - void appendControlState(const AtomicString& name, const AtomicString& type, const AtomicString& formKey, const FormControlState&); - FormControlState takeControlState(const AtomicString& name, const AtomicString& type, const AtomicString& formKey); + void appendControlState(const AtomicString& name, const AtomicString& type, const FormControlState&); + FormControlState takeControlState(const AtomicString& name, const AtomicString& type); private: - SavedFormState() { } + SavedFormState() : m_controlStateCount(0) { } typedef HashMap<FormElementKey, Deque<FormControlState>, FormElementKeyHash, FormElementKeyHashTraits> FormElementStateMap; FormElementStateMap m_stateForNewFormElements; + size_t m_controlStateCount; }; PassOwnPtr<SavedFormState> SavedFormState::create() @@ -196,9 +193,50 @@ PassOwnPtr<SavedFormState> SavedFormState::create() return adoptPtr(new SavedFormState); } -void SavedFormState::appendControlState(const AtomicString& name, const AtomicString& type, const AtomicString& formKey, const FormControlState& state) +static bool isNotFormControlTypeCharacter(UChar ch) +{ + return ch != '-' && (ch > 'z' || ch < 'a'); +} + +PassOwnPtr<SavedFormState> SavedFormState::deserialize(const Vector<String>& stateVector, size_t& index) +{ + if (index >= stateVector.size()) + return nullptr; + // FIXME: We need String::toSizeT(). + size_t itemCount = stateVector[index++].toUInt(); + if (!itemCount) + return nullptr; + OwnPtr<SavedFormState> savedFormState = adoptPtr(new SavedFormState); + while (itemCount--) { + if (index + 1 >= stateVector.size()) + return nullptr; + String name = stateVector[index++]; + String type = stateVector[index++]; + FormControlState state = FormControlState::deserialize(stateVector, index); + if (type.isEmpty() || type.find(isNotFormControlTypeCharacter) != notFound || state.isFailure()) + return nullptr; + savedFormState->appendControlState(name, type, state); + } + return savedFormState.release(); +} + +void SavedFormState::serializeTo(Vector<String>& stateVector) const +{ + stateVector.append(String::number(m_controlStateCount)); + for (FormElementStateMap::const_iterator it = m_stateForNewFormElements.begin(); it != m_stateForNewFormElements.end(); ++it) { + const FormElementKey& key = it->first; + const Deque<FormControlState>& queue = it->second; + for (Deque<FormControlState>::const_iterator queIterator = queue.begin(); queIterator != queue.end(); ++queIterator) { + stateVector.append(key.name()); + stateVector.append(key.type()); + queIterator->serializeTo(stateVector); + } + } +} + +void SavedFormState::appendControlState(const AtomicString& name, const AtomicString& type, const FormControlState& state) { - FormElementKey key(name.impl(), type.impl(), formKey.impl()); + FormElementKey key(name.impl(), type.impl()); FormElementStateMap::iterator it = m_stateForNewFormElements.find(key); if (it != m_stateForNewFormElements.end()) it->second.append(state); @@ -207,17 +245,19 @@ void SavedFormState::appendControlState(const AtomicString& name, const AtomicSt stateList.append(state); m_stateForNewFormElements.set(key, stateList); } + m_controlStateCount++; } -FormControlState SavedFormState::takeControlState(const AtomicString& name, const AtomicString& type, const AtomicString& formKey) +FormControlState SavedFormState::takeControlState(const AtomicString& name, const AtomicString& type) { if (m_stateForNewFormElements.isEmpty()) return FormControlState(); - FormElementStateMap::iterator it = m_stateForNewFormElements.find(FormElementKey(name.impl(), type.impl(), formKey.impl())); + FormElementStateMap::iterator it = m_stateForNewFormElements.find(FormElementKey(name.impl(), type.impl())); if (it == m_stateForNewFormElements.end()) return FormControlState(); ASSERT(it->second.size()); FormControlState state = it->second.takeFirst(); + m_controlStateCount--; if (!it->second.size()) m_stateForNewFormElements.remove(it); return state; @@ -238,23 +278,45 @@ private: FormKeyGenerator() { } typedef HashMap<HTMLFormElement*, AtomicString> FormToKeyMap; + typedef HashMap<String, unsigned> FormSignatureToNextIndexMap; FormToKeyMap m_formToKeyMap; - HashSet<AtomicString> m_existingKeys; + FormSignatureToNextIndexMap m_formSignatureToNextIndexMap; }; -static inline AtomicString createKey(HTMLFormElement* form, unsigned index) +static inline void recordFormStructure(const HTMLFormElement& form, StringBuilder& builder) { - ASSERT(form); - KURL actionURL = form->getURLAttribute(actionAttr); + // 2 is enough to distinguish forms in webkit.org/b/91209#c0 + const size_t namedControlsToBeRecorded = 2; + const Vector<FormAssociatedElement*>& controls = form.associatedElements(); + builder.append(" ["); + for (size_t i = 0, namedControls = 0; i < controls.size() && namedControls < namedControlsToBeRecorded; ++i) { + if (!controls[i]->isFormControlElementWithState()) + continue; + HTMLFormControlElementWithState* control = static_cast<HTMLFormControlElementWithState*>(controls[i]); + if (!ownerFormForState(*control)) + continue; + AtomicString name = control->name(); + if (name.isEmpty()) + continue; + namedControls++; + builder.append(name); + builder.append(" "); + } + builder.append("]"); +} + +static inline String formSignature(const HTMLFormElement& form) +{ + KURL actionURL = form.getURLAttribute(actionAttr); // Remove the query part because it might contain volatile parameters such // as a session key. actionURL.setQuery(String()); StringBuilder builder; if (!actionURL.isEmpty()) builder.append(actionURL.string()); - builder.append(" #"); - builder.append(String::number(index)); - return builder.toAtomicString(); + + recordFormStructure(form, builder); + return builder.toString(); } AtomicString FormKeyGenerator::formKey(const HTMLFormControlElementWithState& control) @@ -268,13 +330,18 @@ AtomicString FormKeyGenerator::formKey(const HTMLFormControlElementWithState& co if (it != m_formToKeyMap.end()) return it->second; - AtomicString candidateKey; - unsigned index = 0; - do { - candidateKey = createKey(form, index++); - } while (!m_existingKeys.add(candidateKey).isNewEntry); - m_formToKeyMap.add(form, candidateKey); - return candidateKey; + String signature = formSignature(*form); + ASSERT(!signature.isNull()); + FormSignatureToNextIndexMap::AddResult result = m_formSignatureToNextIndexMap.add(signature, 0); + unsigned nextIndex = result.iterator->second++; + + StringBuilder builder; + builder.append(signature); + builder.append(" #"); + builder.append(String::number(nextIndex)); + AtomicString formKey = builder.toAtomicString(); + m_formToKeyMap.add(form, formKey); + return formKey; } void FormKeyGenerator::willDeleteForm(HTMLFormElement* form) @@ -285,7 +352,6 @@ void FormKeyGenerator::willDeleteForm(HTMLFormElement* form) FormToKeyMap::iterator it = m_formToKeyMap.find(form); if (it == m_formToKeyMap.end()) return; - m_existingKeys.remove(it->second); m_formToKeyMap.remove(it); } @@ -304,26 +370,35 @@ static String formStateSignature() // In the legacy version of serialized state, the first item was a name // attribute value of a form control. The following string literal should // contain some characters which are rarely used for name attribute values. - DEFINE_STATIC_LOCAL(String, signature, ("\n\r?% WebKit serialized form state version 5 \n\r=&")); + DEFINE_STATIC_LOCAL(String, signature, ("\n\r?% WebKit serialized form state version 7 \n\r=&")); return signature; } -Vector<String> FormController::formElementsState() const +PassOwnPtr<FormController::SavedFormStateMap> FormController::createSavedFormStateMap(const FormElementListHashSet& controlList) { OwnPtr<FormKeyGenerator> keyGenerator = FormKeyGenerator::create(); + OwnPtr<SavedFormStateMap> stateMap = adoptPtr(new SavedFormStateMap); + for (FormElementListHashSet::const_iterator it = controlList.begin(); it != controlList.end(); ++it) { + HTMLFormControlElementWithState* control = *it; + if (!control->shouldSaveAndRestoreFormControlState()) + continue; + SavedFormStateMap::AddResult result = stateMap->add(keyGenerator->formKey(*control).impl(), nullptr); + if (result.isNewEntry) + result.iterator->second = SavedFormState::create(); + result.iterator->second->appendControlState(control->name(), control->type(), control->saveFormControlState()); + } + return stateMap.release(); +} + +Vector<String> FormController::formElementsState() const +{ + OwnPtr<SavedFormStateMap> stateMap = createSavedFormStateMap(m_formElementsWithState); Vector<String> stateVector; - stateVector.reserveInitialCapacity(m_formElementsWithState.size() * 5 + 1); + stateVector.reserveInitialCapacity(m_formElementsWithState.size() * 4); stateVector.append(formStateSignature()); - typedef FormElementListHashSet::const_iterator Iterator; - Iterator end = m_formElementsWithState.end(); - for (Iterator it = m_formElementsWithState.begin(); it != end; ++it) { - HTMLFormControlElementWithState* elementWithState = *it; - if (!elementWithState->shouldSaveAndRestoreFormControlState()) - continue; - stateVector.append(elementWithState->name().string()); - stateVector.append(elementWithState->formControlType().string()); - stateVector.append(keyGenerator->formKey(*elementWithState).string()); - elementWithState->saveFormControlState().serializeTo(stateVector); + for (SavedFormStateMap::const_iterator it = stateMap->begin(); it != stateMap->end(); ++it) { + stateVector.append(it->first.get()); + it->second->serializeTo(stateVector); } bool hasOnlySignature = stateVector.size() == 1; if (hasOnlySignature) @@ -331,11 +406,6 @@ Vector<String> FormController::formElementsState() const return stateVector; } -static bool isNotFormControlTypeCharacter(UChar ch) -{ - return ch != '-' && (ch > 'z' || ch < 'a'); -} - void FormController::setStateForNewFormElements(const Vector<String>& stateVector) { m_formElementsWithState.clear(); @@ -344,30 +414,31 @@ void FormController::setStateForNewFormElements(const Vector<String>& stateVecto if (stateVector.size() < 1 || stateVector[i++] != formStateSignature()) return; - while (i + 2 < stateVector.size()) { - AtomicString name = stateVector[i++]; - AtomicString type = stateVector[i++]; + while (i + 1 < stateVector.size()) { AtomicString formKey = stateVector[i++]; - FormControlState state = FormControlState::deserialize(stateVector, i); - if (type.isEmpty() || type.impl()->find(isNotFormControlTypeCharacter) != notFound || state.isFailure()) + OwnPtr<SavedFormState> state = SavedFormState::deserialize(stateVector, i); + if (!state) { + i = 0; break; - if (!m_savedFormState) - m_savedFormState = SavedFormState::create(); - m_savedFormState->appendControlState(name, type, formKey, state); + } + m_savedFormStateMap.add(formKey.impl(), state.release()); } if (i != stateVector.size()) - m_savedFormState.clear(); + m_savedFormStateMap.clear(); } FormControlState FormController::takeStateForFormElement(const HTMLFormControlElementWithState& control) { - if (!m_savedFormState) + if (m_savedFormStateMap.isEmpty()) return FormControlState(); if (!m_formKeyGenerator) m_formKeyGenerator = FormKeyGenerator::create(); - FormControlState state = m_savedFormState->takeControlState(control.name(), control.type(), m_formKeyGenerator->formKey(control)); - if (m_savedFormState->isEmpty()) - m_savedFormState.clear(); + SavedFormStateMap::iterator it = m_savedFormStateMap.find(m_formKeyGenerator->formKey(control).impl()); + if (it == m_savedFormStateMap.end()) + return FormControlState(); + FormControlState state = it->second->takeControlState(control.name(), control.type()); + if (it->second->isEmpty()) + m_savedFormStateMap.remove(it); return state; } diff --git a/Source/WebCore/html/FormController.h b/Source/WebCore/html/FormController.h index 2dd7b2202..5d3748d0e 100644 --- a/Source/WebCore/html/FormController.h +++ b/Source/WebCore/html/FormController.h @@ -93,15 +93,16 @@ public: void restoreControlStateIn(HTMLFormElement&); private: + typedef ListHashSet<HTMLFormControlElementWithState*, 64> FormElementListHashSet; + typedef HashMap<RefPtr<AtomicStringImpl>, OwnPtr<SavedFormState> > SavedFormStateMap; + FormController(); + static PassOwnPtr<SavedFormStateMap> createSavedFormStateMap(const FormElementListHashSet&); FormControlState takeStateForFormElement(const HTMLFormControlElementWithState&); CheckedRadioButtons m_checkedRadioButtons; - - typedef ListHashSet<HTMLFormControlElementWithState*, 64> FormElementListHashSet; FormElementListHashSet m_formElementsWithState; - - OwnPtr<SavedFormState> m_savedFormState; + SavedFormStateMap m_savedFormStateMap; OwnPtr<FormKeyGenerator> m_formKeyGenerator; }; diff --git a/Source/WebCore/html/HTMLAllCollection.cpp b/Source/WebCore/html/HTMLAllCollection.cpp index e769b2641..1dd5c15aa 100644 --- a/Source/WebCore/html/HTMLAllCollection.cpp +++ b/Source/WebCore/html/HTMLAllCollection.cpp @@ -36,7 +36,7 @@ PassRefPtr<HTMLAllCollection> HTMLAllCollection::create(Document* document) } HTMLAllCollection::HTMLAllCollection(Document* document) - : HTMLCollection(document, DocAll, SupportItemBefore) + : HTMLCollection(document, DocAll, DoesNotOverrideItemAfter) { } diff --git a/Source/WebCore/html/HTMLCollection.cpp b/Source/WebCore/html/HTMLCollection.cpp index 2b53edd98..57953ac98 100644 --- a/Source/WebCore/html/HTMLCollection.cpp +++ b/Source/WebCore/html/HTMLCollection.cpp @@ -69,7 +69,7 @@ static bool shouldOnlyIncludeDirectChildren(CollectionType type) case TSectionRows: case TableTBodies: return true; - case InvalidCollectionType: + case NodeListCollectionType: break; } ASSERT_NOT_REACHED(); @@ -104,7 +104,7 @@ static NodeListRootType rootTypeFromCollectionType(CollectionType type) case SelectedOptions: case DataListOptions: case MapAreas: - case InvalidCollectionType: + case NodeListCollectionType: return NodeListIsRootedAtNode; } ASSERT_NOT_REACHED(); @@ -144,7 +144,7 @@ static NodeListInvalidationType invalidationTypeExcludingIdAndNameAttributes(Col #endif case FormControls: return InvalidateForFormControls; - case InvalidCollectionType: + case NodeListCollectionType: break; } ASSERT_NOT_REACHED(); @@ -152,17 +152,16 @@ static NodeListInvalidationType invalidationTypeExcludingIdAndNameAttributes(Col } -HTMLCollection::HTMLCollection(Node* base, CollectionType type, ItemBeforeSupportType itemBeforeSupportType) - : HTMLCollectionCacheBase(rootTypeFromCollectionType(type), invalidationTypeExcludingIdAndNameAttributes(type), type, itemBeforeSupportType) - , m_base(base) +HTMLCollection::HTMLCollection(Node* ownerNode, CollectionType type, ItemAfterOverrideType itemAfterOverrideType) + : HTMLCollectionCacheBase(ownerNode, rootTypeFromCollectionType(type), invalidationTypeExcludingIdAndNameAttributes(type), + WebCore::shouldOnlyIncludeDirectChildren(type), type, itemAfterOverrideType) { - ASSERT(m_base); - m_base->document()->registerNodeListCache(this); + document()->registerNodeListCache(this); } PassRefPtr<HTMLCollection> HTMLCollection::create(Node* base, CollectionType type) { - return adoptRef(new HTMLCollection(base, type, SupportItemBefore)); + return adoptRef(new HTMLCollection(base, type, DoesNotOverrideItemAfter)); } HTMLCollection::~HTMLCollection() @@ -176,7 +175,7 @@ HTMLCollection::~HTMLCollection() } else // HTMLNameCollection removes cache by itself. ASSERT(type() == WindowNamedItems || type() == DocumentNamedItems); - m_base->document()->unregisterNodeListCache(this); + document()->unregisterNodeListCache(this); } static inline bool isAcceptableElement(CollectionType type, Element* element) @@ -231,7 +230,7 @@ static inline bool isAcceptableElement(CollectionType type, Element* element) case DocumentNamedItems: case TableRows: case WindowNamedItems: - case InvalidCollectionType: + case NodeListCollectionType: ASSERT_NOT_REACHED(); } return false; @@ -254,41 +253,65 @@ static inline Node* lastDescendent(Node* node) return node; } -template<bool forward> -static Element* itemBeforeOrAfter(CollectionType type, Node* base, unsigned& offsetInArray, Node* previous) +static Node* firstNode(bool forward, Node* rootNode, bool onlyIncludeDirectChildren) { - ASSERT_UNUSED(offsetInArray, !offsetInArray); - bool onlyIncludeDirectChildren = shouldOnlyIncludeDirectChildren(type); - Node* rootNode = base; - Node* current; - if (previous) - current = nextNode<forward>(rootNode, previous, onlyIncludeDirectChildren); - else { - if (forward) - current = rootNode->firstChild(); - else - current = onlyIncludeDirectChildren ? rootNode->lastChild() : lastDescendent(rootNode); - } + if (forward) + return rootNode->firstChild(); + else + return onlyIncludeDirectChildren ? rootNode->lastChild() : lastDescendent(rootNode); +} +template <bool forward> +Node* DynamicNodeListCacheBase::iterateForNextNode(Node* current) const +{ + bool onlyIncludeDirectChildren = shouldOnlyIncludeDirectChildren(); + CollectionType collectionType = type(); + Node* rootNode = this->rootNode(); for (; current; current = nextNode<forward>(rootNode, current, onlyIncludeDirectChildren)) { - if (current->isElementNode() && isAcceptableElement(type, toElement(current))) - return toElement(current); + if (collectionType == NodeListCollectionType) { + if (current->isElementNode() && static_cast<const DynamicNodeList*>(this)->nodeMatches(toElement(current))) + return toElement(current); + } else { + if (current->isElementNode() && isAcceptableElement(collectionType, toElement(current))) + return toElement(current); + } } return 0; } -Element* HTMLCollection::itemBefore(unsigned& offsetInArray, Element* previous) const +// Without this ALWAYS_INLINE, length() and item() can be 100% slower. +template<bool forward> ALWAYS_INLINE +Node* DynamicNodeListCacheBase::itemBeforeOrAfter(Node* previous) const +{ + Node* current; + if (LIKELY(!!previous)) // Without this LIKELY, length() and item() can be 10% slower. + current = nextNode<forward>(rootNode(), previous, shouldOnlyIncludeDirectChildren()); + else + current = firstNode(forward, rootNode(), previous); + + if (type() == NodeListCollectionType && shouldOnlyIncludeDirectChildren()) // ChildNodeList + return current; + + return iterateForNextNode<forward>(current); +} + +// Without this ALWAYS_INLINE, length() and item() can be 100% slower. +ALWAYS_INLINE Node* DynamicNodeListCacheBase::itemBefore(Node* previous) const { - return itemBeforeOrAfter<false>(type(), base(), offsetInArray, previous); + return itemBeforeOrAfter<false>(previous); } -Element* HTMLCollection::itemAfter(unsigned& offsetInArray, Element* previous) const +// Without this ALWAYS_INLINE, length() and item() can be 100% slower. +ALWAYS_INLINE Node* DynamicNodeListCacheBase::itemAfter(unsigned& offsetInArray, Node* previous) const { - return itemBeforeOrAfter<true>(type(), base(), offsetInArray, previous); + if (UNLIKELY(overridesItemAfter())) // Without this UNLIKELY, length() can be 100% slower. + return static_cast<const HTMLCollection*>(this)->virtualItemAfter(offsetInArray, toElement(previous)); + ASSERT(!offsetInArray); + return itemBeforeOrAfter<true>(previous); } -bool ALWAYS_INLINE HTMLCollection::isLastItemCloserThanLastOrCachedItem(unsigned offset) const +bool ALWAYS_INLINE DynamicNodeListCacheBase::isLastItemCloserThanLastOrCachedItem(unsigned offset) const { ASSERT(isLengthCacheValid()); unsigned distanceFromLastItem = cachedLength() - offset; @@ -298,7 +321,7 @@ bool ALWAYS_INLINE HTMLCollection::isLastItemCloserThanLastOrCachedItem(unsigned return cachedItemOffset() < offset && distanceFromLastItem < offset - cachedItemOffset(); } -bool ALWAYS_INLINE HTMLCollection::isFirstItemCloserThanCachedItem(unsigned offset) const +bool ALWAYS_INLINE DynamicNodeListCacheBase::isFirstItemCloserThanCachedItem(unsigned offset) const { ASSERT(isItemCacheValid()); if (cachedItemOffset() < offset) @@ -308,28 +331,33 @@ bool ALWAYS_INLINE HTMLCollection::isFirstItemCloserThanCachedItem(unsigned offs return offset < distanceFromCachedItem; } -unsigned HTMLCollection::length() const +ALWAYS_INLINE void DynamicNodeListCacheBase::setItemCache(Node* item, unsigned offset, unsigned elementsArrayOffset) const +{ + setItemCache(item, offset); + if (overridesItemAfter()) { + ASSERT(item->isElementNode()); + static_cast<const HTMLCollectionCacheBase*>(this)->m_cachedElementsArrayOffset = elementsArrayOffset; + } else + ASSERT(!elementsArrayOffset); +} + +ALWAYS_INLINE unsigned DynamicNodeListCacheBase::cachedElementsArrayOffset() const +{ + return overridesItemAfter() ? static_cast<const HTMLCollectionCacheBase*>(this)->m_cachedElementsArrayOffset : 0; +} + +unsigned DynamicNodeListCacheBase::lengthCommon() const { if (isLengthCacheValid()) return cachedLength(); - if (!isItemCacheValid() && !item(0)) { - ASSERT(isLengthCacheValid()); - return 0; - } - - ASSERT(isItemCacheValid()); - ASSERT(cachedItem()); - unsigned offset = cachedItemOffset(); - do { - offset++; - } while (itemBeforeOrAfterCachedItem(offset)); + itemCommon(UINT_MAX); ASSERT(isLengthCacheValid()); - - return offset; + + return cachedLength(); } -Node* HTMLCollection::item(unsigned offset) const +Node* DynamicNodeListCacheBase::itemCommon(unsigned offset) const { if (isItemCacheValid() && cachedItemOffset() == offset) return cachedItem(); @@ -342,14 +370,11 @@ Node* HTMLCollection::item(unsigned offset) const static_cast<const HTMLPropertiesCollection*>(this)->updateRefElements(); #endif - if (isLengthCacheValid() && supportsItemBefore() && isLastItemCloserThanLastOrCachedItem(offset)) { - // FIXME: Need to figure out the last offset in array for HTMLFormCollection and HTMLPropertiesCollection - unsigned unusedOffsetInArray = 0; - Node* lastItem = itemBefore(unusedOffsetInArray, 0); - ASSERT(!unusedOffsetInArray); + if (isLengthCacheValid() && !overridesItemAfter() && isLastItemCloserThanLastOrCachedItem(offset)) { + Node* lastItem = itemBefore(0); ASSERT(lastItem); setItemCache(lastItem, cachedLength() - 1, 0); - } else if (!isItemCacheValid() || isFirstItemCloserThanCachedItem(offset) || (!supportsItemBefore() && offset < cachedItemOffset())) { + } else if (!isItemCacheValid() || isFirstItemCloserThanCachedItem(offset) || (overridesItemAfter() && offset < cachedItemOffset())) { unsigned offsetInArray = 0; Node* firstItem = itemAfter(offsetInArray, 0); if (!firstItem) { @@ -366,22 +391,19 @@ Node* HTMLCollection::item(unsigned offset) const return itemBeforeOrAfterCachedItem(offset); } -Element* HTMLCollection::itemBeforeOrAfterCachedItem(unsigned offset) const +Node* DynamicNodeListCacheBase::itemBeforeOrAfterCachedItem(unsigned offset) const { unsigned currentOffset = cachedItemOffset(); - ASSERT(cachedItem()->isElementNode()); - Element* currentItem = toElement(cachedItem()); + Node* currentItem = cachedItem(); ASSERT(currentOffset != offset); - unsigned offsetInArray = cachedElementsArrayOffset(); - if (offset < cachedItemOffset()) { - ASSERT(supportsItemBefore()); - while ((currentItem = itemBefore(offsetInArray, currentItem))) { + ASSERT(!overridesItemAfter()); + while ((currentItem = itemBefore(currentItem))) { ASSERT(currentOffset); currentOffset--; if (currentOffset == offset) { - setItemCache(currentItem, currentOffset, offsetInArray); + setItemCache(currentItem, currentOffset, 0); return currentItem; } } @@ -389,6 +411,7 @@ Element* HTMLCollection::itemBeforeOrAfterCachedItem(unsigned offset) const return 0; } + unsigned offsetInArray = cachedElementsArrayOffset(); while ((currentItem = itemAfter(offsetInArray, currentItem))) { currentOffset++; if (currentOffset == offset) { @@ -403,6 +426,12 @@ Element* HTMLCollection::itemBeforeOrAfterCachedItem(unsigned offset) const return 0; } +Element* HTMLCollection::virtualItemAfter(unsigned&, Element*) const +{ + ASSERT_NOT_REACHED(); + return 0; +} + static inline bool nameShouldBeVisibleInDocumentAll(HTMLElement* element) { // The document.all collection returns only certain types of elements by name, @@ -441,8 +470,8 @@ Node* HTMLCollection::namedItem(const AtomicString& name) const unsigned arrayOffset = 0; unsigned i = 0; - for (Element* e = itemAfter(arrayOffset, 0); e; e = itemAfter(arrayOffset, e)) { - if (checkForNameMatch(e, /* checkName */ false, name)) { + for (Node* e = itemAfter(arrayOffset, 0); e; e = itemAfter(arrayOffset, e)) { + if (checkForNameMatch(toElement(e), /* checkName */ false, name)) { setItemCache(e, i, arrayOffset); return e; } @@ -450,10 +479,10 @@ Node* HTMLCollection::namedItem(const AtomicString& name) const } i = 0; - for (Element* e = itemAfter(arrayOffset, 0); e; e = itemAfter(arrayOffset, e)) { - if (checkForNameMatch(e, /* checkName */ true, name)) { + for (Node* e = itemAfter(arrayOffset, 0); e; e = itemAfter(arrayOffset, e)) { + if (checkForNameMatch(toElement(e), /* checkName */ true, name)) { setItemCache(e, i, arrayOffset); - return e; + return toElement(e); } i++; } @@ -467,10 +496,10 @@ void HTMLCollection::updateNameCache() const return; unsigned arrayOffset = 0; - for (Element* element = itemAfter(arrayOffset, 0); element; element = itemAfter(arrayOffset, element)) { - if (!element->isHTMLElement()) + for (Node* node = itemAfter(arrayOffset, 0); node; node = itemAfter(arrayOffset, node)) { + if (!node->isHTMLElement()) continue; - HTMLElement* e = toHTMLElement(element); + HTMLElement* e = toHTMLElement(node); const AtomicString& idAttrVal = e->getIdAttribute(); const AtomicString& nameAttrVal = e->getNameAttribute(); if (!idAttrVal.isEmpty()) @@ -522,7 +551,7 @@ void HTMLCollection::namedItems(const AtomicString& name, Vector<RefPtr<Node> >& PassRefPtr<NodeList> HTMLCollection::tags(const String& name) { - return m_base->getElementsByTagName(name); + return ownerNode()->getElementsByTagName(name); } void HTMLCollectionCacheBase::append(NodeCacheMap& map, const AtomicString& key, Element* element) diff --git a/Source/WebCore/html/HTMLCollection.h b/Source/WebCore/html/HTMLCollection.h index 6343e8edf..833618373 100644 --- a/Source/WebCore/html/HTMLCollection.h +++ b/Source/WebCore/html/HTMLCollection.h @@ -39,20 +39,13 @@ class NodeList; class HTMLCollectionCacheBase : public DynamicNodeListCacheBase { public: - HTMLCollectionCacheBase(NodeListRootType rootType, NodeListInvalidationType invalidationType, CollectionType collectionType, ItemBeforeSupportType itemBeforeSupportType) - : DynamicNodeListCacheBase(rootType, invalidationType, collectionType, itemBeforeSupportType) - , m_cachedElementsArrayOffset(0) + HTMLCollectionCacheBase(Node* ownerNode, NodeListRootType rootType, NodeListInvalidationType invalidationType, + bool shouldOnlyIncludeDirectChildren, CollectionType collectionType, ItemAfterOverrideType itemAfterOverrideType) + : DynamicNodeListCacheBase(ownerNode, rootType, invalidationType, shouldOnlyIncludeDirectChildren, collectionType, itemAfterOverrideType) { } protected: - void setItemCache(Node* item, unsigned offset, unsigned elementsArrayOffset) const - { - setItemCache(item, offset); - m_cachedElementsArrayOffset = elementsArrayOffset; - } - unsigned cachedElementsArrayOffset() const { return m_cachedElementsArrayOffset; } - typedef HashMap<AtomicStringImpl*, OwnPtr<Vector<Element*> > > NodeCacheMap; Vector<Element*>* idCache(const AtomicString& name) const { return m_idCache.get(name.impl()); } Vector<Element*>* nameCache(const AtomicString& name) const { return m_nameCache.get(name.impl()); } @@ -63,13 +56,12 @@ protected: private: using DynamicNodeListCacheBase::isRootedAtDocument; - using DynamicNodeListCacheBase::setItemCache; mutable NodeCacheMap m_idCache; mutable NodeCacheMap m_nameCache; mutable unsigned m_cachedElementsArrayOffset; - friend void DynamicNodeListCacheBase::invalidateCache() const; + friend class DynamicNodeListCacheBase; }; class HTMLCollection : public RefCounted<HTMLCollection>, public HTMLCollectionCacheBase { @@ -78,8 +70,8 @@ public: virtual ~HTMLCollection(); // DOM API - unsigned length() const; - Node* item(unsigned index) const; + unsigned length() const { return lengthCommon(); } + Node* item(unsigned offset) const { return itemCommon(offset); } virtual Node* namedItem(const AtomicString& name) const; PassRefPtr<NodeList> tags(const String&); @@ -103,23 +95,16 @@ public: return item(0) && !item(1); } - Node* base() const { return m_base.get(); } + Node* base() const { return ownerNode(); } + virtual Element* virtualItemAfter(unsigned& offsetInArray, Element*) const; protected: - HTMLCollection(Node* base, CollectionType, ItemBeforeSupportType); + HTMLCollection(Node* base, CollectionType, ItemAfterOverrideType); virtual void updateNameCache() const; - virtual Element* itemAfter(unsigned& offsetInArray, Element*) const; private: bool checkForNameMatch(Element*, bool checkName, const AtomicString& name) const; - - Element* itemBefore(unsigned& offsetInArray, Element*) const; - bool isLastItemCloserThanLastOrCachedItem(unsigned offset) const; - bool isFirstItemCloserThanCachedItem(unsigned offset) const; - Element* itemBeforeOrAfterCachedItem(unsigned offset) const; - - RefPtr<Node> m_base; }; } // namespace diff --git a/Source/WebCore/html/HTMLDataListElement.cpp b/Source/WebCore/html/HTMLDataListElement.cpp index ed842eecc..d6dcb28d7 100644 --- a/Source/WebCore/html/HTMLDataListElement.cpp +++ b/Source/WebCore/html/HTMLDataListElement.cpp @@ -30,10 +30,11 @@ */ #include "config.h" -#if ENABLE(DATALIST) #include "HTMLDataListElement.h" +#if ENABLE(DATALIST_ELEMENT) #include "HTMLNames.h" +#include "IdTargetObserverRegistry.h" namespace WebCore { @@ -52,5 +53,10 @@ PassRefPtr<HTMLCollection> HTMLDataListElement::options() return ensureCachedHTMLCollection(DataListOptions); } -} // namespace WebCore -#endif // ENABLE(DATALIST) +void HTMLDataListElement::optionElementChildrenChanged() +{ + treeScope()->idTargetObserverRegistry().notifyObservers(getIdAttribute()); +} + +} // namespace WebCore +#endif // ENABLE(DATALIST_ELEMENT) diff --git a/Source/WebCore/html/HTMLDataListElement.h b/Source/WebCore/html/HTMLDataListElement.h index 9129f295e..3572643cb 100644 --- a/Source/WebCore/html/HTMLDataListElement.h +++ b/Source/WebCore/html/HTMLDataListElement.h @@ -32,8 +32,7 @@ #ifndef HTMLDataListElement_h #define HTMLDataListElement_h -#if ENABLE(DATALIST) - +#if ENABLE(DATALIST_ELEMENT) #include "HTMLCollection.h" #include "HTMLElement.h" @@ -45,11 +44,13 @@ public: PassRefPtr<HTMLCollection> options(); + void optionElementChildrenChanged(); + private: HTMLDataListElement(const QualifiedName&, Document*); }; -} // namespace WebCore -#endif // ENABLE(DATALIST) +} // namespace WebCore +#endif // ENABLE(DATALIST_ELEMENT) -#endif // HTMLDataListElement_h +#endif // HTMLDataListElement_h diff --git a/Source/WebCore/html/HTMLDataListElement.idl b/Source/WebCore/html/HTMLDataListElement.idl index 1f38105f8..7e0d69c96 100644 --- a/Source/WebCore/html/HTMLDataListElement.idl +++ b/Source/WebCore/html/HTMLDataListElement.idl @@ -30,7 +30,7 @@ module html { interface [ - Conditional=DATALIST, + Conditional=DATALIST_ELEMENT, ] HTMLDataListElement : HTMLElement { readonly attribute HTMLCollection options; }; diff --git a/Source/WebCore/html/HTMLDetailsElement.cpp b/Source/WebCore/html/HTMLDetailsElement.cpp index 531bd3306..86a7b48ca 100644 --- a/Source/WebCore/html/HTMLDetailsElement.cpp +++ b/Source/WebCore/html/HTMLDetailsElement.cpp @@ -21,8 +21,7 @@ #include "config.h" #include "HTMLDetailsElement.h" -#if ENABLE(DETAILS) - +#if ENABLE(DETAILS_ELEMENT) #include "ElementShadow.h" #include "HTMLContentElement.h" #include "HTMLNames.h" @@ -124,7 +123,7 @@ Element* HTMLDetailsElement::findMainSummary() const return toElement(child); } - return static_cast<DetailsSummaryElement*>(shadow()->oldestShadowRoot()->firstChild())->fallbackSummary(); + return static_cast<DetailsSummaryElement*>(userAgentShadowRoot()->firstChild())->fallbackSummary(); } void HTMLDetailsElement::parseAttribute(const Attribute& attribute) diff --git a/Source/WebCore/html/HTMLDetailsElement.idl b/Source/WebCore/html/HTMLDetailsElement.idl index 5ad9508c9..087f083ff 100644 --- a/Source/WebCore/html/HTMLDetailsElement.idl +++ b/Source/WebCore/html/HTMLDetailsElement.idl @@ -18,8 +18,9 @@ */ module html { - - interface HTMLDetailsElement : HTMLElement { + interface [ + Conditional=DETAILS_ELEMENT + ] HTMLDetailsElement : HTMLElement { attribute [Reflect] boolean open; }; diff --git a/Source/WebCore/html/HTMLDialogElement.cpp b/Source/WebCore/html/HTMLDialogElement.cpp index bd630ef67..4510d8143 100644 --- a/Source/WebCore/html/HTMLDialogElement.cpp +++ b/Source/WebCore/html/HTMLDialogElement.cpp @@ -28,6 +28,8 @@ #if ENABLE(DIALOG_ELEMENT) +#include "ExceptionCode.h" + namespace WebCore { using namespace HTMLNames; @@ -43,14 +45,30 @@ PassRefPtr<HTMLDialogElement> HTMLDialogElement::create(const QualifiedName& tag return adoptRef(new HTMLDialogElement(tagName, document)); } -void HTMLDialogElement::close() +void HTMLDialogElement::close(ExceptionCode& ec) { - // FIXME: Implement. + if (!fastHasAttribute(openAttr)) { + ec = INVALID_STATE_ERR; + return; + } + setBooleanAttribute(openAttr, false); } void HTMLDialogElement::show() { - // FIXME: Implement. + if (fastHasAttribute(openAttr)) + return; + setBooleanAttribute(openAttr, true); +} + +bool HTMLDialogElement::isPresentationAttribute(const QualifiedName& name) const +{ + // FIXME: Workaround for <https://bugs.webkit.org/show_bug.cgi?id=91058>: modifying an attribute for which there is an attribute selector + // in html.css sometimes does not trigger a style recalc. + if (name == openAttr) + return true; + + return HTMLElement::isPresentationAttribute(name); } } diff --git a/Source/WebCore/html/HTMLDialogElement.h b/Source/WebCore/html/HTMLDialogElement.h index cc5c2db0b..d1dd77689 100644 --- a/Source/WebCore/html/HTMLDialogElement.h +++ b/Source/WebCore/html/HTMLDialogElement.h @@ -39,11 +39,13 @@ class HTMLDialogElement : public HTMLElement { public: static PassRefPtr<HTMLDialogElement> create(const QualifiedName&, Document*); - void close(); + void close(ExceptionCode&); void show(); private: HTMLDialogElement(const QualifiedName&, Document*); + + virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE; }; } // namespace WebCore diff --git a/Source/WebCore/html/HTMLDialogElement.idl b/Source/WebCore/html/HTMLDialogElement.idl index e5d6479ba..442f93fd8 100644 --- a/Source/WebCore/html/HTMLDialogElement.idl +++ b/Source/WebCore/html/HTMLDialogElement.idl @@ -29,7 +29,7 @@ module html { Conditional=DIALOG_ELEMENT ] HTMLDialogElement : HTMLElement { attribute [Reflect] boolean open; - void close(); + void close() raises(DOMException); void show(); }; diff --git a/Source/WebCore/html/HTMLFormCollection.cpp b/Source/WebCore/html/HTMLFormCollection.cpp index b845f0c6f..a5cc6ac4a 100644 --- a/Source/WebCore/html/HTMLFormCollection.cpp +++ b/Source/WebCore/html/HTMLFormCollection.cpp @@ -37,7 +37,7 @@ using namespace HTMLNames; // calculation every time if anything has changed. HTMLFormCollection::HTMLFormCollection(Element* base) - : HTMLCollection(base, FormControls, DoNotSupportItemBefore) + : HTMLCollection(base, FormControls, OverridesItemAfter) { ASSERT(base->hasTagName(formTag) || base->hasTagName(fieldsetTag)); } @@ -67,7 +67,7 @@ const Vector<HTMLImageElement*>& HTMLFormCollection::formImageElements() const return static_cast<HTMLFormElement*>(base())->imageElements(); } -Element* HTMLFormCollection::itemAfter(unsigned& offset, Element* previousItem) const +Element* HTMLFormCollection::virtualItemAfter(unsigned& offset, Element* previousItem) const { const Vector<FormAssociatedElement*>& elementsArray = formControlElements(); if (previousItem) diff --git a/Source/WebCore/html/HTMLFormCollection.h b/Source/WebCore/html/HTMLFormCollection.h index 82cbfed15..978a26f8f 100644 --- a/Source/WebCore/html/HTMLFormCollection.h +++ b/Source/WebCore/html/HTMLFormCollection.h @@ -49,7 +49,7 @@ private: const Vector<FormAssociatedElement*>& formControlElements() const; const Vector<HTMLImageElement*>& formImageElements() const; - virtual Element* itemAfter(unsigned& offsetInArray, Element*) const OVERRIDE; + virtual Element* virtualItemAfter(unsigned& offsetInArray, Element*) const OVERRIDE; }; } //namespace diff --git a/Source/WebCore/html/HTMLFrameElementBase.cpp b/Source/WebCore/html/HTMLFrameElementBase.cpp index 16cf36051..d12e7b434 100644 --- a/Source/WebCore/html/HTMLFrameElementBase.cpp +++ b/Source/WebCore/html/HTMLFrameElementBase.cpp @@ -246,11 +246,4 @@ int HTMLFrameElementBase::height() return renderBox()->height(); } -#if ENABLE(FULLSCREEN_API) -bool HTMLFrameElementBase::allowFullScreen() const -{ - return hasAttribute(webkitallowfullscreenAttr); -} -#endif - } // namespace WebCore diff --git a/Source/WebCore/html/HTMLFrameElementBase.h b/Source/WebCore/html/HTMLFrameElementBase.h index 11dc94d3d..0f84df36e 100644 --- a/Source/WebCore/html/HTMLFrameElementBase.h +++ b/Source/WebCore/html/HTMLFrameElementBase.h @@ -42,10 +42,6 @@ public: int width(); int height(); -#if ENABLE(FULLSCREEN_API) - virtual bool allowFullScreen() const; -#endif - virtual bool canContainRangeEndPoint() const { return false; } protected: diff --git a/Source/WebCore/html/HTMLImageElement.cpp b/Source/WebCore/html/HTMLImageElement.cpp index 2992b6a17..e3138e6e0 100644 --- a/Source/WebCore/html/HTMLImageElement.cpp +++ b/Source/WebCore/html/HTMLImageElement.cpp @@ -96,7 +96,7 @@ HTMLImageElement::~HTMLImageElement() void HTMLImageElement::willAddAuthorShadowRoot() { - if (shadow()->oldestShadowRoot()) + if (userAgentShadowRoot()) return; createShadowSubtree(); @@ -112,9 +112,9 @@ void HTMLImageElement::createShadowSubtree() Element* HTMLImageElement::imageElement() { - if (ElementShadow* elementShadow = shadow()) { - ASSERT(elementShadow->oldestShadowRoot()->firstChild()->hasTagName(webkitInnerImageTag)); - return toElement(elementShadow->oldestShadowRoot()->firstChild()); + if (ShadowRoot* root = userAgentShadowRoot()) { + ASSERT(root->firstChild()->hasTagName(webkitInnerImageTag)); + return toElement(root->firstChild()); } return this; @@ -409,8 +409,8 @@ void HTMLImageElement::setItemValueText(const String& value, ExceptionCode&) inline ImageInnerElement* HTMLImageElement::innerElement() const { - ASSERT(shadow()); - return toImageInnerElement(shadow()->oldestShadowRoot()->firstChild()); + ASSERT(userAgentShadowRoot()); + return toImageInnerElement(userAgentShadowRoot()->firstChild()); } } diff --git a/Source/WebCore/html/HTMLImageLoader.cpp b/Source/WebCore/html/HTMLImageLoader.cpp index e69c3e091..46a652780 100644 --- a/Source/WebCore/html/HTMLImageLoader.cpp +++ b/Source/WebCore/html/HTMLImageLoader.cpp @@ -74,13 +74,13 @@ void HTMLImageLoader::notifyFinished(CachedResource*) { CachedImage* cachedImage = image(); - Element* elem = client()->sourceElement(); + RefPtr<Element> element = client()->sourceElement(); ImageLoader::notifyFinished(cachedImage); bool loadError = cachedImage->errorOccurred() || cachedImage->response().httpStatusCode() >= 400; #if USE(JSC) if (!loadError) { - if (!elem->inDocument()) { + if (!element->inDocument()) { JSC::JSGlobalData* globalData = JSDOMWindowBase::commonJSGlobalData(); JSC::JSLockHolder lock(globalData); globalData->heap.reportExtraMemoryCost(cachedImage->encodedSize()); @@ -88,8 +88,8 @@ void HTMLImageLoader::notifyFinished(CachedResource*) } #endif - if (loadError && elem->hasTagName(HTMLNames::objectTag)) - static_cast<HTMLObjectElement*>(elem)->renderFallbackContent(); + if (loadError && element->hasTagName(HTMLNames::objectTag)) + static_cast<HTMLObjectElement*>(element.get())->renderFallbackContent(); } } diff --git a/Source/WebCore/html/HTMLInputElement.cpp b/Source/WebCore/html/HTMLInputElement.cpp index 77ea42567..407c1233b 100644 --- a/Source/WebCore/html/HTMLInputElement.cpp +++ b/Source/WebCore/html/HTMLInputElement.cpp @@ -45,6 +45,7 @@ #include "HTMLNames.h" #include "HTMLOptionElement.h" #include "HTMLParserIdioms.h" +#include "IdTargetObserver.h" #include "InputType.h" #include "KeyboardEvent.h" #include "LocalizedStrings.h" @@ -77,6 +78,19 @@ namespace WebCore { using namespace HTMLNames; +#if ENABLE(DATALIST_ELEMENT) +class ListAttributeTargetObserver : IdTargetObserver { +public: + static PassOwnPtr<ListAttributeTargetObserver> create(const AtomicString& id, HTMLInputElement*); + virtual void idTargetChanged() OVERRIDE; + +private: + ListAttributeTargetObserver(const AtomicString& id, HTMLInputElement*); + + HTMLInputElement* m_element; +}; +#endif + // FIXME: According to HTML4, the length attribute's value can be arbitrarily // large. However, due to https://bugs.webkit.org/show_bug.cgi?id=14536 things // get rather sluggish when a text field has a larger number of characters than @@ -183,6 +197,11 @@ HTMLElement* HTMLInputElement::speechButtonElement() const } #endif +HTMLElement* HTMLInputElement::sliderThumbElement() const +{ + return m_inputType->sliderThumbElement(); +} + HTMLElement* HTMLInputElement::placeholderElement() const { return m_inputType->placeholderElement(); @@ -678,10 +697,14 @@ void HTMLInputElement::parseAttribute(const Attribute& attribute) HTMLTextFormControlElement::parseAttribute(attribute); m_inputType->readonlyAttributeChanged(); } -#if ENABLE(DATALIST) - else if (attribute.name() == listAttr) +#if ENABLE(DATALIST_ELEMENT) + else if (attribute.name() == listAttr) { m_hasNonEmptyList = !attribute.isEmpty(); - // FIXME: we need to tell this change to a renderer if the attribute affects the appearance. + if (m_hasNonEmptyList) { + resetListAttributeTargetObserver(); + listAttributeTargetChanged(); + } + } #endif #if ENABLE(INPUT_SPEECH) else if (attribute.name() == webkitspeechAttr) { @@ -1412,6 +1435,9 @@ Node::InsertionNotificationRequest HTMLInputElement::insertedInto(ContainerNode* HTMLTextFormControlElement::insertedInto(insertionPoint); if (insertionPoint->inDocument() && !form()) addToRadioButtonGroup(); +#if ENABLE(DATALIST_ELEMENT) + resetListAttributeTargetObserver(); +#endif return InsertionDone; } @@ -1420,6 +1446,10 @@ void HTMLInputElement::removedFrom(ContainerNode* insertionPoint) if (insertionPoint->inDocument() && !form()) removeFromRadioButtonGroup(); HTMLTextFormControlElement::removedFrom(insertionPoint); + ASSERT(!inDocument()); +#if ENABLE(DATALIST_ELEMENT) + resetListAttributeTargetObserver(); +#endif } void HTMLInputElement::didMoveToNewDocument(Document* oldDocument) @@ -1468,8 +1498,7 @@ void HTMLInputElement::selectColorInColorChooser(const Color& color) } #endif -#if ENABLE(DATALIST) - +#if ENABLE(DATALIST_ELEMENT) HTMLElement* HTMLInputElement::list() const { return dataList(); @@ -1492,7 +1521,19 @@ HTMLDataListElement* HTMLInputElement::dataList() const return static_cast<HTMLDataListElement*>(element); } -#endif // ENABLE(DATALIST) +void HTMLInputElement::resetListAttributeTargetObserver() +{ + if (inDocument()) + m_listAttributeTargetObserver = ListAttributeTargetObserver::create(fastGetAttribute(listAttr), this); + else + m_listAttributeTargetObserver = nullptr; +} + +void HTMLInputElement::listAttributeTargetChanged() +{ + m_inputType->listAttributeTargetChanged(); +} +#endif // ENABLE(DATALIST_ELEMENT) bool HTMLInputElement::isSteppable() const { @@ -1760,4 +1801,22 @@ void HTMLInputElement::setWidth(unsigned width) setAttribute(widthAttr, String::number(width)); } +#if ENABLE(DATALIST_ELEMENT) +PassOwnPtr<ListAttributeTargetObserver> ListAttributeTargetObserver::create(const AtomicString& id, HTMLInputElement* element) +{ + return adoptPtr(new ListAttributeTargetObserver(id, element)); +} + +ListAttributeTargetObserver::ListAttributeTargetObserver(const AtomicString& id, HTMLInputElement* element) + : IdTargetObserver(element->treeScope()->idTargetObserverRegistry(), id) + , m_element(element) +{ +} + +void ListAttributeTargetObserver::idTargetChanged() +{ + m_element->listAttributeTargetChanged(); +} +#endif + } // namespace diff --git a/Source/WebCore/html/HTMLInputElement.h b/Source/WebCore/html/HTMLInputElement.h index 2fd43d863..3fd66c9e4 100644 --- a/Source/WebCore/html/HTMLInputElement.h +++ b/Source/WebCore/html/HTMLInputElement.h @@ -39,6 +39,7 @@ class HTMLOptionElement; class Icon; class InputType; class KURL; +class ListAttributeTargetObserver; class HTMLInputElement : public HTMLTextFormControlElement, public ImageLoaderClientBase<HTMLInputElement> { public: @@ -122,6 +123,7 @@ public: #if ENABLE(INPUT_SPEECH) HTMLElement* speechButtonElement() const; #endif + HTMLElement* sliderThumbElement() const; virtual HTMLElement* placeholderElement() const; bool checked() const { return m_isChecked; } @@ -232,8 +234,9 @@ public: void addSearchResult(); void onSearch(); -#if ENABLE(DATALIST) +#if ENABLE(DATALIST_ELEMENT) HTMLElement* list() const; + void listAttributeTargetChanged(); #endif HTMLInputElement* checkedRadioButtonForGroup() const; @@ -359,9 +362,9 @@ private: virtual void subtreeHasChanged(); - -#if ENABLE(DATALIST) +#if ENABLE(DATALIST_ELEMENT) HTMLDataListElement* dataList() const; + void resetListAttributeTargetObserver(); #endif void parseMaxLengthAttribute(const Attribute&); void updateValueIfNeeded(); @@ -384,7 +387,7 @@ private: bool m_isActivatedSubmit : 1; unsigned m_autocomplete : 2; // AutoCompleteSetting bool m_isAutofilled : 1; -#if ENABLE(DATALIST) +#if ENABLE(DATALIST_ELEMENT) bool m_hasNonEmptyList : 1; #endif bool m_stateRestored : 1; @@ -394,6 +397,9 @@ private: bool m_canReceiveDroppedFiles : 1; bool m_hasTouchEventHandler: 1; OwnPtr<InputType> m_inputType; +#if ENABLE(DATALIST_ELEMENT) + OwnPtr<ListAttributeTargetObserver> m_listAttributeTargetObserver; +#endif }; } //namespace diff --git a/Source/WebCore/html/HTMLInputElement.idl b/Source/WebCore/html/HTMLInputElement.idl index e326ce7be..879a34f57 100644 --- a/Source/WebCore/html/HTMLInputElement.idl +++ b/Source/WebCore/html/HTMLInputElement.idl @@ -39,7 +39,7 @@ module html { attribute [Reflect] DOMString formTarget; attribute unsigned long height; attribute boolean indeterminate; - readonly attribute [Conditional=DATALIST] HTMLElement list; + readonly attribute [Conditional=DATALIST_ELEMENT] HTMLElement list; attribute [Reflect] DOMString max; attribute long maxLength setter raises(DOMException); attribute [Reflect] DOMString min; diff --git a/Source/WebCore/html/HTMLKeygenElement.cpp b/Source/WebCore/html/HTMLKeygenElement.cpp index a1b032e06..cfe2d8e49 100644 --- a/Source/WebCore/html/HTMLKeygenElement.cpp +++ b/Source/WebCore/html/HTMLKeygenElement.cpp @@ -136,7 +136,7 @@ bool HTMLKeygenElement::shouldSaveAndRestoreFormControlState() const HTMLSelectElement* HTMLKeygenElement::shadowSelect() const { - ShadowRoot* root = this->shadow()->oldestShadowRoot(); + ShadowRoot* root = userAgentShadowRoot(); return root ? toHTMLSelectElement(root->firstChild()) : 0; } diff --git a/Source/WebCore/html/HTMLMediaElement.cpp b/Source/WebCore/html/HTMLMediaElement.cpp index 705a05c5f..f16271bcd 100644 --- a/Source/WebCore/html/HTMLMediaElement.cpp +++ b/Source/WebCore/html/HTMLMediaElement.cpp @@ -1862,20 +1862,14 @@ void HTMLMediaElement::progressEventTimerFired(Timer<HTMLMediaElement>*) void HTMLMediaElement::createShadowSubtree() { - ASSERT(!shadow() || !shadow()->oldestShadowRoot()); - + ASSERT(!userAgentShadowRoot()); ShadowRoot::create(this, ShadowRoot::UserAgentShadowRoot); } void HTMLMediaElement::willAddAuthorShadowRoot() { - ASSERT(shadow()); - if (shadow()->oldestShadowRoot()) { - ASSERT(shadow()->oldestShadowRoot()->type() == ShadowRoot::UserAgentShadowRoot); - return; - } - - createShadowSubtree(); + if (!userAgentShadowRoot()) + createShadowSubtree(); } void HTMLMediaElement::rewind(float timeDelta) @@ -4180,17 +4174,18 @@ void HTMLMediaElement::privateBrowsingStateDidChange() MediaControls* HTMLMediaElement::mediaControls() const { - return toMediaControls(shadow()->oldestShadowRoot()->firstChild()); + return toMediaControls(userAgentShadowRoot()->firstChild()); } bool HTMLMediaElement::hasMediaControls() const { - ElementShadow* elementShadow = shadow(); - if (!elementShadow) - return false; + if (ShadowRoot* userAgent = userAgentShadowRoot()) { + Node* node = userAgent->firstChild(); + ASSERT(!node || node->isMediaControls()); + return node; + } - Node* node = elementShadow->oldestShadowRoot()->firstChild(); - return node && node->isMediaControls(); + return false; } bool HTMLMediaElement::createMediaControls() @@ -4211,8 +4206,8 @@ bool HTMLMediaElement::createMediaControls() if (!shadow()) createShadowSubtree(); - ASSERT(shadow()->oldestShadowRoot()->type() == ShadowRoot::UserAgentShadowRoot); - shadow()->oldestShadowRoot()->appendChild(controls, ec); + ASSERT(userAgentShadowRoot()); + userAgentShadowRoot()->appendChild(controls, ec); return true; } diff --git a/Source/WebCore/html/HTMLMeterElement.cpp b/Source/WebCore/html/HTMLMeterElement.cpp index 13dea1513..290de5b07 100644 --- a/Source/WebCore/html/HTMLMeterElement.cpp +++ b/Source/WebCore/html/HTMLMeterElement.cpp @@ -19,9 +19,9 @@ */ #include "config.h" -#if ENABLE(METER_TAG) #include "HTMLMeterElement.h" +#if ENABLE(METER_ELEMENT) #include "Attribute.h" #include "EventNames.h" #include "ExceptionCode.h" diff --git a/Source/WebCore/html/HTMLMeterElement.h b/Source/WebCore/html/HTMLMeterElement.h index bca0be6e6..188309157 100644 --- a/Source/WebCore/html/HTMLMeterElement.h +++ b/Source/WebCore/html/HTMLMeterElement.h @@ -21,7 +21,7 @@ #ifndef HTMLMeterElement_h #define HTMLMeterElement_h -#if ENABLE(METER_TAG) +#if ENABLE(METER_ELEMENT) #include "LabelableElement.h" namespace WebCore { diff --git a/Source/WebCore/html/HTMLMeterElement.idl b/Source/WebCore/html/HTMLMeterElement.idl index 7c11fe4ce..8d3e1074c 100644 --- a/Source/WebCore/html/HTMLMeterElement.idl +++ b/Source/WebCore/html/HTMLMeterElement.idl @@ -19,7 +19,7 @@ module html { interface [ - Conditional=METER_TAG + Conditional=METER_ELEMENT ] HTMLMeterElement : HTMLElement { attribute double value setter raises(DOMException); diff --git a/Source/WebCore/html/HTMLNameCollection.cpp b/Source/WebCore/html/HTMLNameCollection.cpp index 246235d07..36c7350a4 100644 --- a/Source/WebCore/html/HTMLNameCollection.cpp +++ b/Source/WebCore/html/HTMLNameCollection.cpp @@ -33,7 +33,7 @@ namespace WebCore { using namespace HTMLNames; HTMLNameCollection::HTMLNameCollection(Document* document, CollectionType type, const AtomicString& name) - : HTMLCollection(document, type, DoNotSupportItemBefore) + : HTMLCollection(document, type, OverridesItemAfter) , m_name(name) { } @@ -49,7 +49,7 @@ HTMLNameCollection::~HTMLNameCollection() static_cast<Document*>(base())->removeDocumentNamedItemCache(this, m_name); } -Element* HTMLNameCollection::itemAfter(unsigned& offsetInArray, Element* previous) const +Element* HTMLNameCollection::virtualItemAfter(unsigned& offsetInArray, Element* previous) const { ASSERT_UNUSED(offsetInArray, !offsetInArray); ASSERT(previous != base()); diff --git a/Source/WebCore/html/HTMLNameCollection.h b/Source/WebCore/html/HTMLNameCollection.h index dd9d45d9d..4a7afebb7 100644 --- a/Source/WebCore/html/HTMLNameCollection.h +++ b/Source/WebCore/html/HTMLNameCollection.h @@ -43,7 +43,7 @@ public: private: HTMLNameCollection(Document*, CollectionType, const AtomicString& name); - virtual Element* itemAfter(unsigned& offsetInArray, Element*) const OVERRIDE; + virtual Element* virtualItemAfter(unsigned& offsetInArray, Element*) const OVERRIDE; AtomicString m_name; }; diff --git a/Source/WebCore/html/HTMLOptionElement.cpp b/Source/WebCore/html/HTMLOptionElement.cpp index 3691e8241..bb68a9d32 100644 --- a/Source/WebCore/html/HTMLOptionElement.cpp +++ b/Source/WebCore/html/HTMLOptionElement.cpp @@ -30,6 +30,7 @@ #include "Attribute.h" #include "Document.h" #include "ExceptionCode.h" +#include "HTMLDataListElement.h" #include "HTMLNames.h" #include "HTMLParserIdioms.h" #include "HTMLSelectElement.h" @@ -187,6 +188,12 @@ int HTMLOptionElement::index() const void HTMLOptionElement::parseAttribute(const Attribute& attribute) { +#if ENABLE(DATALIST_ELEMENT) + if (attribute.name() == valueAttr) { + if (HTMLDataListElement* dataList = ownerDataListElement()) + dataList->optionElementChildrenChanged(); + } else +#endif if (attribute.name() == disabledAttr) { bool oldDisabled = m_disabled; m_disabled = !attribute.isNull(); @@ -252,11 +259,27 @@ void HTMLOptionElement::setSelectedState(bool selected) void HTMLOptionElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) { +#if ENABLE(DATALIST_ELEMENT) + if (HTMLDataListElement* dataList = ownerDataListElement()) + dataList->optionElementChildrenChanged(); + else +#endif if (HTMLSelectElement* select = ownerSelectElement()) select->optionElementChildrenChanged(); HTMLElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); } +#if ENABLE(DATALIST_ELEMENT) +HTMLDataListElement* HTMLOptionElement::ownerDataListElement() const +{ + for (ContainerNode* parent = parentNode(); parent ; parent = parent->parentNode()) { + if (parent->hasTagName(datalistTag)) + return static_cast<HTMLDataListElement*>(parent); + } + return 0; +} +#endif + HTMLSelectElement* HTMLOptionElement::ownerSelectElement() const { ContainerNode* select = parentNode(); diff --git a/Source/WebCore/html/HTMLOptionElement.h b/Source/WebCore/html/HTMLOptionElement.h index 247b6c1a9..24cdcdb5e 100644 --- a/Source/WebCore/html/HTMLOptionElement.h +++ b/Source/WebCore/html/HTMLOptionElement.h @@ -29,6 +29,7 @@ namespace WebCore { +class HTMLDataListElement; class HTMLSelectElement; class HTMLOptionElement : public HTMLElement { @@ -49,6 +50,9 @@ public: bool selected(); void setSelected(bool); +#if ENABLE(DATALIST_ELEMENT) + HTMLDataListElement* ownerDataListElement() const; +#endif HTMLSelectElement* ownerSelectElement() const; String label() const; diff --git a/Source/WebCore/html/HTMLOptionsCollection.cpp b/Source/WebCore/html/HTMLOptionsCollection.cpp index 960fc8995..8d2aff9e0 100644 --- a/Source/WebCore/html/HTMLOptionsCollection.cpp +++ b/Source/WebCore/html/HTMLOptionsCollection.cpp @@ -28,7 +28,7 @@ namespace WebCore { HTMLOptionsCollection::HTMLOptionsCollection(Element* select) - : HTMLCollection(select, SelectOptions, SupportItemBefore) + : HTMLCollection(select, SelectOptions, DoesNotOverrideItemAfter) { ASSERT(select->hasTagName(HTMLNames::selectTag)); } diff --git a/Source/WebCore/html/HTMLProgressElement.cpp b/Source/WebCore/html/HTMLProgressElement.cpp index 4030ee238..742b09ffa 100644 --- a/Source/WebCore/html/HTMLProgressElement.cpp +++ b/Source/WebCore/html/HTMLProgressElement.cpp @@ -19,9 +19,9 @@ */ #include "config.h" -#if ENABLE(PROGRESS_TAG) #include "HTMLProgressElement.h" +#if ENABLE(PROGRESS_ELEMENT) #include "Attribute.h" #include "EventNames.h" #include "ExceptionCode.h" diff --git a/Source/WebCore/html/HTMLProgressElement.h b/Source/WebCore/html/HTMLProgressElement.h index e2e8a270d..72180b93d 100644 --- a/Source/WebCore/html/HTMLProgressElement.h +++ b/Source/WebCore/html/HTMLProgressElement.h @@ -21,7 +21,7 @@ #ifndef HTMLProgressElement_h #define HTMLProgressElement_h -#if ENABLE(PROGRESS_TAG) +#if ENABLE(PROGRESS_ELEMENT) #include "LabelableElement.h" namespace WebCore { diff --git a/Source/WebCore/html/HTMLProgressElement.idl b/Source/WebCore/html/HTMLProgressElement.idl index ace4def83..6ad1ab53e 100644 --- a/Source/WebCore/html/HTMLProgressElement.idl +++ b/Source/WebCore/html/HTMLProgressElement.idl @@ -19,7 +19,7 @@ module html { interface [ - Conditional=PROGRESS_TAG + Conditional=PROGRESS_ELEMENT ] HTMLProgressElement : HTMLElement { attribute double value setter raises(DOMException); diff --git a/Source/WebCore/html/HTMLPropertiesCollection.cpp b/Source/WebCore/html/HTMLPropertiesCollection.cpp index c17e7c696..d86bf6c65 100644 --- a/Source/WebCore/html/HTMLPropertiesCollection.cpp +++ b/Source/WebCore/html/HTMLPropertiesCollection.cpp @@ -51,7 +51,7 @@ PassRefPtr<HTMLPropertiesCollection> HTMLPropertiesCollection::create(Node* item } HTMLPropertiesCollection::HTMLPropertiesCollection(Node* itemNode) - : HTMLCollection(itemNode, ItemProperties, DoNotSupportItemBefore) + : HTMLCollection(itemNode, ItemProperties, OverridesItemAfter) , m_hasPropertyNameCache(false) , m_hasItemRefElements(false) { @@ -112,10 +112,10 @@ static Node* nextNodeWithProperty(Node* base, Node* node) ? node->traverseNextNode(base) : node->traverseNextSibling(base); } -Element* HTMLPropertiesCollection::itemAfter(unsigned& offsetInArray, Element* previousItem) const +Element* HTMLPropertiesCollection::virtualItemAfter(unsigned& offsetInArray, Element* previousItem) const { while (offsetInArray < m_itemRefElements.size()) { - if (Element* next = itemAfter(m_itemRefElements[offsetInArray], previousItem)) + if (Element* next = virtualItemAfter(m_itemRefElements[offsetInArray], previousItem)) return next; offsetInArray++; previousItem = 0; @@ -123,7 +123,7 @@ Element* HTMLPropertiesCollection::itemAfter(unsigned& offsetInArray, Element* p return 0; } -HTMLElement* HTMLPropertiesCollection::itemAfter(HTMLElement* base, Element* previous) const +HTMLElement* HTMLPropertiesCollection::virtualItemAfter(HTMLElement* base, Element* previous) const { Node* current; current = previous ? nextNodeWithProperty(base, previous) : base; @@ -149,7 +149,7 @@ void HTMLPropertiesCollection::updateNameCache() const for (unsigned i = 0; i < m_itemRefElements.size(); ++i) { HTMLElement* refElement = m_itemRefElements[i]; - for (HTMLElement* element = itemAfter(refElement, 0); element; element = itemAfter(refElement, element)) { + for (HTMLElement* element = virtualItemAfter(refElement, 0); element; element = virtualItemAfter(refElement, element)) { DOMSettableTokenList* itemProperty = element->itemProp(); for (unsigned propertyIndex = 0; propertyIndex < itemProperty->length(); ++propertyIndex) updatePropertyCache(element, itemProperty->item(propertyIndex)); diff --git a/Source/WebCore/html/HTMLPropertiesCollection.h b/Source/WebCore/html/HTMLPropertiesCollection.h index dba91cac1..29a84ed71 100644 --- a/Source/WebCore/html/HTMLPropertiesCollection.h +++ b/Source/WebCore/html/HTMLPropertiesCollection.h @@ -65,8 +65,8 @@ private: Node* findRefElements(Node* previous) const; - virtual Element* itemAfter(unsigned& offsetInArray, Element*) const OVERRIDE; - HTMLElement* itemAfter(HTMLElement* base, Element* previous) const; + virtual Element* virtualItemAfter(unsigned& offsetInArray, Element*) const OVERRIDE; + HTMLElement* virtualItemAfter(HTMLElement* base, Element* previous) const; void updateNameCache() const; diff --git a/Source/WebCore/html/HTMLSummaryElement.cpp b/Source/WebCore/html/HTMLSummaryElement.cpp index 800a0efc2..daf126cfb 100644 --- a/Source/WebCore/html/HTMLSummaryElement.cpp +++ b/Source/WebCore/html/HTMLSummaryElement.cpp @@ -21,8 +21,7 @@ #include "config.h" #include "HTMLSummaryElement.h" -#if ENABLE(DETAILS) - +#if ENABLE(DETAILS_ELEMENT) #include "DetailsMarkerControl.h" #include "ElementShadow.h" #include "HTMLContentElement.h" diff --git a/Source/WebCore/html/HTMLTableRowsCollection.cpp b/Source/WebCore/html/HTMLTableRowsCollection.cpp index 206864ec2..2619f94f1 100644 --- a/Source/WebCore/html/HTMLTableRowsCollection.cpp +++ b/Source/WebCore/html/HTMLTableRowsCollection.cpp @@ -152,7 +152,7 @@ HTMLTableRowElement* HTMLTableRowsCollection::lastRow(HTMLTableElement* table) // table to get at the collection cache. Order of argument evaluation is undefined and can // differ between compilers. HTMLTableRowsCollection::HTMLTableRowsCollection(Element* table) - : HTMLCollection(table, TableRows, DoNotSupportItemBefore) + : HTMLCollection(table, TableRows, OverridesItemAfter) { ASSERT(table->hasTagName(tableTag)); } @@ -162,7 +162,7 @@ PassRefPtr<HTMLTableRowsCollection> HTMLTableRowsCollection::create(Element* tab return adoptRef(new HTMLTableRowsCollection(table)); } -Element* HTMLTableRowsCollection::itemAfter(unsigned& offsetInArray, Element* previous) const +Element* HTMLTableRowsCollection::virtualItemAfter(unsigned& offsetInArray, Element* previous) const { ASSERT_UNUSED(offsetInArray, !offsetInArray); ASSERT(!previous || (previous->isHTMLElement() && toHTMLElement(previous)->hasLocalName(trTag))); diff --git a/Source/WebCore/html/HTMLTableRowsCollection.h b/Source/WebCore/html/HTMLTableRowsCollection.h index 817b14373..c5068dbac 100644 --- a/Source/WebCore/html/HTMLTableRowsCollection.h +++ b/Source/WebCore/html/HTMLTableRowsCollection.h @@ -46,7 +46,7 @@ public: private: HTMLTableRowsCollection(Element*); - virtual Element* itemAfter(unsigned& offsetInArray, Element*) const OVERRIDE; + virtual Element* virtualItemAfter(unsigned& offsetInArray, Element*) const OVERRIDE; }; } // namespace diff --git a/Source/WebCore/html/HTMLTagNames.in b/Source/WebCore/html/HTMLTagNames.in index 4119ba9b6..c40672863 100644 --- a/Source/WebCore/html/HTMLTagNames.in +++ b/Source/WebCore/html/HTMLTagNames.in @@ -33,10 +33,10 @@ colgroup interfaceName=HTMLTableColElement command interfaceName=HTMLElement content interfaceName=HTMLContentElement, conditional=SHADOW_DOM, contextConditional=shadowDOM webkitShadowContent interfaceName=HTMLElement, noConstructor -datalist interfaceName=HTMLDataListElement, conditional=DATALIST +datalist interfaceName=HTMLDataListElement, conditional=DATALIST_ELEMENT dd interfaceName=HTMLElement del interfaceName=HTMLModElement -details conditional=DETAILS +details conditional=DETAILS_ELEMENT dfn interfaceName=HTMLElement dir interfaceName=HTMLDirectoryElement dialog conditional=DIALOG_ELEMENT, contextConditional=dialogElement @@ -86,7 +86,7 @@ mark interfaceName=HTMLElement marquee menu meta -meter interfaceName=HTMLMeterElement, conditional=METER_TAG +meter interfaceName=HTMLMeterElement, conditional=METER_ELEMENT nav interfaceName=HTMLElement nobr interfaceName=HTMLElement noembed interfaceName=HTMLElement @@ -102,7 +102,7 @@ p interfaceName=HTMLParagraphElement param plaintext interfaceName=HTMLElement pre -progress interfaceName=HTMLProgressElement, conditional=PROGRESS_TAG +progress interfaceName=HTMLProgressElement, conditional=PROGRESS_ELEMENT q interfaceName=HTMLQuoteElement rp interfaceName=HTMLElement rt interfaceName=HTMLElement @@ -119,7 +119,7 @@ strike interfaceName=HTMLElement strong interfaceName=HTMLElement style constructorNeedsCreatedByParser sub interfaceName=HTMLElement -summary interfaceName=HTMLSummaryElement, JSInterfaceName=HTMLElement, conditional=DETAILS +summary interfaceName=HTMLSummaryElement, JSInterfaceName=HTMLElement, conditional=DETAILS_ELEMENT sup interfaceName=HTMLElement table tbody interfaceName=HTMLTableSectionElement diff --git a/Source/WebCore/html/HTMLTextAreaElement.cpp b/Source/WebCore/html/HTMLTextAreaElement.cpp index d07a972c6..bad8571d3 100644 --- a/Source/WebCore/html/HTMLTextAreaElement.cpp +++ b/Source/WebCore/html/HTMLTextAreaElement.cpp @@ -294,7 +294,7 @@ String HTMLTextAreaElement::sanitizeUserInputValue(const String& proposedValue, HTMLElement* HTMLTextAreaElement::innerTextElement() const { - Node* node = shadow()->oldestShadowRoot()->firstChild(); + Node* node = userAgentShadowRoot()->firstChild(); ASSERT(!node || node->hasTagName(divTag)); return toHTMLElement(node); } @@ -505,7 +505,7 @@ void HTMLTextAreaElement::updatePlaceholderText() String placeholderText = strippedPlaceholder(); if (placeholderText.isEmpty()) { if (m_placeholder) { - shadow()->oldestShadowRoot()->removeChild(m_placeholder.get(), ec); + userAgentShadowRoot()->removeChild(m_placeholder.get(), ec); ASSERT(!ec); m_placeholder.clear(); } @@ -514,7 +514,7 @@ void HTMLTextAreaElement::updatePlaceholderText() if (!m_placeholder) { m_placeholder = HTMLDivElement::create(document()); m_placeholder->setShadowPseudoId("-webkit-input-placeholder"); - shadow()->oldestShadowRoot()->insertBefore(m_placeholder, innerTextElement()->nextSibling(), ec); + userAgentShadowRoot()->insertBefore(m_placeholder, innerTextElement()->nextSibling(), ec); ASSERT(!ec); } m_placeholder->setInnerText(placeholderText, ec); diff --git a/Source/WebCore/html/InputType.cpp b/Source/WebCore/html/InputType.cpp index 4c4586523..d9097c4de 100644 --- a/Source/WebCore/html/InputType.cpp +++ b/Source/WebCore/html/InputType.cpp @@ -453,12 +453,10 @@ void InputType::createShadowSubtree() void InputType::destroyShadowSubtree() { - ElementShadow* shadow = element()->shadow(); - if (!shadow) + ShadowRoot* root = element()->userAgentShadowRoot(); + if (!root) return; - ShadowRoot* root = shadow->oldestShadowRoot(); - ASSERT(root->type() == ShadowRoot::UserAgentShadowRoot); root->removeAllChildren(); // It's ok to clear contents of all other ShadowRoots because they must have @@ -897,6 +895,12 @@ String InputType::defaultToolTip() const return String(); } +#if ENABLE(DATALIST_ELEMENT) +void InputType::listAttributeTargetChanged() +{ +} +#endif + bool InputType::supportsIndeterminateAppearance() const { return false; diff --git a/Source/WebCore/html/InputType.h b/Source/WebCore/html/InputType.h index 6c6659a7c..348148b10 100644 --- a/Source/WebCore/html/InputType.h +++ b/Source/WebCore/html/InputType.h @@ -226,6 +226,7 @@ public: #if ENABLE(INPUT_SPEECH) virtual HTMLElement* speechButtonElement() const { return 0; } #endif + virtual HTMLElement* sliderThumbElement() const { return 0; } virtual HTMLElement* placeholderElement() const; // Miscellaneous functions @@ -275,6 +276,9 @@ public: virtual void disabledAttributeChanged(); virtual void readonlyAttributeChanged(); virtual String defaultToolTip() const; +#if ENABLE(DATALIST_ELEMENT) + virtual void listAttributeTargetChanged(); +#endif // Parses the specified string for the type, and return // the Decimal value for the parsing result if the parsing diff --git a/Source/WebCore/html/LabelsNodeList.cpp b/Source/WebCore/html/LabelsNodeList.cpp index d3a4ba162..3b2b8d3ef 100644 --- a/Source/WebCore/html/LabelsNodeList.cpp +++ b/Source/WebCore/html/LabelsNodeList.cpp @@ -34,7 +34,7 @@ namespace WebCore { using namespace HTMLNames; LabelsNodeList::LabelsNodeList(Node* forNode) - : DynamicSubtreeNodeList(forNode, InvalidateOnForAttrChange, NodeListIsRootedAtDocument) + : DynamicSubtreeNodeList(forNode, LabelsNodeListType, InvalidateOnForAttrChange, NodeListIsRootedAtDocument) { } diff --git a/Source/WebCore/html/RadioNodeList.cpp b/Source/WebCore/html/RadioNodeList.cpp index bd3cc87b5..944f7b40d 100644 --- a/Source/WebCore/html/RadioNodeList.cpp +++ b/Source/WebCore/html/RadioNodeList.cpp @@ -38,7 +38,7 @@ namespace WebCore { using namespace HTMLNames; RadioNodeList::RadioNodeList(Node* rootNode, const AtomicString& name) - : DynamicSubtreeNodeList(rootNode, InvalidateForFormControls, rootNode->hasTagName(formTag) ? NodeListIsRootedAtDocument : NodeListIsRootedAtNode) + : DynamicSubtreeNodeList(rootNode, RadioNodeListType, InvalidateForFormControls, rootNode->hasTagName(formTag) ? NodeListIsRootedAtDocument : NodeListIsRootedAtNode) , m_name(name) { } diff --git a/Source/WebCore/html/RangeInputType.cpp b/Source/WebCore/html/RangeInputType.cpp index 10c7576bf..901a9acc1 100644 --- a/Source/WebCore/html/RangeInputType.cpp +++ b/Source/WebCore/html/RangeInputType.cpp @@ -96,6 +96,11 @@ void RangeInputType::setValueAsDecimal(const Decimal& newValue, TextFieldEventBe element()->setValue(serialize(newValue), eventBehavior); } +bool RangeInputType::typeMismatchFor(const String& value) const +{ + return !value.isEmpty() && !isfinite(parseToDoubleForNumberType(value)); +} + bool RangeInputType::supportsRequired() const { return false; @@ -132,7 +137,7 @@ void RangeInputType::handleMouseDownEvent(MouseEvent* event) if (event->button() != LeftButton || !targetNode) return; ASSERT(element()->shadow()); - if (targetNode != element() && !targetNode->isDescendantOf(element()->shadow()->oldestShadowRoot())) + if (targetNode != element() && !targetNode->isDescendantOf(element()->userAgentShadowRoot())) return; SliderThumbElement* thumb = sliderThumbElementOf(element()); if (targetNode == thumb) @@ -239,7 +244,7 @@ void RangeInputType::createShadowSubtree() RefPtr<HTMLElement> container = SliderContainerElement::create(document); container->appendChild(track.release(), ec); container->appendChild(TrackLimiterElement::create(document), ec); - element()->shadow()->oldestShadowRoot()->appendChild(container.release(), ec); + element()->userAgentShadowRoot()->appendChild(container.release(), ec); } RenderObject* RangeInputType::createRenderer(RenderArena* arena, RenderStyle*) const @@ -306,4 +311,16 @@ bool RangeInputType::shouldRespectListAttribute() return InputType::themeSupportsDataListUI(this); } +HTMLElement* RangeInputType::sliderThumbElement() const +{ + return sliderThumbElementOf(element()); +} + +#if ENABLE(DATALIST_ELEMENT) +void RangeInputType::listAttributeTargetChanged() +{ + element()->setNeedsStyleRecalc(); +} +#endif + } // namespace WebCore diff --git a/Source/WebCore/html/RangeInputType.h b/Source/WebCore/html/RangeInputType.h index 0983b3d57..69d2ec7c6 100644 --- a/Source/WebCore/html/RangeInputType.h +++ b/Source/WebCore/html/RangeInputType.h @@ -47,6 +47,7 @@ private: virtual const AtomicString& formControlType() const OVERRIDE; virtual double valueAsDouble() const OVERRIDE; virtual void setValueAsDecimal(const Decimal&, TextFieldEventBehavior, ExceptionCode&) const OVERRIDE; + virtual bool typeMismatchFor(const String&) const OVERRIDE; virtual bool supportsRequired() const OVERRIDE; virtual StepRange createStepRange(AnyStepHandling) const OVERRIDE; virtual bool isSteppable() const OVERRIDE; @@ -68,6 +69,10 @@ private: virtual String fallbackValue() const OVERRIDE; virtual String sanitizeValue(const String& proposedValue) const OVERRIDE; virtual bool shouldRespectListAttribute() OVERRIDE; + virtual HTMLElement* sliderThumbElement() const OVERRIDE; +#if ENABLE(DATALIST_ELEMENT) + virtual void listAttributeTargetChanged() OVERRIDE; +#endif }; } // namespace WebCore diff --git a/Source/WebCore/html/TextFieldInputType.cpp b/Source/WebCore/html/TextFieldInputType.cpp index 632816be7..10ed8fb0a 100644 --- a/Source/WebCore/html/TextFieldInputType.cpp +++ b/Source/WebCore/html/TextFieldInputType.cpp @@ -246,11 +246,11 @@ void TextFieldInputType::createShadowSubtree() ExceptionCode ec = 0; m_innerText = TextControlInnerTextElement::create(document); if (!createsContainer) { - element()->shadow()->oldestShadowRoot()->appendChild(m_innerText, ec); + element()->userAgentShadowRoot()->appendChild(m_innerText, ec); return; } - ShadowRoot* shadowRoot = element()->shadow()->oldestShadowRoot(); + ShadowRoot* shadowRoot = element()->userAgentShadowRoot(); m_container = HTMLDivElement::create(document); m_container->setShadowPseudoId("-webkit-textfield-decoration-container"); shadowRoot->appendChild(m_container, ec); @@ -417,7 +417,7 @@ void TextFieldInputType::updatePlaceholderText() if (!m_placeholder) { m_placeholder = HTMLDivElement::create(element()->document()); m_placeholder->setShadowPseudoId("-webkit-input-placeholder"); - element()->shadow()->oldestShadowRoot()->insertBefore(m_placeholder, m_container ? m_container->nextSibling() : innerTextElement()->nextSibling(), ec); + element()->userAgentShadowRoot()->insertBefore(m_placeholder, m_container ? m_container->nextSibling() : innerTextElement()->nextSibling(), ec); ASSERT(!ec); } m_placeholder->setInnerText(placeholderText, ec); diff --git a/Source/WebCore/html/ValidationMessage.cpp b/Source/WebCore/html/ValidationMessage.cpp index b63d8837d..1901f46ce 100644 --- a/Source/WebCore/html/ValidationMessage.cpp +++ b/Source/WebCore/html/ValidationMessage.cpp @@ -196,7 +196,7 @@ void ValidationMessage::deleteBubbleTree(Timer<ValidationMessage>*) m_messageBody = 0; HTMLElement* host = toHTMLElement(m_element); ExceptionCode ec; - host->shadow()->oldestShadowRoot()->removeChild(m_bubble.get(), ec); + host->userAgentShadowRoot()->removeChild(m_bubble.get(), ec); m_bubble = 0; } m_message = String(); diff --git a/Source/WebCore/html/parser/HTMLConstructionSite.cpp b/Source/WebCore/html/parser/HTMLConstructionSite.cpp index 4da7a7ae9..9454f5fd9 100644 --- a/Source/WebCore/html/parser/HTMLConstructionSite.cpp +++ b/Source/WebCore/html/parser/HTMLConstructionSite.cpp @@ -220,8 +220,6 @@ void HTMLConstructionSite::mergeAttributesFromTokenIntoElement(AtomicHTMLToken& void HTMLConstructionSite::insertHTMLHtmlStartTagInBody(AtomicHTMLToken& token) { - // FIXME: parse error - // Fragments do not have a root HTML element, so any additional HTML elements // encountered during fragment parsing should be ignored. if (m_isParsingFragment) @@ -232,7 +230,6 @@ void HTMLConstructionSite::insertHTMLHtmlStartTagInBody(AtomicHTMLToken& token) void HTMLConstructionSite::insertHTMLBodyStartTagInBody(AtomicHTMLToken& token) { - // FIXME: parse error mergeAttributesFromTokenIntoElement(token, m_openElements.bodyElement()); } diff --git a/Source/WebCore/html/parser/HTMLTreeBuilder.cpp b/Source/WebCore/html/parser/HTMLTreeBuilder.cpp index 803b0e7d3..6a2b0e770 100644 --- a/Source/WebCore/html/parser/HTMLTreeBuilder.cpp +++ b/Source/WebCore/html/parser/HTMLTreeBuilder.cpp @@ -346,11 +346,10 @@ private: }; -HTMLTreeBuilder::HTMLTreeBuilder(HTMLDocumentParser* parser, HTMLDocument* document, bool reportErrors, bool usePreHTML5ParserQuirks, unsigned maximumDOMTreeDepth) +HTMLTreeBuilder::HTMLTreeBuilder(HTMLDocumentParser* parser, HTMLDocument* document, bool, bool usePreHTML5ParserQuirks, unsigned maximumDOMTreeDepth) : m_framesetOk(true) , m_document(document) , m_tree(document, maximumDOMTreeDepth) - , m_reportErrors(reportErrors) , m_insertionMode(InitialMode) , m_originalInsertionMode(InitialMode) , m_shouldSkipLeadingNewline(false) @@ -367,7 +366,6 @@ HTMLTreeBuilder::HTMLTreeBuilder(HTMLDocumentParser* parser, DocumentFragment* f , m_fragmentContext(fragment, contextElement, scriptingPermission) , m_document(fragment->document()) , m_tree(fragment, scriptingPermission, maximumDOMTreeDepth) - , m_reportErrors(false) // FIXME: Why not report errors in fragments? , m_insertionMode(InitialMode) , m_originalInsertionMode(InitialMode) , m_shouldSkipLeadingNewline(false) @@ -729,7 +727,7 @@ void HTMLTreeBuilder::processStartTagForInBody(AtomicHTMLToken& token) { ASSERT(token.type() == HTMLTokenTypes::StartTag); if (token.name() == htmlTag) { - m_tree.insertHTMLHtmlStartTagInBody(token); + processHtmlStartTagForInBody(token); return; } if (token.name() == baseTag @@ -1142,7 +1140,7 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken& token) case BeforeHeadMode: ASSERT(insertionMode() == BeforeHeadMode); if (token.name() == htmlTag) { - m_tree.insertHTMLHtmlStartTagInBody(token); + processHtmlStartTagForInBody(token); return; } if (token.name() == headTag) { @@ -1161,7 +1159,7 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken& token) case AfterHeadMode: ASSERT(insertionMode() == AfterHeadMode); if (token.name() == htmlTag) { - m_tree.insertHTMLHtmlStartTagInBody(token); + processHtmlStartTagForInBody(token); return; } if (token.name() == bodyTag) { @@ -1224,7 +1222,7 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken& token) case InColumnGroupMode: ASSERT(insertionMode() == InColumnGroupMode); if (token.name() == htmlTag) { - m_tree.insertHTMLHtmlStartTagInBody(token); + processHtmlStartTagForInBody(token); return; } if (token.name() == colTag) { @@ -1311,7 +1309,7 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken& token) case AfterAfterBodyMode: ASSERT(insertionMode() == AfterBodyMode || insertionMode() == AfterAfterBodyMode); if (token.name() == htmlTag) { - m_tree.insertHTMLHtmlStartTagInBody(token); + processHtmlStartTagForInBody(token); return; } setInsertionMode(InBodyMode); @@ -1320,7 +1318,7 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken& token) case InHeadNoscriptMode: ASSERT(insertionMode() == InHeadNoscriptMode); if (token.name() == htmlTag) { - m_tree.insertHTMLHtmlStartTagInBody(token); + processHtmlStartTagForInBody(token); return; } if (token.name() == basefontTag @@ -1343,7 +1341,7 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken& token) case InFramesetMode: ASSERT(insertionMode() == InFramesetMode); if (token.name() == htmlTag) { - m_tree.insertHTMLHtmlStartTagInBody(token); + processHtmlStartTagForInBody(token); return; } if (token.name() == framesetTag) { @@ -1364,7 +1362,7 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken& token) case AfterAfterFramesetMode: ASSERT(insertionMode() == AfterFramesetMode || insertionMode() == AfterAfterFramesetMode); if (token.name() == htmlTag) { - m_tree.insertHTMLHtmlStartTagInBody(token); + processHtmlStartTagForInBody(token); return; } if (token.name() == noframesTag) { @@ -1390,7 +1388,7 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken& token) case InSelectMode: ASSERT(insertionMode() == InSelectMode || insertionMode() == InSelectInTableMode); if (token.name() == htmlTag) { - m_tree.insertHTMLHtmlStartTagInBody(token); + processHtmlStartTagForInBody(token); return; } if (token.name() == optionTag) { @@ -1448,6 +1446,12 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken& token) } } +void HTMLTreeBuilder::processHtmlStartTagForInBody(AtomicHTMLToken& token) +{ + parseError(token); + m_tree.insertHTMLHtmlStartTagInBody(token); +} + bool HTMLTreeBuilder::processBodyEndTagForInBody(AtomicHTMLToken& token) { ASSERT(token.type() == HTMLTokenTypes::EndTag); @@ -1964,6 +1968,7 @@ void HTMLTreeBuilder::processEndTagForInTable(AtomicHTMLToken& token) parseError(token); return; } + parseError(token); // Is this redirection necessary here? HTMLConstructionSite::RedirectToFosterParentGuard redirecter(m_tree); processEndTagForInBody(token); @@ -2558,7 +2563,7 @@ bool HTMLTreeBuilder::processStartTagForInHead(AtomicHTMLToken& token) { ASSERT(token.type() == HTMLTokenTypes::StartTag); if (token.name() == htmlTag) { - m_tree.insertHTMLHtmlStartTagInBody(token); + processHtmlStartTagForInBody(token); return true; } if (token.name() == baseTag diff --git a/Source/WebCore/html/parser/HTMLTreeBuilder.h b/Source/WebCore/html/parser/HTMLTreeBuilder.h index e7c689084..192884e5b 100644 --- a/Source/WebCore/html/parser/HTMLTreeBuilder.h +++ b/Source/WebCore/html/parser/HTMLTreeBuilder.h @@ -137,6 +137,7 @@ private: void processEndTagForInCell(AtomicHTMLToken&); void processIsindexStartTagForInBody(AtomicHTMLToken&); + void processHtmlStartTagForInBody(AtomicHTMLToken&); bool processBodyEndTagForInBody(AtomicHTMLToken&); bool processTableEndTagForInTable(); bool processCaptionEndTagForInCaption(); @@ -213,8 +214,6 @@ private: Document* m_document; HTMLConstructionSite m_tree; - bool m_reportErrors; - // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#insertion-mode InsertionMode m_insertionMode; diff --git a/Source/WebCore/html/shadow/CalendarPickerElement.cpp b/Source/WebCore/html/shadow/CalendarPickerElement.cpp index b4176b296..ea9fbb7b3 100644 --- a/Source/WebCore/html/shadow/CalendarPickerElement.cpp +++ b/Source/WebCore/html/shadow/CalendarPickerElement.cpp @@ -81,9 +81,11 @@ RenderObject* CalendarPickerElement::createRenderer(RenderArena* arena, RenderSt inline HTMLInputElement* CalendarPickerElement::hostInput() { - ASSERT(shadowAncestorNode()); - ASSERT(shadowAncestorNode()->hasTagName(inputTag)); - return static_cast<HTMLInputElement*>(shadowAncestorNode()); + // JavaScript code can't create CalendarPickerElement objects. This is + // always in shadow of <input>. + ASSERT(shadowHost()); + ASSERT(shadowHost()->hasTagName(inputTag)); + return static_cast<HTMLInputElement*>(shadowHost()); } void CalendarPickerElement::defaultEventHandler(Event* event) diff --git a/Source/WebCore/html/shadow/DetailsMarkerControl.cpp b/Source/WebCore/html/shadow/DetailsMarkerControl.cpp index d4fddd30f..b3be3c45c 100644 --- a/Source/WebCore/html/shadow/DetailsMarkerControl.cpp +++ b/Source/WebCore/html/shadow/DetailsMarkerControl.cpp @@ -31,8 +31,7 @@ #include "config.h" #include "DetailsMarkerControl.h" -#if ENABLE(DETAILS) - +#if ENABLE(DETAILS_ELEMENT) #include "HTMLNames.h" #include "HTMLSummaryElement.h" #include "RenderDetailsMarker.h" diff --git a/Source/WebCore/html/shadow/ImageInnerElement.cpp b/Source/WebCore/html/shadow/ImageInnerElement.cpp index 4ca44e9c1..b23d6b1a5 100644 --- a/Source/WebCore/html/shadow/ImageInnerElement.cpp +++ b/Source/WebCore/html/shadow/ImageInnerElement.cpp @@ -68,4 +68,10 @@ RenderObject* ImageInnerElement::createRenderer(RenderArena* arena, RenderStyle* return createRendererForImage(this, arena); } +const AtomicString& ImageInnerElement::shadowPseudoId() const +{ + DEFINE_STATIC_LOCAL(AtomicString, pseudoId, ("-webkit-image-inner-element")); + return pseudoId; +} + } diff --git a/Source/WebCore/html/shadow/ImageInnerElement.h b/Source/WebCore/html/shadow/ImageInnerElement.h index 2586306e5..3d61b239e 100644 --- a/Source/WebCore/html/shadow/ImageInnerElement.h +++ b/Source/WebCore/html/shadow/ImageInnerElement.h @@ -53,6 +53,8 @@ private: virtual void attach() OVERRIDE; virtual RenderObject* createRenderer(RenderArena*, RenderStyle*) OVERRIDE; + + virtual const AtomicString& shadowPseudoId() const OVERRIDE; }; inline PassRefPtr<ImageInnerElement> ImageInnerElement::create(Document* document) diff --git a/Source/WebCore/html/shadow/MediaControlRootElementChromium.cpp b/Source/WebCore/html/shadow/MediaControlRootElementChromium.cpp index 9edbd8ad3..9f0e8c62e 100644 --- a/Source/WebCore/html/shadow/MediaControlRootElementChromium.cpp +++ b/Source/WebCore/html/shadow/MediaControlRootElementChromium.cpp @@ -80,7 +80,6 @@ MediaControlRootElementChromium::MediaControlRootElementChromium(Document* docum #if ENABLE(VIDEO_TRACK) , m_textDisplayContainer(0) #endif - , m_opaque(true) , m_hideFullscreenControlsTimer(this, &MediaControlRootElementChromium::hideFullscreenControlsTimerFired) , m_isMouseOverControls(false) , m_isFullscreen(false) @@ -245,7 +244,7 @@ void MediaControlRootElementChromium::reset() } } - if (m_mediaController->supportsFullscreen()) + if (m_mediaController->supportsFullscreen() && m_mediaController->hasVideo()) m_fullscreenButton->show(); else m_fullscreenButton->hide(); diff --git a/Source/WebCore/html/shadow/MediaControlRootElementChromium.h b/Source/WebCore/html/shadow/MediaControlRootElementChromium.h index f86bc615a..2fb4c3cfe 100644 --- a/Source/WebCore/html/shadow/MediaControlRootElementChromium.h +++ b/Source/WebCore/html/shadow/MediaControlRootElementChromium.h @@ -149,7 +149,6 @@ private: MediaControlTextTrackContainerElement* m_textDisplayContainer; #endif - bool m_opaque; Timer<MediaControlRootElementChromium> m_hideFullscreenControlsTimer; bool m_isMouseOverControls; bool m_isFullscreen; diff --git a/Source/WebCore/html/shadow/MeterShadowElement.cpp b/Source/WebCore/html/shadow/MeterShadowElement.cpp index bc5ea6295..2d4d84481 100644 --- a/Source/WebCore/html/shadow/MeterShadowElement.cpp +++ b/Source/WebCore/html/shadow/MeterShadowElement.cpp @@ -29,9 +29,9 @@ */ #include "config.h" -#if ENABLE(METER_TAG) #include "MeterShadowElement.h" +#if ENABLE(METER_ELEMENT) #include "CSSPropertyNames.h" #include "HTMLMeterElement.h" #include "HTMLNames.h" diff --git a/Source/WebCore/html/shadow/MeterShadowElement.h b/Source/WebCore/html/shadow/MeterShadowElement.h index c36b01b24..6b8bf62ae 100644 --- a/Source/WebCore/html/shadow/MeterShadowElement.h +++ b/Source/WebCore/html/shadow/MeterShadowElement.h @@ -31,6 +31,7 @@ #ifndef MeterShadowElement_h #define MeterShadowElement_h +#if ENABLE(METER_ELEMENT) #include "HTMLDivElement.h" #include <wtf/Forward.h> @@ -82,5 +83,5 @@ inline PassRefPtr<MeterValueElement> MeterValueElement::create(Document* documen } } - -#endif +#endif // ENABLE(METER_ELEMENT) +#endif // MeterShadowElement_h diff --git a/Source/WebCore/html/shadow/ProgressShadowElement.cpp b/Source/WebCore/html/shadow/ProgressShadowElement.cpp index 548571302..780815212 100644 --- a/Source/WebCore/html/shadow/ProgressShadowElement.cpp +++ b/Source/WebCore/html/shadow/ProgressShadowElement.cpp @@ -29,9 +29,9 @@ */ #include "config.h" -#if ENABLE(PROGRESS_TAG) #include "ProgressShadowElement.h" +#if ENABLE(PROGRESS_ELEMENT) #include "HTMLNames.h" #include "HTMLProgressElement.h" #include "RenderObject.h" @@ -78,4 +78,3 @@ void ProgressValueElement::setWidthPercentage(double width) } #endif - diff --git a/Source/WebCore/html/shadow/ProgressShadowElement.h b/Source/WebCore/html/shadow/ProgressShadowElement.h index e135c71da..aff94fba3 100644 --- a/Source/WebCore/html/shadow/ProgressShadowElement.h +++ b/Source/WebCore/html/shadow/ProgressShadowElement.h @@ -32,6 +32,7 @@ #ifndef ProgressShadowElement_h #define ProgressShadowElement_h +#if ENABLE(PROGRESS_ELEMENT) #include "HTMLDivElement.h" #include <wtf/Forward.h> @@ -83,5 +84,5 @@ inline PassRefPtr<ProgressValueElement> ProgressValueElement::create(Document* d } } - -#endif +#endif // ENABLE(PROGRESS_ELEMENT) +#endif // ProgressShadowElement_h diff --git a/Source/WebCore/html/shadow/SliderThumbElement.cpp b/Source/WebCore/html/shadow/SliderThumbElement.cpp index 0186fa57d..bb5948690 100644 --- a/Source/WebCore/html/shadow/SliderThumbElement.cpp +++ b/Source/WebCore/html/shadow/SliderThumbElement.cpp @@ -74,7 +74,7 @@ inline static bool hasVerticalAppearance(HTMLInputElement* input) SliderThumbElement* sliderThumbElementOf(Node* node) { ASSERT(node); - ShadowRoot* shadow = node->toInputElement()->shadow()->oldestShadowRoot(); + ShadowRoot* shadow = node->toInputElement()->userAgentShadowRoot(); ASSERT(shadow); Node* thumb = shadow->firstChild()->firstChild()->firstChild(); ASSERT(thumb); @@ -148,19 +148,38 @@ void RenderSliderContainer::layout() // Sets the concrete height if the height of the <input> is not fixed or a // percentage value because a percentage height value of this box won't be // based on the <input> height in such case. - Length inputHeight = input->renderer()->style()->height(); - RenderObject* trackRenderer = node()->firstChild()->renderer(); - if (!isVertical && input->renderer()->isSlider() && !inputHeight.isFixed() && !inputHeight.isPercent()) { - RenderObject* thumbRenderer = input->shadow()->oldestShadowRoot()->firstChild()->firstChild()->firstChild()->renderer(); - if (thumbRenderer) { - style()->setHeight(thumbRenderer->style()->height()); - if (trackRenderer) - trackRenderer->style()->setHeight(thumbRenderer->style()->height()); + if (input->renderer()->isSlider()) { + if (!isVertical) { + RenderObject* trackRenderer = node()->firstChild()->renderer(); + Length inputHeight = input->renderer()->style()->height(); + if (!inputHeight.isSpecified()) { + RenderObject* thumbRenderer = input->sliderThumbElement()->renderer(); + if (thumbRenderer) { + Length height = thumbRenderer->style()->height(); +#if ENABLE(DATALIST_ELEMENT) + if (input && input->list()) { + int offsetFromCenter = theme()->sliderTickOffsetFromTrackCenter(); + int trackHeight = 0; + if (offsetFromCenter < 0) + trackHeight = -2 * offsetFromCenter; + else { + int tickLength = theme()->sliderTickSize().height(); + trackHeight = 2 * (offsetFromCenter + tickLength); + } + float zoomFactor = style()->effectiveZoom(); + if (zoomFactor != 1.0) + trackHeight *= zoomFactor; + height = Length(trackHeight, Fixed); + } +#endif + style()->setHeight(height); + } + } else { + style()->setHeight(Length(100, Percent)); + if (trackRenderer) + trackRenderer->style()->setHeight(Length()); + } } - } else { - style()->setHeight(Length(100, Percent)); - if (trackRenderer) - trackRenderer->style()->setHeight(Length()); } RenderDeprecatedFlexibleBox::layout(); @@ -405,8 +424,7 @@ const AtomicString& TrackLimiterElement::shadowPseudoId() const TrackLimiterElement* trackLimiterElementOf(Node* node) { ASSERT(node); - ASSERT(node->toInputElement()->shadow()); - ShadowRoot* shadow = node->toInputElement()->shadow()->oldestShadowRoot(); + ShadowRoot* shadow = node->toInputElement()->userAgentShadowRoot(); ASSERT(shadow); Node* limiter = shadow->firstChild()->lastChild(); ASSERT(limiter); diff --git a/Source/WebCore/html/shadow/TextFieldDecorationElement.cpp b/Source/WebCore/html/shadow/TextFieldDecorationElement.cpp index 9423aa8d2..09cc7b1d4 100644 --- a/Source/WebCore/html/shadow/TextFieldDecorationElement.cpp +++ b/Source/WebCore/html/shadow/TextFieldDecorationElement.cpp @@ -116,9 +116,10 @@ void TextFieldDecorationElement::decorate(HTMLInputElement* input, bool visible) inline HTMLInputElement* TextFieldDecorationElement::hostInput() { - ASSERT(shadowAncestorNode()); - ASSERT(shadowAncestorNode()->hasTagName(inputTag)); - return static_cast<HTMLInputElement*>(shadowAncestorNode()); + // TextFieldDecorationElement is created only by C++ code, and it is always + // in <input> shadow. + ASSERT(!shadowHost() || shadowHost()->hasTagName(inputTag)); + return static_cast<HTMLInputElement*>(shadowHost()); } bool TextFieldDecorationElement::isTextFieldDecoration() const @@ -181,7 +182,7 @@ bool TextFieldDecorationElement::isMouseFocusable() const void TextFieldDecorationElement::defaultEventHandler(Event* event) { RefPtr<HTMLInputElement> input(hostInput()); - if (input->disabled() || input->readOnly() || !event->isMouseEvent()) { + if (!input || input->disabled() || input->readOnly() || !event->isMouseEvent()) { if (!event->defaultHandled()) HTMLDivElement::defaultEventHandler(event); return; |