From cd44dc59cdfc39534aef4d417e9f3c412e3be139 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Fri, 3 Feb 2012 09:55:33 +0100 Subject: Imported WebKit commit fce473cb4d55aa9fe9d0b0322a2fffecb731b961 (http://svn.webkit.org/repository/webkit/trunk@106560) --- Source/WebCore/html/CheckboxInputType.cpp | 2 +- Source/WebCore/html/ClassList.cpp | 2 +- Source/WebCore/html/DOMSettableTokenList.idl | 1 - Source/WebCore/html/DOMTokenList.idl | 1 - Source/WebCore/html/FileInputType.cpp | 4 +- Source/WebCore/html/HTMLAnchorElement.cpp | 50 +- Source/WebCore/html/HTMLAnchorElement.h | 10 +- Source/WebCore/html/HTMLAnchorElement.idl | 16 +- Source/WebCore/html/HTMLAreaElement.cpp | 4 +- Source/WebCore/html/HTMLAttributeNames.in | 2 + Source/WebCore/html/HTMLButtonElement.idl | 4 +- Source/WebCore/html/HTMLCanvasElement.cpp | 19 +- Source/WebCore/html/HTMLCanvasElement.h | 2 + Source/WebCore/html/HTMLCollection.idl | 2 +- Source/WebCore/html/HTMLDetailsElement.cpp | 35 +- Source/WebCore/html/HTMLDocument.idl | 14 +- Source/WebCore/html/HTMLElement.cpp | 2 + Source/WebCore/html/HTMLElement.idl | 10 +- Source/WebCore/html/HTMLElementsAllInOne.cpp | 2 +- Source/WebCore/html/HTMLEmbedElement.cpp | 43 +- Source/WebCore/html/HTMLEmbedElement.h | 1 - Source/WebCore/html/HTMLEmbedElement.idl | 2 +- Source/WebCore/html/HTMLFormCollection.cpp | 1 + Source/WebCore/html/HTMLFormControlElement.cpp | 16 +- Source/WebCore/html/HTMLFormControlElement.h | 1 + Source/WebCore/html/HTMLFormElement.cpp | 2 +- Source/WebCore/html/HTMLFormElement.idl | 6 +- Source/WebCore/html/HTMLFrameElement.idl | 6 +- Source/WebCore/html/HTMLFrameElementBase.cpp | 18 +- Source/WebCore/html/HTMLIFrameElement.cpp | 4 +- Source/WebCore/html/HTMLIFrameElement.idl | 4 +- Source/WebCore/html/HTMLImageElement.cpp | 4 +- Source/WebCore/html/HTMLInputElement.cpp | 64 +- Source/WebCore/html/HTMLInputElement.h | 4 +- Source/WebCore/html/HTMLInputElement.idl | 12 +- Source/WebCore/html/HTMLIsIndexElement.cpp | 68 -- Source/WebCore/html/HTMLIsIndexElement.h | 46 -- Source/WebCore/html/HTMLIsIndexElement.idl | 27 - Source/WebCore/html/HTMLLinkElement.cpp | 4 +- Source/WebCore/html/HTMLMediaElement.cpp | 343 +++++---- Source/WebCore/html/HTMLMediaElement.h | 46 +- Source/WebCore/html/HTMLMediaElement.idl | 4 +- Source/WebCore/html/HTMLMetaElement.cpp | 4 +- Source/WebCore/html/HTMLObjectElement.cpp | 21 +- Source/WebCore/html/HTMLObjectElement.idl | 4 +- Source/WebCore/html/HTMLOutputElement.idl | 4 +- Source/WebCore/html/HTMLParamElement.cpp | 8 +- Source/WebCore/html/HTMLPlugInElement.cpp | 11 + Source/WebCore/html/HTMLPlugInElement.h | 4 + Source/WebCore/html/HTMLPlugInImageElement.cpp | 20 +- Source/WebCore/html/HTMLPropertiesCollection.cpp | 4 +- Source/WebCore/html/HTMLPropertiesCollection.h | 4 +- Source/WebCore/html/HTMLScriptElement.cpp | 6 - Source/WebCore/html/HTMLScriptElement.h | 1 - Source/WebCore/html/HTMLScriptElement.idl | 2 +- Source/WebCore/html/HTMLSelectElement.cpp | 132 ++-- Source/WebCore/html/HTMLSelectElement.idl | 4 +- Source/WebCore/html/HTMLSourceElement.cpp | 4 +- Source/WebCore/html/HTMLStyleElement.cpp | 78 ++ Source/WebCore/html/HTMLStyleElement.h | 8 + Source/WebCore/html/HTMLSummaryElement.cpp | 6 +- Source/WebCore/html/HTMLTableCellElement.cpp | 7 +- Source/WebCore/html/HTMLTableCellElement.h | 6 +- Source/WebCore/html/HTMLTableColElement.cpp | 9 +- Source/WebCore/html/HTMLTableColElement.h | 5 +- Source/WebCore/html/HTMLTableElement.cpp | 208 +++--- Source/WebCore/html/HTMLTableElement.h | 17 +- Source/WebCore/html/HTMLTableSectionElement.cpp | 7 +- Source/WebCore/html/HTMLTableSectionElement.h | 3 +- Source/WebCore/html/HTMLTagNames.in | 3 +- Source/WebCore/html/HTMLTextAreaElement.idl | 6 +- Source/WebCore/html/HTMLTitleElement.idl | 2 +- Source/WebCore/html/HTMLTrackElement.cpp | 14 +- Source/WebCore/html/HTMLTrackElement.h | 4 +- Source/WebCore/html/HiddenInputType.cpp | 14 +- Source/WebCore/html/HiddenInputType.h | 2 + Source/WebCore/html/ImageDocument.cpp | 14 +- Source/WebCore/html/InputType.cpp | 4 + Source/WebCore/html/InputType.h | 1 + Source/WebCore/html/NumberInputType.cpp | 10 +- Source/WebCore/html/PasswordInputType.cpp | 15 + Source/WebCore/html/PasswordInputType.h | 2 + Source/WebCore/html/RadioInputType.cpp | 8 +- Source/WebCore/html/RadioInputType.h | 1 - Source/WebCore/html/StepRange.cpp | 6 +- Source/WebCore/html/TextFieldInputType.cpp | 9 +- Source/WebCore/html/TextFieldInputType.h | 1 + Source/WebCore/html/ValidationMessage.cpp | 2 +- Source/WebCore/html/canvas/CanvasGradient.idl | 5 +- Source/WebCore/html/canvas/CanvasPattern.idl | 6 +- .../WebCore/html/canvas/CanvasRenderingContext.cpp | 2 + .../WebCore/html/canvas/CanvasRenderingContext.idl | 4 +- .../html/canvas/CanvasRenderingContext2D.cpp | 29 +- .../WebCore/html/canvas/CanvasRenderingContext2D.h | 1 + .../html/canvas/CanvasRenderingContext2D.idl | 17 +- Source/WebCore/html/canvas/CanvasStyle.cpp | 2 +- Source/WebCore/html/canvas/CanvasStyle.h | 4 +- .../WebCore/html/canvas/OESVertexArrayObject.cpp | 6 +- Source/WebCore/html/canvas/Uint8ClampedArray.idl | 47 ++ Source/WebCore/html/canvas/WebGLBuffer.cpp | 14 +- Source/WebCore/html/canvas/WebGLBuffer.h | 8 +- .../html/canvas/WebGLCompressedTextures.cpp | 44 +- .../WebCore/html/canvas/WebGLCompressedTextures.h | 3 +- Source/WebCore/html/canvas/WebGLContextGroup.cpp | 106 +++ Source/WebCore/html/canvas/WebGLContextGroup.h | 71 ++ Source/WebCore/html/canvas/WebGLContextObject.cpp | 65 ++ Source/WebCore/html/canvas/WebGLContextObject.h | 69 ++ Source/WebCore/html/canvas/WebGLDebugShaders.cpp | 2 +- Source/WebCore/html/canvas/WebGLFramebuffer.cpp | 59 +- Source/WebCore/html/canvas/WebGLFramebuffer.h | 25 +- Source/WebCore/html/canvas/WebGLGetInfo.cpp | 60 ++ Source/WebCore/html/canvas/WebGLObject.cpp | 43 +- Source/WebCore/html/canvas/WebGLObject.h | 35 +- Source/WebCore/html/canvas/WebGLProgram.cpp | 21 +- Source/WebCore/html/canvas/WebGLProgram.h | 10 +- Source/WebCore/html/canvas/WebGLRenderbuffer.cpp | 14 +- Source/WebCore/html/canvas/WebGLRenderbuffer.h | 8 +- .../WebCore/html/canvas/WebGLRenderingContext.cpp | 812 ++++++++++++--------- Source/WebCore/html/canvas/WebGLRenderingContext.h | 83 ++- .../WebCore/html/canvas/WebGLRenderingContext.idl | 10 +- Source/WebCore/html/canvas/WebGLShader.cpp | 14 +- Source/WebCore/html/canvas/WebGLShader.h | 8 +- Source/WebCore/html/canvas/WebGLSharedObject.cpp | 66 ++ Source/WebCore/html/canvas/WebGLSharedObject.h | 75 ++ Source/WebCore/html/canvas/WebGLTexture.cpp | 14 +- Source/WebCore/html/canvas/WebGLTexture.h | 8 +- .../html/canvas/WebGLVertexArrayObjectOES.cpp | 11 +- .../html/canvas/WebGLVertexArrayObjectOES.h | 8 +- Source/WebCore/html/parser/CSSPreloadScanner.cpp | 1 + .../WebCore/html/parser/HTMLConstructionSite.cpp | 11 +- Source/WebCore/html/parser/HTMLPreloadScanner.cpp | 30 +- Source/WebCore/html/parser/HTMLPreloadScanner.h | 4 +- .../html/shadow/ContentInclusionSelector.cpp | 155 ++++ .../WebCore/html/shadow/ContentInclusionSelector.h | 150 ++++ .../WebCore/html/shadow/ContentSelectorQuery.cpp | 161 ++++ Source/WebCore/html/shadow/ContentSelectorQuery.h | 67 ++ Source/WebCore/html/shadow/HTMLContentElement.cpp | 130 ++++ Source/WebCore/html/shadow/HTMLContentElement.h | 89 +++ Source/WebCore/html/shadow/HTMLContentElement.idl | 34 + .../WebCore/html/shadow/MediaControlElements.cpp | 14 +- Source/WebCore/html/shadow/SliderThumbElement.cpp | 2 +- .../html/shadow/TextControlInnerElements.cpp | 10 +- Source/WebCore/html/track/WebVTTParser.cpp | 2 + 143 files changed, 2968 insertions(+), 1394 deletions(-) delete mode 100644 Source/WebCore/html/HTMLIsIndexElement.cpp delete mode 100644 Source/WebCore/html/HTMLIsIndexElement.h delete mode 100644 Source/WebCore/html/HTMLIsIndexElement.idl create mode 100644 Source/WebCore/html/canvas/Uint8ClampedArray.idl create mode 100644 Source/WebCore/html/canvas/WebGLContextGroup.cpp create mode 100644 Source/WebCore/html/canvas/WebGLContextGroup.h create mode 100644 Source/WebCore/html/canvas/WebGLContextObject.cpp create mode 100644 Source/WebCore/html/canvas/WebGLContextObject.h create mode 100644 Source/WebCore/html/canvas/WebGLSharedObject.cpp create mode 100644 Source/WebCore/html/canvas/WebGLSharedObject.h create mode 100644 Source/WebCore/html/shadow/ContentInclusionSelector.cpp create mode 100644 Source/WebCore/html/shadow/ContentInclusionSelector.h create mode 100644 Source/WebCore/html/shadow/ContentSelectorQuery.cpp create mode 100644 Source/WebCore/html/shadow/ContentSelectorQuery.h create mode 100644 Source/WebCore/html/shadow/HTMLContentElement.cpp create mode 100644 Source/WebCore/html/shadow/HTMLContentElement.h create mode 100644 Source/WebCore/html/shadow/HTMLContentElement.idl (limited to 'Source/WebCore/html') diff --git a/Source/WebCore/html/CheckboxInputType.cpp b/Source/WebCore/html/CheckboxInputType.cpp index dda172aec..ed83517b9 100644 --- a/Source/WebCore/html/CheckboxInputType.cpp +++ b/Source/WebCore/html/CheckboxInputType.cpp @@ -51,7 +51,7 @@ const AtomicString& CheckboxInputType::formControlType() const bool CheckboxInputType::valueMissing(const String&) const { - return !element()->checked(); + return element()->required() && !element()->checked(); } String CheckboxInputType::valueMissingText() const diff --git a/Source/WebCore/html/ClassList.cpp b/Source/WebCore/html/ClassList.cpp index 349d64dce..2ea838202 100644 --- a/Source/WebCore/html/ClassList.cpp +++ b/Source/WebCore/html/ClassList.cpp @@ -140,7 +140,7 @@ const SpaceSplitString& ClassList::classNames() const ASSERT(m_element->hasClass()); if (!m_classNamesForQuirksMode.isNull()) return m_classNamesForQuirksMode; - return m_element->attributeMap()->classNames(); + return m_element->attributeData()->classNames(); } } // namespace WebCore diff --git a/Source/WebCore/html/DOMSettableTokenList.idl b/Source/WebCore/html/DOMSettableTokenList.idl index 6260623ee..02c6500b0 100644 --- a/Source/WebCore/html/DOMSettableTokenList.idl +++ b/Source/WebCore/html/DOMSettableTokenList.idl @@ -25,7 +25,6 @@ module core { interface [ - GenerateConstructor, HasIndexGetter, GenerateToJS ] DOMSettableTokenList : DOMTokenList { diff --git a/Source/WebCore/html/DOMTokenList.idl b/Source/WebCore/html/DOMTokenList.idl index f94491cbe..0bcc4889f 100644 --- a/Source/WebCore/html/DOMTokenList.idl +++ b/Source/WebCore/html/DOMTokenList.idl @@ -26,7 +26,6 @@ module core { interface [ GenerateIsReachable=ImplElementRoot, - GenerateConstructor, HasIndexGetter ] DOMTokenList { readonly attribute unsigned long length; diff --git a/Source/WebCore/html/FileInputType.cpp b/Source/WebCore/html/FileInputType.cpp index 655e81ead..ea9a2ee68 100644 --- a/Source/WebCore/html/FileInputType.cpp +++ b/Source/WebCore/html/FileInputType.cpp @@ -129,7 +129,7 @@ bool FileInputType::appendFormData(FormDataList& encoding, bool multipart) const bool FileInputType::valueMissing(const String& value) const { - return value.isEmpty(); + return element()->required() && value.isEmpty(); } String FileInputType::valueMissingText() const @@ -139,7 +139,7 @@ String FileInputType::valueMissingText() const void FileInputType::handleDOMActivateEvent(Event* event) { - if (element()->disabled() || !element()->renderer()) + if (element()->disabled()) return; if (!ScriptController::processingUserGesture()) diff --git a/Source/WebCore/html/HTMLAnchorElement.cpp b/Source/WebCore/html/HTMLAnchorElement.cpp index d60185282..6cfce16df 100644 --- a/Source/WebCore/html/HTMLAnchorElement.cpp +++ b/Source/WebCore/html/HTMLAnchorElement.cpp @@ -48,6 +48,7 @@ using namespace HTMLNames; HTMLAnchorElement::HTMLAnchorElement(const QualifiedName& tagName, Document* document) : HTMLElement(tagName, document) + , m_hasRootEditableElementForSelectionOnMouseDown(false) , m_wasShiftKeyDownOnMouseDown(false) , m_linkRelations(0) , m_cachedVisitedLinkHash(0) @@ -64,6 +65,11 @@ PassRefPtr HTMLAnchorElement::create(const QualifiedName& tag return adoptRef(new HTMLAnchorElement(tagName, document)); } +HTMLAnchorElement::~HTMLAnchorElement() +{ + clearRootEditableElementForSelectionOnMouseDown(); +} + // This function does not allow leading spaces before the port number. static unsigned parsePortFromStringPosition(const String& value, unsigned portStart, unsigned& portEnd) { @@ -158,12 +164,12 @@ void HTMLAnchorElement::defaultEventHandler(Event* event) // This keeps track of the editable block that the selection was in (if it was in one) just before the link was clicked // for the LiveWhenNotFocused editable link behavior if (event->type() == eventNames().mousedownEvent && event->isMouseEvent() && static_cast(event)->button() != RightButton && document()->frame() && document()->frame()->selection()) { - m_rootEditableElementForSelectionOnMouseDown = document()->frame()->selection()->rootEditableElement(); + setRootEditableElementForSelectionOnMouseDown(document()->frame()->selection()->rootEditableElement()); m_wasShiftKeyDownOnMouseDown = static_cast(event)->shiftKey(); } else if (event->type() == eventNames().mouseoverEvent) { // These are cleared on mouseover and not mouseout because their values are needed for drag events, // but drag events happen after mouse out events. - m_rootEditableElementForSelectionOnMouseDown = 0; + clearRootEditableElementForSelectionOnMouseDown(); m_wasShiftKeyDownOnMouseDown = false; } } @@ -546,7 +552,7 @@ bool HTMLAnchorElement::treatLinkAsLiveForEventType(EventType eventType) const // If the selection prior to clicking on this link resided in the same editable block as this link, // and the shift key isn't pressed, we don't want to follow the link. case EditableLinkLiveWhenNotFocused: - return eventType == MouseEventWithShiftKey || (eventType == MouseEventWithoutShiftKey && m_rootEditableElementForSelectionOnMouseDown != rootEditableElement()); + return eventType == MouseEventWithShiftKey || (eventType == MouseEventWithoutShiftKey && rootEditableElementForSelectionOnMouseDown() != rootEditableElement()); case EditableLinkOnlyLiveWithShiftKey: return eventType == MouseEventWithShiftKey; @@ -587,10 +593,44 @@ String HTMLAnchorElement::itemValueText() const return getURLAttribute(hrefAttr); } -void HTMLAnchorElement::setItemValueText(const String& value, ExceptionCode& ec) +void HTMLAnchorElement::setItemValueText(const String& value, ExceptionCode&) { - setAttribute(hrefAttr, value, ec); + setAttribute(hrefAttr, value); } #endif +typedef HashMap > RootEditableElementMap; + +static RootEditableElementMap& rootEditableElementMap() +{ + DEFINE_STATIC_LOCAL(RootEditableElementMap, map, ()); + return map; +} + +Element* HTMLAnchorElement::rootEditableElementForSelectionOnMouseDown() const +{ + if (!m_hasRootEditableElementForSelectionOnMouseDown) + return 0; + return rootEditableElementMap().get(this).get(); +} + +void HTMLAnchorElement::clearRootEditableElementForSelectionOnMouseDown() +{ + if (!m_hasRootEditableElementForSelectionOnMouseDown) + return; + rootEditableElementMap().remove(this); + m_hasRootEditableElementForSelectionOnMouseDown = false; +} + +void HTMLAnchorElement::setRootEditableElementForSelectionOnMouseDown(Element* element) +{ + if (!element) { + clearRootEditableElementForSelectionOnMouseDown(); + return; + } + + rootEditableElementMap().set(this, element); + m_hasRootEditableElementForSelectionOnMouseDown = true; +} + } diff --git a/Source/WebCore/html/HTMLAnchorElement.h b/Source/WebCore/html/HTMLAnchorElement.h index cbda84145..99a6332ce 100644 --- a/Source/WebCore/html/HTMLAnchorElement.h +++ b/Source/WebCore/html/HTMLAnchorElement.h @@ -58,6 +58,8 @@ public: static PassRefPtr create(Document*); static PassRefPtr create(const QualifiedName&, Document*); + virtual ~HTMLAnchorElement(); + KURL href() const; void setHref(const AtomicString&); @@ -133,9 +135,13 @@ private: virtual void setItemValueText(const String&, ExceptionCode&) OVERRIDE; #endif - RefPtr m_rootEditableElementForSelectionOnMouseDown; + Element* rootEditableElementForSelectionOnMouseDown() const; + void setRootEditableElementForSelectionOnMouseDown(Element*); + void clearRootEditableElementForSelectionOnMouseDown(); + + bool m_hasRootEditableElementForSelectionOnMouseDown : 1; bool m_wasShiftKeyDownOnMouseDown : 1; - uint32_t m_linkRelations : 31; + uint32_t m_linkRelations : 30; mutable LinkHash m_cachedVisitedLinkHash; }; diff --git a/Source/WebCore/html/HTMLAnchorElement.idl b/Source/WebCore/html/HTMLAnchorElement.idl index 5669a281c..898f9eab7 100644 --- a/Source/WebCore/html/HTMLAnchorElement.idl +++ b/Source/WebCore/html/HTMLAnchorElement.idl @@ -43,15 +43,15 @@ module html { readonly attribute DOMString protocol; readonly attribute DOMString search; #else - attribute [ConvertNullToNullString] DOMString hash; - attribute [ConvertNullToNullString] DOMString host; - attribute [ConvertNullToNullString] DOMString hostname; - attribute [ConvertNullToNullString] DOMString pathname; - attribute [ConvertNullToNullString] DOMString port; - attribute [ConvertNullToNullString] DOMString protocol; - attribute [ConvertNullToNullString] DOMString search; + attribute [TreatNullAs=EmptyString] DOMString hash; + attribute [TreatNullAs=EmptyString] DOMString host; + attribute [TreatNullAs=EmptyString] DOMString hostname; + attribute [TreatNullAs=EmptyString] DOMString pathname; + attribute [TreatNullAs=EmptyString] DOMString port; + attribute [TreatNullAs=EmptyString] DOMString protocol; + attribute [TreatNullAs=EmptyString] DOMString search; - readonly attribute [ConvertNullToNullString] DOMString origin; + readonly attribute [TreatNullAs=EmptyString] DOMString origin; #endif readonly attribute DOMString text; diff --git a/Source/WebCore/html/HTMLAreaElement.cpp b/Source/WebCore/html/HTMLAreaElement.cpp index d763d789a..b00471678 100644 --- a/Source/WebCore/html/HTMLAreaElement.cpp +++ b/Source/WebCore/html/HTMLAreaElement.cpp @@ -252,9 +252,9 @@ String HTMLAreaElement::itemValueText() const return getURLAttribute(hrefAttr); } -void HTMLAreaElement::setItemValueText(const String& value, ExceptionCode& ec) +void HTMLAreaElement::setItemValueText(const String& value, ExceptionCode&) { - setAttribute(hrefAttr, value, ec); + setAttribute(hrefAttr, value); } #endif diff --git a/Source/WebCore/html/HTMLAttributeNames.in b/Source/WebCore/html/HTMLAttributeNames.in index 776c5e9d9..60d96d53d 100644 --- a/Source/WebCore/html/HTMLAttributeNames.in +++ b/Source/WebCore/html/HTMLAttributeNames.in @@ -246,6 +246,7 @@ onwebkitanimationend onwebkitbeginfullscreen onwebkitendfullscreen onwebkitfullscreenchange +onwebkitfullscreenerror onwebkittransitionend open optimum @@ -278,6 +279,7 @@ scoped scrollamount scrolldelay scrolling +select selected shape size diff --git a/Source/WebCore/html/HTMLButtonElement.idl b/Source/WebCore/html/HTMLButtonElement.idl index ff7dab7ba..c91947bb3 100644 --- a/Source/WebCore/html/HTMLButtonElement.idl +++ b/Source/WebCore/html/HTMLButtonElement.idl @@ -24,8 +24,8 @@ module html { readonly attribute HTMLFormElement form; attribute [Reflect, URL] DOMString formAction; - attribute [ConvertNullToNullString] DOMString formEnctype; - attribute [ConvertNullToNullString] DOMString formMethod; + attribute [TreatNullAs=EmptyString] DOMString formEnctype; + attribute [TreatNullAs=EmptyString] DOMString formMethod; attribute [Reflect] boolean formNoValidate; attribute [Reflect] DOMString formTarget; readonly attribute ValidityState validity; diff --git a/Source/WebCore/html/HTMLCanvasElement.cpp b/Source/WebCore/html/HTMLCanvasElement.cpp index 681fb93ca..143d33475 100644 --- a/Source/WebCore/html/HTMLCanvasElement.cpp +++ b/Source/WebCore/html/HTMLCanvasElement.cpp @@ -443,6 +443,22 @@ bool HTMLCanvasElement::shouldAccelerate(const IntSize& size) const #endif } +bool HTMLCanvasElement::shouldDefer() const +{ +#if USE(SKIA) + if (m_context && !m_context->is2d()) + return false; + + Settings* settings = document()->settings(); + if (!settings || !settings->deferred2dCanvasEnabled()) + return false; + + return true; +#else + return false; +#endif +} + void HTMLCanvasElement::createImageBuffer() const { ASSERT(!m_imageBuffer); @@ -471,7 +487,8 @@ void HTMLCanvasElement::createImageBuffer() const #else Unaccelerated; #endif - m_imageBuffer = ImageBuffer::create(bufferSize, ColorSpaceDeviceRGB, renderingMode); + DeferralMode deferralMode = shouldDefer() ? Deferred : NonDeferred; + m_imageBuffer = ImageBuffer::create(bufferSize, ColorSpaceDeviceRGB, renderingMode, deferralMode); if (!m_imageBuffer) return; m_imageBuffer->context()->scale(FloatSize(bufferSize.width() / logicalSize.width(), bufferSize.height() / logicalSize.height())); diff --git a/Source/WebCore/html/HTMLCanvasElement.h b/Source/WebCore/html/HTMLCanvasElement.h index 1bfe52cfe..0493902b2 100644 --- a/Source/WebCore/html/HTMLCanvasElement.h +++ b/Source/WebCore/html/HTMLCanvasElement.h @@ -146,6 +146,8 @@ private: void setSurfaceSize(const IntSize&); + bool shouldDefer() const; + HashSet m_observers; IntSize m_size; diff --git a/Source/WebCore/html/HTMLCollection.idl b/Source/WebCore/html/HTMLCollection.idl index a25f8b0d8..8fa2309cc 100644 --- a/Source/WebCore/html/HTMLCollection.idl +++ b/Source/WebCore/html/HTMLCollection.idl @@ -28,7 +28,7 @@ module html { Polymorphic ] HTMLCollection { readonly attribute unsigned long length; - [Custom] Node item(in [Optional=CallWithDefaultValue] unsigned long index); + Node item(in [Optional=CallWithDefaultValue] unsigned long index); [Custom] Node namedItem(in [Optional=CallWithDefaultValue] DOMString name); #if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C diff --git a/Source/WebCore/html/HTMLDetailsElement.cpp b/Source/WebCore/html/HTMLDetailsElement.cpp index fad9af804..ddec73876 100644 --- a/Source/WebCore/html/HTMLDetailsElement.cpp +++ b/Source/WebCore/html/HTMLDetailsElement.cpp @@ -23,12 +23,12 @@ #if ENABLE(DETAILS) +#include "HTMLContentElement.h" #include "HTMLNames.h" #include "HTMLSummaryElement.h" #include "LocalizedStrings.h" #include "MouseEvent.h" #include "RenderDetails.h" -#include "ShadowContentElement.h" #include "ShadowRoot.h" #include "Text.h" @@ -36,17 +36,21 @@ namespace WebCore { using namespace HTMLNames; -class DetailsContentElement : public ShadowContentElement { +static const AtomicString& summaryQuerySelector() +{ + DEFINE_STATIC_LOCAL(AtomicString, selector, ("summary:first-of-type")); + return selector; +}; + +class DetailsContentElement : public HTMLContentElement { public: static PassRefPtr create(Document*); private: DetailsContentElement(Document* document) - : ShadowContentElement(HTMLNames::divTag, document) + : HTMLContentElement(HTMLNames::divTag, document) { } - - virtual bool shouldInclude(Node*); }; PassRefPtr DetailsContentElement::create(Document* document) @@ -54,24 +58,16 @@ PassRefPtr DetailsContentElement::create(Document* docume return adoptRef(new DetailsContentElement(document)); } -bool DetailsContentElement::shouldInclude(Node* node) -{ - HTMLDetailsElement* details = static_cast(shadowAncestorNode()); - return details->mainSummary() != node; -} - - -class DetailsSummaryElement : public ShadowContentElement { +class DetailsSummaryElement : public HTMLContentElement { public: static PassRefPtr create(Document*); private: DetailsSummaryElement(Document* document) - : ShadowContentElement(HTMLNames::divTag, document) + : HTMLContentElement(HTMLNames::divTag, document) { + setSelect(summaryQuerySelector()); } - - virtual bool shouldInclude(Node*); }; PassRefPtr DetailsSummaryElement::create(Document* document) @@ -79,13 +75,6 @@ PassRefPtr DetailsSummaryElement::create(Document* docume return adoptRef(new DetailsSummaryElement(document)); } -bool DetailsSummaryElement::shouldInclude(Node* node) -{ - HTMLDetailsElement* details = static_cast(shadowAncestorNode()); - return details->mainSummary() == node; -} - - PassRefPtr HTMLDetailsElement::create(const QualifiedName& tagName, Document* document) { RefPtr result = adoptRef(new HTMLDetailsElement(tagName, document)); diff --git a/Source/WebCore/html/HTMLDocument.idl b/Source/WebCore/html/HTMLDocument.idl index d2400a884..a7a6bcda6 100644 --- a/Source/WebCore/html/HTMLDocument.idl +++ b/Source/WebCore/html/HTMLDocument.idl @@ -48,19 +48,19 @@ module html { readonly attribute long width; readonly attribute long height; #endif - attribute [ConvertNullToNullString] DOMString dir; - attribute [ConvertNullToNullString] DOMString designMode; + attribute [TreatNullAs=EmptyString] DOMString dir; + attribute [TreatNullAs=EmptyString] DOMString designMode; readonly attribute DOMString compatMode; readonly attribute Element activeElement; boolean hasFocus(); // Deprecated attributes - attribute [ConvertNullToNullString] DOMString bgColor; - attribute [ConvertNullToNullString] DOMString fgColor; - attribute [ConvertNullToNullString] DOMString alinkColor; - attribute [ConvertNullToNullString] DOMString linkColor; - attribute [ConvertNullToNullString] DOMString vlinkColor; + attribute [TreatNullAs=EmptyString] DOMString bgColor; + attribute [TreatNullAs=EmptyString] DOMString fgColor; + attribute [TreatNullAs=EmptyString] DOMString alinkColor; + attribute [TreatNullAs=EmptyString] DOMString linkColor; + attribute [TreatNullAs=EmptyString] DOMString vlinkColor; }; } diff --git a/Source/WebCore/html/HTMLElement.cpp b/Source/WebCore/html/HTMLElement.cpp index a78f4d057..680c23b5d 100644 --- a/Source/WebCore/html/HTMLElement.cpp +++ b/Source/WebCore/html/HTMLElement.cpp @@ -330,6 +330,8 @@ void HTMLElement::parseMappedAttribute(Attribute* attr) #if ENABLE(FULLSCREEN_API) } else if (attr->name() == onwebkitfullscreenchangeAttr) { setAttributeEventListener(eventNames().webkitfullscreenchangeEvent, createAttributeEventListener(this, attr)); + } else if (attr->name() == onwebkitfullscreenerrorAttr) { + setAttributeEventListener(eventNames().webkitfullscreenerrorEvent, createAttributeEventListener(this, attr)); #endif } } diff --git a/Source/WebCore/html/HTMLElement.idl b/Source/WebCore/html/HTMLElement.idl index 7257755ae..068cb8d74 100644 --- a/Source/WebCore/html/HTMLElement.idl +++ b/Source/WebCore/html/HTMLElement.idl @@ -40,13 +40,13 @@ module html { attribute [Reflect] DOMString accessKey; // Extensions - attribute [ConvertNullToNullString] DOMString innerHTML + attribute [TreatNullAs=EmptyString] DOMString innerHTML setter raises(DOMException); - attribute [ConvertNullToNullString] DOMString innerText + attribute [TreatNullAs=EmptyString] DOMString innerText setter raises(DOMException); - attribute [ConvertNullToNullString] DOMString outerHTML + attribute [TreatNullAs=EmptyString] DOMString outerHTML setter raises(DOMException); - attribute [ConvertNullToNullString] DOMString outerText + attribute [TreatNullAs=EmptyString] DOMString outerText setter raises(DOMException); Element insertAdjacentElement(in [Optional=CallWithDefaultValue] DOMString where, @@ -61,7 +61,7 @@ module html { readonly attribute HTMLCollection children; - attribute [ConvertNullToNullString] DOMString contentEditable + attribute [TreatNullAs=EmptyString] DOMString contentEditable setter raises(DOMException); readonly attribute boolean isContentEditable; diff --git a/Source/WebCore/html/HTMLElementsAllInOne.cpp b/Source/WebCore/html/HTMLElementsAllInOne.cpp index b624e627b..ba4b99aba 100644 --- a/Source/WebCore/html/HTMLElementsAllInOne.cpp +++ b/Source/WebCore/html/HTMLElementsAllInOne.cpp @@ -41,6 +41,7 @@ #include "HTMLBodyElement.cpp" #include "HTMLButtonElement.cpp" #include "HTMLCanvasElement.cpp" +#include "HTMLContentElement.cpp" #include "HTMLDataListElement.cpp" #include "HTMLDetailsElement.cpp" #include "HTMLDListElement.cpp" @@ -64,7 +65,6 @@ #include "HTMLIFrameElement.cpp" #include "HTMLImageElement.cpp" #include "HTMLInputElement.cpp" -#include "HTMLIsIndexElement.cpp" #include "HTMLKeygenElement.cpp" #include "HTMLLIElement.cpp" #include "HTMLLabelElement.cpp" diff --git a/Source/WebCore/html/HTMLEmbedElement.cpp b/Source/WebCore/html/HTMLEmbedElement.cpp index d0bd344f2..309aafe05 100644 --- a/Source/WebCore/html/HTMLEmbedElement.cpp +++ b/Source/WebCore/html/HTMLEmbedElement.cpp @@ -117,7 +117,7 @@ void HTMLEmbedElement::parseMappedAttribute(Attribute* attr) void HTMLEmbedElement::parametersForPlugin(Vector& paramNames, Vector& paramValues) { - NamedNodeMap* attributes = this->attributes(true); + NamedNodeMap* attributes = updatedAttributes(); if (!attributes) return; @@ -154,11 +154,8 @@ void HTMLEmbedElement::updateWidget(PluginCreationOption pluginCreationOption) Vector paramValues; parametersForPlugin(paramNames, paramValues); - ASSERT(!m_inBeforeLoadEventHandler); - m_inBeforeLoadEventHandler = true; - bool beforeLoadAllowedLoad = dispatchBeforeLoadEvent(m_url); - m_inBeforeLoadEventHandler = false; - + RefPtr protect(this); // Loading the plugin might remove us from the document. + bool beforeLoadAllowedLoad = guardedDispatchBeforeLoadEvent(m_url); if (!beforeLoadAllowedLoad) { if (document()->isPluginDocument()) { // Plugins inside plugin documents load differently than other plugins. By the time @@ -168,8 +165,9 @@ void HTMLEmbedElement::updateWidget(PluginCreationOption pluginCreationOption) } return; } + if (!renderer()) // Do not load the plugin if beforeload removed this element or its renderer. + return; - RefPtr protect(this); // Loading the plugin might remove us from the document. SubframeLoader* loader = document()->frame()->loader()->subframeLoader(); // FIXME: beforeLoad could have detached the renderer! Just like in the case above. loader->requestObject(this, m_url, getAttribute(nameAttr), m_serviceType, paramNames, paramValues); @@ -211,33 +209,6 @@ void HTMLEmbedElement::insertedIntoDocument() HTMLPlugInImageElement::insertedIntoDocument(); if (!inDocument()) return; - - String width = getAttribute(widthAttr); - String height = getAttribute(heightAttr); - if (!width.isEmpty() || !height.isEmpty()) { - Node* n = parentNode(); - while (n && !n->hasTagName(objectTag)) - n = n->parentNode(); - if (n) { - if (!width.isEmpty()) - static_cast(n)->setAttribute(widthAttr, width); - if (!height.isEmpty()) - static_cast(n)->setAttribute(heightAttr, height); - } - } -} - -void HTMLEmbedElement::attributeChanged(Attribute* attr, bool preserveDecls) -{ - HTMLPlugInImageElement::attributeChanged(attr, preserveDecls); - - if ((attr->name() == widthAttr || attr->name() == heightAttr) && !attr->isEmpty()) { - ContainerNode* n = parentNode(); - while (n && !n->hasTagName(objectTag)) - n = n->parentNode(); - if (n) - static_cast(n)->setAttribute(attr->name(), attr->value()); - } } bool HTMLEmbedElement::isURLAttribute(Attribute* attr) const @@ -263,9 +234,9 @@ String HTMLEmbedElement::itemValueText() const return getURLAttribute(srcAttr); } -void HTMLEmbedElement::setItemValueText(const String& value, ExceptionCode& ec) +void HTMLEmbedElement::setItemValueText(const String& value, ExceptionCode&) { - setAttribute(srcAttr, value, ec); + setAttribute(srcAttr, value); } #endif diff --git a/Source/WebCore/html/HTMLEmbedElement.h b/Source/WebCore/html/HTMLEmbedElement.h index bd6764df9..12ce2714b 100644 --- a/Source/WebCore/html/HTMLEmbedElement.h +++ b/Source/WebCore/html/HTMLEmbedElement.h @@ -39,7 +39,6 @@ private: virtual bool rendererIsNeeded(const NodeRenderingContext&); virtual void insertedIntoDocument(); - virtual void attributeChanged(Attribute*, bool preserveDecls = false); virtual bool isURLAttribute(Attribute*) const; virtual const QualifiedName& imageSourceAttributeName() const; diff --git a/Source/WebCore/html/HTMLEmbedElement.idl b/Source/WebCore/html/HTMLEmbedElement.idl index e395fc65e..0ef638450 100644 --- a/Source/WebCore/html/HTMLEmbedElement.idl +++ b/Source/WebCore/html/HTMLEmbedElement.idl @@ -42,7 +42,7 @@ module html { #if defined(ENABLE_SVG) && ENABLE_SVG #if !defined(LANGUAGE_OBJECTIVE_C) || !LANGUAGE_OBJECTIVE_C || defined(ENABLE_SVG_DOM_OBJC_BINDINGS) && ENABLE_SVG_DOM_OBJC_BINDINGS - [SVGCheckSecurityDocument] SVGDocument getSVGDocument() raises(DOMException); + [CheckAccessToNode] SVGDocument getSVGDocument() raises(DOMException); #endif #endif }; diff --git a/Source/WebCore/html/HTMLFormCollection.cpp b/Source/WebCore/html/HTMLFormCollection.cpp index d25653fe8..919e09c01 100644 --- a/Source/WebCore/html/HTMLFormCollection.cpp +++ b/Source/WebCore/html/HTMLFormCollection.cpp @@ -37,6 +37,7 @@ using namespace HTMLNames; HTMLFormCollection::HTMLFormCollection(HTMLFormElement* form) : HTMLCollection(form, OtherCollection) + , currentPos(0) { } diff --git a/Source/WebCore/html/HTMLFormControlElement.cpp b/Source/WebCore/html/HTMLFormControlElement.cpp index b13b25676..2b06f3d04 100644 --- a/Source/WebCore/html/HTMLFormControlElement.cpp +++ b/Source/WebCore/html/HTMLFormControlElement.cpp @@ -122,15 +122,21 @@ void HTMLFormControlElement::parseMappedAttribute(Attribute* attr) } else if (attr->name() == requiredAttr) { bool oldRequired = m_required; m_required = !attr->isNull(); - if (oldRequired != m_required) { - setNeedsValidityCheck(); - setNeedsStyleRecalc(); // Updates for :required :optional classes. - } + if (oldRequired != m_required) + requiredAttributeChanged(); } else HTMLElement::parseMappedAttribute(attr); setNeedsWillValidateCheck(); } +void HTMLFormControlElement::requiredAttributeChanged() +{ + setNeedsValidityCheck(); + // Style recalculation is needed because style selectors may include + // :required and :optional pseudo-classes. + setNeedsStyleRecalc(); +} + static bool shouldAutofocus(HTMLFormControlElement* element) { if (!element->autofocus()) @@ -139,6 +145,8 @@ static bool shouldAutofocus(HTMLFormControlElement* element) return false; if (element->document()->ignoreAutofocus()) return false; + if (element->document()->isSandboxed(SandboxAutomaticFeatures)) + return false; if (element->hasAutofocused()) return false; diff --git a/Source/WebCore/html/HTMLFormControlElement.h b/Source/WebCore/html/HTMLFormControlElement.h index f500b6df9..edc406f51 100644 --- a/Source/WebCore/html/HTMLFormControlElement.h +++ b/Source/WebCore/html/HTMLFormControlElement.h @@ -115,6 +115,7 @@ protected: HTMLFormControlElement(const QualifiedName& tagName, Document*, HTMLFormElement*); virtual void parseMappedAttribute(Attribute*); + virtual void requiredAttributeChanged(); virtual void attach(); virtual void insertedIntoTree(bool deep); virtual void removedFromTree(bool deep); diff --git a/Source/WebCore/html/HTMLFormElement.cpp b/Source/WebCore/html/HTMLFormElement.cpp index 92b684a4e..695a39b10 100644 --- a/Source/WebCore/html/HTMLFormElement.cpp +++ b/Source/WebCore/html/HTMLFormElement.cpp @@ -248,7 +248,7 @@ bool HTMLFormElement::validateInteractively(Event* event) continue; String message("An invalid form control with name='%name' is not focusable."); message.replace("%name", unhandledAssociatedElement->name()); - frame->domWindow()->console()->addMessage(HTMLMessageSource, LogMessageType, ErrorMessageLevel, message, 0, document()->url().string()); + frame->domWindow()->console()->addMessage(HTMLMessageSource, LogMessageType, ErrorMessageLevel, message, document()->url().string()); } } return false; diff --git a/Source/WebCore/html/HTMLFormElement.idl b/Source/WebCore/html/HTMLFormElement.idl index c6967eacf..d1884efe8 100644 --- a/Source/WebCore/html/HTMLFormElement.idl +++ b/Source/WebCore/html/HTMLFormElement.idl @@ -31,9 +31,9 @@ module html { attribute [Reflect] boolean noValidate; attribute [Reflect=accept_charset] DOMString acceptCharset; attribute [Reflect, URL] DOMString action; - attribute [ConvertNullToNullString] DOMString encoding; - attribute [ConvertNullToNullString] DOMString enctype; - attribute [ConvertNullToNullString] DOMString method; + attribute [TreatNullAs=EmptyString] DOMString encoding; + attribute [TreatNullAs=EmptyString] DOMString enctype; + attribute [TreatNullAs=EmptyString] DOMString method; attribute [Reflect] DOMString target; attribute [Reflect] DOMString autocomplete; diff --git a/Source/WebCore/html/HTMLFrameElement.idl b/Source/WebCore/html/HTMLFrameElement.idl index dfe4ef89c..1c6851b8a 100644 --- a/Source/WebCore/html/HTMLFrameElement.idl +++ b/Source/WebCore/html/HTMLFrameElement.idl @@ -32,19 +32,19 @@ module html { attribute [Reflect, URL] DOMString src; // Introduced in DOM Level 2: - readonly attribute [CheckFrameSecurity] Document contentDocument; + readonly attribute [CheckAccessToNode] Document contentDocument; // Extensions readonly attribute DOMWindow contentWindow; #if defined(ENABLE_SVG) && ENABLE_SVG #if !defined(LANGUAGE_OBJECTIVE_C) || !LANGUAGE_OBJECTIVE_C || defined(ENABLE_SVG_DOM_OBJC_BINDINGS) && ENABLE_SVG_DOM_OBJC_BINDINGS - [SVGCheckSecurityDocument] SVGDocument getSVGDocument() + [CheckAccessToNode] SVGDocument getSVGDocument() raises(DOMException); #endif #endif - attribute [ConvertNullToNullString, CustomSetter] DOMString location; + attribute [TreatNullAs=EmptyString, CustomSetter] DOMString location; readonly attribute long width; readonly attribute long height; diff --git a/Source/WebCore/html/HTMLFrameElementBase.cpp b/Source/WebCore/html/HTMLFrameElementBase.cpp index f5d22a418..fddec7f92 100644 --- a/Source/WebCore/html/HTMLFrameElementBase.cpp +++ b/Source/WebCore/html/HTMLFrameElementBase.cpp @@ -201,16 +201,14 @@ void HTMLFrameElementBase::insertedIntoDocument() if (!document()->frame()) return; - // Loads may cause synchronous javascript execution (e.g. beforeload or - // src=javascript), which could try to access the renderer before the normal - // parser machinery would call lazyAttach() and set us as needing style - // resolve. Any code which expects this to be attached will resolve style - // before using renderer(), so this will make sure we attach in time. - // FIXME: Normally lazyAttach marks the renderer as attached(), but we don't - // want to do that here, as as callers expect to call attach() right after - // this and attach() will ASSERT(!attached()) - ASSERT(!renderer()); // This recalc is unecessary if we already have a renderer. - lazyAttach(DoNotSetAttached); + // JavaScript in src=javascript: and beforeonload can access the renderer + // during attribute parsing *before* the normal parser machinery would + // attach the element. To support this, we lazyAttach here, but only + // if we don't already have a renderer (if we're inserted + // as part of a DocumentFragment, insertedIntoDocument from an earlier element + // could have forced a style resolve and already attached us). + if (!renderer()) + lazyAttach(DoNotSetAttached); setNameAndOpenURL(); } diff --git a/Source/WebCore/html/HTMLIFrameElement.cpp b/Source/WebCore/html/HTMLIFrameElement.cpp index ae60a1e74..817b5d749 100644 --- a/Source/WebCore/html/HTMLIFrameElement.cpp +++ b/Source/WebCore/html/HTMLIFrameElement.cpp @@ -128,9 +128,9 @@ String HTMLIFrameElement::itemValueText() const return getURLAttribute(srcAttr); } -void HTMLIFrameElement::setItemValueText(const String& value, ExceptionCode& ec) +void HTMLIFrameElement::setItemValueText(const String& value, ExceptionCode&) { - setAttribute(srcAttr, value, ec); + setAttribute(srcAttr, value); } #endif diff --git a/Source/WebCore/html/HTMLIFrameElement.idl b/Source/WebCore/html/HTMLIFrameElement.idl index 7f9e25a97..1e88269e0 100644 --- a/Source/WebCore/html/HTMLIFrameElement.idl +++ b/Source/WebCore/html/HTMLIFrameElement.idl @@ -34,14 +34,14 @@ module html { attribute [Reflect] DOMString width; // Introduced in DOM Level 2: - readonly attribute [CheckFrameSecurity] Document contentDocument; + readonly attribute [CheckAccessToNode] Document contentDocument; // Extensions readonly attribute DOMWindow contentWindow; #if defined(ENABLE_SVG) && ENABLE_SVG #if !defined(LANGUAGE_OBJECTIVE_C) || !LANGUAGE_OBJECTIVE_C || defined(ENABLE_SVG_DOM_OBJC_BINDINGS) && ENABLE_SVG_DOM_OBJC_BINDINGS - [SVGCheckSecurityDocument] SVGDocument getSVGDocument() + [CheckAccessToNode] SVGDocument getSVGDocument() raises(DOMException); #endif #endif diff --git a/Source/WebCore/html/HTMLImageElement.cpp b/Source/WebCore/html/HTMLImageElement.cpp index adc9eb904..b5c513de7 100644 --- a/Source/WebCore/html/HTMLImageElement.cpp +++ b/Source/WebCore/html/HTMLImageElement.cpp @@ -375,9 +375,9 @@ String HTMLImageElement::itemValueText() const return getURLAttribute(srcAttr); } -void HTMLImageElement::setItemValueText(const String& value, ExceptionCode& ec) +void HTMLImageElement::setItemValueText(const String& value, ExceptionCode&) { - setAttribute(srcAttr, value, ec); + setAttribute(srcAttr, value); } #endif diff --git a/Source/WebCore/html/HTMLInputElement.cpp b/Source/WebCore/html/HTMLInputElement.cpp index 3bb9af093..413c1277c 100644 --- a/Source/WebCore/html/HTMLInputElement.cpp +++ b/Source/WebCore/html/HTMLInputElement.cpp @@ -119,6 +119,9 @@ HTMLInputElement::~HTMLInputElement() // Need to remove form association while this is still an HTMLInputElement // so that virtual functions are called correctly. setForm(0); + // setForm(0) may register this to a document-level radio button group. + // We should unregister it to avoid accessing a deleted object. + document()->checkedRadioButtons().removeButton(this); } const AtomicString& HTMLInputElement::formControlName() const @@ -175,38 +178,6 @@ bool HTMLInputElement::shouldAutocomplete() const return HTMLTextFormControlElement::shouldAutocomplete(); } -void HTMLInputElement::updateCheckedRadioButtons() -{ - checkedRadioButtons().addButton(this); - - if (form()) { - const Vector& controls = form()->associatedElements(); - for (unsigned i = 0; i < controls.size(); ++i) { - if (!controls[i]->isFormControlElement()) - continue; - HTMLFormControlElement* control = static_cast(controls[i]); - if (control->name() != name()) - continue; - if (control->type() != type()) - continue; - control->setNeedsValidityCheck(); - } - } else { - typedef Document::FormElementListHashSet::const_iterator Iterator; - Iterator end = document()->formElements()->end(); - for (Iterator it = document()->formElements()->begin(); it != end; ++it) { - HTMLFormControlElementWithState* control = *it; - if (control->formControlName() != name()) - continue; - if (control->formControlType() != type()) - continue; - if (control->form()) - continue; - control->setNeedsValidityCheck(); - } - } -} - bool HTMLInputElement::isValidValue(const String& value) const { if (!m_inputType->canSetStringValue()) { @@ -229,8 +200,6 @@ bool HTMLInputElement::typeMismatch() const bool HTMLInputElement::valueMissing(const String& value) const { - if (!isRequiredFormControl() || readOnly() || disabled()) - return false; return m_inputType->valueMissing(value); } @@ -503,23 +472,12 @@ bool HTMLInputElement::shouldUseInputMethod() void HTMLInputElement::handleFocusEvent() { - if (!isTextField()) - return; - if (isPasswordField() && document()->frame()) - document()->setUseSecureKeyboardEntryWhenActive(true); + m_inputType->handleFocusEvent(); } void HTMLInputElement::handleBlurEvent() { m_inputType->handleBlurEvent(); - if (!isTextField()) - return; - Frame* frame = document()->frame(); - if (!frame) - return; - if (isPasswordField()) - document()->setUseSecureKeyboardEntryWhenActive(false); - frame->editor()->textFieldDidEndEditing(this); } void HTMLInputElement::setType(const String& type) @@ -960,13 +918,11 @@ void HTMLInputElement::setChecked(bool nowChecked, bool sendChangeEvent) if (checked() == nowChecked) return; - checkedRadioButtons().removeButton(this); - m_reflectsCheckedAttribute = false; m_isChecked = nowChecked; setNeedsStyleRecalc(); if (isRadioButton()) - updateCheckedRadioButtons(); + checkedRadioButtons().updateCheckedState(this); if (renderer() && renderer()->style()->hasAppearance()) renderer()->theme()->stateChanged(renderer(), CheckedState); setNeedsValidityCheck(); @@ -1300,8 +1256,10 @@ void HTMLInputElement::setDefaultValue(const String &value) setAttribute(valueAttr, value); } -void HTMLInputElement::setDefaultName(const AtomicString& name) +void HTMLInputElement::setInitialName(const AtomicString& name) { + ASSERT(hasTagName(isindexTag)); + ASSERT(m_name.isNull()); m_name = name; } @@ -1554,6 +1512,12 @@ bool HTMLInputElement::recalcWillValidate() const return m_inputType->supportsValidation() && HTMLTextFormControlElement::recalcWillValidate(); } +void HTMLInputElement::requiredAttributeChanged() +{ + HTMLTextFormControlElement::requiredAttributeChanged(); + checkedRadioButtons().requiredAttributeChanged(this); +} + #if ENABLE(INPUT_COLOR) void HTMLInputElement::selectColorInColorChooser(const Color& color) { diff --git a/Source/WebCore/html/HTMLInputElement.h b/Source/WebCore/html/HTMLInputElement.h index d21244d39..47ac4d326 100644 --- a/Source/WebCore/html/HTMLInputElement.h +++ b/Source/WebCore/html/HTMLInputElement.h @@ -188,8 +188,6 @@ public: String defaultValue() const; void setDefaultValue(const String&); - void setDefaultName(const AtomicString&); - Vector acceptMIMETypes(); String accept() const; String alt() const; @@ -243,6 +241,7 @@ public: protected: HTMLInputElement(const QualifiedName&, Document*, HTMLFormElement*, bool createdByParser); void createShadowSubtree(); + void setInitialName(const AtomicString&); virtual void defaultEventHandler(Event*); private: @@ -322,6 +321,7 @@ private: virtual bool isOptionalFormControl() const { return !isRequiredFormControl(); } virtual bool isRequiredFormControl() const; virtual bool recalcWillValidate() const; + virtual void requiredAttributeChanged() OVERRIDE; void updateType(); diff --git a/Source/WebCore/html/HTMLInputElement.idl b/Source/WebCore/html/HTMLInputElement.idl index 7463334bb..bedeb9ae4 100644 --- a/Source/WebCore/html/HTMLInputElement.idl +++ b/Source/WebCore/html/HTMLInputElement.idl @@ -21,13 +21,13 @@ module html { interface HTMLInputElement : HTMLElement { - attribute [ConvertNullToNullString] DOMString defaultValue; + attribute [TreatNullAs=EmptyString] DOMString defaultValue; attribute [Reflect=checked] boolean defaultChecked; attribute [Reflect] DOMString dirName; readonly attribute HTMLFormElement form; attribute [Reflect, URL] DOMString formAction; - attribute [ConvertNullToNullString] DOMString formEnctype; - attribute [ConvertNullToNullString] DOMString formMethod; + attribute [TreatNullAs=EmptyString] DOMString formEnctype; + attribute [TreatNullAs=EmptyString] DOMString formMethod; attribute [Reflect] boolean formNoValidate; attribute [Reflect] DOMString formTarget; readonly attribute ValidityState validity; @@ -57,9 +57,9 @@ module html { #endif attribute [Reflect, URL] DOMString src; attribute [Reflect] DOMString step; - attribute [ConvertNullToNullString] DOMString type; // readonly dropped as part of DOM level 2 + attribute [TreatNullAs=EmptyString] DOMString type; // readonly dropped as part of DOM level 2 attribute [Reflect] DOMString useMap; - attribute [ConvertNullToNullString] DOMString value; + attribute [TreatNullAs=EmptyString] DOMString value; #if !defined(LANGUAGE_CPP) || !LANGUAGE_CPP attribute Date valueAsDate setter raises(DOMException); #endif @@ -78,7 +78,7 @@ module html { void click(); #if !defined(LANGUAGE_JAVASCRIPT) || !LANGUAGE_JAVASCRIPT - void setValueForUser(in [ConvertNullToNullString] DOMString value); + void setValueForUser(in [TreatNullAs=EmptyString] DOMString value); #endif // WinIE extension: diff --git a/Source/WebCore/html/HTMLIsIndexElement.cpp b/Source/WebCore/html/HTMLIsIndexElement.cpp deleted file mode 100644 index f7cf5ecd1..000000000 --- a/Source/WebCore/html/HTMLIsIndexElement.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 1999 Lars Knoll (knoll@kde.org) - * (C) 1999 Antti Koivisto (koivisto@kde.org) - * (C) 2001 Dirk Mueller (mueller@kde.org) - * Copyright (C) 2004, 2005, 2006, 2010 Apple Inc. All rights reserved. - * (C) 2006 Alexey Proskuryakov (ap@nypop.com) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" -#include "HTMLIsIndexElement.h" - -#include "Attribute.h" -#include "HTMLNames.h" - -namespace WebCore { - -using namespace HTMLNames; - -HTMLIsIndexElement::HTMLIsIndexElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form) - : HTMLInputElement(tagName, document, form, false) -{ - ASSERT(hasTagName(isindexTag)); - setDefaultName(isindexTag.localName()); -} - -PassRefPtr HTMLIsIndexElement::create(Document* document, HTMLFormElement* form) -{ - RefPtr element = adoptRef(new HTMLIsIndexElement(isindexTag, document, form)); - element->createShadowSubtree(); - return element.release(); -} - -PassRefPtr HTMLIsIndexElement::create(const QualifiedName& tagName, Document* document, HTMLFormElement* form) -{ - RefPtr element = adoptRef(new HTMLIsIndexElement(tagName, document, form)); - element->createShadowSubtree(); - return element.release(); -} - -void HTMLIsIndexElement::parseMappedAttribute(Attribute* attr) -{ - if (attr->name() == promptAttr) - setValue(attr->value()); - else if (attr->name() == placeholderAttr) - updatePlaceholderVisibility(true); - else - // don't call HTMLInputElement::parseMappedAttribute here, as it would - // accept attributes this element does not support - HTMLFormControlElement::parseMappedAttribute(attr); -} - -} // namespace diff --git a/Source/WebCore/html/HTMLIsIndexElement.h b/Source/WebCore/html/HTMLIsIndexElement.h deleted file mode 100644 index 857ef7578..000000000 --- a/Source/WebCore/html/HTMLIsIndexElement.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 1999 Lars Knoll (knoll@kde.org) - * (C) 1999 Antti Koivisto (koivisto@kde.org) - * (C) 2000 Dirk Mueller (mueller@kde.org) - * Copyright (C) 2004, 2005, 2006, 2010 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef HTMLIsIndexElement_h -#define HTMLIsIndexElement_h - -#include "HTMLInputElement.h" - -namespace WebCore { - -class HTMLIsIndexElement : public HTMLInputElement { -public: - static PassRefPtr create(Document*, HTMLFormElement*); - static PassRefPtr create(const QualifiedName&, Document*, HTMLFormElement*); - -private: - HTMLIsIndexElement(const QualifiedName&, Document*, HTMLFormElement*); - - virtual bool canTriggerImplicitSubmission() const { return true; } - - virtual void parseMappedAttribute(Attribute*); -}; - -} // namespace - -#endif diff --git a/Source/WebCore/html/HTMLIsIndexElement.idl b/Source/WebCore/html/HTMLIsIndexElement.idl deleted file mode 100644 index 028a1800a..000000000 --- a/Source/WebCore/html/HTMLIsIndexElement.idl +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2006, 2010 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -module html { - - interface HTMLIsIndexElement : HTMLInputElement { - readonly attribute HTMLFormElement form; - attribute [Reflect] DOMString prompt; - }; - -} diff --git a/Source/WebCore/html/HTMLLinkElement.cpp b/Source/WebCore/html/HTMLLinkElement.cpp index 124163d93..fa54279ca 100644 --- a/Source/WebCore/html/HTMLLinkElement.cpp +++ b/Source/WebCore/html/HTMLLinkElement.cpp @@ -454,9 +454,9 @@ String HTMLLinkElement::itemValueText() const return getURLAttribute(hrefAttr); } -void HTMLLinkElement::setItemValueText(const String& value, ExceptionCode& ec) +void HTMLLinkElement::setItemValueText(const String& value, ExceptionCode&) { - setAttribute(hrefAttr, value, ec); + setAttribute(hrefAttr, value); } #endif diff --git a/Source/WebCore/html/HTMLMediaElement.cpp b/Source/WebCore/html/HTMLMediaElement.cpp index 4f06af6ea..e8bb788d6 100644 --- a/Source/WebCore/html/HTMLMediaElement.cpp +++ b/Source/WebCore/html/HTMLMediaElement.cpp @@ -51,6 +51,7 @@ #include "HTMLNames.h" #include "HTMLSourceElement.h" #include "HTMLVideoElement.h" +#include "Language.h" #include "Logging.h" #include "MediaController.h" #include "MediaControls.h" @@ -174,7 +175,6 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document* docum : HTMLElement(tagName, document) , ActiveDOMObject(document, this) , m_loadTimer(this, &HTMLMediaElement::loadTimerFired) - , m_asyncEventTimer(this, &HTMLMediaElement::asyncEventTimerFired) , m_progressEventTimer(this, &HTMLMediaElement::progressEventTimerFired) , m_playbackProgressTimer(this, &HTMLMediaElement::playbackProgressTimerFired) , m_playedTimeRanges() @@ -541,29 +541,10 @@ void HTMLMediaElement::scheduleEvent(const AtomicString& eventName) #if LOG_MEDIA_EVENTS LOG(Media, "HTMLMediaElement::scheduleEvent - scheduling '%s'", eventName.string().ascii().data()); #endif - m_pendingEvents.append(Event::create(eventName, false, true)); - if (!m_asyncEventTimer.isActive()) - m_asyncEventTimer.startOneShot(0); -} - -void HTMLMediaElement::asyncEventTimerFired(Timer*) -{ - Vector > pendingEvents; - ExceptionCode ec = 0; + RefPtr event = Event::create(eventName, false, true); + event->setTarget(this); - m_pendingEvents.swap(pendingEvents); - unsigned count = pendingEvents.size(); - for (unsigned ndx = 0; ndx < count; ++ndx) { -#if LOG_MEDIA_EVENTS - LOG(Media, "HTMLMediaElement::asyncEventTimerFired - dispatching '%s'", pendingEvents[ndx]->type().string().ascii().data()); -#endif - if (pendingEvents[ndx]->type() == eventNames().canplayEvent) { - m_dispatchingCanPlayEvent = true; - dispatchEvent(pendingEvents[ndx].release(), ec); - m_dispatchingCanPlayEvent = false; - } else - dispatchEvent(pendingEvents[ndx].release(), ec); - } + m_asyncEventQueue.enqueueEvent(event.release()); } void HTMLMediaElement::loadTimerFired(Timer*) @@ -577,7 +558,7 @@ void HTMLMediaElement::loadTimerFired(Timer*) #if ENABLE(VIDEO_TRACK) if (m_pendingLoadFlags & TextTrackResource) - configureTextTracks(); + configureNewTextTracks(); #endif m_pendingLoadFlags = 0; @@ -985,6 +966,8 @@ void HTMLMediaElement::updateActiveTextTrackCues(float movieTime) bool HTMLMediaElement::textTracksAreReady() const { + // 4.8.10.12.1 Text track model + // ... // The text tracks of a media element are ready if all the text tracks whose mode was not // in the disabled state when the element's resource selection algorithm last started now // have a text track readiness state of loaded or failed to load. @@ -1020,7 +1003,7 @@ void HTMLMediaElement::textTrackModeChanged(TextTrack* track) if (trackElement->track() != track) continue; - // Mark this track as "configured" so configureTextTrack won't change the mode again. + // Mark this track as "configured" so configureNewTextTracks won't change the mode again. trackElement->setHasBeenConfigured(true); if (track->mode() != TextTrack::DISABLED && trackElement->readyState() == HTMLTrackElement::NONE) trackElement->scheduleLoad(); @@ -1192,8 +1175,7 @@ void HTMLMediaElement::mediaEngineError(PassRefPtr err) void HTMLMediaElement::cancelPendingEventsAndCallbacks() { LOG(Media, "HTMLMediaElement::cancelPendingEventsAndCallbacks"); - - m_pendingEvents.clear(); + m_asyncEventQueue.cancelAllEvents(); for (Node* node = firstChild(); node; node = node->nextSibling()) { if (node->hasTagName(sourceTag)) @@ -1273,14 +1255,12 @@ void HTMLMediaElement::setNetworkState(MediaPlayer::NetworkState state) if (state == MediaPlayer::Idle) { if (m_networkState > NETWORK_IDLE) { - m_progressEventTimer.stop(); - if (hasMediaControls() && m_player->bytesLoaded() != m_previousProgress) - mediaControls()->bufferingProgressed(); - + changeNetworkStateFromLoadingToIdle(); scheduleEvent(eventNames().suspendEvent); setShouldDelayLoadEvent(false); + } else { + m_networkState = NETWORK_IDLE; } - m_networkState = NETWORK_IDLE; } if (state == MediaPlayer::Loading) { @@ -1290,16 +1270,8 @@ void HTMLMediaElement::setNetworkState(MediaPlayer::NetworkState state) } if (state == MediaPlayer::Loaded) { - if (m_networkState != NETWORK_IDLE) { - m_progressEventTimer.stop(); - if (hasMediaControls() && m_player->bytesLoaded() != m_previousProgress) - mediaControls()->bufferingProgressed(); - - // Schedule one last progress event so we guarantee that at least one is fired - // for files that load very quickly. - scheduleEvent(eventNames().progressEvent); - } - m_networkState = NETWORK_IDLE; + if (m_networkState != NETWORK_IDLE) + changeNetworkStateFromLoadingToIdle(); m_completelyLoaded = true; } @@ -1307,6 +1279,18 @@ void HTMLMediaElement::setNetworkState(MediaPlayer::NetworkState state) mediaControls()->updateStatusDisplay(); } +void HTMLMediaElement::changeNetworkStateFromLoadingToIdle() +{ + m_progressEventTimer.stop(); + if (hasMediaControls() && m_player->bytesLoaded() != m_previousProgress) + mediaControls()->bufferingProgressed(); + + // Schedule one last progress event so we guarantee that at least one is fired + // for files that load very quickly. + scheduleEvent(eventNames().progressEvent); + m_networkState = NETWORK_IDLE; +} + void HTMLMediaElement::mediaPlayerReadyStateChanged(MediaPlayer*) { beginProcessingMediaPlayerCallback(); @@ -1398,7 +1382,7 @@ void HTMLMediaElement::setReadyState(MediaPlayer::ReadyState state) if (isPotentiallyPlaying && oldState <= HAVE_CURRENT_DATA) scheduleEvent(eventNames().playingEvent); - if (m_autoplaying && m_paused && autoplay()) { + if (m_autoplaying && m_paused && autoplay() && !document()->isSandboxed(SandboxAutomaticFeatures)) { m_paused = false; invalidateCachedTime(); scheduleEvent(eventNames().playEvent); @@ -2217,7 +2201,7 @@ float HTMLMediaElement::percentLoaded() const } #if ENABLE(VIDEO_TRACK) -PassRefPtr HTMLMediaElement::addTrack(const String& kind, const String& label, const String& language, ExceptionCode& ec) +PassRefPtr HTMLMediaElement::addTextTrack(const String& kind, const String& label, const String& language, ExceptionCode& ec) { if (!RuntimeEnabledFeatures::webkitVideoTrackEnabled()) return 0; @@ -2259,15 +2243,13 @@ TextTrackList* HTMLMediaElement::textTracks() HTMLTrackElement* HTMLMediaElement::showingTrackWithSameKind(HTMLTrackElement* trackElement) const { - HTMLTrackElement* showingTrack = 0; - for (Node* node = firstChild(); node; node = node->nextSibling()) { if (trackElement == node) continue; if (!node->hasTagName(trackTag)) continue; - showingTrack = static_cast(node); + HTMLTrackElement* showingTrack = static_cast(node); if (showingTrack->kind() == trackElement->kind() && showingTrack->track()->mode() == TextTrack::SHOWING) return showingTrack; } @@ -2298,7 +2280,7 @@ void HTMLMediaElement::trackWasAdded(HTMLTrackElement* trackElement) scheduleLoad(TextTrackResource); } -void HTMLMediaElement::trackWillBeRemoved(HTMLTrackElement* trackElement) +void HTMLMediaElement::trackWasRemoved(HTMLTrackElement* trackElement) { ASSERT(trackElement->hasTagName(trackTag)); @@ -2308,7 +2290,7 @@ void HTMLMediaElement::trackWillBeRemoved(HTMLTrackElement* trackElement) #if !LOG_DISABLED if (trackElement->hasTagName(trackTag)) { KURL url = trackElement->getNonEmptyURLAttribute(srcAttr); - LOG(Media, "HTMLMediaElement::trackWillBeRemoved - 'src' is %s", urlForLogging(url).utf8().data()); + LOG(Media, "HTMLMediaElement::trackWasRemoved - 'src' is %s", urlForLogging(url).utf8().data()); } #endif @@ -2334,131 +2316,176 @@ bool HTMLMediaElement::userIsInterestedInThisLanguage(const String&) const return true; } -bool HTMLMediaElement::userIsInterestedInThisTrack(HTMLTrackElement* trackElement) const +bool HTMLMediaElement::userIsInterestedInThisTrackKind(String kind) const { - RefPtr textTrack = trackElement->track(); - if (!textTrack) - return false; - - String kind = textTrack->kind(); - if (!TextTrack::isValidKindKeyword(kind)) - return false; - // If ... the user has indicated an interest in having a track with this text track kind, text track language, ... Settings* settings = document()->settings(); if (!settings) return false; - if (kind == TextTrack::subtitlesKeyword() || kind == TextTrack::captionsKeyword()) { - if (kind == TextTrack::subtitlesKeyword() && !settings->shouldDisplaySubtitles()) - return false; - if (kind == TextTrack::captionsKeyword() && !settings->shouldDisplayCaptions()) - return false; - return userIsInterestedInThisLanguage(trackElement->srclang()); - } + if (kind == TextTrack::subtitlesKeyword()) + return settings->shouldDisplaySubtitles(); + if (kind == TextTrack::captionsKeyword()) + return settings->shouldDisplayCaptions(); + if (kind == TextTrack::descriptionsKeyword()) + return settings->shouldDisplayTextDescriptions(); - if (kind == TextTrack::descriptionsKeyword()) { - if (!settings->shouldDisplayTextDescriptions()) - return false; - return userIsInterestedInThisLanguage(trackElement->srclang()); - } - return false; } -void HTMLMediaElement::configureTextTrack(HTMLTrackElement* trackElement) +void HTMLMediaElement::configureTextTrackGroup(const TrackGroup& group) const { -#if !LOG_DISABLED - if (trackElement->hasTagName(trackTag)) { - KURL url = trackElement->getNonEmptyURLAttribute(srcAttr); - LOG(Media, "HTMLMediaElement::configureTextTrack - 'src' is %s", urlForLogging(url).utf8().data()); + ASSERT(group.tracks.size()); + + String bestMatchingLanguage; + if (group.hasSrcLang) { + Vector languages; + languages.reserveInitialCapacity(group.tracks.size()); + for (size_t i = 0; i < group.tracks.size(); ++i) { + String srcLanguage = group.tracks[i]->track()->language(); + if (srcLanguage.length()) + languages.append(srcLanguage); + } + bestMatchingLanguage = preferredLanguageFromList(languages); } -#endif - // 4.8.10.12.3 Sourcing out-of-band text tracks - - // When a text track corresponding to a track element is added to a media element's list of text tracks, - // the user agent must set the text track mode appropriately, as determined by the following conditions: - RefPtr textTrack = trackElement->track(); - if (!textTrack) - return; - - TextTrack::Mode mode = TextTrack::HIDDEN; - HTMLTrackElement* trackElementCurrentlyShowing = showingTrackWithSameKind(trackElement); - String kind = textTrack->kind(); - bool hideDefaultTrack = false; - - if (userIsInterestedInThisTrack(trackElement)) { - if (kind == TextTrack::subtitlesKeyword() || kind == TextTrack::captionsKeyword()) { - // * If the text track kind is subtitles or captions and the user has indicated an interest in having a + // First, find the track in the group that should be enabled (if any). + HTMLTrackElement* trackElementToEnable = 0; + HTMLTrackElement* defaultTrack = 0; + HTMLTrackElement* fallbackTrack = 0; + for (size_t i = 0; !trackElementToEnable && i < group.tracks.size(); ++i) { + HTMLTrackElement* trackElement = group.tracks[i]; + RefPtr textTrack = trackElement->track(); + + if (userIsInterestedInThisTrackKind(textTrack->kind())) { + // * If the text track kind is { [subtitles or captions] [descriptions] } and the user has indicated an interest in having a // track with this text track kind, text track language, and text track label enabled, and there is no // other text track in the media element's list of text tracks with a text track kind of either subtitles // or captions whose text track mode is showing - hideDefaultTrack = trackElementCurrentlyShowing && trackElementCurrentlyShowing->track()->showingByDefault(); - if (!trackElementCurrentlyShowing || hideDefaultTrack) { - // Let the text track mode be showing. - // If there is a text track in the media element's list of text tracks whose text track mode is showing - // by default, the user agent must furthermore change that text track's text track mode to hidden. - mode = TextTrack::SHOWING; - } - } else if (kind == TextTrack::descriptionsKeyword()) { - // * If the text track kind is descriptions and the user has indicated an interest in having text - // descriptions with this text track language and text track label enabled, and there is no other text - // track in the media element's list of text tracks with a text track kind of descriptions whose text - // track mode is showing - hideDefaultTrack = trackElementCurrentlyShowing && trackElementCurrentlyShowing->track()->showingByDefault(); - if (!trackElementCurrentlyShowing || hideDefaultTrack) { - // Let the text track mode be showing. - // If there is a text track in the media element's list of text tracks whose text track mode is showing - // by default, the user agent must furthermore change that text track's text track mode to hidden. - mode = TextTrack::SHOWING; - } - } else if (kind == TextTrack::chaptersKeyword()) { + // ... // * If the text track kind is chapters and the text track language is one that the user agent has reason // to believe is appropriate for the user, and there is no other text track in the media element's list of // text tracks with a text track kind of chapters whose text track mode is showing // Let the text track mode be showing. - if (!trackElementCurrentlyShowing) - mode = TextTrack::SHOWING; + if (bestMatchingLanguage.length()) { + if (textTrack->language() == bestMatchingLanguage) + trackElementToEnable = trackElement; + } else if (trackElement->isDefault()) { + // The user is interested in this type of track, but their language preference doesn't match any track so we will + // enable the 'default' track. + defaultTrack = trackElement; + } + + // Remember the first track that doesn't match language or have 'default' to potentially use as fallback. + if (!fallbackTrack) + fallbackTrack = trackElement; + } else if (!group.visibleTrack && !defaultTrack && trackElement->isDefault()) { + // * If the track element has a default attribute specified, and there is no other text track in the media + // element's list of text tracks whose text track mode is showing or showing by default + // Let the text track mode be showing by default. + defaultTrack = trackElement; } - } else if (!trackElementCurrentlyShowing && trackElement->isDefault()) { - // * If the track element has a default attribute specified, and there is no other text track in the media - // element's list of text tracks whose text track mode is showing or showing by default - // Let the text track mode be showing by default. - mode = TextTrack::SHOWING; - textTrack->setShowingByDefault(false); - } else { - // Otherwise - // Let the text track mode be disabled. - mode = TextTrack::DISABLED; } - ExceptionCode unusedException; - if (hideDefaultTrack) { - trackElementCurrentlyShowing->track()->setMode(TextTrack::HIDDEN, unusedException); - trackElementCurrentlyShowing->track()->setShowingByDefault(false); + if (!trackElementToEnable && defaultTrack) + trackElementToEnable = defaultTrack; + + // If no track matches the user's preferred language and non was marked 'default', enable the first track + // because the user has explicitly stated a preference for this kind of track. + if (!trackElementToEnable && fallbackTrack) + trackElementToEnable = fallbackTrack; + + for (size_t i = 0; i < group.tracks.size(); ++i) { + HTMLTrackElement* trackElement = group.tracks[i]; + RefPtr textTrack = trackElement->track(); + ExceptionCode unusedException; + + if (trackElementToEnable == trackElement) { + textTrack->setMode(TextTrack::SHOWING, unusedException); + if (defaultTrack == trackElement) + textTrack->setShowingByDefault(true); + } else { + if (textTrack->showingByDefault()) { + // If there is a text track in the media element's list of text tracks whose text track + // mode is showing by default, the user agent must furthermore change that text track's + // text track mode to hidden. + textTrack->setShowingByDefault(false); + textTrack->setMode(TextTrack::HIDDEN, unusedException); + } else + textTrack->setMode(TextTrack::DISABLED, unusedException); + } } - textTrack->setMode(mode, unusedException); + if (trackElementToEnable && group.defaultTrack && group.defaultTrack != trackElementToEnable) { + RefPtr textTrack = group.defaultTrack->track(); + if (textTrack && textTrack->showingByDefault()) { + ExceptionCode unusedException; + textTrack->setShowingByDefault(false); + textTrack->setMode(TextTrack::HIDDEN, unusedException); + } + } } - -void HTMLMediaElement::configureTextTracks() + +void HTMLMediaElement::configureNewTextTracks() { + TrackGroup captionAndSubtitleTracks(TrackGroup::CaptionsAndSubtitles); + TrackGroup descriptionTracks(TrackGroup::Description); + TrackGroup chapterTracks(TrackGroup::Chapter); + TrackGroup metadataTracks(TrackGroup::Metadata); + TrackGroup otherTracks(TrackGroup::Other); + for (Node* node = firstChild(); node; node = node->nextSibling()) { if (!node->hasTagName(trackTag)) continue; + HTMLTrackElement* trackElement = static_cast(node); + RefPtr textTrack = trackElement->track(); + if (!textTrack) + continue; + + String kind = textTrack->kind(); + TrackGroup* currentGroup; + if (kind == TextTrack::subtitlesKeyword() || kind == TextTrack::captionsKeyword()) + currentGroup = &captionAndSubtitleTracks; + else if (kind == TextTrack::descriptionsKeyword()) + currentGroup = &descriptionTracks; + else if (kind == TextTrack::chaptersKeyword()) + currentGroup = &chapterTracks; + else if (kind == TextTrack::metadataKeyword()) + currentGroup = &metadataTracks; + else + currentGroup = &otherTracks; + + if (!currentGroup->visibleTrack && textTrack->mode() == TextTrack::SHOWING) + currentGroup->visibleTrack = trackElement; + if (!currentGroup->defaultTrack && trackElement->isDefault()) + currentGroup->defaultTrack = trackElement; + + // Do not add this track to the group if it has already been automatically configured + // as we only want to call configureTextTrack once per track so that adding another + // track after the initial configuration doesn't reconfigure every track - only those + // that should be changed by the new addition. For example all metadata tracks are + // disabled by default, and we don't want a track that has been enabled by script + // to be disabled automatically when a new metadata track is added later. + if (trackElement->hasBeenConfigured()) + continue; - // Only call configureTextTrack once per track so that adding another track after - // the initial configuration doesn't reconfigure every track, only those that should - // be changed by the new addition. For example all metadata tracks are disabled by - // default, and we don't want a track that has been enabled by script to be disabled - // automatically when a new track element is added later. - if (!trackElement->hasBeenConfigured()) - configureTextTrack(trackElement); + if (textTrack->language().length()) + currentGroup->hasSrcLang = true; + currentGroup->tracks.append(trackElement); } + + if (captionAndSubtitleTracks.tracks.size()) + configureTextTrackGroup(captionAndSubtitleTracks); + if (descriptionTracks.tracks.size()) + configureTextTrackGroup(descriptionTracks); + if (chapterTracks.tracks.size()) + configureTextTrackGroup(chapterTracks); + if (metadataTracks.tracks.size()) + configureTextTrackGroup(metadataTracks); + if (otherTracks.tracks.size()) + configureTextTrackGroup(otherTracks); } - #endif bool HTMLMediaElement::havePotentialSourceChild() @@ -2785,6 +2812,14 @@ void HTMLMediaElement::mediaPlayerSawUnsupportedTracks(MediaPlayer*) } } +void HTMLMediaElement::mediaPlayerResourceNotSupported(MediaPlayer*) +{ + LOG(Media, "HTMLMediaElement::mediaPlayerResourceNotSupported"); + + // The MediaPlayer came across content which no installed engine supports. + mediaLoadingFailed(MediaPlayer::FormatError); +} + // MediaPlayerPresentation methods void HTMLMediaElement::mediaPlayerRepaint(MediaPlayer*) { @@ -3167,11 +3202,7 @@ void HTMLMediaElement::resume() bool HTMLMediaElement::hasPendingActivity() const { - // Return true when we have pending events so we can't fire events after the JS - // object gets collected. - bool pending = m_pendingEvents.size(); - LOG(Media, "HTMLMediaElement::hasPendingActivity -> %s", boolString(pending)); - return pending; + return m_asyncEventQueue.hasPendingEvents(); } void HTMLMediaElement::mediaVolumeDidChange() @@ -3610,9 +3641,9 @@ String HTMLMediaElement::itemValueText() const return getURLAttribute(srcAttr); } -void HTMLMediaElement::setItemValueText(const String& value, ExceptionCode& ec) +void HTMLMediaElement::setItemValueText(const String& value, ExceptionCode&) { - setAttribute(srcAttr, value, ec); + setAttribute(srcAttr, value); } #endif @@ -3682,6 +3713,24 @@ void HTMLMediaElement::updateMediaController() m_mediaController->reportControllerState(); } +bool HTMLMediaElement::dispatchEvent(PassRefPtr event) +{ + bool dispatchResult; + bool isCanPlayEvent; + + isCanPlayEvent = (event->type() == eventNames().canplayEvent); + + if (isCanPlayEvent) + m_dispatchingCanPlayEvent = true; + + dispatchResult = HTMLElement::dispatchEvent(event); + + if (isCanPlayEvent) + m_dispatchingCanPlayEvent = false; + + return dispatchResult; +} + bool HTMLMediaElement::isBlocked() const { // A media element is a blocked media element if its readyState attribute is in the diff --git a/Source/WebCore/html/HTMLMediaElement.h b/Source/WebCore/html/HTMLMediaElement.h index 198b9b210..98fdf5a0f 100644 --- a/Source/WebCore/html/HTMLMediaElement.h +++ b/Source/WebCore/html/HTMLMediaElement.h @@ -30,6 +30,7 @@ #include "HTMLElement.h" #include "ActiveDOMObject.h" +#include "GenericEventQueue.h" #include "MediaCanStartListener.h" #include "MediaControllerInterface.h" #include "MediaPlayer.h" @@ -196,18 +197,39 @@ public: float percentLoaded() const; #if ENABLE(VIDEO_TRACK) - PassRefPtr addTrack(const String& kind, const String& label, const String& language, ExceptionCode&); - PassRefPtr addTrack(const String& kind, const String& label, ExceptionCode& ec) { return addTrack(kind, label, emptyString(), ec); } - PassRefPtr addTrack(const String& kind, ExceptionCode& ec) { return addTrack(kind, emptyString(), emptyString(), ec); } + PassRefPtr addTextTrack(const String& kind, const String& label, const String& language, ExceptionCode&); + PassRefPtr addTextTrack(const String& kind, const String& label, ExceptionCode& ec) { return addTextTrack(kind, label, emptyString(), ec); } + PassRefPtr addTextTrack(const String& kind, ExceptionCode& ec) { return addTextTrack(kind, emptyString(), emptyString(), ec); } TextTrackList* textTracks(); CueList currentlyActiveCues() const { return m_currentlyActiveCues; } virtual void trackWasAdded(HTMLTrackElement*); - virtual void trackWillBeRemoved(HTMLTrackElement*); - - void configureTextTrack(HTMLTrackElement*); - void configureTextTracks(); + virtual void trackWasRemoved(HTMLTrackElement*); + + struct TrackGroup { + enum GroupKind { CaptionsAndSubtitles, Description, Chapter, Metadata, Other }; + + TrackGroup(GroupKind kind) + : visibleTrack(0) + , defaultTrack(0) + , kind(kind) + , hasSrcLang(false) + { + } + + Vector tracks; + HTMLTrackElement* visibleTrack; + HTMLTrackElement* defaultTrack; + GroupKind kind; + bool hasSrcLang; + }; + + void configureTextTrackGroupForLanguage(const TrackGroup&) const; + void configureNewTextTracks(); + void configureTextTrackGroup(const TrackGroup&) const; + + bool userIsInterestedInThisTrackKind(String) const; bool textTracksAreReady() const; void configureTextTrackDisplay(); @@ -273,6 +295,8 @@ public: MediaController* controller() const; void setController(PassRefPtr); + virtual bool dispatchEvent(PassRefPtr); + protected: HTMLMediaElement(const QualifiedName&, Document*, bool); virtual ~HTMLMediaElement(); @@ -347,6 +371,7 @@ private: virtual void mediaPlayerRateChanged(MediaPlayer*); virtual void mediaPlayerPlaybackStateChanged(MediaPlayer*); virtual void mediaPlayerSawUnsupportedTracks(MediaPlayer*); + virtual void mediaPlayerResourceNotSupported(MediaPlayer*); virtual void mediaPlayerRepaint(MediaPlayer*); virtual void mediaPlayerSizeChanged(MediaPlayer*); #if USE(ACCELERATED_COMPOSITING) @@ -364,7 +389,6 @@ private: #endif void loadTimerFired(Timer*); - void asyncEventTimerFired(Timer*); void progressEventTimerFired(Timer*); void playbackProgressTimerFired(Timer*); void startPlaybackProgressTimer(); @@ -398,7 +422,6 @@ private: #if ENABLE(VIDEO_TRACK) void updateActiveTextTrackCues(float); bool userIsInterestedInThisLanguage(const String&) const; - bool userIsInterestedInThisTrack(HTMLTrackElement*) const; HTMLTrackElement* showingTrackWithSameKind(HTMLTrackElement*) const; bool ignoreTrackDisplayUpdateRequests() const { return m_ignoreTrackDisplayUpdate > 0; } @@ -449,6 +472,8 @@ private: virtual void* preDispatchEventHandler(Event*); + void changeNetworkStateFromLoadingToIdle(); + #if ENABLE(MICRODATA) virtual String itemValueText() const; virtual void setItemValueText(const String&, ExceptionCode&); @@ -467,11 +492,10 @@ private: #endif Timer m_loadTimer; - Timer m_asyncEventTimer; Timer m_progressEventTimer; Timer m_playbackProgressTimer; - Vector > m_pendingEvents; RefPtr m_playedTimeRanges; + GenericEventQueue m_asyncEventQueue; float m_playbackRate; float m_defaultPlaybackRate; diff --git a/Source/WebCore/html/HTMLMediaElement.idl b/Source/WebCore/html/HTMLMediaElement.idl index 2dd55d562..484d574e8 100644 --- a/Source/WebCore/html/HTMLMediaElement.idl +++ b/Source/WebCore/html/HTMLMediaElement.idl @@ -112,12 +112,12 @@ module html { #endif #if defined(ENABLE_VIDEO_TRACK) && ENABLE_VIDEO_TRACK - [EnabledAtRuntime=webkitVideoTrack] TextTrack addTrack(in DOMString kind, in [Optional] DOMString label, in [Optional] DOMString language) + [EnabledAtRuntime=webkitVideoTrack] TextTrack addTextTrack(in DOMString kind, in [Optional] DOMString label, in [Optional] DOMString language) raises (DOMException); readonly attribute [EnabledAtRuntime=webkitVideoTrack] TextTrackList textTracks; #endif - attribute [Reflect, ConvertNullToNullString, ConvertNullStringToNull] DOMString mediaGroup; + attribute [Reflect, TreatNullAs=EmptyString, ConvertNullStringToNull] DOMString mediaGroup; attribute [CustomSetter] MediaController controller; }; } diff --git a/Source/WebCore/html/HTMLMetaElement.cpp b/Source/WebCore/html/HTMLMetaElement.cpp index c27b9ba23..213ae15b1 100644 --- a/Source/WebCore/html/HTMLMetaElement.cpp +++ b/Source/WebCore/html/HTMLMetaElement.cpp @@ -103,9 +103,9 @@ String HTMLMetaElement::itemValueText() const return getAttribute(contentAttr); } -void HTMLMetaElement::setItemValueText(const String& value, ExceptionCode& ec) +void HTMLMetaElement::setItemValueText(const String& value, ExceptionCode&) { - setAttribute(contentAttr, value, ec); + setAttribute(contentAttr, value); } #endif diff --git a/Source/WebCore/html/HTMLObjectElement.cpp b/Source/WebCore/html/HTMLObjectElement.cpp index 3f9f77fb2..590d69b98 100644 --- a/Source/WebCore/html/HTMLObjectElement.cpp +++ b/Source/WebCore/html/HTMLObjectElement.cpp @@ -177,7 +177,7 @@ void HTMLObjectElement::parametersForPlugin(Vector& paramNames, Vector element into arrays, but don't override values. - NamedNodeMap* attributes = this->attributes(true); + NamedNodeMap* attributes = updatedAttributes(); if (attributes) { for (unsigned i = 0; i < attributes->length(); ++i) { Attribute* it = attributes->attributeItem(i); @@ -289,22 +289,13 @@ void HTMLObjectElement::updateWidget(PluginCreationOption pluginCreationOption) if (pluginCreationOption == CreateOnlyNonNetscapePlugins && wouldLoadAsNetscapePlugin(url, serviceType)) return; - ASSERT(!m_inBeforeLoadEventHandler); - m_inBeforeLoadEventHandler = true; - bool beforeLoadAllowedLoad = dispatchBeforeLoadEvent(url); - m_inBeforeLoadEventHandler = false; - - // beforeload events can modify the DOM, potentially causing - // RenderWidget::destroy() to be called. Ensure we haven't been - // destroyed before continuing. - // FIXME: Should this render fallback content? - if (!renderer()) + RefPtr protect(this); // beforeload and plugin loading can make arbitrary DOM mutations. + bool beforeLoadAllowedLoad = guardedDispatchBeforeLoadEvent(url); + if (!renderer()) // Do not load the plugin if beforeload removed this element or its renderer. return; - RefPtr protect(this); // Loading the plugin might remove us from the document. SubframeLoader* loader = document()->frame()->loader()->subframeLoader(); bool success = beforeLoadAllowedLoad && hasValidClassId() && loader->requestObject(this, url, getAttribute(nameAttr), serviceType, paramNames, paramValues); - if (!success && fallbackContent) renderFallbackContent(); } @@ -520,9 +511,9 @@ String HTMLObjectElement::itemValueText() const return getURLAttribute(dataAttr); } -void HTMLObjectElement::setItemValueText(const String& value, ExceptionCode& ec) +void HTMLObjectElement::setItemValueText(const String& value, ExceptionCode&) { - setAttribute(dataAttr, value, ec); + setAttribute(dataAttr, value); } #endif diff --git a/Source/WebCore/html/HTMLObjectElement.idl b/Source/WebCore/html/HTMLObjectElement.idl index c1fa8c003..27e998a1b 100644 --- a/Source/WebCore/html/HTMLObjectElement.idl +++ b/Source/WebCore/html/HTMLObjectElement.idl @@ -49,11 +49,11 @@ module html { void setCustomValidity(in [ConvertUndefinedOrNullToNullString] DOMString error); // Introduced in DOM Level 2: - readonly attribute [CheckFrameSecurity] Document contentDocument; + readonly attribute [CheckAccessToNode] Document contentDocument; #if defined(ENABLE_SVG) && ENABLE_SVG #if !defined(LANGUAGE_OBJECTIVE_C) || !LANGUAGE_OBJECTIVE_C || defined(ENABLE_SVG_DOM_OBJC_BINDINGS) && ENABLE_SVG_DOM_OBJC_BINDINGS - [SVGCheckSecurityDocument] SVGDocument getSVGDocument() raises(DOMException); + [CheckAccessToNode] SVGDocument getSVGDocument() raises(DOMException); #endif #endif diff --git a/Source/WebCore/html/HTMLOutputElement.idl b/Source/WebCore/html/HTMLOutputElement.idl index 4e6cbfbd7..378ae53de 100644 --- a/Source/WebCore/html/HTMLOutputElement.idl +++ b/Source/WebCore/html/HTMLOutputElement.idl @@ -29,8 +29,8 @@ module html { attribute [Reflect] DOMString name; readonly attribute DOMString type; - attribute [ConvertNullToNullString] DOMString defaultValue; - attribute [ConvertNullToNullString] DOMString value; + attribute [TreatNullAs=EmptyString] DOMString defaultValue; + attribute [TreatNullAs=EmptyString] DOMString value; readonly attribute boolean willValidate; readonly attribute ValidityState validity; diff --git a/Source/WebCore/html/HTMLParamElement.cpp b/Source/WebCore/html/HTMLParamElement.cpp index d1f53a14d..aa228bc31 100644 --- a/Source/WebCore/html/HTMLParamElement.cpp +++ b/Source/WebCore/html/HTMLParamElement.cpp @@ -65,10 +65,10 @@ void HTMLParamElement::parseMappedAttribute(Attribute* attr) bool HTMLParamElement::isURLAttribute(Attribute* attr) const { - if (attr->name() == valueAttr) { - Attribute* attr = attributes()->getAttributeItem(nameAttr); - if (attr) { - const AtomicString& value = attr->value(); + if (attr->name() == valueAttr && hasAttributes()) { + Attribute* nameAttribute = attributeMap()->getAttributeItem(nameAttr); + if (nameAttribute) { + const AtomicString& value = nameAttribute->value(); if (isURLParameter(value)) return true; } diff --git a/Source/WebCore/html/HTMLPlugInElement.cpp b/Source/WebCore/html/HTMLPlugInElement.cpp index cc6f3dea6..6229d2e03 100644 --- a/Source/WebCore/html/HTMLPlugInElement.cpp +++ b/Source/WebCore/html/HTMLPlugInElement.cpp @@ -110,6 +110,17 @@ PassScriptInstance HTMLPlugInElement::getInstance() return m_instance; } +bool HTMLPlugInElement::guardedDispatchBeforeLoadEvent(const String& sourceURL) +{ + ASSERT(!m_inBeforeLoadEventHandler); + m_inBeforeLoadEventHandler = true; + // static_cast is used to avoid a compile error since dispatchBeforeLoadEvent + // is intentionally undefined on this class. + bool beforeLoadAllowedLoad = static_cast(this)->dispatchBeforeLoadEvent(sourceURL); + m_inBeforeLoadEventHandler = false; + return beforeLoadAllowedLoad; +} + Widget* HTMLPlugInElement::pluginWidget() { if (m_inBeforeLoadEventHandler) { diff --git a/Source/WebCore/html/HTMLPlugInElement.h b/Source/WebCore/html/HTMLPlugInElement.h index 7dadfda9f..a10af6141 100644 --- a/Source/WebCore/html/HTMLPlugInElement.h +++ b/Source/WebCore/html/HTMLPlugInElement.h @@ -62,8 +62,12 @@ protected: virtual void parseMappedAttribute(Attribute*); bool m_inBeforeLoadEventHandler; + // Subclasses should use guardedDispatchBeforeLoadEvent instead of calling dispatchBeforeLoadEvent directly. + bool guardedDispatchBeforeLoadEvent(const String& sourceURL); private: + bool dispatchBeforeLoadEvent(const String& sourceURL); // Not implemented, generates a compile error if subclasses call this by mistake. + virtual void defaultEventHandler(Event*); virtual RenderWidget* renderWidgetForJSBindings() = 0; diff --git a/Source/WebCore/html/HTMLPlugInImageElement.cpp b/Source/WebCore/html/HTMLPlugInImageElement.cpp index ce9bb7431..515022aad 100644 --- a/Source/WebCore/html/HTMLPlugInImageElement.cpp +++ b/Source/WebCore/html/HTMLPlugInImageElement.cpp @@ -217,25 +217,23 @@ void HTMLPlugInImageElement::didMoveToNewDocument(Document* oldDocument) void HTMLPlugInImageElement::documentWillSuspendForPageCache() { - if (RenderStyle* rs = renderStyle()) { - m_customStyleForPageCache = RenderStyle::clone(rs); + if (RenderStyle* renderStyle = this->renderStyle()) { + m_customStyleForPageCache = RenderStyle::clone(renderStyle); m_customStyleForPageCache->setDisplay(NONE); - } - - setHasCustomStyleForRenderer(); + setHasCustomStyleForRenderer(); - if (m_customStyleForPageCache) recalcStyle(Force); - + } + HTMLPlugInElement::documentWillSuspendForPageCache(); } void HTMLPlugInImageElement::documentDidResumeFromPageCache() { - clearHasCustomStyleForRenderer(); - if (m_customStyleForPageCache) { m_customStyleForPageCache = 0; + clearHasCustomStyleForRenderer(); + recalcStyle(Force); } @@ -244,9 +242,7 @@ void HTMLPlugInImageElement::documentDidResumeFromPageCache() PassRefPtr HTMLPlugInImageElement::customStyleForRenderer() { - if (!m_customStyleForPageCache) - return renderStyle(); - + ASSERT(m_customStyleForPageCache); return m_customStyleForPageCache; } diff --git a/Source/WebCore/html/HTMLPropertiesCollection.cpp b/Source/WebCore/html/HTMLPropertiesCollection.cpp index 86fcecfae..6aac467ad 100644 --- a/Source/WebCore/html/HTMLPropertiesCollection.cpp +++ b/Source/WebCore/html/HTMLPropertiesCollection.cpp @@ -49,12 +49,12 @@ static inline bool compareTreeOrder(Node* node1, Node* node2) return (node2->compareDocumentPosition(node1) & (Node::DOCUMENT_POSITION_PRECEDING | Node::DOCUMENT_POSITION_DISCONNECTED)) == Node::DOCUMENT_POSITION_PRECEDING; } -PassOwnPtr HTMLPropertiesCollection::create(PassRefPtr itemNode) +PassOwnPtr HTMLPropertiesCollection::create(Node* itemNode) { return adoptPtr(new HTMLPropertiesCollection(itemNode)); } -HTMLPropertiesCollection::HTMLPropertiesCollection(PassRefPtr itemNode) +HTMLPropertiesCollection::HTMLPropertiesCollection(Node* itemNode) : HTMLCollection(itemNode, ItemProperties) , m_propertyNames(DOMStringList::create()) { diff --git a/Source/WebCore/html/HTMLPropertiesCollection.h b/Source/WebCore/html/HTMLPropertiesCollection.h index e7524f983..2572eebc4 100644 --- a/Source/WebCore/html/HTMLPropertiesCollection.h +++ b/Source/WebCore/html/HTMLPropertiesCollection.h @@ -41,7 +41,7 @@ class DOMStringList; class HTMLPropertiesCollection : public HTMLCollection { public: - static PassOwnPtr create(PassRefPtr); + static PassOwnPtr create(Node*); virtual ~HTMLPropertiesCollection(); unsigned length() const OVERRIDE; @@ -51,7 +51,7 @@ public: PassRefPtr names() const; private: - HTMLPropertiesCollection(PassRefPtr); + HTMLPropertiesCollection(Node*); void findPropetiesOfAnItem(Node* current) const; diff --git a/Source/WebCore/html/HTMLScriptElement.cpp b/Source/WebCore/html/HTMLScriptElement.cpp index 9b18ec5d3..a4c5586dc 100644 --- a/Source/WebCore/html/HTMLScriptElement.cpp +++ b/Source/WebCore/html/HTMLScriptElement.cpp @@ -85,12 +85,6 @@ void HTMLScriptElement::insertedIntoDocument() ScriptElement::insertedIntoDocument(); } -void HTMLScriptElement::removedFromDocument() -{ - HTMLElement::removedFromDocument(); - ScriptElement::removedFromDocument(); -} - void HTMLScriptElement::setText(const String &value) { ExceptionCode ec = 0; diff --git a/Source/WebCore/html/HTMLScriptElement.h b/Source/WebCore/html/HTMLScriptElement.h index ee6f7b560..a5fe048a1 100644 --- a/Source/WebCore/html/HTMLScriptElement.h +++ b/Source/WebCore/html/HTMLScriptElement.h @@ -46,7 +46,6 @@ private: virtual void parseMappedAttribute(Attribute*); virtual void insertedIntoDocument(); - virtual void removedFromDocument(); virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0); virtual void attributeChanged(Attribute*, bool preserveDecls = false); diff --git a/Source/WebCore/html/HTMLScriptElement.idl b/Source/WebCore/html/HTMLScriptElement.idl index fa799cb2c..03b5ac816 100644 --- a/Source/WebCore/html/HTMLScriptElement.idl +++ b/Source/WebCore/html/HTMLScriptElement.idl @@ -20,7 +20,7 @@ module html { interface HTMLScriptElement : HTMLElement { - attribute [ConvertNullToNullString] DOMString text; + attribute [TreatNullAs=EmptyString] DOMString text; attribute [Reflect=for] DOMString htmlFor; attribute [Reflect] DOMString event; attribute [Reflect] DOMString charset; diff --git a/Source/WebCore/html/HTMLSelectElement.cpp b/Source/WebCore/html/HTMLSelectElement.cpp index bfebf8e64..4bd10b800 100644 --- a/Source/WebCore/html/HTMLSelectElement.cpp +++ b/Source/WebCore/html/HTMLSelectElement.cpp @@ -61,19 +61,6 @@ using namespace HTMLNames; // Upper limit agreed upon with representatives of Opera and Mozilla. static const unsigned maxSelectItems = 10000; -// Configure platform-specific behavior when focused pop-up receives arrow/space/return keystroke. -// (PLATFORM(MAC) and PLATFORM(GTK) are always false in Chromium, hence the extra tests.) -#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && OS(DARWIN)) -#define ARROW_KEYS_POP_MENU 1 -#define SPACE_OR_RETURN_POP_MENU 0 -#elif PLATFORM(GTK) || (PLATFORM(CHROMIUM) && OS(UNIX)) -#define ARROW_KEYS_POP_MENU 0 -#define SPACE_OR_RETURN_POP_MENU 1 -#else -#define ARROW_KEYS_POP_MENU 0 -#define SPACE_OR_RETURN_POP_MENU 0 -#endif - static const DOMTimeStamp typeAheadTimeout = 1000; HTMLSelectElement::HTMLSelectElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form) @@ -247,10 +234,13 @@ String HTMLSelectElement::value() const void HTMLSelectElement::setValue(const String &value) { - if (value.isNull()) + // We clear the previously selected option(s) when needed, to guarantee calling setSelectedIndex() only once. + if (value.isNull()) { + setSelectedIndex(-1); return; - // find the option with value() matching the given parameter - // and make it the current selection. + } + + // Find the option with value() matching the given parameter and make it the current selection. const Vector& items = listItems(); unsigned optionIndex = 0; for (unsigned i = 0; i < items.size(); i++) { @@ -262,6 +252,8 @@ void HTMLSelectElement::setValue(const String &value) optionIndex++; } } + + setSelectedIndex(-1); } void HTMLSelectElement::parseMappedAttribute(Attribute* attr) @@ -775,8 +767,10 @@ void HTMLSelectElement::optionSelectionStateChanged(HTMLOptionElement* option, b ASSERT(option->ownerSelectElement() == this); if (optionIsSelected) selectOption(option->index()); + else if (!usesMenuList()) + selectOption(-1); else - selectOption(m_multiple ? -1 : nextSelectableListIndex(-1)); + selectOption(nextSelectableListIndex(-1)); } void HTMLSelectElement::selectOption(int optionIndex, SelectOptionFlags flags) @@ -986,7 +980,12 @@ void HTMLSelectElement::reset() #if !PLATFORM(WIN) || OS(WINCE) bool HTMLSelectElement::platformHandleKeydownEvent(KeyboardEvent* event) { -#if ARROW_KEYS_POP_MENU + const Page* page = document()->page(); + RefPtr renderTheme = page ? page->theme() : RenderTheme::defaultTheme(); + + if (!renderTheme->popsMenuByArrowKeys()) + return false; + if (!isSpatialNavigationEnabled(document()->frame())) { if (event->keyIdentifier() == "Down" || event->keyIdentifier() == "Up") { focus(); @@ -1007,15 +1006,16 @@ bool HTMLSelectElement::platformHandleKeydownEvent(KeyboardEvent* event) } return true; } -#else - UNUSED_PARAM(event); -#endif + return false; } #endif void HTMLSelectElement::menuListDefaultEventHandler(Event* event) { + const Page* page = document()->page(); + RefPtr renderTheme = page ? page->theme() : RenderTheme::defaultTheme(); + if (event->type() == eventNames().keydownEvent) { if (!renderer() || !event->isKeyboardEvent()) return; @@ -1074,48 +1074,49 @@ void HTMLSelectElement::menuListDefaultEventHandler(Event* event) return; } -#if SPACE_OR_RETURN_POP_MENU - if (keyCode == ' ' || keyCode == '\r') { - focus(); - - // Calling focus() may cause us to lose our renderer, in which case - // do not want to handle the event. - if (!renderer()) - return; - - // Save the selection so it can be compared to the new selection - // when dispatching change events during selectOption, which - // gets called from RenderMenuList::valueChanged, which gets called - // after the user makes a selection from the menu. - saveLastSelection(); - if (RenderMenuList* menuList = toRenderMenuList(renderer())) - menuList->showPopup(); - handled = true; + if (renderTheme->popsMenuBySpaceOrReturn()) { + if (keyCode == ' ' || keyCode == '\r') { + focus(); + + // Calling focus() may cause us to lose our renderer, in which case + // do not want to handle the event. + if (!renderer()) + return; + + // Save the selection so it can be compared to the new selection + // when dispatching change events during selectOption, which + // gets called from RenderMenuList::valueChanged, which gets called + // after the user makes a selection from the menu. + saveLastSelection(); + if (RenderMenuList* menuList = toRenderMenuList(renderer())) + menuList->showPopup(); + handled = true; + } + } else if (renderTheme->popsMenuByArrowKeys()) { + if (keyCode == ' ') { + focus(); + + // Calling focus() may cause us to lose our renderer, in which case + // do not want to handle the event. + if (!renderer()) + return; + + // Save the selection so it can be compared to the new selection + // when dispatching change events during selectOption, which + // gets called from RenderMenuList::valueChanged, which gets called + // after the user makes a selection from the menu. + saveLastSelection(); + if (RenderMenuList* menuList = toRenderMenuList(renderer())) + menuList->showPopup(); + handled = true; + } else if (keyCode == '\r') { + if (form()) + form()->submitImplicitly(event, false); + dispatchChangeEventForMenuList(); + handled = true; + } } -#elif ARROW_KEYS_POP_MENU - if (keyCode == ' ') { - focus(); - - // Calling focus() may cause us to lose our renderer, in which case - // do not want to handle the event. - if (!renderer()) - return; - // Save the selection so it can be compared to the new selection - // when dispatching change events during selectOption, which - // gets called from RenderMenuList::valueChanged, which gets called - // after the user makes a selection from the menu. - saveLastSelection(); - if (RenderMenuList* menuList = toRenderMenuList(renderer())) - menuList->showPopup(); - handled = true; - } else if (keyCode == '\r') { - if (form()) - form()->submitImplicitly(event, false); - dispatchChangeEventForMenuList(); - handled = true; - } -#endif if (handled) event->setDefaultHandled(); } @@ -1158,7 +1159,7 @@ void HTMLSelectElement::updateSelectedState(int listIndex, bool multi, bool shif if (clickedElement->hasTagName(optionTag)) { // Keep track of whether an active selection (like during drag // selection), should select or deselect. - if (toHTMLOptionElement(clickedElement)->selected() && multi) + if (toHTMLOptionElement(clickedElement)->selected() && multiSelect) m_activeSelectionState = false; if (!m_activeSelectionState) toHTMLOptionElement(clickedElement)->setSelectedState(false); @@ -1226,8 +1227,11 @@ void HTMLSelectElement::listBoxDefaultEventHandler(Event* event) if (m_multiple) { setActiveSelectionEndIndex(listIndex); updateListBoxSelection(false); - } else - updateSelectedState(listIndex, false, false); + } else { + setActiveSelectionAnchorIndex(listIndex); + setActiveSelectionEndIndex(listIndex); + updateListBoxSelection(true); + } event->setDefaultHandled(); } } else if (event->type() == eventNames().mouseupEvent && event->isMouseEvent() && static_cast(event)->button() == LeftButton && document()->frame()->eventHandler()->autoscrollRenderer() != renderer()) { diff --git a/Source/WebCore/html/HTMLSelectElement.idl b/Source/WebCore/html/HTMLSelectElement.idl index 45a345601..9749780c1 100644 --- a/Source/WebCore/html/HTMLSelectElement.idl +++ b/Source/WebCore/html/HTMLSelectElement.idl @@ -26,7 +26,7 @@ module html { ] HTMLSelectElement : HTMLElement { readonly attribute DOMString type; attribute long selectedIndex; - attribute [ConvertNullToNullString] DOMString value; + attribute [TreatNullAs=EmptyString] DOMString value; // Modified in DOM Level 2: #if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C @@ -48,7 +48,7 @@ module html { attribute [Reflect] boolean disabled; attribute [Reflect] boolean autofocus; attribute boolean multiple; - attribute [ConvertNullToNullString] DOMString name; + attribute [TreatNullAs=EmptyString] DOMString name; attribute [Reflect] boolean required; attribute long size; diff --git a/Source/WebCore/html/HTMLSourceElement.cpp b/Source/WebCore/html/HTMLSourceElement.cpp index 99f211ad2..df2605756 100644 --- a/Source/WebCore/html/HTMLSourceElement.cpp +++ b/Source/WebCore/html/HTMLSourceElement.cpp @@ -127,9 +127,9 @@ String HTMLSourceElement::itemValueText() const return getURLAttribute(srcAttr); } -void HTMLSourceElement::setItemValueText(const String& value, ExceptionCode& ec) +void HTMLSourceElement::setItemValueText(const String& value, ExceptionCode&) { - setAttribute(srcAttr, value, ec); + setAttribute(srcAttr, value); } #endif diff --git a/Source/WebCore/html/HTMLStyleElement.cpp b/Source/WebCore/html/HTMLStyleElement.cpp index 9efe80aa0..cc1fa2300 100644 --- a/Source/WebCore/html/HTMLStyleElement.cpp +++ b/Source/WebCore/html/HTMLStyleElement.cpp @@ -38,12 +38,17 @@ using namespace HTMLNames; inline HTMLStyleElement::HTMLStyleElement(const QualifiedName& tagName, Document* document, bool createdByParser) : HTMLElement(tagName, document) , StyleElement(document, createdByParser) +#if ENABLE(STYLE_SCOPED) + , m_isRegisteredWithScopingNode(false) +#endif { ASSERT(hasTagName(styleTag)); } HTMLStyleElement::~HTMLStyleElement() { + // During tear-down, willRemove isn't called, so m_isRegisteredWithScopingNode may still be set here. + // Therefore we can't ASSERT(!m_isRegisteredWithScopingNode). StyleElement::clearDocumentData(document(), this); } @@ -56,6 +61,15 @@ void HTMLStyleElement::parseMappedAttribute(Attribute* attr) { if (attr->name() == titleAttr && m_sheet) m_sheet->setTitle(attr->value()); +#if ENABLE(STYLE_SCOPED) + else if (attr->name() == scopedAttr) { + if (!attr->isNull() && !m_isRegisteredWithScopingNode && inDocument()) + registerWithScopingNode(); + else if (attr->isNull() && m_isRegisteredWithScopingNode) + unregisterWithScopingNode(); + + } +#endif else HTMLElement::parseMappedAttribute(attr); } @@ -66,18 +80,82 @@ void HTMLStyleElement::finishParsingChildren() HTMLElement::finishParsingChildren(); } +#if ENABLE(STYLE_SCOPED) +void HTMLStyleElement::registerWithScopingNode() +{ + // Note: We cannot rely on the 'scoped' element already being present when this method is invoked. + // Therefore we cannot rely on scoped()! + ASSERT(!m_isRegisteredWithScopingNode); + ASSERT(inDocument()); + if (!m_isRegisteredWithScopingNode) { + Element* scope = parentElement(); + if (!scope) + return; + + scope->registerScopedHTMLStyleChild(); + scope->setNeedsStyleRecalc(); + if (inDocument() && !document()->parsing() && document()->renderer()) + document()->styleSelectorChanged(DeferRecalcStyle); + + m_isRegisteredWithScopingNode = true; + } +} + +void HTMLStyleElement::unregisterWithScopingNode() +{ + // Note: We cannot rely on the 'scoped' element still being present when this method is invoked. + // Therefore we cannot rely on scoped()! + ASSERT(m_isRegisteredWithScopingNode); + if (m_isRegisteredWithScopingNode) { + Element* scope = parentElement(); + ASSERT(scope); + if (scope) { + ASSERT(scope->hasScopedHTMLStyleChild()); + scope->unregisterScopedHTMLStyleChild(); + scope->setNeedsStyleRecalc(); + } + if (inDocument() && !document()->parsing() && document()->renderer()) + document()->styleSelectorChanged(DeferRecalcStyle); + + m_isRegisteredWithScopingNode = false; + } +} +#endif + void HTMLStyleElement::insertedIntoDocument() { HTMLElement::insertedIntoDocument(); StyleElement::insertedIntoDocument(document(), this); +#if ENABLE(STYLE_SCOPED) + if (scoped() && !m_isRegisteredWithScopingNode) + registerWithScopingNode(); +#endif } void HTMLStyleElement::removedFromDocument() { +#if ENABLE(STYLE_SCOPED) + ASSERT(!m_isRegisteredWithScopingNode); +#endif HTMLElement::removedFromDocument(); StyleElement::removedFromDocument(document(), this); } + +#if ENABLE(STYLE_SCOPED) +void HTMLStyleElement::willRemove() +{ + // In the current implementation,