summaryrefslogtreecommitdiff
path: root/Source/WebCore/html
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-07-23 09:28:44 +0200
committerSimon Hausmann <simon.hausmann@nokia.com>2012-07-23 09:28:44 +0200
commit815f1ed417bd26fbe2abbdf20ac5d3423b30796c (patch)
tree923c9a9e2834ccab60f5caecfb8f0ac410c1dd9e /Source/WebCore/html
parentb4ad5d9d2b96baacd0180ead50de5195ca78af2d (diff)
downloadqtwebkit-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')
-rw-r--r--Source/WebCore/html/CollectionType.h2
-rw-r--r--Source/WebCore/html/ColorInputType.cpp13
-rw-r--r--Source/WebCore/html/ColorInputType.h1
-rw-r--r--Source/WebCore/html/FTPDirectoryDocument.cpp2
-rw-r--r--Source/WebCore/html/FileInputType.cpp4
-rw-r--r--Source/WebCore/html/FormController.cpp201
-rw-r--r--Source/WebCore/html/FormController.h9
-rw-r--r--Source/WebCore/html/HTMLAllCollection.cpp2
-rw-r--r--Source/WebCore/html/HTMLCollection.cpp171
-rw-r--r--Source/WebCore/html/HTMLCollection.h33
-rw-r--r--Source/WebCore/html/HTMLDataListElement.cpp12
-rw-r--r--Source/WebCore/html/HTMLDataListElement.h11
-rw-r--r--Source/WebCore/html/HTMLDataListElement.idl2
-rw-r--r--Source/WebCore/html/HTMLDetailsElement.cpp5
-rw-r--r--Source/WebCore/html/HTMLDetailsElement.idl5
-rw-r--r--Source/WebCore/html/HTMLDialogElement.cpp24
-rw-r--r--Source/WebCore/html/HTMLDialogElement.h4
-rw-r--r--Source/WebCore/html/HTMLDialogElement.idl2
-rw-r--r--Source/WebCore/html/HTMLFormCollection.cpp4
-rw-r--r--Source/WebCore/html/HTMLFormCollection.h2
-rw-r--r--Source/WebCore/html/HTMLFrameElementBase.cpp7
-rw-r--r--Source/WebCore/html/HTMLFrameElementBase.h4
-rw-r--r--Source/WebCore/html/HTMLImageElement.cpp12
-rw-r--r--Source/WebCore/html/HTMLImageLoader.cpp8
-rw-r--r--Source/WebCore/html/HTMLInputElement.cpp71
-rw-r--r--Source/WebCore/html/HTMLInputElement.h14
-rw-r--r--Source/WebCore/html/HTMLInputElement.idl2
-rw-r--r--Source/WebCore/html/HTMLKeygenElement.cpp2
-rw-r--r--Source/WebCore/html/HTMLMediaElement.cpp29
-rw-r--r--Source/WebCore/html/HTMLMeterElement.cpp2
-rw-r--r--Source/WebCore/html/HTMLMeterElement.h2
-rw-r--r--Source/WebCore/html/HTMLMeterElement.idl2
-rw-r--r--Source/WebCore/html/HTMLNameCollection.cpp4
-rw-r--r--Source/WebCore/html/HTMLNameCollection.h2
-rw-r--r--Source/WebCore/html/HTMLOptionElement.cpp23
-rw-r--r--Source/WebCore/html/HTMLOptionElement.h4
-rw-r--r--Source/WebCore/html/HTMLOptionsCollection.cpp2
-rw-r--r--Source/WebCore/html/HTMLProgressElement.cpp2
-rw-r--r--Source/WebCore/html/HTMLProgressElement.h2
-rw-r--r--Source/WebCore/html/HTMLProgressElement.idl2
-rw-r--r--Source/WebCore/html/HTMLPropertiesCollection.cpp10
-rw-r--r--Source/WebCore/html/HTMLPropertiesCollection.h4
-rw-r--r--Source/WebCore/html/HTMLSummaryElement.cpp3
-rw-r--r--Source/WebCore/html/HTMLTableRowsCollection.cpp4
-rw-r--r--Source/WebCore/html/HTMLTableRowsCollection.h2
-rw-r--r--Source/WebCore/html/HTMLTagNames.in10
-rw-r--r--Source/WebCore/html/HTMLTextAreaElement.cpp6
-rw-r--r--Source/WebCore/html/InputType.cpp12
-rw-r--r--Source/WebCore/html/InputType.h4
-rw-r--r--Source/WebCore/html/LabelsNodeList.cpp2
-rw-r--r--Source/WebCore/html/RadioNodeList.cpp2
-rw-r--r--Source/WebCore/html/RangeInputType.cpp21
-rw-r--r--Source/WebCore/html/RangeInputType.h5
-rw-r--r--Source/WebCore/html/TextFieldInputType.cpp6
-rw-r--r--Source/WebCore/html/ValidationMessage.cpp2
-rw-r--r--Source/WebCore/html/parser/HTMLConstructionSite.cpp3
-rw-r--r--Source/WebCore/html/parser/HTMLTreeBuilder.cpp31
-rw-r--r--Source/WebCore/html/parser/HTMLTreeBuilder.h3
-rw-r--r--Source/WebCore/html/shadow/CalendarPickerElement.cpp8
-rw-r--r--Source/WebCore/html/shadow/DetailsMarkerControl.cpp3
-rw-r--r--Source/WebCore/html/shadow/ImageInnerElement.cpp6
-rw-r--r--Source/WebCore/html/shadow/ImageInnerElement.h2
-rw-r--r--Source/WebCore/html/shadow/MediaControlRootElementChromium.cpp3
-rw-r--r--Source/WebCore/html/shadow/MediaControlRootElementChromium.h1
-rw-r--r--Source/WebCore/html/shadow/MeterShadowElement.cpp2
-rw-r--r--Source/WebCore/html/shadow/MeterShadowElement.h5
-rw-r--r--Source/WebCore/html/shadow/ProgressShadowElement.cpp3
-rw-r--r--Source/WebCore/html/shadow/ProgressShadowElement.h5
-rw-r--r--Source/WebCore/html/shadow/SliderThumbElement.cpp48
-rw-r--r--Source/WebCore/html/shadow/TextFieldDecorationElement.cpp9
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;