diff options
author | Simon Hausmann <simon.hausmann@digia.com> | 2012-11-29 12:18:48 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@digia.com> | 2012-11-29 12:18:57 +0100 |
commit | 4c01d0526ba4dd8cff0c0ff22a6f0ab5eb973064 (patch) | |
tree | bed2fe914fe0f7ec70abfb47d2d84af8a3604d09 /Source/WebCore/html | |
parent | 01485457c9a5da3f1121015afd25bb53af77662e (diff) |
Imported WebKit commit c60cfe0fc09efd257aa0111d7b133b02deb8a63e (http://svn.webkit.org/repository/webkit/trunk@136119)
New snapshot that includes the fix for installing the QtWebProcess into libexec
Change-Id: I01344e079cbdac5678c4cba6ffcc05f4597cf0d7
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'Source/WebCore/html')
54 files changed, 486 insertions, 241 deletions
diff --git a/Source/WebCore/html/BaseDateAndTimeInputType.cpp b/Source/WebCore/html/BaseDateAndTimeInputType.cpp index 00a1ffc38..2ad9fea79 100644 --- a/Source/WebCore/html/BaseDateAndTimeInputType.cpp +++ b/Source/WebCore/html/BaseDateAndTimeInputType.cpp @@ -180,5 +180,10 @@ String BaseDateAndTimeInputType::sanitizeValue(const String& proposedValue) cons return typeMismatchFor(proposedValue) ? String() : proposedValue; } +bool BaseDateAndTimeInputType::supportsReadOnly() const +{ + return true; +} + } // namespace WebCore #endif diff --git a/Source/WebCore/html/BaseDateAndTimeInputType.h b/Source/WebCore/html/BaseDateAndTimeInputType.h index 63b26723e..bcc7b2310 100644 --- a/Source/WebCore/html/BaseDateAndTimeInputType.h +++ b/Source/WebCore/html/BaseDateAndTimeInputType.h @@ -66,6 +66,7 @@ private: virtual String serializeWithMilliseconds(double) const; virtual String localizeValue(const String&) const OVERRIDE; virtual String convertFromVisibleValue(const String&) const OVERRIDE; + virtual bool supportsReadOnly() const OVERRIDE; }; } // namespace WebCore diff --git a/Source/WebCore/html/BaseMultipleFieldsDateAndTimeInputType.cpp b/Source/WebCore/html/BaseMultipleFieldsDateAndTimeInputType.cpp index 4bd7cde2c..b55e9a5a7 100644 --- a/Source/WebCore/html/BaseMultipleFieldsDateAndTimeInputType.cpp +++ b/Source/WebCore/html/BaseMultipleFieldsDateAndTimeInputType.cpp @@ -41,6 +41,7 @@ #include "HTMLInputElement.h" #include "HTMLOptionElement.h" #include "KeyboardEvent.h" +#include "LocalizedStrings.h" #include "Page.h" #include "PickerIndicatorElement.h" #include "PlatformLocale.h" @@ -168,6 +169,11 @@ BaseMultipleFieldsDateAndTimeInputType::~BaseMultipleFieldsDateAndTimeInputType( m_pickerIndicatorElement->removePickerIndicatorOwner(); } +String BaseMultipleFieldsDateAndTimeInputType::badInputText() const +{ + return validationMessageBadInputForDateTimeText(); +} + void BaseMultipleFieldsDateAndTimeInputType::blur() { if (m_dateTimeEditElement) @@ -273,6 +279,11 @@ void BaseMultipleFieldsDateAndTimeInputType::handleKeydownEvent(KeyboardEvent* e forwardEvent(event); } +bool BaseMultipleFieldsDateAndTimeInputType::hasBadInput() const +{ + return element()->value().isEmpty() && m_dateTimeEditElement && m_dateTimeEditElement->anyEditableFieldsHaveValues(); +} + bool BaseMultipleFieldsDateAndTimeInputType::isKeyboardFocusable(KeyboardEvent*) const { return false; @@ -325,8 +336,10 @@ FormControlState BaseMultipleFieldsDateAndTimeInputType::saveFormControlState() void BaseMultipleFieldsDateAndTimeInputType::setValue(const String& sanitizedValue, bool valueChanged, TextFieldEventBehavior eventBehavior) { InputType::setValue(sanitizedValue, valueChanged, eventBehavior); - if (valueChanged || (sanitizedValue.isEmpty() && m_dateTimeEditElement && m_dateTimeEditElement->anyEditableFieldsHaveValues())) + if (valueChanged || (sanitizedValue.isEmpty() && m_dateTimeEditElement && m_dateTimeEditElement->anyEditableFieldsHaveValues())) { updateInnerTextValue(); + element()->setNeedsValidityCheck(); + } } bool BaseMultipleFieldsDateAndTimeInputType::shouldUseInputMethod() const diff --git a/Source/WebCore/html/BaseMultipleFieldsDateAndTimeInputType.h b/Source/WebCore/html/BaseMultipleFieldsDateAndTimeInputType.h index b5acc9e6b..bd41fffef 100644 --- a/Source/WebCore/html/BaseMultipleFieldsDateAndTimeInputType.h +++ b/Source/WebCore/html/BaseMultipleFieldsDateAndTimeInputType.h @@ -73,6 +73,7 @@ private: virtual bool setupDateTimeChooserParameters(DateTimeChooserParameters&) OVERRIDE FINAL; // InputType functions + virtual String badInputText() const OVERRIDE; virtual void blur() OVERRIDE FINAL; virtual RenderObject* createRenderer(RenderArena*, RenderStyle*) const OVERRIDE FINAL; virtual void createShadowSubtree() OVERRIDE FINAL; @@ -81,6 +82,7 @@ private: virtual void focus(bool restorePreviousSelection) OVERRIDE FINAL; virtual void forwardEvent(Event*) OVERRIDE FINAL; virtual void handleKeydownEvent(KeyboardEvent*) OVERRIDE FINAL; + virtual bool hasBadInput() const OVERRIDE; virtual bool hasCustomFocusLogic() const OVERRIDE FINAL; virtual bool isKeyboardFocusable(KeyboardEvent*) const OVERRIDE FINAL; virtual bool isMouseFocusable() const OVERRIDE FINAL; diff --git a/Source/WebCore/html/CollectionType.h b/Source/WebCore/html/CollectionType.h index f43d5df0d..9ec75c054 100644 --- a/Source/WebCore/html/CollectionType.h +++ b/Source/WebCore/html/CollectionType.h @@ -26,8 +26,7 @@ namespace WebCore { enum CollectionType { - // unnamed collection types cached in the document - + // Unnamed HTMLCollection types cached in the document. DocImages, // all <img> elements in the document DocApplets, // all <object> and <applet> elements DocEmbeds, // all <embed> elements @@ -35,16 +34,13 @@ enum CollectionType { DocLinks, // all <a> _and_ <area> elements with a value for href DocAnchors, // all <a> elements with a value for name DocScripts, // all <script> elements - DocAll, // "all" elements (IE) - // named collection types cached in the document - + // Named collection types cached in the document. WindowNamedItems, DocumentNamedItems, - // types not cached in the document; these are types that can't be used on a document - + // Unnamed HTMLCollection types cached in elements. NodeChildren, // first-level children (IE) TableTBodies, // all <tbody> elements in this table TSectionRows, // all row elements in this table section @@ -54,15 +50,12 @@ enum CollectionType { SelectedOptions, DataListOptions, MapAreas, - #if ENABLE(MICRODATA) ItemProperties, // Microdata item properties in the document #endif - FormControls, - // Live node lists. - + // Live NodeList. ChildNodeListType, ClassNodeListType, NameNodeListType, @@ -73,22 +66,8 @@ enum CollectionType { PropertyNodeListType, }; -static const CollectionType FirstUnnamedDocumentCachedType = DocImages; -static const unsigned NumUnnamedDocumentCachedTypes = WindowNamedItems - DocImages; - -static const CollectionType FirstNodeCollectionType = NodeChildren; static const CollectionType FirstNodeListType = ChildNodeListType; -inline bool isUnnamedDocumentCachedType(CollectionType type) -{ - return static_cast<unsigned>(type) < NumUnnamedDocumentCachedTypes; -} - -inline bool isNodeCollectionType(CollectionType type) -{ - return type >= FirstNodeCollectionType; -} - inline bool isNodeList(CollectionType type) { return type >= FirstNodeListType; diff --git a/Source/WebCore/html/FormAssociatedElement.cpp b/Source/WebCore/html/FormAssociatedElement.cpp index 3d889783e..8dfdae096 100644 --- a/Source/WebCore/html/FormAssociatedElement.cpp +++ b/Source/WebCore/html/FormAssociatedElement.cpp @@ -189,6 +189,11 @@ bool FormAssociatedElement::customError() const return element->willValidate() && !m_customValidationMessage.isEmpty(); } +bool FormAssociatedElement::hasBadInput() const +{ + return false; +} + bool FormAssociatedElement::patternMismatch() const { return false; @@ -222,7 +227,7 @@ bool FormAssociatedElement::typeMismatch() const bool FormAssociatedElement::valid() const { bool someError = typeMismatch() || stepMismatch() || rangeUnderflow() || rangeOverflow() - || tooLong() || patternMismatch() || valueMissing() || customError(); + || tooLong() || patternMismatch() || valueMissing() || hasBadInput() || customError(); return !someError; } diff --git a/Source/WebCore/html/FormAssociatedElement.h b/Source/WebCore/html/FormAssociatedElement.h index 390e0ee75..d1dc9a59c 100644 --- a/Source/WebCore/html/FormAssociatedElement.h +++ b/Source/WebCore/html/FormAssociatedElement.h @@ -77,6 +77,7 @@ public: // Override functions for patterMismatch, rangeOverflow, rangerUnderflow, // stepMismatch, tooLong and valueMissing must call willValidate method. + virtual bool hasBadInput() const; virtual bool patternMismatch() const; virtual bool rangeOverflow() const; virtual bool rangeUnderflow() const; diff --git a/Source/WebCore/html/HTMLCollection.cpp b/Source/WebCore/html/HTMLCollection.cpp index df20954de..278f7931a 100644 --- a/Source/WebCore/html/HTMLCollection.cpp +++ b/Source/WebCore/html/HTMLCollection.cpp @@ -29,6 +29,7 @@ #include "HTMLObjectElement.h" #include "HTMLOptionElement.h" #include "NodeList.h" +#include "NodeRareData.h" #if ENABLE(MICRODATA) #include "HTMLPropertiesCollection.h" @@ -179,7 +180,6 @@ HTMLCollection::HTMLCollection(Node* ownerNode, CollectionType type, ItemAfterOv : LiveNodeListBase(ownerNode, rootTypeFromCollectionType(type), invalidationTypeExcludingIdAndNameAttributes(type), WebCore::shouldOnlyIncludeDirectChildren(type), type, itemAfterOverrideType) { - document()->registerNodeListCache(this); } PassRefPtr<HTMLCollection> HTMLCollection::create(Node* base, CollectionType type) @@ -189,16 +189,9 @@ PassRefPtr<HTMLCollection> HTMLCollection::create(Node* base, CollectionType typ HTMLCollection::~HTMLCollection() { - if (isUnnamedDocumentCachedType(type())) { - ASSERT(base()->isDocumentNode()); - static_cast<Document*>(base())->removeCachedHTMLCollection(this, type()); - } else if (isNodeCollectionType(type())) { - ASSERT(base()->isElementNode()); - toElement(base())->removeCachedHTMLCollection(this, type()); - } else // HTMLNameCollection removes cache by itself. - ASSERT(type() == WindowNamedItems || type() == DocumentNamedItems); - - document()->unregisterNodeListCache(this); + // HTMLNameCollection removes cache by itself. + if (type() != WindowNamedItems && type() != DocumentNamedItems) + ownerNode()->nodeLists()->removeCacheWithAtomicName(this, type()); } static inline bool isAcceptableElement(CollectionType type, Element* element) diff --git a/Source/WebCore/html/HTMLFontElement.cpp b/Source/WebCore/html/HTMLFontElement.cpp index a5bc8de31..1bad02e73 100644 --- a/Source/WebCore/html/HTMLFontElement.cpp +++ b/Source/WebCore/html/HTMLFontElement.cpp @@ -51,13 +51,14 @@ PassRefPtr<HTMLFontElement> HTMLFontElement::create(const QualifiedName& tagName } // http://www.whatwg.org/specs/web-apps/current-work/multipage/rendering.html#fonts-and-colors -static bool parseFontSize(const String& input, int& size) +template <typename CharacterType> +static bool parseFontSize(const CharacterType* characters, unsigned length, int& size) { // Step 1 // Step 2 - const UChar* position = input.characters(); - const UChar* end = position + input.length(); + const CharacterType* position = characters; + const CharacterType* end = characters + length; // Step 3 while (position < end) { @@ -106,7 +107,12 @@ static bool parseFontSize(const String& input, int& size) return false; // Step 8 - int value = charactersToIntStrict(digits.characters(), digits.length()); + int value; + + if (digits.is8Bit()) + value = charactersToIntStrict(digits.characters8(), digits.length()); + else + value = charactersToIntStrict(digits.characters16(), digits.length()); // Step 9 if (mode == RelativePlus) @@ -126,6 +132,17 @@ static bool parseFontSize(const String& input, int& size) return true; } +static bool parseFontSize(const String& input, int& size) +{ + if (input.isEmpty()) + return false; + + if (input.is8Bit()) + return parseFontSize(input.characters8(), input.length(), size); + + return parseFontSize(input.characters16(), input.length(), size); +} + bool HTMLFontElement::cssValueFromFontSizeNumber(const String& s, int& size) { int num = 0; diff --git a/Source/WebCore/html/HTMLFormControlElement.cpp b/Source/WebCore/html/HTMLFormControlElement.cpp index 9b19f8c4d..d433946e8 100644 --- a/Source/WebCore/html/HTMLFormControlElement.cpp +++ b/Source/WebCore/html/HTMLFormControlElement.cpp @@ -172,8 +172,11 @@ static bool shouldAutofocus(HTMLFormControlElement* element) return false; if (element->document()->ignoreAutofocus()) return false; - if (element->document()->isSandboxed(SandboxAutomaticFeatures)) + if (element->document()->isSandboxed(SandboxAutomaticFeatures)) { + // FIXME: This message should be moved off the console once a solution to https://bugs.webkit.org/show_bug.cgi?id=103274 exists. + element->document()->addConsoleMessage(HTMLMessageSource, LogMessageType, ErrorMessageLevel, "Blocked autofocusing on a form control because the form's frame is sandboxed and the 'allow-script' permission is not set."); return false; + } if (element->hasAutofocused()) return false; @@ -459,16 +462,6 @@ void HTMLFormControlElement::setCustomValidity(const String& error) setNeedsValidityCheck(); } -bool HTMLFormControlElement::shouldMatchReadOnlySelector() const -{ - return readOnly(); -} - -bool HTMLFormControlElement::shouldMatchReadWriteSelector() const -{ - return !readOnly(); -} - bool HTMLFormControlElement::validationMessageShadowTreeContains(Node* node) const { return m_validationMessage && m_validationMessage->shadowTreeContains(node); diff --git a/Source/WebCore/html/HTMLFormControlElement.h b/Source/WebCore/html/HTMLFormControlElement.h index ec6e885f5..185b37d92 100644 --- a/Source/WebCore/html/HTMLFormControlElement.h +++ b/Source/WebCore/html/HTMLFormControlElement.h @@ -81,8 +81,6 @@ public: virtual const AtomicString& formControlType() const OVERRIDE = 0; virtual bool isEnabledFormControl() const { return !disabled(); } - virtual bool shouldMatchReadOnlySelector() const OVERRIDE; - virtual bool shouldMatchReadWriteSelector() const OVERRIDE; virtual bool canTriggerImplicitSubmission() const { return false; } diff --git a/Source/WebCore/html/HTMLFormControlsCollection.cpp b/Source/WebCore/html/HTMLFormControlsCollection.cpp index e73520901..aac92ba46 100644 --- a/Source/WebCore/html/HTMLFormControlsCollection.cpp +++ b/Source/WebCore/html/HTMLFormControlsCollection.cpp @@ -36,13 +36,13 @@ using namespace HTMLNames; // Since the collections are to be "live", we have to do the // calculation every time if anything has changed. -HTMLFormControlsCollection::HTMLFormControlsCollection(Element* base) +HTMLFormControlsCollection::HTMLFormControlsCollection(Node* base) : HTMLCollection(base, FormControls, OverridesItemAfter) { ASSERT(base->hasTagName(formTag) || base->hasTagName(fieldsetTag)); } -PassRefPtr<HTMLFormControlsCollection> HTMLFormControlsCollection::create(Element* base, CollectionType) +PassRefPtr<HTMLFormControlsCollection> HTMLFormControlsCollection::create(Node* base, CollectionType) { return adoptRef(new HTMLFormControlsCollection(base)); } diff --git a/Source/WebCore/html/HTMLFormControlsCollection.h b/Source/WebCore/html/HTMLFormControlsCollection.h index 7846a504e..cef0f14d5 100644 --- a/Source/WebCore/html/HTMLFormControlsCollection.h +++ b/Source/WebCore/html/HTMLFormControlsCollection.h @@ -37,14 +37,14 @@ class QualifiedName; class HTMLFormControlsCollection : public HTMLCollection { public: - static PassRefPtr<HTMLFormControlsCollection> create(Element*, CollectionType); + static PassRefPtr<HTMLFormControlsCollection> create(Node*, CollectionType); virtual ~HTMLFormControlsCollection(); virtual Node* namedItem(const AtomicString& name) const; private: - HTMLFormControlsCollection(Element*); + HTMLFormControlsCollection(Node*); virtual void updateNameCache() const; diff --git a/Source/WebCore/html/HTMLInputElement.cpp b/Source/WebCore/html/HTMLInputElement.cpp index 4cae786f1..124af4e60 100644 --- a/Source/WebCore/html/HTMLInputElement.cpp +++ b/Source/WebCore/html/HTMLInputElement.cpp @@ -266,6 +266,11 @@ bool HTMLInputElement::valueMissing() const return willValidate() && m_inputType->valueMissing(value()); } +bool HTMLInputElement::hasBadInput() const +{ + return willValidate() && m_inputType->hasBadInput(); +} + bool HTMLInputElement::patternMismatch() const { return willValidate() && m_inputType->patternMismatch(value()); @@ -1391,11 +1396,6 @@ String HTMLInputElement::localizeValue(const String& proposedValue) const return m_inputType->localizeValue(proposedValue); } -bool HTMLInputElement::hasUnacceptableValue() const -{ - return m_inputType->hasUnacceptableValue(); -} - bool HTMLInputElement::isInRange() const { return m_inputType->isInRange(value()); @@ -1438,6 +1438,16 @@ bool HTMLInputElement::isRequiredFormControl() const return m_inputType->supportsRequired() && required(); } +bool HTMLInputElement::shouldMatchReadOnlySelector() const +{ + return m_inputType->supportsReadOnly() && readOnly(); +} + +bool HTMLInputElement::shouldMatchReadWriteSelector() const +{ + return m_inputType->supportsReadOnly() && !readOnly(); +} + void HTMLInputElement::addSearchResult() { m_inputType->addSearchResult(); diff --git a/Source/WebCore/html/HTMLInputElement.h b/Source/WebCore/html/HTMLInputElement.h index b0ac6ae96..f98b019f6 100644 --- a/Source/WebCore/html/HTMLInputElement.h +++ b/Source/WebCore/html/HTMLInputElement.h @@ -55,6 +55,7 @@ public: virtual bool shouldAutocomplete() const; // For ValidityState + virtual bool hasBadInput() const OVERRIDE; virtual bool patternMismatch() const OVERRIDE; virtual bool rangeUnderflow() const OVERRIDE; virtual bool rangeOverflow() const; @@ -288,6 +289,8 @@ public: static Vector<FileChooserFileInfo> filesFromFileInputFormControlState(const FormControlState&); + virtual bool shouldMatchReadOnlySelector() const OVERRIDE; + virtual bool shouldMatchReadWriteSelector() const OVERRIDE; virtual void setRangeText(const String& replacement, ExceptionCode&) OVERRIDE; virtual void setRangeText(const String& replacement, unsigned start, unsigned end, const String& selectionMode, ExceptionCode&) OVERRIDE; @@ -355,8 +358,6 @@ private: virtual bool isURLAttribute(const Attribute&) const OVERRIDE; - virtual bool hasUnacceptableValue() const; - virtual bool isInRange() const; virtual bool isOutOfRange() const; diff --git a/Source/WebCore/html/HTMLMediaElement.cpp b/Source/WebCore/html/HTMLMediaElement.cpp index 027dd21d9..732b91717 100644 --- a/Source/WebCore/html/HTMLMediaElement.cpp +++ b/Source/WebCore/html/HTMLMediaElement.cpp @@ -316,6 +316,10 @@ HTMLMediaElement::~HTMLMediaElement() if (m_mediaController) m_mediaController->removeMediaElement(this); +#if ENABLE(MEDIA_SOURCE) + setSourceState(MediaSource::closedKeyword()); +#endif + removeElementFromDocumentMap(this, document()); } @@ -676,16 +680,14 @@ String HTMLMediaElement::canPlayType(const String& mimeType, const String& keySy return canPlay; } -void HTMLMediaElement::load(ExceptionCode& ec) +void HTMLMediaElement::load() { RefPtr<HTMLMediaElement> protect(this); // loadInternal may result in a 'beforeload' event, which can make arbitrary DOM mutations. LOG(Media, "HTMLMediaElement::load()"); - if (userGestureRequiredForLoad() && !ScriptController::processingUserGesture()) { - ec = INVALID_STATE_ERR; + if (userGestureRequiredForLoad() && !ScriptController::processingUserGesture()) return; - } m_loadInitiatedByUserGesture = ScriptController::processingUserGesture(); if (m_loadInitiatedByUserGesture) @@ -2996,6 +2998,22 @@ void HTMLMediaElement::configureTextTrackGroup(const TrackGroup& group) const } } +void HTMLMediaElement::toggleTrackAtIndex(int index, bool exclusive) +{ + TextTrackList* trackList = textTracks(); + if (!trackList || !trackList->length()) + return; + + for (int i = 0, length = trackList->length(); i < length; ++i) { + TextTrack* track = trackList->item(i); + track->setShowingByDefault(false); + if (i == index) + track->setMode(TextTrack::showingKeyword()); + else if (exclusive || index == HTMLMediaElement::textTracksOffIndex()) + track->setMode(TextTrack::disabledKeyword()); + } +} + void HTMLMediaElement::configureTextTracks() { TrackGroup captionAndSubtitleTracks(TrackGroup::CaptionsAndSubtitles); @@ -3752,6 +3770,11 @@ void HTMLMediaElement::userCancelledLoad() void HTMLMediaElement::clearMediaPlayer(int flags) { #if !ENABLE(PLUGIN_PROXY_FOR_VIDEO) + +#if ENABLE(MEDIA_SOURCE) + setSourceState(MediaSource::closedKeyword()); +#endif + m_player.clear(); #endif stopPeriodicTimers(); @@ -3815,8 +3838,7 @@ void HTMLMediaElement::resume() // m_error is only left at MEDIA_ERR_ABORTED when the document becomes inactive (it is set to // MEDIA_ERR_ABORTED while the abortEvent is being sent, but cleared immediately afterwards). // This behavior is not specified but it seems like a sensible thing to do. - ExceptionCode ec; - load(ec); + load(); } if (renderer()) diff --git a/Source/WebCore/html/HTMLMediaElement.h b/Source/WebCore/html/HTMLMediaElement.h index c53129d62..80549c262 100644 --- a/Source/WebCore/html/HTMLMediaElement.h +++ b/Source/WebCore/html/HTMLMediaElement.h @@ -134,7 +134,7 @@ public: void setPreload(const String&); PassRefPtr<TimeRanges> buffered() const; - void load(ExceptionCode&); + void load(); String canPlayType(const String& mimeType, const String& keySystem = String(), const KURL& = KURL()) const; // ready state @@ -245,6 +245,9 @@ public: void configureTextTracks(); void configureTextTrackGroup(const TrackGroup&) const; + void toggleTrackAtIndex(int index, bool exclusive = true); + static int textTracksOffIndex() { return -1; } + bool userPrefersCaptions() const; bool userIsInterestedInThisTrackKind(String) const; bool textTracksAreReady() const; diff --git a/Source/WebCore/html/HTMLMediaElement.idl b/Source/WebCore/html/HTMLMediaElement.idl index ece0f5348..2ece5acaa 100644 --- a/Source/WebCore/html/HTMLMediaElement.idl +++ b/Source/WebCore/html/HTMLMediaElement.idl @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2010, 2011 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2010, 2011, 2012 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -43,8 +43,7 @@ readonly attribute unsigned short networkState; attribute DOMString preload; readonly attribute TimeRanges buffered; -void load() - raises (DOMException); +void load(); #if defined(ENABLE_ENCRYPTED_MEDIA) && ENABLE_ENCRYPTED_MEDIA DOMString canPlayType(in [Optional=DefaultIsUndefined] DOMString type, in [Optional=DefaultIsUndefined, TreatNullAs=NullString, TreatUndefinedAs=NullString] DOMString keySystem); #else diff --git a/Source/WebCore/html/HTMLNameCollection.cpp b/Source/WebCore/html/HTMLNameCollection.cpp index 36c7350a4..9e48527e9 100644 --- a/Source/WebCore/html/HTMLNameCollection.cpp +++ b/Source/WebCore/html/HTMLNameCollection.cpp @@ -27,12 +27,13 @@ #include "HTMLDocument.h" #include "HTMLNames.h" #include "HTMLObjectElement.h" +#include "NodeRareData.h" namespace WebCore { using namespace HTMLNames; -HTMLNameCollection::HTMLNameCollection(Document* document, CollectionType type, const AtomicString& name) +HTMLNameCollection::HTMLNameCollection(Node* document, CollectionType type, const AtomicString& name) : HTMLCollection(document, type, OverridesItemAfter) , m_name(name) { @@ -43,10 +44,8 @@ HTMLNameCollection::~HTMLNameCollection() ASSERT(base()); ASSERT(base()->isDocumentNode()); ASSERT(type() == WindowNamedItems || type() == DocumentNamedItems); - if (type() == WindowNamedItems) - static_cast<Document*>(base())->removeWindowNamedItemCache(this, m_name); - else - static_cast<Document*>(base())->removeDocumentNamedItemCache(this, m_name); + + ownerNode()->nodeLists()->removeCacheWithAtomicName(this, type(), m_name); } Element* HTMLNameCollection::virtualItemAfter(unsigned& offsetInArray, Element* previous) const diff --git a/Source/WebCore/html/HTMLNameCollection.h b/Source/WebCore/html/HTMLNameCollection.h index 4a7afebb7..1fb85b994 100644 --- a/Source/WebCore/html/HTMLNameCollection.h +++ b/Source/WebCore/html/HTMLNameCollection.h @@ -33,7 +33,7 @@ class Document; class HTMLNameCollection : public HTMLCollection { public: - static PassRefPtr<HTMLNameCollection> create(Document* document, CollectionType type, const AtomicString& name) + static PassRefPtr<HTMLNameCollection> create(Node* document, CollectionType type, const AtomicString& name) { return adoptRef(new HTMLNameCollection(document, type, name)); } @@ -41,7 +41,7 @@ public: ~HTMLNameCollection(); private: - HTMLNameCollection(Document*, CollectionType, const AtomicString& name); + HTMLNameCollection(Node*, CollectionType, const AtomicString& name); virtual Element* virtualItemAfter(unsigned& offsetInArray, Element*) const OVERRIDE; diff --git a/Source/WebCore/html/HTMLOptionElement.h b/Source/WebCore/html/HTMLOptionElement.h index 1bcb9433c..19f569b97 100644 --- a/Source/WebCore/html/HTMLOptionElement.h +++ b/Source/WebCore/html/HTMLOptionElement.h @@ -92,8 +92,6 @@ private: String collectOptionInnerText() const; - String m_value; - String m_label; bool m_disabled; bool m_isSelected; RefPtr<RenderStyle> m_style; diff --git a/Source/WebCore/html/HTMLOptionsCollection.cpp b/Source/WebCore/html/HTMLOptionsCollection.cpp index 06dda7a25..75b707e55 100644 --- a/Source/WebCore/html/HTMLOptionsCollection.cpp +++ b/Source/WebCore/html/HTMLOptionsCollection.cpp @@ -27,13 +27,13 @@ namespace WebCore { -HTMLOptionsCollection::HTMLOptionsCollection(Element* select) +HTMLOptionsCollection::HTMLOptionsCollection(Node* select) : HTMLCollection(select, SelectOptions, DoesNotOverrideItemAfter) { ASSERT(select->hasTagName(HTMLNames::selectTag)); } -PassRefPtr<HTMLOptionsCollection> HTMLOptionsCollection::create(Element* select, CollectionType) +PassRefPtr<HTMLOptionsCollection> HTMLOptionsCollection::create(Node* select, CollectionType) { return adoptRef(new HTMLOptionsCollection(select)); } diff --git a/Source/WebCore/html/HTMLOptionsCollection.h b/Source/WebCore/html/HTMLOptionsCollection.h index 46e450df2..d76580fe7 100644 --- a/Source/WebCore/html/HTMLOptionsCollection.h +++ b/Source/WebCore/html/HTMLOptionsCollection.h @@ -35,7 +35,7 @@ typedef int ExceptionCode; class HTMLOptionsCollection : public HTMLCollection { public: - static PassRefPtr<HTMLOptionsCollection> create(Element*, CollectionType); + static PassRefPtr<HTMLOptionsCollection> create(Node*, CollectionType); void add(PassRefPtr<HTMLOptionElement>, ExceptionCode&); void add(PassRefPtr<HTMLOptionElement>, int index, ExceptionCode&); @@ -47,7 +47,7 @@ public: void setLength(unsigned, ExceptionCode&); private: - HTMLOptionsCollection(Element*); + HTMLOptionsCollection(Node*); }; } //namespace diff --git a/Source/WebCore/html/HTMLPlugInElement.cpp b/Source/WebCore/html/HTMLPlugInElement.cpp index bd99dbfd7..e2902ad71 100644 --- a/Source/WebCore/html/HTMLPlugInElement.cpp +++ b/Source/WebCore/html/HTMLPlugInElement.cpp @@ -201,7 +201,7 @@ void HTMLPlugInElement::defaultEventHandler(Event* event) toRenderEmbeddedObject(r)->handleUnavailablePluginIndicatorEvent(event); return; } - if (r->isSnapshottedPlugIn() && displayState() < Playing) { + if (r->isSnapshottedPlugIn() && displayState() < PlayingWithPendingMouseClick) { toRenderSnapshottedPlugIn(r)->handleEvent(event); return; } diff --git a/Source/WebCore/html/HTMLPlugInElement.h b/Source/WebCore/html/HTMLPlugInElement.h index 379324f70..5a62d54f3 100644 --- a/Source/WebCore/html/HTMLPlugInElement.h +++ b/Source/WebCore/html/HTMLPlugInElement.h @@ -51,11 +51,13 @@ public: enum DisplayState { WaitingForSnapshot, DisplayingSnapshot, + PlayingWithPendingMouseClick, Playing }; DisplayState displayState() const { return m_displayState; } void setDisplayState(DisplayState state) { m_displayState = state; } virtual void updateSnapshot(PassRefPtr<Image>) { } + virtual void dispatchPendingMouseClick() { } #if ENABLE(NETSCAPE_PLUGIN_API) NPObject* getNPObject(); diff --git a/Source/WebCore/html/HTMLPlugInImageElement.cpp b/Source/WebCore/html/HTMLPlugInImageElement.cpp index b809a1340..421ac1b0f 100644 --- a/Source/WebCore/html/HTMLPlugInImageElement.cpp +++ b/Source/WebCore/html/HTMLPlugInImageElement.cpp @@ -27,6 +27,7 @@ #include "HTMLImageLoader.h" #include "HTMLNames.h" #include "Image.h" +#include "MouseEvent.h" #include "NodeRenderStyle.h" #include "Page.h" #include "RenderEmbeddedObject.h" @@ -38,6 +39,9 @@ namespace WebCore { +// This delay should not exceed the snapshot delay in PluginView.cpp +static const double simulatedMouseClickTimerDelay = .75; + HTMLPlugInImageElement::HTMLPlugInImageElement(const QualifiedName& tagName, Document* document, bool createdByParser, PreferPlugInsForImagesOption preferPlugInsForImagesOption) : HTMLPlugInElement(tagName, document) // m_needsWidgetUpdate(!createdByParser) allows HTMLObjectElement to delay @@ -47,6 +51,7 @@ HTMLPlugInImageElement::HTMLPlugInImageElement(const QualifiedName& tagName, Doc , m_needsWidgetUpdate(!createdByParser) , m_shouldPreferPlugInsForImages(preferPlugInsForImagesOption == ShouldPreferPlugInsForImages) , m_needsDocumentActivationCallbacks(false) + , m_simulatedMouseClickTimer(this, &HTMLPlugInImageElement::simulatedMouseClickTimerFired, simulatedMouseClickTimerDelay) { setHasCustomCallbacks(); @@ -257,4 +262,26 @@ void HTMLPlugInImageElement::updateSnapshot(PassRefPtr<Image> image) setDisplayState(DisplayingSnapshot); } +void HTMLPlugInImageElement::setPendingClickEvent(PassRefPtr<MouseEvent> event) +{ + m_pendingClickEventFromSnapshot = event; +} + +void HTMLPlugInImageElement::dispatchPendingMouseClick() +{ + ASSERT(!m_simulatedMouseClickTimer.isActive()); + m_simulatedMouseClickTimer.restart(); +} + +void HTMLPlugInImageElement::simulatedMouseClickTimerFired(DeferrableOneShotTimer<HTMLPlugInImageElement>*) +{ + ASSERT(displayState() == PlayingWithPendingMouseClick); + ASSERT(m_pendingClickEventFromSnapshot); + + dispatchSimulatedClick(m_pendingClickEventFromSnapshot.get(), SendMouseOverUpDownEvents, DoNotShowPressedLook); + + setDisplayState(Playing); + m_pendingClickEventFromSnapshot = nullptr; +} + } // namespace WebCore diff --git a/Source/WebCore/html/HTMLPlugInImageElement.h b/Source/WebCore/html/HTMLPlugInImageElement.h index 95fbd8a79..c5bf6fa1f 100644 --- a/Source/WebCore/html/HTMLPlugInImageElement.h +++ b/Source/WebCore/html/HTMLPlugInImageElement.h @@ -30,6 +30,7 @@ namespace WebCore { class HTMLImageLoader; class FrameLoader; +class MouseEvent; enum PluginCreationOption { CreateAnyWidgetType, @@ -58,6 +59,8 @@ public: bool needsWidgetUpdate() const { return m_needsWidgetUpdate; } void setNeedsWidgetUpdate(bool needsWidgetUpdate) { m_needsWidgetUpdate = needsWidgetUpdate; } + void setPendingClickEvent(PassRefPtr<MouseEvent>); + protected: HTMLPlugInImageElement(const QualifiedName& tagName, Document*, bool createdByParser, PreferPlugInsForImagesOption); @@ -91,11 +94,15 @@ private: virtual bool useFallbackContent() const { return false; } virtual void updateSnapshot(PassRefPtr<Image>) OVERRIDE; + virtual void dispatchPendingMouseClick() OVERRIDE; + void simulatedMouseClickTimerFired(DeferrableOneShotTimer<HTMLPlugInImageElement>*); bool m_needsWidgetUpdate; bool m_shouldPreferPlugInsForImages; bool m_needsDocumentActivationCallbacks; RefPtr<RenderStyle> m_customStyleForPageCache; + RefPtr<MouseEvent> m_pendingClickEventFromSnapshot; + DeferrableOneShotTimer<HTMLPlugInImageElement> m_simulatedMouseClickTimer; }; } // namespace WebCore diff --git a/Source/WebCore/html/HTMLTableRowsCollection.cpp b/Source/WebCore/html/HTMLTableRowsCollection.cpp index d94038e63..98459366e 100644 --- a/Source/WebCore/html/HTMLTableRowsCollection.cpp +++ b/Source/WebCore/html/HTMLTableRowsCollection.cpp @@ -151,13 +151,13 @@ HTMLTableRowElement* HTMLTableRowsCollection::lastRow(HTMLTableElement* table) // Must call get() on the table in case that argument is compiled before dereferencing the // table to get at the collection cache. Order of argument evaluation is undefined and can // differ between compilers. -HTMLTableRowsCollection::HTMLTableRowsCollection(Element* table) +HTMLTableRowsCollection::HTMLTableRowsCollection(Node* table) : HTMLCollection(table, TableRows, OverridesItemAfter) { ASSERT(table->hasTagName(tableTag)); } -PassRefPtr<HTMLTableRowsCollection> HTMLTableRowsCollection::create(Element* table, CollectionType) +PassRefPtr<HTMLTableRowsCollection> HTMLTableRowsCollection::create(Node* table, CollectionType) { return adoptRef(new HTMLTableRowsCollection(table)); } diff --git a/Source/WebCore/html/HTMLTableRowsCollection.h b/Source/WebCore/html/HTMLTableRowsCollection.h index c4312896f..1a54f0f1f 100644 --- a/Source/WebCore/html/HTMLTableRowsCollection.h +++ b/Source/WebCore/html/HTMLTableRowsCollection.h @@ -38,13 +38,13 @@ class HTMLTableRowElement; class HTMLTableRowsCollection : public HTMLCollection { public: - static PassRefPtr<HTMLTableRowsCollection> create(Element*, CollectionType); + static PassRefPtr<HTMLTableRowsCollection> create(Node*, CollectionType); static HTMLTableRowElement* rowAfter(HTMLTableElement*, HTMLTableRowElement*); static HTMLTableRowElement* lastRow(HTMLTableElement*); private: - HTMLTableRowsCollection(Element*); + HTMLTableRowsCollection(Node*); virtual Element* virtualItemAfter(unsigned& offsetInArray, Element*) const OVERRIDE; }; diff --git a/Source/WebCore/html/HTMLTextAreaElement.cpp b/Source/WebCore/html/HTMLTextAreaElement.cpp index 1632927dc..fa6da55c0 100644 --- a/Source/WebCore/html/HTMLTextAreaElement.cpp +++ b/Source/WebCore/html/HTMLTextAreaElement.cpp @@ -529,6 +529,16 @@ void HTMLTextAreaElement::attach() fixPlaceholderRenderer(m_placeholder, innerTextElement()); } +bool HTMLTextAreaElement::shouldMatchReadOnlySelector() const +{ + return readOnly(); +} + +bool HTMLTextAreaElement::shouldMatchReadWriteSelector() const +{ + return !readOnly(); +} + void HTMLTextAreaElement::updatePlaceholderText() { ExceptionCode ec = 0; diff --git a/Source/WebCore/html/HTMLTextAreaElement.h b/Source/WebCore/html/HTMLTextAreaElement.h index fcc19f8d4..3964ce2be 100644 --- a/Source/WebCore/html/HTMLTextAreaElement.h +++ b/Source/WebCore/html/HTMLTextAreaElement.h @@ -112,6 +112,8 @@ private: virtual bool shouldUseInputMethod(); virtual void attach() OVERRIDE; + virtual bool shouldMatchReadOnlySelector() const OVERRIDE; + virtual bool shouldMatchReadWriteSelector() const OVERRIDE; bool valueMissing(const String& value) const { return isRequiredFormControl() && !disabled() && !readOnly() && value.isEmpty(); } bool tooLong(const String&, NeedsToCheckDirtyFlag) const; diff --git a/Source/WebCore/html/InputType.cpp b/Source/WebCore/html/InputType.cpp index 4a437e029..b16fa3b18 100644 --- a/Source/WebCore/html/InputType.cpp +++ b/Source/WebCore/html/InputType.cpp @@ -258,6 +258,11 @@ bool InputType::valueMissing(const String&) const return false; } +bool InputType::hasBadInput() const +{ + return false; +} + bool InputType::patternMismatch(const String&) const { return false; @@ -346,6 +351,12 @@ bool InputType::stepMismatch(const String& value) const return createStepRange(RejectAny).stepMismatch(numericValue); } +String InputType::badInputText() const +{ + ASSERT_NOT_REACHED(); + return validationMessageTypeMismatchText(); +} + String InputType::typeMismatchText() const { return validationMessageTypeMismatchText(); @@ -368,6 +379,9 @@ String InputType::validationMessage() const if (typeMismatch()) return typeMismatchText(); + if (hasBadInput()) + return badInputText(); + if (patternMismatch(value)) return validationMessagePatternMismatchText(); @@ -689,11 +703,6 @@ String InputType::sanitizeValue(const String& proposedValue) const return proposedValue; } -bool InputType::hasUnacceptableValue() -{ - return false; -} - bool InputType::receiveDroppedFiles(const DragData*) { ASSERT_NOT_REACHED(); @@ -861,6 +870,11 @@ bool InputType::supportsPlaceholder() const return false; } +bool InputType::supportsReadOnly() const +{ + return false; +} + void InputType::updateInnerTextValue() { } diff --git a/Source/WebCore/html/InputType.h b/Source/WebCore/html/InputType.h index fe4a9e4d9..333a256a0 100644 --- a/Source/WebCore/html/InputType.h +++ b/Source/WebCore/html/InputType.h @@ -156,6 +156,7 @@ public: virtual bool typeMismatch() const; virtual bool supportsRequired() const; virtual bool valueMissing(const String&) const; + virtual bool hasBadInput() const; virtual bool patternMismatch(const String&) const; bool rangeUnderflow(const String&) const; bool rangeOverflow(const String&) const; @@ -170,6 +171,7 @@ public: virtual StepRange createStepRange(AnyStepHandling) const; virtual void stepUp(int, ExceptionCode&); virtual void stepUpFromRenderer(int); + virtual String badInputText() const; virtual String typeMismatchText() const; virtual String valueMissingText() const; virtual bool canSetStringValue() const; @@ -178,7 +180,6 @@ public: // Returing the null string means "use the default value." // This function must be called only by HTMLInputElement::sanitizeValue(). virtual String sanitizeValue(const String&) const; - virtual bool hasUnacceptableValue(); // Event handlers @@ -267,6 +268,7 @@ public: virtual bool isSteppable() const; virtual bool shouldRespectHeightAndWidthAttributes(); virtual bool supportsPlaceholder() const; + virtual bool supportsReadOnly() const; virtual void updateInnerTextValue(); virtual void updatePlaceholderText(); virtual void multipleAttributeChanged(); diff --git a/Source/WebCore/html/LabelsNodeList.h b/Source/WebCore/html/LabelsNodeList.h index 9052eedd6..0da4f3c7e 100644 --- a/Source/WebCore/html/LabelsNodeList.h +++ b/Source/WebCore/html/LabelsNodeList.h @@ -32,8 +32,9 @@ namespace WebCore { class LabelsNodeList : public LiveNodeList { public: - static PassRefPtr<LabelsNodeList> create(Node* forNode, const AtomicString&) + static PassRefPtr<LabelsNodeList> create(Node* forNode, CollectionType type, const AtomicString&) { + ASSERT_UNUSED(type, type == LabelsNodeListType); return adoptRef(new LabelsNodeList(forNode)); } ~LabelsNodeList(); diff --git a/Source/WebCore/html/NumberInputType.cpp b/Source/WebCore/html/NumberInputType.cpp index 7498cc991..440ee7b9b 100644 --- a/Source/WebCore/html/NumberInputType.cpp +++ b/Source/WebCore/html/NumberInputType.cpp @@ -39,6 +39,7 @@ #include "HTMLParserIdioms.h" #include "InputTypeNames.h" #include "KeyboardEvent.h" +#include "LocalizedStrings.h" #include "PlatformLocale.h" #include "RenderTextControl.h" #include <limits> @@ -213,16 +214,6 @@ String NumberInputType::serialize(const Decimal& value) const return serializeForNumberType(value); } -void NumberInputType::handleBlurEvent() -{ - // Reset the renderer value, which might be unmatched with the element value. - element()->setFormControlValueMatchesRenderer(false); - - // We need to reset the renderer value explicitly because an unacceptable - // renderer value should be purged before style calculation. - updateInnerTextValue(); -} - static bool isE(UChar ch) { return ch == 'e' || ch == 'E'; @@ -260,14 +251,17 @@ String NumberInputType::sanitizeValue(const String& proposedValue) const return isfinite(parseToDoubleForNumberType(proposedValue)) ? proposedValue : emptyString(); } -bool NumberInputType::hasUnacceptableValue() +bool NumberInputType::hasBadInput() const { - if (!element()->renderer()) - return false; String standardValue = convertFromVisibleValue(element()->innerTextValue()); return !standardValue.isEmpty() && !isfinite(parseToDoubleForNumberType(standardValue)); } +String NumberInputType::badInputText() const +{ + return validationMessageBadInputForNumberText(); +} + bool NumberInputType::shouldRespectSpeechAttribute() { return true; diff --git a/Source/WebCore/html/NumberInputType.h b/Source/WebCore/html/NumberInputType.h index 11cca557b..c77a9a78e 100644 --- a/Source/WebCore/html/NumberInputType.h +++ b/Source/WebCore/html/NumberInputType.h @@ -53,12 +53,12 @@ private: virtual void handleKeydownEvent(KeyboardEvent*) OVERRIDE; virtual Decimal parseToNumber(const String&, const Decimal&) const OVERRIDE; virtual String serialize(const Decimal&) const OVERRIDE; - virtual void handleBlurEvent() OVERRIDE; virtual String localizeValue(const String&) const OVERRIDE; virtual String visibleValue() const OVERRIDE; virtual String convertFromVisibleValue(const String&) const OVERRIDE; virtual String sanitizeValue(const String&) const OVERRIDE; - virtual bool hasUnacceptableValue() OVERRIDE; + virtual bool hasBadInput() const OVERRIDE; + virtual String badInputText() const OVERRIDE; virtual bool shouldRespectSpeechAttribute() OVERRIDE; virtual bool supportsPlaceholder() const OVERRIDE; virtual bool isNumberField() const OVERRIDE; diff --git a/Source/WebCore/html/RadioNodeList.h b/Source/WebCore/html/RadioNodeList.h index 23a527d35..57cad32d4 100644 --- a/Source/WebCore/html/RadioNodeList.h +++ b/Source/WebCore/html/RadioNodeList.h @@ -36,8 +36,9 @@ namespace WebCore { class RadioNodeList : public LiveNodeList { public: - static PassRefPtr<RadioNodeList> create(Node* rootNode, const AtomicString& name) + static PassRefPtr<RadioNodeList> create(Node* rootNode, CollectionType type, const AtomicString& name) { + ASSERT_UNUSED(type, type == RadioNodeListType); return adoptRef(new RadioNodeList(rootNode, name)); } diff --git a/Source/WebCore/html/RangeInputType.cpp b/Source/WebCore/html/RangeInputType.cpp index c37f6b770..ed2a8a118 100644 --- a/Source/WebCore/html/RangeInputType.cpp +++ b/Source/WebCore/html/RangeInputType.cpp @@ -260,7 +260,6 @@ void RangeInputType::createShadowSubtree() track->appendChild(SliderThumbElement::create(document), ec); RefPtr<HTMLElement> container = SliderContainerElement::create(document); container->appendChild(track.release(), ec); - container->appendChild(TrackLimiterElement::create(document), ec); element()->userAgentShadowRoot()->appendChild(container.release(), ec); } diff --git a/Source/WebCore/html/TextFieldInputType.cpp b/Source/WebCore/html/TextFieldInputType.cpp index a5edcb0b3..4a95b89c9 100644 --- a/Source/WebCore/html/TextFieldInputType.cpp +++ b/Source/WebCore/html/TextFieldInputType.cpp @@ -329,6 +329,11 @@ void TextFieldInputType::readonlyAttributeChanged() m_innerSpinButton->releaseCapture(); } +bool TextFieldInputType::supportsReadOnly() const +{ + return true; +} + bool TextFieldInputType::shouldUseInputMethod() const { return true; @@ -458,7 +463,7 @@ void TextFieldInputType::subtreeHasChanged() // sanitizeValue() is needed because IME input doesn't dispatch BeforeTextInsertedEvent. element()->setValueFromRenderer(sanitizeValue(convertFromVisibleValue(element()->innerTextValue()))); element()->updatePlaceholderVisibility(false); - // Recalc for :invalid and hasUnacceptableValue() change. + // Recalc for :invalid change. element()->setNeedsStyleRecalc(); didSetValueByUserEdit(wasChanged ? ValueChangeStateChanged : ValueChangeStateNone); diff --git a/Source/WebCore/html/TextFieldInputType.h b/Source/WebCore/html/TextFieldInputType.h index b32aeaa68..a79887138 100644 --- a/Source/WebCore/html/TextFieldInputType.h +++ b/Source/WebCore/html/TextFieldInputType.h @@ -64,6 +64,7 @@ protected: virtual void destroyShadowSubtree() OVERRIDE; virtual void disabledAttributeChanged() OVERRIDE; virtual void readonlyAttributeChanged() OVERRIDE; + virtual bool supportsReadOnly() const OVERRIDE; virtual void handleBlurEvent() OVERRIDE; virtual void setValue(const String&, bool valueChanged, TextFieldEventBehavior) OVERRIDE; virtual void updateInnerTextValue() OVERRIDE; diff --git a/Source/WebCore/html/ValidityState.cpp b/Source/WebCore/html/ValidityState.cpp index 649765df9..f04ea76ef 100644 --- a/Source/WebCore/html/ValidityState.cpp +++ b/Source/WebCore/html/ValidityState.cpp @@ -76,6 +76,11 @@ bool ValidityState::stepMismatch() const return m_control->stepMismatch(); } +bool ValidityState::badInput() const +{ + return m_control->hasBadInput(); +} + bool ValidityState::customError() const { return m_control->customError(); diff --git a/Source/WebCore/html/ValidityState.h b/Source/WebCore/html/ValidityState.h index 28f9ec640..452739a77 100644 --- a/Source/WebCore/html/ValidityState.h +++ b/Source/WebCore/html/ValidityState.h @@ -52,6 +52,7 @@ public: bool rangeUnderflow() const; bool rangeOverflow() const; bool stepMismatch() const; + bool badInput() const; bool customError() const; bool valid() const; diff --git a/Source/WebCore/html/ValidityState.idl b/Source/WebCore/html/ValidityState.idl index dae343b9a..170c45e69 100644 --- a/Source/WebCore/html/ValidityState.idl +++ b/Source/WebCore/html/ValidityState.idl @@ -30,6 +30,7 @@ readonly attribute boolean rangeUnderflow; readonly attribute boolean rangeOverflow; readonly attribute boolean stepMismatch; + readonly attribute boolean badInput; readonly attribute boolean customError; readonly attribute boolean valid; }; diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp b/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp index ef754f597..3eb38a105 100644 --- a/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp +++ b/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp @@ -2070,8 +2070,11 @@ void CanvasRenderingContext2D::setFont(const String& newFont) if (parsedStyle->isEmpty()) return; - RefPtr<CSSValue> fontValue = parsedStyle->getPropertyCSSValue(CSSPropertyFont); - if (fontValue && fontValue->isInheritedValue()) + String fontValue = parsedStyle->getPropertyValue(CSSPropertyFont); + + // According to http://lists.w3.org/Archives/Public/public-html/2009Jul/0947.html, + // the "inherit" and "initial" values must be ignored. + if (fontValue == "inherit" || fontValue == "initial") return; // The parse succeeded. @@ -2303,10 +2306,10 @@ void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, flo maskImageContext->translate(location.x() - maskRect.x(), location.y() - maskRect.y()); // We draw when fontWidth is 0 so compositing operations (eg, a "copy" op) still work. maskImageContext->scale(FloatSize((fontWidth > 0 ? (width / fontWidth) : 0), 1)); - maskImageContext->drawBidiText(font, textRun, FloatPoint(0, 0)); + maskImageContext->drawBidiText(font, textRun, FloatPoint(0, 0), Font::UseFallbackIfFontNotReady); } else { maskImageContext->translate(-maskRect.x(), -maskRect.y()); - maskImageContext->drawBidiText(font, textRun, location); + maskImageContext->drawBidiText(font, textRun, location, Font::UseFallbackIfFontNotReady); } GraphicsContextStateSaver stateSaver(*c); @@ -2330,9 +2333,9 @@ void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, flo c->translate(location.x(), location.y()); // We draw when fontWidth is 0 so compositing operations (eg, a "copy" op) still work. c->scale(FloatSize((fontWidth > 0 ? (width / fontWidth) : 0), 1)); - c->drawBidiText(font, textRun, FloatPoint(0, 0)); + c->drawBidiText(font, textRun, FloatPoint(0, 0), Font::UseFallbackIfFontNotReady); } else - c->drawBidiText(font, textRun, location); + c->drawBidiText(font, textRun, location, Font::UseFallbackIfFontNotReady); didDraw(textRect); diff --git a/Source/WebCore/html/parser/XSSAuditor.cpp b/Source/WebCore/html/parser/XSSAuditor.cpp index 19b6ca6e3..93becd993 100644 --- a/Source/WebCore/html/parser/XSSAuditor.cpp +++ b/Source/WebCore/html/parser/XSSAuditor.cpp @@ -542,13 +542,16 @@ String XSSAuditor::decodedSnippetForAttribute(const HTMLToken& token, const HTML // In HTTP URLs, characters following the first ?, #, or third slash may come from // the page itself and can be merely ignored by an attacker's server when a remote // script or script-like resource is requested. In DATA URLS, the payload starts at - // the first comma, and the the first /* or // may introduce a comment. Characters + // the first comma, and the the first /*, //, or <!-- may introduce a comment. Characters // following this may come from the page itself and may be ignored when the script is // executed. For simplicity, we don't differentiate based on URL scheme, and stop at - // the first # or ?, the third slash, or the first slash once a comma is seen. + // the first # or ?, the third slash, or the first slash or < once a comma is seen. for (size_t currentLength = 0; currentLength < decodedSnippet.length(); ++currentLength) { UChar currentChar = decodedSnippet[currentLength]; - if (currentChar == '?' || currentChar == '#' || ((currentChar == '/' || currentChar == '\\') && (commaSeen || ++slashCount > 2))) { + if (currentChar == '?' + || currentChar == '#' + || ((currentChar == '/' || currentChar == '\\') && (commaSeen || ++slashCount > 2)) + || (currentChar == '<' && commaSeen)) { decodedSnippet.truncate(currentLength); break; } diff --git a/Source/WebCore/html/shadow/ContentDistributor.cpp b/Source/WebCore/html/shadow/ContentDistributor.cpp index e3216839f..0c095e437 100644 --- a/Source/WebCore/html/shadow/ContentDistributor.cpp +++ b/Source/WebCore/html/shadow/ContentDistributor.cpp @@ -58,6 +58,40 @@ size_t ContentDistribution::find(const Node* node) const return it.get()->value; } +ShadowRootContentDistributionData::ShadowRootContentDistributionData() + : m_insertionPointAssignedTo(0) + , m_numberOfShadowElementChildren(0) + , m_numberOfContentElementChildren(0) + , m_numberOfElementShadowChildren(0) + , m_insertionPointListIsValid(false) +{ +} + +void ShadowRootContentDistributionData::invalidateInsertionPointList() +{ + m_insertionPointListIsValid = false; + m_insertionPointList.clear(); +} + +const Vector<InsertionPoint*>& ShadowRootContentDistributionData::ensureInsertionPointList(ShadowRoot* shadowRoot) +{ + if (m_insertionPointListIsValid) + return m_insertionPointList; + + m_insertionPointListIsValid = true; + ASSERT(m_insertionPointList.isEmpty()); + + if (!shadowRoot->hasInsertionPoint()) + return m_insertionPointList; + + for (Node* node = shadowRoot; node; node = node->traverseNextNode(shadowRoot)) { + if (node->isInsertionPoint()) + m_insertionPointList.append(toInsertionPoint(node)); + } + + return m_insertionPointList; +} + ContentDistributor::ContentDistributor() : m_validity(Undetermined) { @@ -107,17 +141,18 @@ void ContentDistributor::distribute(Element* host) for (ShadowRoot* root = host->youngestShadowRoot(); root; root = root->olderShadowRoot()) { HTMLShadowElement* firstActiveShadowInsertionPoint = 0; - for (Node* node = root; node; node = node->traverseNextNode(root)) { - if (!isActiveInsertionPoint(node)) + const Vector<InsertionPoint*>& insertionPoints = root->insertionPointList(); + for (size_t i = 0; i < insertionPoints.size(); ++i) { + InsertionPoint* point = insertionPoints[i]; + if (!point->isActive()) continue; - InsertionPoint* point = toInsertionPoint(node); - if (isHTMLShadowElement(node)) { + if (isHTMLShadowElement(point)) { if (!firstActiveShadowInsertionPoint) - firstActiveShadowInsertionPoint = toHTMLShadowElement(node); + firstActiveShadowInsertionPoint = toHTMLShadowElement(point); } else { distributeSelectionsTo(point, pool, distributed); - if (ElementShadow* shadow = node->parentNode()->isElementNode() ? toElement(node->parentNode())->shadow() : 0) + if (ElementShadow* shadow = point->parentNode()->isElementNode() ? toElement(point->parentNode())->shadow() : 0) shadow->invalidateDistribution(); } } @@ -148,13 +183,10 @@ bool ContentDistributor::invalidate(Element* host) for (ShadowRoot* root = host->youngestShadowRoot(); root; root = root->olderShadowRoot()) { root->setAssignedTo(0); - - for (Node* node = root; node; node = node->traverseNextNode(root)) { - if (!node->isInsertionPoint()) - continue; + const Vector<InsertionPoint*>& insertionPoints = root->insertionPointList(); + for (size_t i = 0; i < insertionPoints.size(); ++i) { needsReattach = needsReattach || true; - InsertionPoint* point = toInsertionPoint(node); - point->clearDistribution(); + insertionPoints[i]->clearDistribution(); } } diff --git a/Source/WebCore/html/shadow/ContentDistributor.h b/Source/WebCore/html/shadow/ContentDistributor.h index 97cffbcc7..cc2fc232e 100644 --- a/Source/WebCore/html/shadow/ContentDistributor.h +++ b/Source/WebCore/html/shadow/ContentDistributor.h @@ -68,6 +68,38 @@ private: HashMap<const Node*, size_t> m_indices; }; +class ShadowRootContentDistributionData { +public: + ShadowRootContentDistributionData(); + + InsertionPoint* insertionPointAssignedTo() const { return m_insertionPointAssignedTo; } + void setInsertionPointAssignedTo(InsertionPoint* insertionPoint) { m_insertionPointAssignedTo = insertionPoint; } + + void incrementNumberOfShadowElementChildren() { ++m_numberOfShadowElementChildren; invalidateInsertionPointList(); } + void decrementNumberOfShadowElementChildren() { ASSERT(m_numberOfShadowElementChildren > 0); --m_numberOfShadowElementChildren; invalidateInsertionPointList(); } + bool hasShadowElementChildren() const { return m_numberOfShadowElementChildren > 0; } + + void incrementNumberOfContentElementChildren() { ++m_numberOfContentElementChildren; invalidateInsertionPointList(); } + void decrementNumberOfContentElementChildren() { ASSERT(m_numberOfContentElementChildren > 0); --m_numberOfContentElementChildren; invalidateInsertionPointList(); } + bool hasContentElementChildren() const { return m_numberOfContentElementChildren > 0; } + + void incrementNumberOfElementShadowChildren() { ++m_numberOfElementShadowChildren; } + void decrementNumberOfElementShadowChildren() { ASSERT(m_numberOfElementShadowChildren > 0); --m_numberOfElementShadowChildren; } + unsigned numberOfElementShadowChildren() const { return m_numberOfElementShadowChildren; } + bool hasElementShadowChildren() const { return m_numberOfElementShadowChildren > 0; } + + void invalidateInsertionPointList(); + const Vector<InsertionPoint*>& ensureInsertionPointList(ShadowRoot*); + +private: + InsertionPoint* m_insertionPointAssignedTo; + unsigned m_numberOfShadowElementChildren; + unsigned m_numberOfContentElementChildren; + unsigned m_numberOfElementShadowChildren; + bool m_insertionPointListIsValid; + Vector<InsertionPoint*> m_insertionPointList; +}; + class ContentDistributor { WTF_MAKE_NONCOPYABLE(ContentDistributor); public: diff --git a/Source/WebCore/html/shadow/MediaControlElements.cpp b/Source/WebCore/html/shadow/MediaControlElements.cpp index 2128bc232..6ae55f3d9 100644 --- a/Source/WebCore/html/shadow/MediaControlElements.cpp +++ b/Source/WebCore/html/shadow/MediaControlElements.cpp @@ -36,6 +36,7 @@ #include "CSSValueKeywords.h" #include "DOMTokenList.h" #include "EventNames.h" +#include "EventTarget.h" #include "FloatConversion.h" #include "FloatPoint.h" #include "Frame.h" @@ -63,6 +64,7 @@ #include "StyleResolver.h" #include "Text.h" #if ENABLE(VIDEO_TRACK) +#include "TextTrack.h" #include "TextTrackList.h" #endif @@ -77,6 +79,11 @@ static const float cSkipTime = 0.2f; static const float cScanRepeatDelay = 1.5f; static const float cScanMaximumRate = 8; +#if ENABLE(VIDEO_TRACK) +static const char* textTracksOffAttrValue = "-1"; // This must match HTMLMediaElement::textTracksOffIndex() +static const int textTracksIndexNotFound = -2; +#endif + HTMLMediaElement* toParentMediaElement(Node* node) { if (!node) @@ -99,6 +106,26 @@ MediaControlElementType mediaControlElementType(Node* node) return static_cast<MediaControlElement*>(element)->displayType(); } +#if ENABLE(VIDEO_TRACK) +static const AtomicString& trackIndexAttributeName() +{ + DEFINE_STATIC_LOCAL(AtomicString, name, ("x-webkit-track-index", AtomicString::ConstructFromLiteral)); + return name; +} + +static int trackListIndexForElement(Element* element) +{ + const AtomicString trackIndexAttributeValue = element->getAttribute(trackIndexAttributeName()); + if (trackIndexAttributeValue.isNull() || trackIndexAttributeValue.isEmpty()) + return textTracksIndexNotFound; + bool ok; + int trackIndex = trackIndexAttributeValue.toInt(&ok); + if (!ok) + return textTracksIndexNotFound; + return trackIndex; +} +#endif + // ---------------------------- MediaControlElement::MediaControlElement(Document* document) @@ -884,8 +911,13 @@ const AtomicString& MediaControlClosedCaptionsContainerElement::shadowPseudoId() inline MediaControlToggleClosedCaptionsButtonElement::MediaControlToggleClosedCaptionsButtonElement(Document* document, MediaControls* controls) : MediaControlInputElement(document, MediaShowClosedCaptionsButton) +#if PLATFORM(MAC) , m_controls(controls) +#endif { +#if !PLATFORM(MAC) + UNUSED_PARAM(controls); +#endif } PassRefPtr<MediaControlToggleClosedCaptionsButtonElement> MediaControlToggleClosedCaptionsButtonElement::create(Document* document, MediaControls* controls) @@ -901,18 +933,25 @@ PassRefPtr<MediaControlToggleClosedCaptionsButtonElement> MediaControlToggleClos void MediaControlToggleClosedCaptionsButtonElement::updateDisplayType() { - setDisplayType(mediaController()->closedCaptionsVisible() ? MediaHideClosedCaptionsButton : MediaShowClosedCaptionsButton); + bool captionsVisible = mediaController()->closedCaptionsVisible(); + setDisplayType(captionsVisible ? MediaHideClosedCaptionsButton : MediaShowClosedCaptionsButton); + setChecked(captionsVisible); } void MediaControlToggleClosedCaptionsButtonElement::defaultEventHandler(Event* event) { if (event->type() == eventNames().clickEvent) { - // FIXME: This is now incorrectly doing two things at once: showing the list of captions and toggling display. - // https://bugs.webkit.org/show_bug.cgi?id=101670 + // FIXME: It's not great that the shared code is dictating behavior of platform-specific + // UI. Not all ports may want the closed captions button to toggle a list of tracks, so + // we have to use #if. + // https://bugs.webkit.org/show_bug.cgi?id=101877 +#if !PLATFORM(MAC) mediaController()->setClosedCaptionsVisible(!mediaController()->closedCaptionsVisible()); setChecked(mediaController()->closedCaptionsVisible()); - m_controls->toggleClosedCaptionTrackList(); updateDisplayType(); +#else + m_controls->toggleClosedCaptionTrackList(); +#endif event->setDefaultHandled(); } @@ -927,22 +966,52 @@ const AtomicString& MediaControlToggleClosedCaptionsButtonElement::shadowPseudoI // ---------------------------- -inline MediaControlClosedCaptionsTrackListElement::MediaControlClosedCaptionsTrackListElement(Document* document) +inline MediaControlClosedCaptionsTrackListElement::MediaControlClosedCaptionsTrackListElement(Document* document, MediaControls* controls) : MediaControlElement(document) + , m_controls(controls) { } -PassRefPtr<MediaControlClosedCaptionsTrackListElement> MediaControlClosedCaptionsTrackListElement::create(Document* document) +PassRefPtr<MediaControlClosedCaptionsTrackListElement> MediaControlClosedCaptionsTrackListElement::create(Document* document, MediaControls* controls) { - RefPtr<MediaControlClosedCaptionsTrackListElement> element = adoptRef(new MediaControlClosedCaptionsTrackListElement(document)); + ASSERT(controls); + RefPtr<MediaControlClosedCaptionsTrackListElement> element = adoptRef(new MediaControlClosedCaptionsTrackListElement(document, controls)); return element.release(); } void MediaControlClosedCaptionsTrackListElement::defaultEventHandler(Event* event) { - // FIXME: Hook this up to actual text tracks. - // https://bugs.webkit.org/show_bug.cgi?id=101670 - UNUSED_PARAM(event); +#if ENABLE(VIDEO_TRACK) + if (event->type() == eventNames().clickEvent) { + // FIXME: Add modifier key for exclusivity override. + // http://webkit.org/b/103361 + + Node* target = event->target()->toNode(); + if (!target || !target->isElementNode()) + return; + + // When we created the elements in the track list, we gave them a custom + // attribute representing the index in the HTMLMediaElement's list of tracks. + // Check if the event target has such a custom element and, if so, + // tell the HTMLMediaElement to enable that track. + + int trackIndex = trackListIndexForElement(toElement(target)); + if (trackIndex == textTracksIndexNotFound) + return; + + HTMLMediaElement* mediaElement = toParentMediaElement(this); + if (!mediaElement) + return; + + mediaElement->toggleTrackAtIndex(trackIndex); + + // We've selected a track to display, so we can now close the menu. + m_controls->toggleClosedCaptionTrackList(); + updateDisplay(); + } + + MediaControlElement::defaultEventHandler(event); +#endif } const AtomicString& MediaControlClosedCaptionsTrackListElement::shadowPseudoId() const @@ -954,8 +1023,50 @@ const AtomicString& MediaControlClosedCaptionsTrackListElement::shadowPseudoId() void MediaControlClosedCaptionsTrackListElement::updateDisplay() { #if ENABLE(VIDEO_TRACK) + DEFINE_STATIC_LOCAL(AtomicString, selectedClassValue, ("selected", AtomicString::ConstructFromLiteral)); + + if (!mediaController()->hasClosedCaptions()) + return; + + HTMLMediaElement* mediaElement = toParentMediaElement(this); + if (!mediaElement) + return; + + TextTrackList* trackList = mediaElement->textTracks(); + + if (!trackList || !trackList->length()) + return; + + bool captionsVisible = mediaElement->closedCaptionsVisible(); + for (unsigned i = 0, length = menuItems.size(); i < length; ++i) { + RefPtr<Element> trackItem = menuItems[i]; + int trackIndex = trackListIndexForElement(trackItem.get()); + if (trackIndex != textTracksIndexNotFound) { + if (trackIndex == HTMLMediaElement::textTracksOffIndex()) { + if (captionsVisible) + trackItem->classList()->remove(selectedClassValue, ASSERT_NO_EXCEPTION); + else + trackItem->classList()->add(selectedClassValue, ASSERT_NO_EXCEPTION); + } else { + TextTrack* track = trackList->item(trackIndex); + if (!track) + continue; + if (track->mode() == TextTrack::showingKeyword()) + trackItem->classList()->add(selectedClassValue, ASSERT_NO_EXCEPTION); + else + trackItem->classList()->remove(selectedClassValue, ASSERT_NO_EXCEPTION); + } + } + } +#endif +} + +void MediaControlClosedCaptionsTrackListElement::resetTrackListMenu() +{ +#if ENABLE(VIDEO_TRACK) // Remove any existing content. removeChildren(); + menuItems.clear(); if (!mediaController()->hasClosedCaptions()) return; @@ -987,15 +1098,15 @@ void MediaControlClosedCaptionsTrackListElement::updateDisplay() trackItem = doc->createElement(liTag, ASSERT_NO_EXCEPTION); trackItem->appendChild(doc->createTextNode("Off")); - // FIXME: These lists are not yet live. Mark the Off entry as the selected one for now. - trackItem->setAttribute(classAttr, "selected"); + trackItem->setAttribute(trackIndexAttributeName(), textTracksOffAttrValue, ASSERT_NO_EXCEPTION); captionsList->appendChild(trackItem); + menuItems.append(trackItem); trackItem = doc->createElement(liTag, ASSERT_NO_EXCEPTION); trackItem->appendChild(doc->createTextNode("Off")); - // FIXME: These lists are not yet live. Mark the Off entry as the selected one for now. - trackItem->setAttribute(classAttr, "selected"); + trackItem->setAttribute(trackIndexAttributeName(), textTracksOffAttrValue, ASSERT_NO_EXCEPTION); subtitlesList->appendChild(trackItem); + menuItems.append(trackItem); bool hasCaptions = false; bool hasSubtitles = false; @@ -1003,6 +1114,13 @@ void MediaControlClosedCaptionsTrackListElement::updateDisplay() for (unsigned i = 0, length = trackList->length(); i < length; ++i) { TextTrack* track = trackList->item(i); trackItem = doc->createElement(liTag, ASSERT_NO_EXCEPTION); + + // Add a custom attribute to the <li> element which will allow + // us to easily associate the user tapping here with the + // track. Since this list is rebuilt if the tracks change, we + // should always be in sync. + trackItem->setAttribute(trackIndexAttributeName(), String::number(i), ASSERT_NO_EXCEPTION); + AtomicString labelText = track->label(); if (labelText.isNull() || labelText.isEmpty()) labelText = displayNameForLanguageLocale(track->language()); @@ -1018,6 +1136,7 @@ void MediaControlClosedCaptionsTrackListElement::updateDisplay() subtitlesList->appendChild(trackItem); } trackItem->appendChild(doc->createTextNode(labelText)); + menuItems.append(trackItem); } captionsSection->appendChild(captionsList); @@ -1027,6 +1146,8 @@ void MediaControlClosedCaptionsTrackListElement::updateDisplay() appendChild(captionsSection); if (hasSubtitles) appendChild(subtitlesSection); + + updateDisplay(); #endif } diff --git a/Source/WebCore/html/shadow/MediaControlElements.h b/Source/WebCore/html/shadow/MediaControlElements.h index c3fbc8121..e05032854 100644 --- a/Source/WebCore/html/shadow/MediaControlElements.h +++ b/Source/WebCore/html/shadow/MediaControlElements.h @@ -393,7 +393,9 @@ private: MediaControlToggleClosedCaptionsButtonElement(Document*, MediaControls*); virtual const AtomicString& shadowPseudoId() const; +#if PLATFORM(MAC) MediaControls* m_controls; +#endif }; // ---------------------------- @@ -415,18 +417,23 @@ private: class MediaControlClosedCaptionsTrackListElement : public MediaControlElement { public: - static PassRefPtr<MediaControlClosedCaptionsTrackListElement> create(Document*); + static PassRefPtr<MediaControlClosedCaptionsTrackListElement> create(Document*, MediaControls*); virtual void defaultEventHandler(Event*); virtual bool willRespondToMouseClickEvents() OVERRIDE { return true; } void updateDisplay(); + void resetTrackListMenu(); private: - MediaControlClosedCaptionsTrackListElement(Document*); + MediaControlClosedCaptionsTrackListElement(Document*, MediaControls*); virtual MediaControlElementType displayType() const { return MediaClosedCaptionsTrackList; } virtual const AtomicString& shadowPseudoId() const; + + typedef Vector<RefPtr<Element> > TrackMenuItems; + TrackMenuItems menuItems; + MediaControls* m_controls; }; // ---------------------------- diff --git a/Source/WebCore/html/shadow/MediaControlsApple.cpp b/Source/WebCore/html/shadow/MediaControlsApple.cpp index 6cc1c7f7d..93733aeb8 100644 --- a/Source/WebCore/html/shadow/MediaControlsApple.cpp +++ b/Source/WebCore/html/shadow/MediaControlsApple.cpp @@ -149,7 +149,7 @@ PassRefPtr<MediaControlsApple> MediaControlsApple::createControls(Document* docu if (document->page()->theme()->supportsClosedCaptioning()) { RefPtr<MediaControlClosedCaptionsContainerElement> closedCaptionsContainer = MediaControlClosedCaptionsContainerElement::create(document); - RefPtr<MediaControlClosedCaptionsTrackListElement> closedCaptionsTrackList = MediaControlClosedCaptionsTrackListElement::create(document); + RefPtr<MediaControlClosedCaptionsTrackListElement> closedCaptionsTrackList = MediaControlClosedCaptionsTrackListElement::create(document, controls.get()); controls->m_closedCaptionsTrackList = closedCaptionsTrackList.get(); closedCaptionsContainer->appendChild(closedCaptionsTrackList.release(), ec, true); if (ec) @@ -289,6 +289,13 @@ void MediaControlsApple::makeTransparent() m_closedCaptionsContainer->hide(); } +void MediaControlsApple::changedClosedCaptionsVisibility() +{ + MediaControls::changedClosedCaptionsVisibility(); + if (m_closedCaptionsTrackList) + m_closedCaptionsTrackList->updateDisplay(); +} + void MediaControlsApple::reset() { Page* page = document()->page(); @@ -323,7 +330,7 @@ void MediaControlsApple::reset() if (m_mediaController->hasClosedCaptions()) { m_toggleClosedCaptionsButton->show(); if (m_closedCaptionsTrackList) - m_closedCaptionsTrackList->updateDisplay(); + m_closedCaptionsTrackList->resetTrackListMenu(); } else m_toggleClosedCaptionsButton->hide(); } diff --git a/Source/WebCore/html/shadow/MediaControlsApple.h b/Source/WebCore/html/shadow/MediaControlsApple.h index dc47306ec..a1ee8963c 100644 --- a/Source/WebCore/html/shadow/MediaControlsApple.h +++ b/Source/WebCore/html/shadow/MediaControlsApple.h @@ -58,6 +58,7 @@ public: virtual void updateCurrentTimeDisplay() OVERRIDE; virtual void updateStatusDisplay() OVERRIDE; + virtual void changedClosedCaptionsVisibility() OVERRIDE; void toggleClosedCaptionTrackList(); private: diff --git a/Source/WebCore/html/shadow/SliderThumbElement.cpp b/Source/WebCore/html/shadow/SliderThumbElement.cpp index e63954e41..d6c1a3111 100644 --- a/Source/WebCore/html/shadow/SliderThumbElement.cpp +++ b/Source/WebCore/html/shadow/SliderThumbElement.cpp @@ -194,10 +194,11 @@ void RenderSliderContainer::layout() double percentageOffset = sliderPosition(input).toDouble(); LayoutUnit availableExtent = isVertical ? track->contentHeight() : track->contentWidth(); + availableExtent -= isVertical ? thumb->height() : thumb->width(); LayoutUnit offset = percentageOffset * availableExtent; LayoutPoint thumbLocation = thumb->location(); if (isVertical) - thumbLocation.setY(thumbLocation.y() + track->contentHeight() - offset); + thumbLocation.setY(thumbLocation.y() + track->contentHeight() - thumb->height() - offset); else if (style()->isLeftToRightDirection()) thumbLocation.setX(thumbLocation.x() + offset); else @@ -271,16 +272,13 @@ void SliderThumbElement::setPositionFromPoint(const LayoutPoint& point) IntRect trackBoundingBox = trackElement->renderer()->absoluteBoundingBoxRectIgnoringTransforms(); IntRect inputBoundingBox = input->renderer()->absoluteBoundingBoxRectIgnoringTransforms(); if (isVertical) { - trackSize = trackElement->renderBox()->contentHeight(); + trackSize = trackElement->renderBox()->contentHeight() - renderBox()->height(); position = offset.y() - renderBox()->height() / 2 - trackBoundingBox.y() + inputBoundingBox.y() - renderBox()->marginBottom(); currentPosition = absoluteThumbOrigin.y() - absoluteSliderContentOrigin.y(); } else { - trackSize = trackElement->renderBox()->contentWidth(); + trackSize = trackElement->renderBox()->contentWidth() - renderBox()->width(); position = offset.x() - renderBox()->width() / 2 - trackBoundingBox.x() + inputBoundingBox.x(); - if (isLeftToRightDirection) - position -= renderBox()->marginLeft(); - else - position += renderBox()->width() - renderBox()->marginRight(); + position -= isLeftToRightDirection ? renderBox()->marginLeft() : renderBox()->marginRight(); currentPosition = absoluteThumbOrigin.x() - absoluteSliderContentOrigin.x(); } position = max<LayoutUnit>(0, min(position, trackSize)); @@ -438,58 +436,6 @@ const AtomicString& SliderThumbElement::shadowPseudoId() const // -------------------------------- -inline TrackLimiterElement::TrackLimiterElement(Document* document) - : HTMLDivElement(HTMLNames::divTag, document) -{ -} - -PassRefPtr<TrackLimiterElement> TrackLimiterElement::create(Document* document) -{ - RefPtr<TrackLimiterElement> element = adoptRef(new TrackLimiterElement(document)); - - element->setInlineStyleProperty(CSSPropertyVisibility, CSSValueHidden); - element->setInlineStyleProperty(CSSPropertyPosition, CSSValueStatic); - - return element.release(); -} - -RenderObject* TrackLimiterElement::createRenderer(RenderArena* arena, RenderStyle*) -{ - return new (arena) RenderSliderThumb(this); -} - -const AtomicString& TrackLimiterElement::shadowPseudoId() const -{ - HTMLInputElement* input = shadowHost()->toInputElement(); - if (!input) - return sliderThumbShadowPseudoId(); - - RenderStyle* sliderStyle = input->renderer()->style(); - switch (sliderStyle->appearance()) { - case MediaSliderPart: - case MediaSliderThumbPart: - case MediaVolumeSliderPart: - case MediaVolumeSliderThumbPart: - case MediaFullScreenVolumeSliderPart: - case MediaFullScreenVolumeSliderThumbPart: - return mediaSliderThumbShadowPseudoId(); - default: - return sliderThumbShadowPseudoId(); - } -} - -TrackLimiterElement* trackLimiterElementOf(Node* node) -{ - ASSERT(node); - ShadowRoot* shadow = node->toInputElement()->userAgentShadowRoot(); - ASSERT(shadow); - Node* limiter = shadow->firstChild()->lastChild(); - ASSERT(limiter); - return static_cast<TrackLimiterElement*>(limiter); -} - -// -------------------------------- - inline SliderContainerElement::SliderContainerElement(Document* document) : HTMLDivElement(HTMLNames::divTag, document) { diff --git a/Source/WebCore/html/shadow/SliderThumbElement.h b/Source/WebCore/html/shadow/SliderThumbElement.h index f55ecef3d..869ad4b5d 100644 --- a/Source/WebCore/html/shadow/SliderThumbElement.h +++ b/Source/WebCore/html/shadow/SliderThumbElement.h @@ -115,22 +115,6 @@ private: // -------------------------------- -class TrackLimiterElement : public HTMLDivElement { -public: - static PassRefPtr<TrackLimiterElement> create(Document*); - -private: - TrackLimiterElement(Document*); - virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); - virtual const AtomicString& shadowPseudoId() const; -}; - -// This always return a valid pointer. -// An assertion fails if the specified node is not a range input. -TrackLimiterElement* trackLimiterElementOf(Node*); - -// -------------------------------- - class SliderContainerElement : public HTMLDivElement { public: static PassRefPtr<SliderContainerElement> create(Document*); diff --git a/Source/WebCore/html/track/TextTrack.cpp b/Source/WebCore/html/track/TextTrack.cpp index 95ab19080..6a6e90be6 100644 --- a/Source/WebCore/html/track/TextTrack.cpp +++ b/Source/WebCore/html/track/TextTrack.cpp @@ -259,20 +259,18 @@ void TextTrack::removeCue(TextTrackCue* cue, ExceptionCode& ec) if (!cue) return; - // 4.8.10.12.4 Text track API + // 4.8.10.12.5 Text track API // The removeCue(cue) method of TextTrack objects, when invoked, must run the following steps: - // 1. If the given cue is not associated with the method's TextTrack - // object's text track, then throw an InvalidStateError exception. + // 1. If the given cue is not currently listed in the method's TextTrack + // object's text track's text track list of cues, then throw a NotFoundError exception. if (cue->track() != this) { - ec = INVALID_STATE_ERR; + ec = NOT_FOUND_ERR; return; } - - // 2. If the given cue is not currently listed in the method's TextTrack - // object's text track's text track list of cues, then throw a NotFoundError exception. - // 3. Remove cue from the method's TextTrack object's text track's text track list of cues. + + // 2. Remove cue from the method's TextTrack object's text track's text track list of cues. if (!m_cues || !m_cues->remove(cue)) { ec = INVALID_STATE_ERR; return; |