From 2bde8e466a4451c7319e3a072d118917957d6554 Mon Sep 17 00:00:00 2001 From: Steve Block Date: Wed, 25 May 2011 19:08:45 +0100 Subject: Merge WebKit at r82507: Initial merge by git Change-Id: I60ce9d780725b58b45e54165733a8ffee23b683e --- Source/WebCore/html/CollectionCache.h | 2 +- Source/WebCore/html/FormAssociatedElement.cpp | 2 +- Source/WebCore/html/HTMLAnchorElement.cpp | 10 +- Source/WebCore/html/HTMLAnchorElement.idl | 1 + Source/WebCore/html/HTMLAreaElement.cpp | 2 +- Source/WebCore/html/HTMLAreaElement.idl | 1 + Source/WebCore/html/HTMLAttributeNames.in | 1 + Source/WebCore/html/HTMLBodyElement.cpp | 2 +- Source/WebCore/html/HTMLCanvasElement.cpp | 68 ++++- Source/WebCore/html/HTMLCanvasElement.h | 5 + Source/WebCore/html/HTMLCollection.cpp | 2 +- Source/WebCore/html/HTMLDetailsElement.cpp | 91 +++++- Source/WebCore/html/HTMLDetailsElement.h | 14 +- Source/WebCore/html/HTMLElement.cpp | 37 +-- Source/WebCore/html/HTMLElement.h | 5 +- Source/WebCore/html/HTMLEmbedElement.cpp | 10 +- Source/WebCore/html/HTMLFormControlElement.cpp | 17 +- Source/WebCore/html/HTMLFormControlElement.h | 7 + Source/WebCore/html/HTMLFormElement.cpp | 7 +- Source/WebCore/html/HTMLFrameElementBase.cpp | 7 + Source/WebCore/html/HTMLFrameElementBase.h | 3 + Source/WebCore/html/HTMLFrameSetElement.cpp | 30 +- Source/WebCore/html/HTMLFrameSetElement.h | 10 +- Source/WebCore/html/HTMLInputElement.cpp | 19 +- Source/WebCore/html/HTMLInputElement.h | 4 + Source/WebCore/html/HTMLLinkElement.cpp | 39 ++- Source/WebCore/html/HTMLLinkElement.h | 1 + Source/WebCore/html/HTMLMediaElement.cpp | 70 +++-- Source/WebCore/html/HTMLMediaElement.h | 12 +- Source/WebCore/html/HTMLObjectElement.cpp | 11 +- Source/WebCore/html/HTMLPlugInElement.cpp | 2 +- Source/WebCore/html/HTMLPlugInImageElement.cpp | 10 +- Source/WebCore/html/HTMLPlugInImageElement.h | 11 +- Source/WebCore/html/HTMLScriptElement.cpp | 18 ++ Source/WebCore/html/HTMLScriptElement.h | 4 + Source/WebCore/html/HTMLScriptElement.idl | 2 +- Source/WebCore/html/HTMLSelectElement.cpp | 5 + Source/WebCore/html/HTMLSummaryElement.cpp | 7 + Source/WebCore/html/HTMLSummaryElement.h | 2 + Source/WebCore/html/HTMLTextAreaElement.cpp | 9 + Source/WebCore/html/HTMLTextAreaElement.h | 4 +- Source/WebCore/html/HTMLTitleElement.cpp | 9 +- Source/WebCore/html/NumberInputType.cpp | 5 +- Source/WebCore/html/RangeInputType.cpp | 2 +- Source/WebCore/html/ValidationMessage.cpp | 21 +- .../html/canvas/CanvasRenderingContext2D.cpp | 2 +- .../WebCore/html/canvas/WebGLContextAttributes.cpp | 10 + .../WebCore/html/canvas/WebGLContextAttributes.h | 5 + .../WebCore/html/canvas/WebGLContextAttributes.idl | 1 + .../WebCore/html/canvas/WebGLRenderingContext.cpp | 122 +++++++- Source/WebCore/html/canvas/WebGLRenderingContext.h | 14 + Source/WebCore/html/parser/HTMLDocumentParser.cpp | 14 +- Source/WebCore/html/parser/HTMLDocumentParser.h | 1 - Source/WebCore/html/parser/HTMLElementStack.cpp | 44 +-- Source/WebCore/html/parser/HTMLElementStack.h | 10 + Source/WebCore/html/parser/HTMLParserScheduler.cpp | 10 + Source/WebCore/html/parser/HTMLParserScheduler.h | 1 + Source/WebCore/html/parser/HTMLPreloadScanner.cpp | 17 +- Source/WebCore/html/parser/HTMLScriptRunnerHost.h | 2 - Source/WebCore/html/parser/HTMLToken.h | 48 +-- Source/WebCore/html/parser/HTMLTreeBuilder.cpp | 21 +- Source/WebCore/html/shadow/MediaControls.cpp | 332 ++++++++++----------- Source/WebCore/html/shadow/MediaControls.h | 40 ++- Source/WebCore/html/shadow/SliderThumbElement.cpp | 20 +- Source/WebCore/html/shadow/SliderThumbElement.h | 3 +- 65 files changed, 890 insertions(+), 428 deletions(-) (limited to 'Source/WebCore/html') diff --git a/Source/WebCore/html/CollectionCache.h b/Source/WebCore/html/CollectionCache.h index 8e4a066..d160db2 100644 --- a/Source/WebCore/html/CollectionCache.h +++ b/Source/WebCore/html/CollectionCache.h @@ -49,7 +49,7 @@ public: typedef HashMap*> NodeCacheMap; - unsigned version; + uint64_t version; Element* current; unsigned position; unsigned length; diff --git a/Source/WebCore/html/FormAssociatedElement.cpp b/Source/WebCore/html/FormAssociatedElement.cpp index 3571744..ea36b2a 100644 --- a/Source/WebCore/html/FormAssociatedElement.cpp +++ b/Source/WebCore/html/FormAssociatedElement.cpp @@ -132,7 +132,7 @@ void FormAssociatedElement::resetFormOwner(HTMLFormElement* form) m_form->removeFormElement(this); } m_form = 0; - if (!formId.isNull()) { + if (!formId.isNull() && element->inDocument()) { // The HTML5 spec says that the element should be associated with // the first element in the document to have an ID that equal to // the value of form attribute, so we put the result of diff --git a/Source/WebCore/html/HTMLAnchorElement.cpp b/Source/WebCore/html/HTMLAnchorElement.cpp index 0c10022..60f5b4a 100644 --- a/Source/WebCore/html/HTMLAnchorElement.cpp +++ b/Source/WebCore/html/HTMLAnchorElement.cpp @@ -72,7 +72,7 @@ static unsigned parsePortFromStringPosition(const String& value, unsigned portSt bool HTMLAnchorElement::supportsFocus() const { - if (isContentEditable()) + if (rendererIsEditable()) return HTMLElement::supportsFocus(); // If not a link we should still be able to focus the element if it has tabIndex. return isLink() || HTMLElement::supportsFocus(); @@ -154,7 +154,7 @@ void HTMLAnchorElement::defaultEventHandler(Event* event) return; } - if (isContentEditable()) { + if (rendererIsEditable()) { // 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()) { @@ -174,7 +174,7 @@ void HTMLAnchorElement::defaultEventHandler(Event* event) void HTMLAnchorElement::setActive(bool down, bool pause) { - if (isContentEditable()) { + if (rendererIsEditable()) { EditableLinkBehavior editableLinkBehavior = EditableLinkDefaultBehavior; if (Settings* settings = document()->settings()) editableLinkBehavior = settings->editableLinkBehavior(); @@ -247,7 +247,7 @@ bool HTMLAnchorElement::canStartSelection() const // FIXME: We probably want this same behavior in SVGAElement too if (!isLink()) return HTMLElement::canStartSelection(); - return isContentEditable(); + return rendererIsEditable(); } bool HTMLAnchorElement::draggable() const @@ -501,7 +501,7 @@ HTMLAnchorElement::EventType HTMLAnchorElement::eventType(Event* event) bool HTMLAnchorElement::treatLinkAsLiveForEventType(EventType eventType) const { - if (!isContentEditable()) + if (!rendererIsEditable()) return true; Settings* settings = document()->settings(); diff --git a/Source/WebCore/html/HTMLAnchorElement.idl b/Source/WebCore/html/HTMLAnchorElement.idl index 432df69..8f09e41 100644 --- a/Source/WebCore/html/HTMLAnchorElement.idl +++ b/Source/WebCore/html/HTMLAnchorElement.idl @@ -27,6 +27,7 @@ module html { attribute [Reflect, URL] DOMString href; attribute [Reflect] DOMString hreflang; attribute [Reflect] DOMString name; + attribute [Reflect] DOMString ping; attribute [Reflect] DOMString rel; attribute [Reflect] DOMString rev; attribute [Reflect] DOMString shape; diff --git a/Source/WebCore/html/HTMLAreaElement.cpp b/Source/WebCore/html/HTMLAreaElement.cpp index 9832d06..4cb2748 100644 --- a/Source/WebCore/html/HTMLAreaElement.cpp +++ b/Source/WebCore/html/HTMLAreaElement.cpp @@ -175,7 +175,7 @@ Path HTMLAreaElement::getRegion(const IntSize& size) const HTMLImageElement* HTMLAreaElement::imageElement() const { Node* mapElement = parentNode(); - if (!mapElement->hasTagName(mapTag)) + if (!mapElement || !mapElement->hasTagName(mapTag)) return 0; return static_cast(mapElement)->imageElement(); diff --git a/Source/WebCore/html/HTMLAreaElement.idl b/Source/WebCore/html/HTMLAreaElement.idl index a77e615..3358c05 100644 --- a/Source/WebCore/html/HTMLAreaElement.idl +++ b/Source/WebCore/html/HTMLAreaElement.idl @@ -26,6 +26,7 @@ module html { attribute [Reflect] DOMString coords; attribute [Reflect, URL] DOMString href; attribute [Reflect] boolean noHref; + attribute [Reflect] DOMString ping; attribute [Reflect] DOMString shape; attribute [Reflect] DOMString target; diff --git a/Source/WebCore/html/HTMLAttributeNames.in b/Source/WebCore/html/HTMLAttributeNames.in index 956812d..3a6fea4 100644 --- a/Source/WebCore/html/HTMLAttributeNames.in +++ b/Source/WebCore/html/HTMLAttributeNames.in @@ -298,6 +298,7 @@ version viewsource vlink vspace +webkitallowfullscreen webkitdirectory width wrap diff --git a/Source/WebCore/html/HTMLBodyElement.cpp b/Source/WebCore/html/HTMLBodyElement.cpp index 3cc4cd8..9cf8730 100644 --- a/Source/WebCore/html/HTMLBodyElement.cpp +++ b/Source/WebCore/html/HTMLBodyElement.cpp @@ -233,7 +233,7 @@ bool HTMLBodyElement::isURLAttribute(Attribute *attr) const bool HTMLBodyElement::supportsFocus() const { - return isContentEditable() || HTMLElement::supportsFocus(); + return rendererIsEditable() || HTMLElement::supportsFocus(); } String HTMLBodyElement::aLink() const diff --git a/Source/WebCore/html/HTMLCanvasElement.cpp b/Source/WebCore/html/HTMLCanvasElement.cpp index 79ebdad..fbedbf2 100644 --- a/Source/WebCore/html/HTMLCanvasElement.cpp +++ b/Source/WebCore/html/HTMLCanvasElement.cpp @@ -41,6 +41,7 @@ #include "GraphicsContext.h" #include "HTMLNames.h" #include "ImageBuffer.h" +#include "ImageData.h" #include "MIMETypeRegistry.h" #include "Page.h" #include "RenderHTMLCanvas.h" @@ -76,6 +77,7 @@ static const float MaxSkiaDim = 32767.0F; // Maximum width/height in CSS pixels. HTMLCanvasElement::HTMLCanvasElement(const QualifiedName& tagName, Document* document) : HTMLElement(tagName, document) , m_size(DefaultWidth, DefaultHeight) + , m_rendererIsCanvas(false) , m_ignoreReset(false) , m_pageScaleFactor(document->frame() ? document->frame()->page()->chrome()->scaleFactor() : 1) , m_originClean(true) @@ -173,7 +175,7 @@ CanvasRenderingContext* HTMLCanvasElement::getContext(const String& type, Canvas #if ENABLE(WEBGL) Settings* settings = document()->settings(); if (settings && settings->webGLEnabled() -#if !PLATFORM(CHROMIUM) && !PLATFORM(QT) +#if !PLATFORM(CHROMIUM) && settings->acceleratedCompositingEnabled() #endif ) { @@ -275,15 +277,22 @@ void HTMLCanvasElement::paint(GraphicsContext* context, const IntRect& r) if (hasCreatedImageBuffer()) { ImageBuffer* imageBuffer = buffer(); if (imageBuffer) { - if (imageBuffer->drawsUsingCopy()) + if (m_presentedImage) + context->drawImage(m_presentedImage.get(), ColorSpaceDeviceRGB, r); + else if (imageBuffer->drawsUsingCopy()) context->drawImage(copiedImage(), ColorSpaceDeviceRGB, r); else context->drawImageBuffer(imageBuffer, ColorSpaceDeviceRGB, r); } } -} #if ENABLE(WEBGL) + if (is3D()) + static_cast(m_context.get())->markLayerComposited(); +#endif +} + +#if ENABLE(WEBGL) bool HTMLCanvasElement::is3D() const { return m_context && m_context->is3d(); @@ -296,6 +305,19 @@ void HTMLCanvasElement::makeRenderingResultsAvailable() m_context->paintRenderingResultsToCanvas(); } +void HTMLCanvasElement::makePresentationCopy() +{ + if (!m_presentedImage) { + // The buffer contains the last presented data, so save a copy of it. + m_presentedImage = buffer()->copyImage(); + } +} + +void HTMLCanvasElement::clearPresentationCopy() +{ + m_presentedImage.clear(); +} + void HTMLCanvasElement::attach() { HTMLElement::attach(); @@ -337,15 +359,37 @@ String HTMLCanvasElement::toDataURL(const String& mimeType, const double* qualit String lowercaseMimeType = mimeType.lower(); - makeRenderingResultsAvailable(); - // FIXME: Make isSupportedImageMIMETypeForEncoding threadsafe (to allow this method to be used on a worker thread). if (mimeType.isNull() || !MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(lowercaseMimeType)) - return buffer()->toDataURL("image/png"); + lowercaseMimeType = "image/png"; +#if PLATFORM(CG) || USE(SKIA) + // Try to get ImageData first, as that may avoid lossy conversions. + RefPtr imageData = getImageData(); + + if (imageData) + return ImageDataToDataURL(*imageData, lowercaseMimeType, quality); +#endif + + makeRenderingResultsAvailable(); + return buffer()->toDataURL(lowercaseMimeType, quality); } +PassRefPtr HTMLCanvasElement::getImageData() +{ + if (!m_context || !m_context->is3d()) + return 0; + +#if ENABLE(WEBGL) + WebGLRenderingContext* ctx = static_cast(m_context.get()); + + return ctx->paintRenderingResultsToImageData(); +#else + return 0; +#endif +} + IntRect HTMLCanvasElement::convertLogicalToDevice(const FloatRect& logicalRect) const { float left = floorf(logicalRect.x() * m_pageScaleFactor); @@ -399,7 +443,10 @@ void HTMLCanvasElement::createImageBuffer() const return; #if USE(IOSURFACE_CANVAS_BACKING_STORE) - m_imageBuffer = ImageBuffer::create(size, ColorSpaceDeviceRGB, Accelerated); + if (document()->settings()->canvasUsesAcceleratedDrawing()) + m_imageBuffer = ImageBuffer::create(size, ColorSpaceDeviceRGB, Accelerated); + else + m_imageBuffer = ImageBuffer::create(size, ColorSpaceDeviceRGB, Unaccelerated); #else m_imageBuffer = ImageBuffer::create(size); #endif @@ -434,11 +481,8 @@ ImageBuffer* HTMLCanvasElement::buffer() const Image* HTMLCanvasElement::copiedImage() const { if (!m_copiedImage && buffer()) { - if (m_context) { - // If we're not rendering to the ImageBuffer, copy the rendering results to it. - if (!m_context->paintsIntoCanvasBuffer()) - m_context->paintRenderingResultsToCanvas(); - } + if (m_context) + m_context->paintRenderingResultsToCanvas(); m_copiedImage = buffer()->copyImage(); } return m_copiedImage.get(); diff --git a/Source/WebCore/html/HTMLCanvasElement.h b/Source/WebCore/html/HTMLCanvasElement.h index 5c8ac9a..6fdd222 100644 --- a/Source/WebCore/html/HTMLCanvasElement.h +++ b/Source/WebCore/html/HTMLCanvasElement.h @@ -47,6 +47,7 @@ class CanvasRenderingContext; class GraphicsContext; class HTMLCanvasElement; class Image; +class ImageData; class ImageBuffer; class IntSize; @@ -105,6 +106,9 @@ public: ImageBuffer* buffer() const; Image* copiedImage() const; void clearCopiedImage(); + PassRefPtr getImageData(); + void makePresentationCopy(); + void clearPresentationCopy(); IntRect convertLogicalToDevice(const FloatRect&) const; IntSize convertLogicalToDevice(const FloatSize&) const; @@ -175,6 +179,7 @@ private: mutable bool m_hasCreatedImageBuffer; mutable OwnPtr m_imageBuffer; + mutable RefPtr m_presentedImage; mutable RefPtr m_copiedImage; // FIXME: This is temporary for platforms that have to copy the image buffer to render (and for CSSCanvasValue). }; diff --git a/Source/WebCore/html/HTMLCollection.cpp b/Source/WebCore/html/HTMLCollection.cpp index 7d776d1..2782e50 100644 --- a/Source/WebCore/html/HTMLCollection.cpp +++ b/Source/WebCore/html/HTMLCollection.cpp @@ -67,7 +67,7 @@ HTMLCollection::~HTMLCollection() void HTMLCollection::resetCollectionInfo() const { - unsigned docversion = static_cast(m_base->document())->domTreeVersion(); + uint64_t docversion = static_cast(m_base->document())->domTreeVersion(); if (!m_info) { m_info = new CollectionCache; diff --git a/Source/WebCore/html/HTMLDetailsElement.cpp b/Source/WebCore/html/HTMLDetailsElement.cpp index 0bcae0b..f9c2f6c 100644 --- a/Source/WebCore/html/HTMLDetailsElement.cpp +++ b/Source/WebCore/html/HTMLDetailsElement.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + * Copyright (C) 2010, 2011 Nokia Corporation and/or its subsidiary(-ies) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -21,7 +21,10 @@ #include "config.h" #include "HTMLDetailsElement.h" +#include "Frame.h" #include "HTMLNames.h" +#include "MouseEvent.h" +#include "PlatformMouseEvent.h" #include "RenderDetails.h" namespace WebCore { @@ -35,6 +38,8 @@ PassRefPtr HTMLDetailsElement::create(const QualifiedName& t HTMLDetailsElement::HTMLDetailsElement(const QualifiedName& tagName, Document* document) : HTMLElement(tagName, document) + , m_mainSummary(0) + , m_isOpen(false) { ASSERT(hasTagName(detailsTag)); } @@ -44,4 +49,88 @@ RenderObject* HTMLDetailsElement::createRenderer(RenderArena* arena, RenderStyle return new (arena) RenderDetails(this); } +void HTMLDetailsElement::findMainSummary() +{ + m_mainSummary = 0; + + for (Node* child = firstChild(); child; child = child->nextSibling()) { + if (child->hasTagName(summaryTag)) { + m_mainSummary = child; + break; + } + } +} + +void HTMLDetailsElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) +{ + HTMLElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); + if (!changedByParser) { + Node* oldSummary = m_mainSummary; + findMainSummary(); + + if (oldSummary != m_mainSummary && !m_isOpen && attached()) { + if (oldSummary && oldSummary->attached()) + oldSummary->detach(); + if (m_mainSummary && childCountDelta < 0 && !m_mainSummary->renderer()) { + // If childCountDelta is less then zero and the main summary has changed it must be because previous main + // summary was removed. The new main summary was then inside the unrevealed content and needs to be + // reattached to create its renderer. If childCountDelta is not less then zero then a new element + // has been added and it will be attached without our help. + m_mainSummary->detach(); + m_mainSummary->attach(); + } + } + } +} + +void HTMLDetailsElement::finishParsingChildren() +{ + HTMLElement::finishParsingChildren(); + findMainSummary(); + if (attached() && m_mainSummary && !m_mainSummary->renderer()) { + m_mainSummary->detach(); + m_mainSummary->attach(); + } +} + +void HTMLDetailsElement::parseMappedAttribute(Attribute* attr) +{ + if (attr->name() == openAttr) { + bool oldValue = m_isOpen; + m_isOpen = !attr->value().isNull(); + if (attached() && oldValue != m_isOpen) { + detach(); + attach(); + } + } else + HTMLElement::parseMappedAttribute(attr); +} + +bool HTMLDetailsElement::childShouldCreateRenderer(Node* child) const +{ + return m_isOpen || child == m_mainSummary; +} + +void HTMLDetailsElement::defaultEventHandler(Event* event) +{ + HTMLElement::defaultEventHandler(event); + + if (!renderer() || !renderer()->isDetails() || !event->isMouseEvent() || event->type() != eventNames().clickEvent || event->defaultHandled()) + return; + + MouseEvent* mouseEvent = static_cast(event); + if (mouseEvent->button() != LeftButton) + return; + + RenderDetails* renderDetails = static_cast(renderer()); + + float factor = document() && document()->frame() ? document()->frame()->pageZoomFactor() : 1.0f; + FloatPoint pos = renderDetails->absoluteToLocal(FloatPoint(mouseEvent->pageX() * factor, mouseEvent->pageY() * factor)); + + if (renderDetails->interactiveArea().contains(pos.x(), pos.y())) { + setAttribute(openAttr, m_isOpen ? String() : String("")); + event->setDefaultHandled(); + } +} + } diff --git a/Source/WebCore/html/HTMLDetailsElement.h b/Source/WebCore/html/HTMLDetailsElement.h index 16427ef..45a9035 100644 --- a/Source/WebCore/html/HTMLDetailsElement.h +++ b/Source/WebCore/html/HTMLDetailsElement.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + * Copyright (C) 2010, 2011 Nokia Corporation and/or its subsidiary(-ies) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -28,11 +28,23 @@ namespace WebCore { class HTMLDetailsElement : public HTMLElement { public: static PassRefPtr create(const QualifiedName& tagName, Document* document); + Node* mainSummary() const { return m_mainSummary; } private: HTMLDetailsElement(const QualifiedName&, Document*); virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); + virtual void childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta); + virtual void finishParsingChildren(); + + void parseMappedAttribute(Attribute*); + bool childShouldCreateRenderer(Node*) const; + void defaultEventHandler(Event*); + + void findMainSummary(); + + Node* m_mainSummary; + bool m_isOpen; }; diff --git a/Source/WebCore/html/HTMLElement.cpp b/Source/WebCore/html/HTMLElement.cpp index b3981c8..e3b5043 100644 --- a/Source/WebCore/html/HTMLElement.cpp +++ b/Source/WebCore/html/HTMLElement.cpp @@ -654,44 +654,15 @@ void HTMLElement::addHTMLAlignmentToStyledElement(StyledElement* element, Attrib bool HTMLElement::supportsFocus() const { - return Element::supportsFocus() || (isContentEditable() && parentNode() && !parentNode()->isContentEditable()); + return Element::supportsFocus() || (rendererIsEditable() && parentNode() && !parentNode()->rendererIsEditable()); } -bool HTMLElement::isContentEditable() const +bool HTMLElement::isContentEditable() const { - if (document()->inDesignMode()) - return true; - - // Ideally we'd call ASSERT!needsStyleRecalc()) here, but - // ContainerNode::setFocus() calls setNeedsStyleRecalc(), so the assertion - // would fire in the middle of Document::setFocusedNode(). - - if (!renderer()) { - if (parentNode()) - return parentNode()->isContentEditable(); - else - return false; - } - - return renderer()->style()->userModify() == READ_WRITE || renderer()->style()->userModify() == READ_WRITE_PLAINTEXT_ONLY; -} - -bool HTMLElement::isContentRichlyEditable() const -{ - if (document()->inDesignMode()) - return true; - - if (!renderer()) { - if (parentNode()) - return parentNode()->isContentEditable(); - else - return false; - } - - return renderer()->style()->userModify() == READ_WRITE; + return rendererIsEditable(); } -String HTMLElement::contentEditable() const +String HTMLElement::contentEditable() const { const AtomicString& value = fastGetAttribute(contenteditableAttr); diff --git a/Source/WebCore/html/HTMLElement.h b/Source/WebCore/html/HTMLElement.h index 73517df..077b1c3 100644 --- a/Source/WebCore/html/HTMLElement.h +++ b/Source/WebCore/html/HTMLElement.h @@ -56,9 +56,8 @@ public: void insertAdjacentText(const String& where, const String& text, ExceptionCode&); virtual bool supportsFocus() const; - - virtual bool isContentEditable() const; - virtual bool isContentRichlyEditable() const; + + bool isContentEditable() const; String contentEditable() const; void setContentEditable(const String&, ExceptionCode&); diff --git a/Source/WebCore/html/HTMLEmbedElement.cpp b/Source/WebCore/html/HTMLEmbedElement.cpp index f419e2a..851deb8 100644 --- a/Source/WebCore/html/HTMLEmbedElement.cpp +++ b/Source/WebCore/html/HTMLEmbedElement.cpp @@ -2,7 +2,7 @@ * Copyright (C) 1999 Lars Knoll (knoll@kde.org) * (C) 1999 Antti Koivisto (koivisto@kde.org) * (C) 2000 Stefan Schimanski (1Stein@gmx.de) - * Copyright (C) 2004, 2005, 2006, 2008, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2005, 2006, 2008, 2009, 2011 Apple Inc. All rights reserved. * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) * * This library is free software; you can redistribute it and/or @@ -46,7 +46,7 @@ namespace WebCore { using namespace HTMLNames; inline HTMLEmbedElement::HTMLEmbedElement(const QualifiedName& tagName, Document* document, bool createdByParser) - : HTMLPlugInImageElement(tagName, document, createdByParser) + : HTMLPlugInImageElement(tagName, document, createdByParser, ShouldPreferPlugInsForImages) { ASSERT(hasTagName(embedTag)); } @@ -217,6 +217,10 @@ bool HTMLEmbedElement::rendererIsNeeded(RenderStyle* style) void HTMLEmbedElement::insertedIntoDocument() { + HTMLPlugInImageElement::insertedIntoDocument(); + if (!inDocument()) + return; + if (document()->isHTMLDocument()) static_cast(document())->addNamedItem(m_name); @@ -233,8 +237,6 @@ void HTMLEmbedElement::insertedIntoDocument() static_cast(n)->setAttribute(heightAttr, height); } } - - HTMLPlugInImageElement::insertedIntoDocument(); } void HTMLEmbedElement::removedFromDocument() diff --git a/Source/WebCore/html/HTMLFormControlElement.cpp b/Source/WebCore/html/HTMLFormControlElement.cpp index 4b3c48a..af061fe 100644 --- a/Source/WebCore/html/HTMLFormControlElement.cpp +++ b/Source/WebCore/html/HTMLFormControlElement.cpp @@ -141,7 +141,7 @@ void HTMLFormControlElement::attach() if (autofocus() && renderer() && !document()->ignoreAutofocus() && !isReadOnlyFormControl() && ((hasTagName(inputTag) && !isInputTypeHidden) || hasTagName(selectTag) || - hasTagName(buttonTag) || hasTagName(textareaTag))) + hasTagName(keygenTag) || hasTagName(buttonTag) || hasTagName(textareaTag))) focus(); } @@ -547,6 +547,12 @@ HTMLTextFormControlElement::~HTMLTextFormControlElement() { } +void HTMLTextFormControlElement::insertedIntoDocument() +{ + HTMLFormControlElement::insertedIntoDocument(); + setTextAsOfLastFormControlChangeEvent(value()); +} + void HTMLTextFormControlElement::dispatchFocusEvent() { if (supportsPlaceholder()) @@ -629,6 +635,15 @@ void HTMLTextFormControlElement::select() setSelectionRange(0, numeric_limits::max()); } +void HTMLTextFormControlElement::dispatchFormControlChangeEvent() +{ + if (m_textAsOfLastFormControlChangeEvent != value()) { + HTMLElement::dispatchChangeEvents(); + setTextAsOfLastFormControlChangeEvent(value()); + } + setChangedSinceLastFormControlChangeEvent(false); +} + void HTMLTextFormControlElement::setSelectionRange(int start, int end) { WebCore::setSelectionRange(this, start, end); diff --git a/Source/WebCore/html/HTMLFormControlElement.h b/Source/WebCore/html/HTMLFormControlElement.h index 120313d..ede3299 100644 --- a/Source/WebCore/html/HTMLFormControlElement.h +++ b/Source/WebCore/html/HTMLFormControlElement.h @@ -194,6 +194,8 @@ public: virtual ~HTMLTextFormControlElement(); + virtual void insertedIntoDocument(); + // The derived class should return true if placeholder processing is needed. virtual bool supportsPlaceholder() const = 0; String strippedPlaceholder() const; @@ -207,6 +209,8 @@ public: void setSelectionRange(int start, int end); PassRefPtr selection() const; + virtual void dispatchFormControlChangeEvent(); + virtual int maxLength() const = 0; virtual String value() const = 0; @@ -216,6 +220,7 @@ protected: void updatePlaceholderVisibility(bool); virtual void parseMappedAttribute(Attribute*); + virtual void setTextAsOfLastFormControlChangeEvent(String text) { m_textAsOfLastFormControlChangeEvent = text; } private: virtual void dispatchFocusEvent(); @@ -236,6 +241,8 @@ private: virtual void handleBlurEvent() { } RenderTextControl* textRendererAfterUpdateLayout(); + + String m_textAsOfLastFormControlChangeEvent; }; } // namespace diff --git a/Source/WebCore/html/HTMLFormElement.cpp b/Source/WebCore/html/HTMLFormElement.cpp index 8535027..f051ea1 100644 --- a/Source/WebCore/html/HTMLFormElement.cpp +++ b/Source/WebCore/html/HTMLFormElement.cpp @@ -223,7 +223,12 @@ bool HTMLFormElement::validateInteractively(Event* event) Vector > unhandledInvalidControls; if (!checkInvalidControlsAndCollectUnhandled(unhandledInvalidControls)) return true; - // If the form has invalid controls, abort submission. + // Because the form has invalid controls, we abort the form submission and + // show a validation message on a focusable form control. + + // Needs to update layout now because we'd like to call isFocusable(), which + // has !renderer()->needsLayout() assertion. + document()->updateLayoutIgnorePendingStylesheets(); RefPtr protector(this); // Focus on the first focusable control and show a validation message. diff --git a/Source/WebCore/html/HTMLFrameElementBase.cpp b/Source/WebCore/html/HTMLFrameElementBase.cpp index cf079ea..08b6a64 100644 --- a/Source/WebCore/html/HTMLFrameElementBase.cpp +++ b/Source/WebCore/html/HTMLFrameElementBase.cpp @@ -283,4 +283,11 @@ void HTMLFrameElementBase::willRemove() HTMLFrameOwnerElement::willRemove(); } +#if ENABLE(FULLSCREEN_API) +bool HTMLFrameElementBase::allowFullScreen() const +{ + return hasAttribute(webkitallowfullscreenAttr); +} +#endif + } // namespace WebCore diff --git a/Source/WebCore/html/HTMLFrameElementBase.h b/Source/WebCore/html/HTMLFrameElementBase.h index e5f9c46..9922fd1 100644 --- a/Source/WebCore/html/HTMLFrameElementBase.h +++ b/Source/WebCore/html/HTMLFrameElementBase.h @@ -43,6 +43,9 @@ public: int height() const; void setRemainsAliveOnRemovalFromTree(bool); +#if ENABLE(FULLSCREEN_API) + virtual bool allowFullScreen() const; +#endif protected: HTMLFrameElementBase(const QualifiedName&, Document*); diff --git a/Source/WebCore/html/HTMLFrameSetElement.cpp b/Source/WebCore/html/HTMLFrameSetElement.cpp index 50f921b..0affef6 100644 --- a/Source/WebCore/html/HTMLFrameSetElement.cpp +++ b/Source/WebCore/html/HTMLFrameSetElement.cpp @@ -49,9 +49,9 @@ HTMLFrameSetElement::HTMLFrameSetElement(const QualifiedName& tagName, Document* , m_border(6) , m_borderSet(false) , m_borderColorSet(false) - , frameborder(true) - , frameBorderSet(false) - , noresize(false) + , m_frameborder(true) + , m_frameborderSet(false) + , m_noresize(false) { ASSERT(hasTagName(framesetTag)); } @@ -87,21 +87,21 @@ void HTMLFrameSetElement::parseMappedAttribute(Attribute* attr) if (!attr->isNull()) { // false or "no" or "0".. if (attr->value().toInt() == 0) { - frameborder = false; + m_frameborder = false; m_border = 0; } - frameBorderSet = true; + m_frameborderSet = true; } else { - frameborder = false; - frameBorderSet = false; + m_frameborder = false; + m_frameborderSet = false; } } else if (attr->name() == noresizeAttr) { - noresize = true; + m_noresize = true; } else if (attr->name() == borderAttr) { if (!attr->isNull()) { m_border = attr->value().toInt(); if (!m_border) - frameborder = false; + m_frameborder = false; m_borderSet = true; } else m_borderSet = false; @@ -169,16 +169,16 @@ void HTMLFrameSetElement::attach() for (ContainerNode* node = parentNode(); node; node = node->parentNode()) { if (node->hasTagName(framesetTag)) { HTMLFrameSetElement* frameset = static_cast(node); - if (!frameBorderSet) - frameborder = frameset->hasFrameBorder(); - if (frameborder) { + if (!m_frameborderSet) + m_frameborder = frameset->hasFrameBorder(); + if (m_frameborder) { if (!m_borderSet) m_border = frameset->border(); if (!m_borderColorSet) m_borderColorSet = frameset->hasBorderColor(); } - if (!noresize) - noresize = frameset->noResize(); + if (!m_noresize) + m_noresize = frameset->noResize(); break; } } @@ -188,7 +188,7 @@ void HTMLFrameSetElement::attach() void HTMLFrameSetElement::defaultEventHandler(Event* evt) { - if (evt->isMouseEvent() && !noresize && renderer() && renderer()->isFrameSet()) { + if (evt->isMouseEvent() && !m_noresize && renderer() && renderer()->isFrameSet()) { if (toRenderFrameSet(renderer())->userResize(static_cast(evt))) { evt->setDefaultHandled(); return; diff --git a/Source/WebCore/html/HTMLFrameSetElement.h b/Source/WebCore/html/HTMLFrameSetElement.h index bdbec6a..f2f8439 100644 --- a/Source/WebCore/html/HTMLFrameSetElement.h +++ b/Source/WebCore/html/HTMLFrameSetElement.h @@ -33,8 +33,8 @@ class HTMLFrameSetElement : public HTMLElement { public: static PassRefPtr create(const QualifiedName&, Document*); - bool hasFrameBorder() const { return frameborder; } - bool noResize() const { return noresize; } + bool hasFrameBorder() const { return m_frameborder; } + bool noResize() const { return m_noresize; } int totalRows() const { return m_totalRows; } int totalCols() const { return m_totalCols; } @@ -92,9 +92,9 @@ private: bool m_borderColorSet; - bool frameborder; - bool frameBorderSet; - bool noresize; + bool m_frameborder; + bool m_frameborderSet; + bool m_noresize; }; } // namespace WebCore diff --git a/Source/WebCore/html/HTMLInputElement.cpp b/Source/WebCore/html/HTMLInputElement.cpp index c5f1ebc..7ae6ad9 100644 --- a/Source/WebCore/html/HTMLInputElement.cpp +++ b/Source/WebCore/html/HTMLInputElement.cpp @@ -154,6 +154,17 @@ void HTMLInputElement::updateCheckedRadioButtons() renderer()->theme()->stateChanged(renderer(), CheckedState); } +bool HTMLInputElement::lastChangeWasUserEdit() const +{ + if (!isTextField()) + return false; + + if (!renderer()) + return false; + + return toRenderTextControl(renderer())->lastChangeWasUserEdit(); +} + bool HTMLInputElement::isValidValue(const String& value) const { if (!m_inputType->canSetStringValue()) { @@ -751,6 +762,7 @@ void HTMLInputElement::reset() if (m_inputType->storesValueSeparateFromAttribute()) setValue(String()); + setAutofilled(false); setChecked(hasAttribute(checkedAttr)); m_reflectsCheckedAttribute = true; } @@ -790,8 +802,10 @@ void HTMLInputElement::setChecked(bool nowChecked, bool sendChangeEvent) // unchecked to match other browsers. DOM is not a useful standard for this // because it says only to fire change events at "lose focus" time, which is // definitely wrong in practice for these types of elements. - if (sendChangeEvent && inDocument() && m_inputType->shouldSendChangeEventAfterCheckedChanged()) + if (sendChangeEvent && inDocument() && m_inputType->shouldSendChangeEventAfterCheckedChanged()) { + setTextAsOfLastFormControlChangeEvent(String()); dispatchFormControlChangeEvent(); + } } void HTMLInputElement::setIndeterminate(bool newValue) @@ -916,6 +930,9 @@ void HTMLInputElement::setValue(const String& value, bool sendChangeEvent) dispatchFormControlChangeEvent(); } + if (isText() && (!focused() || !sendChangeEvent)) + setTextAsOfLastFormControlChangeEvent(value); + InputElement::notifyFormStateChanged(this); } diff --git a/Source/WebCore/html/HTMLInputElement.h b/Source/WebCore/html/HTMLInputElement.h index 27d556b..f2c2625 100644 --- a/Source/WebCore/html/HTMLInputElement.h +++ b/Source/WebCore/html/HTMLInputElement.h @@ -42,6 +42,8 @@ public: DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitspeechchange); + virtual InputElement* toInputElement() { return this; } + bool autoComplete() const; // For ValidityState @@ -197,6 +199,8 @@ public: void handleBeforeTextInsertedEvent(Event*); void updateCheckedRadioButtons(); + bool lastChangeWasUserEdit() const; + protected: HTMLInputElement(const QualifiedName&, Document*, HTMLFormElement*, bool createdByParser); diff --git a/Source/WebCore/html/HTMLLinkElement.cpp b/Source/WebCore/html/HTMLLinkElement.cpp index 04cfda4..67262d9 100644 --- a/Source/WebCore/html/HTMLLinkElement.cpp +++ b/Source/WebCore/html/HTMLLinkElement.cpp @@ -145,6 +145,8 @@ void HTMLLinkElement::parseMappedAttribute(Attribute* attr) #if ENABLE(LINK_PREFETCH) else if (attr->name() == onloadAttr) setAttributeEventListener(eventNames().loadEvent, createAttributeEventListener(this, attr)); + else if (attr->name() == onerrorAttr) + setAttributeEventListener(eventNames().errorEvent, createAttributeEventListener(this, attr)); #endif else { if (attr->name() == titleAttr && m_sheet) @@ -203,6 +205,17 @@ void HTMLLinkElement::tokenizeRelAttribute(const AtomicString& rel, RelAttribute } } +bool HTMLLinkElement::checkBeforeLoadEvent() +{ + RefPtr originalDocument = document(); + if (!dispatchBeforeLoadEvent(m_url)) + return false; + // A beforeload handler might have removed us from the document or changed the document. + if (!inDocument() || document() != originalDocument) + return false; + return true; +} + void HTMLLinkElement::process() { if (!inDocument() || m_isInShadowTree) { @@ -214,8 +227,11 @@ void HTMLLinkElement::process() // IE extension: location of small icon for locationbar / bookmarks // We'll record this URL per document, even if we later only use it in top level frames - if (m_relAttribute.m_isIcon && m_url.isValid() && !m_url.isEmpty()) + if (m_relAttribute.m_isIcon && m_url.isValid() && !m_url.isEmpty()) { + if (!checkBeforeLoadEvent()) + return; document()->setIconURL(m_url.string(), type); + } #ifdef ANDROID_APPLE_TOUCH_ICON if ((m_relAttribute.m_isTouchIcon || m_relAttribute.m_isPrecomposedTouchIcon) && m_url.isValid() @@ -235,6 +251,8 @@ void HTMLLinkElement::process() #if ENABLE(LINK_PREFETCH) if (m_relAttribute.m_isLinkPrefetch && m_url.isValid() && document()->frame()) { + if (!checkBeforeLoadEvent()) + return; m_cachedLinkPrefetch = document()->cachedResourceLoader()->requestLinkPrefetch(m_url); if (m_cachedLinkPrefetch) m_cachedLinkPrefetch->addClient(this); @@ -256,11 +274,7 @@ void HTMLLinkElement::process() m_cachedSheet = 0; } - RefPtr originalDocument = document(); - if (!dispatchBeforeLoadEvent(m_url)) - return; - // A beforeload handler might have removed us from the document or changed the document. - if (!inDocument() || document() != originalDocument) + if (!checkBeforeLoadEvent()) return; m_loading = true; @@ -413,16 +427,19 @@ bool HTMLLinkElement::isLoading() const void HTMLLinkElement::onloadTimerFired(Timer* timer) { ASSERT_UNUSED(timer, timer == &m_onloadTimer); - dispatchEvent(Event::create(eventNames().loadEvent, false, false)); + if (m_cachedLinkPrefetch->errorOccurred()) + dispatchEvent(Event::create(eventNames().errorEvent, false, false)); + else + dispatchEvent(Event::create(eventNames().loadEvent, false, false)); + + m_cachedLinkPrefetch->removeClient(this); + m_cachedLinkPrefetch = 0; } void HTMLLinkElement::notifyFinished(CachedResource* resource) { m_onloadTimer.startOneShot(0); - if (m_cachedLinkPrefetch.get() == resource) { - m_cachedLinkPrefetch->removeClient(this); - m_cachedLinkPrefetch = 0; - } + ASSERT(m_cachedLinkPrefetch.get() == resource); } #endif diff --git a/Source/WebCore/html/HTMLLinkElement.h b/Source/WebCore/html/HTMLLinkElement.h index 3798c33..d31feeb 100644 --- a/Source/WebCore/html/HTMLLinkElement.h +++ b/Source/WebCore/html/HTMLLinkElement.h @@ -86,6 +86,7 @@ private: #if ENABLE(LINK_PREFETCH) void onloadTimerFired(Timer*); #endif + bool checkBeforeLoadEvent(); void process(); static void processCallback(Node*); diff --git a/Source/WebCore/html/HTMLMediaElement.cpp b/Source/WebCore/html/HTMLMediaElement.cpp index ad0fdef..29c0cb8 100644 --- a/Source/WebCore/html/HTMLMediaElement.cpp +++ b/Source/WebCore/html/HTMLMediaElement.cpp @@ -227,8 +227,8 @@ void HTMLMediaElement::attributeChanged(Attribute* attr, bool preserveDecls) detach(); attach(); } - if (renderer()) - renderer()->updateFromElement(); + if (hasMediaControls()) + mediaControls()->reset(); #else if (m_player) m_player->setControls(controls()); @@ -907,6 +907,7 @@ void HTMLMediaElement::setNetworkState(MediaPlayer::NetworkState state) if (m_networkState > NETWORK_IDLE) { m_progressEventTimer.stop(); scheduleEvent(eventNames().suspendEvent); + setShouldDelayLoadEvent(false); } m_networkState = NETWORK_IDLE; } @@ -1038,6 +1039,7 @@ void HTMLMediaElement::progressEventTimerFired(Timer*) if (timedelta > 3.0 && !m_sentStalledEvent) { scheduleEvent(eventNames().stalledEvent); m_sentStalledEvent = true; + setShouldDelayLoadEvent(false); } } else { scheduleEvent(eventNames().progressEvent); @@ -1311,7 +1313,7 @@ void HTMLMediaElement::setDefaultPlaybackRate(float rate) float HTMLMediaElement::playbackRate() const { - return m_player ? m_player->rate() : 0; + return m_playbackRate; } void HTMLMediaElement::setPlaybackRate(float rate) @@ -1421,8 +1423,6 @@ void HTMLMediaElement::playInternal() seek(0, unused); } - setPlaybackRate(defaultPlaybackRate()); - if (m_paused) { m_paused = false; invalidateCachedTime(); @@ -1536,8 +1536,8 @@ void HTMLMediaElement::setMuted(bool muted) if (!processingMediaPlayerCallback()) { if (m_player) { m_player->setMuted(m_muted); - if (renderer()) - renderer()->updateFromElement(); + if (hasMediaControls()) + mediaControls()->changedMute(); } } scheduleEvent(eventNames().volumechangeEvent); @@ -1550,9 +1550,10 @@ void HTMLMediaElement::togglePlayState() // We can safely call the internal play/pause methods, which don't check restrictions, because // this method is only called from the built-in media controller - if (canPlay()) + if (canPlay()) { + setPlaybackRate(defaultPlaybackRate()); playInternal(); - else + } else pauseInternal(); } @@ -1604,7 +1605,9 @@ void HTMLMediaElement::playbackProgressTimerFired(Timer*) return; scheduleTimeupdateEvent(true); - + if (hasMediaControls()) + mediaControls()->playbackProgressed(); + // FIXME: deal with cue ranges here } @@ -1929,7 +1932,7 @@ void HTMLMediaElement::mediaPlayerPlaybackStateChanged(MediaPlayer*) { LOG(Media, "HTMLMediaElement::mediaPlayerPlaybackStateChanged"); - if (!m_player) + if (!m_player || m_pausedInternal) return; beginProcessingMediaPlayerCallback(); @@ -2111,9 +2114,9 @@ void HTMLMediaElement::updateVolume() m_player->setMuted(m_muted); m_player->setVolume(m_volume * volumeMultiplier); } - - if (renderer()) - renderer()->updateFromElement(); + + if (hasMediaControls()) + mediaControls()->changedVolume(); } void HTMLMediaElement::updatePlayState() @@ -2126,6 +2129,8 @@ void HTMLMediaElement::updatePlayState() m_player->pause(); refreshCachedTime(); m_playbackProgressTimer.stop(); + if (hasMediaControls()) + mediaControls()->playbackStopped(); return; } @@ -2149,6 +2154,8 @@ void HTMLMediaElement::updatePlayState() m_player->play(); } + if (hasMediaControls()) + mediaControls()->playbackStarted(); startPlaybackProgressTimer(); m_playing = true; @@ -2165,6 +2172,9 @@ void HTMLMediaElement::updatePlayState() if (couldPlayIfEnoughData()) m_player->prepareToPlay(); + + if (hasMediaControls()) + mediaControls()->playbackStopped(); } if (renderer()) @@ -2313,8 +2323,8 @@ void HTMLMediaElement::defaultEventHandler(Event* event) if (widget) widget->handleEvent(event); #else - if (renderer() && renderer()->isMedia()) - toRenderMedia(renderer())->controls()->forwardEvent(event); + if (hasMediaControls()) + mediaControls()->forwardEvent(event); if (event->defaultHandled()) return; HTMLElement::defaultEventHandler(event); @@ -2433,6 +2443,19 @@ void HTMLMediaElement::updateWidget(PluginCreationOption) #endif // ENABLE(PLUGIN_PROXY_FOR_VIDEO) +bool HTMLMediaElement::isFullscreen() const +{ + if (m_isFullscreen) + return true; + +#if ENABLE(FULLSCREEN_API) + if (document()->webkitIsFullScreen() && document()->webkitCurrentFullScreenElement() == this) + return true; +#endif + + return false; +} + void HTMLMediaElement::enterFullscreen() { LOG(Media, "HTMLMediaElement::enterFullscreen"); @@ -2490,8 +2513,8 @@ void HTMLMediaElement::setClosedCaptionsVisible(bool closedCaptionVisible) m_closedCaptionsVisible = closedCaptionVisible; m_player->setClosedCaptionsVisible(closedCaptionVisible); - if (renderer()) - renderer()->updateFromElement(); + if (hasMediaControls()) + mediaControls()->changedClosedCaptionsVisibility(); } void HTMLMediaElement::setWebkitClosedCaptionsVisible(bool visible) @@ -2581,6 +2604,17 @@ void HTMLMediaElement::privateBrowsingStateDidChange() m_player->setPrivateBrowsingMode(privateMode); } +MediaControls* HTMLMediaElement::mediaControls() +{ + ASSERT(renderer()); + return toRenderMedia(renderer())->controls(); +} + +bool HTMLMediaElement::hasMediaControls() const +{ + return renderer() && renderer()->isMedia(); +} + } #endif diff --git a/Source/WebCore/html/HTMLMediaElement.h b/Source/WebCore/html/HTMLMediaElement.h index f870586..ea958fa 100644 --- a/Source/WebCore/html/HTMLMediaElement.h +++ b/Source/WebCore/html/HTMLMediaElement.h @@ -41,6 +41,7 @@ namespace WebCore { class Event; class HTMLSourceElement; +class MediaControls; class MediaError; class KURL; class TimeRanges; @@ -163,7 +164,7 @@ public: bool hasSingleSecurityOrigin() const { return !m_player || m_player->hasSingleSecurityOrigin(); } - bool isFullscreen() const { return m_isFullscreen; } + bool isFullscreen() const; void enterFullscreen(); void exitFullscreen(); @@ -171,6 +172,8 @@ public: bool closedCaptionsVisible() const; void setClosedCaptionsVisible(bool); + MediaControls* mediaControls(); + bool processingUserGesture() const; void sourceWillBeRemoved(HTMLSourceElement*); @@ -179,13 +182,14 @@ public: void privateBrowsingStateDidChange(); // Restrictions to change default behaviors. - enum BehaviorRestrictions { + enum BehaviorRestrictionFlags { NoRestrictions = 0, RequireUserGestureForLoadRestriction = 1 << 0, RequireUserGestureForRateChangeRestriction = 1 << 1, RequireUserGestureForFullScreenRestriction = 1 << 2 }; - + typedef unsigned BehaviorRestrictions; + bool requireUserGestureForLoad() const { return m_restrictions & RequireUserGestureForLoadRestriction; } bool requireUserGestureForRateChange() const { return m_restrictions & RequireUserGestureForRateChangeRestriction; } bool requireUserGestureForFullScreen() const { return m_restrictions & RequireUserGestureForFullScreenRestriction; } @@ -319,6 +323,8 @@ private: void invalidateCachedTime(); void refreshCachedTime() const; + bool hasMediaControls() const; + Timer m_loadTimer; Timer m_asyncEventTimer; Timer m_progressEventTimer; diff --git a/Source/WebCore/html/HTMLObjectElement.cpp b/Source/WebCore/html/HTMLObjectElement.cpp index 0f05a3a..4f4d0a1 100644 --- a/Source/WebCore/html/HTMLObjectElement.cpp +++ b/Source/WebCore/html/HTMLObjectElement.cpp @@ -2,7 +2,7 @@ * Copyright (C) 1999 Lars Knoll (knoll@kde.org) * (C) 1999 Antti Koivisto (koivisto@kde.org) * (C) 2000 Stefan Schimanski (1Stein@gmx.de) - * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2011 Apple Inc. All rights reserved. * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) * * This library is free software; you can redistribute it and/or @@ -48,7 +48,7 @@ namespace WebCore { using namespace HTMLNames; inline HTMLObjectElement::HTMLObjectElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form, bool createdByParser) - : HTMLPlugInImageElement(tagName, document, createdByParser) + : HTMLPlugInImageElement(tagName, document, createdByParser, ShouldNotPreferPlugInsForImages) , FormAssociatedElement(form) , m_docNamedItem(true) , m_useFallbackContent(false) @@ -217,7 +217,7 @@ void HTMLObjectElement::parametersForPlugin(Vector& paramNames, Vectorframe()->loader()->subframeLoader(); - if (loader->resourceWillUsePlugin(urlParameter, serviceType)) + if (loader->resourceWillUsePlugin(urlParameter, serviceType, shouldPreferPlugInsForImages())) url = urlParameter; } } @@ -311,13 +311,16 @@ bool HTMLObjectElement::rendererIsNeeded(RenderStyle* style) void HTMLObjectElement::insertedIntoDocument() { + HTMLPlugInImageElement::insertedIntoDocument(); + if (!inDocument()) + return; + if (isDocNamedItem() && document()->isHTMLDocument()) { HTMLDocument* document = static_cast(this->document()); document->addNamedItem(m_name); document->addExtraNamedItem(m_id); } - HTMLPlugInImageElement::insertedIntoDocument(); FormAssociatedElement::insertedIntoDocument(); } diff --git a/Source/WebCore/html/HTMLPlugInElement.cpp b/Source/WebCore/html/HTMLPlugInElement.cpp index bf2722b..9d724d5 100644 --- a/Source/WebCore/html/HTMLPlugInElement.cpp +++ b/Source/WebCore/html/HTMLPlugInElement.cpp @@ -166,7 +166,7 @@ void HTMLPlugInElement::defaultEventHandler(Event* event) if (!r || !r->isWidget()) return; - Widget* widget = toRenderWidget(r)->widget(); + RefPtr widget = toRenderWidget(r)->widget(); if (!widget) return; widget->handleEvent(event); diff --git a/Source/WebCore/html/HTMLPlugInImageElement.cpp b/Source/WebCore/html/HTMLPlugInImageElement.cpp index db07334..f3a99dd 100644 --- a/Source/WebCore/html/HTMLPlugInImageElement.cpp +++ b/Source/WebCore/html/HTMLPlugInImageElement.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All rights reserved. + * Copyright (C) 2008, 2011 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 @@ -25,6 +25,7 @@ #include "FrameLoader.h" #include "FrameLoaderClient.h" #include "HTMLImageLoader.h" +#include "HTMLNames.h" #include "Image.h" #include "Page.h" #include "RenderEmbeddedObject.h" @@ -32,13 +33,14 @@ namespace WebCore { -HTMLPlugInImageElement::HTMLPlugInImageElement(const QualifiedName& tagName, Document* document, bool createdByParser) +HTMLPlugInImageElement::HTMLPlugInImageElement(const QualifiedName& tagName, Document* document, bool createdByParser, PreferPlugInsForImagesOption preferPlugInsForImagesOption) : HTMLPlugInElement(tagName, document) // m_needsWidgetUpdate(!createdByParser) allows HTMLObjectElement to delay // widget updates until after all children are parsed. For HTMLEmbedElement // this delay is unnecessary, but it is simpler to make both classes share // the same codepath in this class. , m_needsWidgetUpdate(!createdByParser) + , m_shouldPreferPlugInsForImages(preferPlugInsForImagesOption == ShouldPreferPlugInsForImages) { } @@ -58,7 +60,7 @@ bool HTMLPlugInImageElement::isImageType() if (Frame* frame = document()->frame()) { KURL completedURL = frame->loader()->completeURL(m_url); - return frame->loader()->client()->objectContentType(completedURL, m_serviceType) == ObjectContentImage; + return frame->loader()->client()->objectContentType(completedURL, m_serviceType, shouldPreferPlugInsForImages()) == ObjectContentImage; } return Image::supportsType(m_serviceType); @@ -99,7 +101,7 @@ bool HTMLPlugInImageElement::wouldLoadAsNetscapePlugin(const String& url, const if (!url.isEmpty()) completedURL = frameLoader->completeURL(url); - if (frameLoader->client()->objectContentType(completedURL, serviceType) == ObjectContentNetscapePlugin) + if (frameLoader->client()->objectContentType(completedURL, serviceType, shouldPreferPlugInsForImages()) == ObjectContentNetscapePlugin) return true; return false; } diff --git a/Source/WebCore/html/HTMLPlugInImageElement.h b/Source/WebCore/html/HTMLPlugInImageElement.h index 364262b..c27c0f8 100644 --- a/Source/WebCore/html/HTMLPlugInImageElement.h +++ b/Source/WebCore/html/HTMLPlugInImageElement.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2008, 2009, 2011 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 @@ -33,6 +33,11 @@ enum PluginCreationOption { CreateAnyWidgetType, CreateOnlyNonNetscapePlugins, }; + +enum PreferPlugInsForImagesOption { + ShouldPreferPlugInsForImages, + ShouldNotPreferPlugInsForImages +}; // Base class for HTMLObjectElement and HTMLEmbedElement class HTMLPlugInImageElement : public HTMLPlugInElement { @@ -43,9 +48,10 @@ public: const String& serviceType() const { return m_serviceType; } const String& url() const { return m_url; } + bool shouldPreferPlugInsForImages() const { return m_shouldPreferPlugInsForImages; } protected: - HTMLPlugInImageElement(const QualifiedName& tagName, Document*, bool createdByParser); + HTMLPlugInImageElement(const QualifiedName& tagName, Document*, bool createdByParser, PreferPlugInsForImagesOption); bool isImageType(); @@ -75,6 +81,7 @@ private: virtual bool useFallbackContent() const { return false; } bool m_needsWidgetUpdate; + bool m_shouldPreferPlugInsForImages; }; } // namespace WebCore diff --git a/Source/WebCore/html/HTMLScriptElement.cpp b/Source/WebCore/html/HTMLScriptElement.cpp index 8e708d1..b56b375 100644 --- a/Source/WebCore/html/HTMLScriptElement.cpp +++ b/Source/WebCore/html/HTMLScriptElement.cpp @@ -58,6 +58,13 @@ void HTMLScriptElement::childrenChanged(bool changedByParser, Node* beforeChange HTMLElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); } +void HTMLScriptElement::attributeChanged(Attribute* attr, bool preserveDecls) +{ + if (attr->name() == asyncAttr) + handleAsyncAttribute(); + HTMLElement::attributeChanged(attr, preserveDecls); +} + void HTMLScriptElement::parseMappedAttribute(Attribute* attr) { const QualifiedName& attrName = attr->name(); @@ -102,6 +109,17 @@ void HTMLScriptElement::setText(const String &value) appendChild(document()->createTextNode(value.impl()), ec); } +void HTMLScriptElement::setAsync(bool async) +{ + setBooleanAttribute(asyncAttr, async); + handleAsyncAttribute(); +} + +bool HTMLScriptElement::async() const +{ + return fastHasAttribute(asyncAttr) || forceAsync(); +} + KURL HTMLScriptElement::src() const { return document()->completeURL(sourceAttributeValue()); diff --git a/Source/WebCore/html/HTMLScriptElement.h b/Source/WebCore/html/HTMLScriptElement.h index efe6a6a..cbe7258 100644 --- a/Source/WebCore/html/HTMLScriptElement.h +++ b/Source/WebCore/html/HTMLScriptElement.h @@ -38,6 +38,9 @@ public: KURL src() const; + void setAsync(bool); + bool async() const; + private: HTMLScriptElement(const QualifiedName&, Document*, bool wasInsertedByParser, bool alreadyStarted); @@ -45,6 +48,7 @@ private: 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); virtual bool isURLAttribute(Attribute*) const; diff --git a/Source/WebCore/html/HTMLScriptElement.idl b/Source/WebCore/html/HTMLScriptElement.idl index 20b7331..fa799cb 100644 --- a/Source/WebCore/html/HTMLScriptElement.idl +++ b/Source/WebCore/html/HTMLScriptElement.idl @@ -24,7 +24,7 @@ module html { attribute [Reflect=for] DOMString htmlFor; attribute [Reflect] DOMString event; attribute [Reflect] DOMString charset; - attribute [Reflect] boolean async; + attribute boolean async; attribute [Reflect] boolean defer; attribute [Reflect, URL] DOMString src; attribute [Reflect] DOMString type; diff --git a/Source/WebCore/html/HTMLSelectElement.cpp b/Source/WebCore/html/HTMLSelectElement.cpp index d23e56a..69d3ffe 100644 --- a/Source/WebCore/html/HTMLSelectElement.cpp +++ b/Source/WebCore/html/HTMLSelectElement.cpp @@ -434,7 +434,12 @@ void HTMLSelectElement::accessKeySetSelectedIndex(int index) void HTMLSelectElement::setMultiple(bool multiple) { + int oldSelectedIndex = selectedIndex(); setAttribute(multipleAttr, multiple ? "" : 0); + + // Restore selectedIndex after changing the multiple flag to preserve + // selection as single-line and multi-line has different defaults. + setSelectedIndex(oldSelectedIndex); } void HTMLSelectElement::setSize(int size) diff --git a/Source/WebCore/html/HTMLSummaryElement.cpp b/Source/WebCore/html/HTMLSummaryElement.cpp index 96e3d74..9c2222a 100644 --- a/Source/WebCore/html/HTMLSummaryElement.cpp +++ b/Source/WebCore/html/HTMLSummaryElement.cpp @@ -21,7 +21,9 @@ #include "config.h" #include "HTMLSummaryElement.h" +#include "HTMLDetailsElement.h" #include "HTMLNames.h" +#include "RenderSummary.h" namespace WebCore { @@ -38,4 +40,9 @@ HTMLSummaryElement::HTMLSummaryElement(const QualifiedName& tagName, Document* d ASSERT(hasTagName(summaryTag)); } +RenderObject* HTMLSummaryElement::createRenderer(RenderArena* arena, RenderStyle*) +{ + return new (arena) RenderSummary(this); +} + } diff --git a/Source/WebCore/html/HTMLSummaryElement.h b/Source/WebCore/html/HTMLSummaryElement.h index 1b24c67..1a93ee9 100644 --- a/Source/WebCore/html/HTMLSummaryElement.h +++ b/Source/WebCore/html/HTMLSummaryElement.h @@ -31,6 +31,8 @@ public: private: HTMLSummaryElement(const QualifiedName&, Document*); + + virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); }; } diff --git a/Source/WebCore/html/HTMLTextAreaElement.cpp b/Source/WebCore/html/HTMLTextAreaElement.cpp index b8b04de..c8ec9ab 100644 --- a/Source/WebCore/html/HTMLTextAreaElement.cpp +++ b/Source/WebCore/html/HTMLTextAreaElement.cpp @@ -295,6 +295,7 @@ void HTMLTextAreaElement::setValue(const String& value) setValueCommon(value); m_isDirty = true; setNeedsValidityCheck(); + setTextAsOfLastFormControlChangeEvent(value); } void HTMLTextAreaElement::setNonDirtyValue(const String& value) @@ -302,6 +303,7 @@ void HTMLTextAreaElement::setNonDirtyValue(const String& value) setValueCommon(value); m_isDirty = false; setNeedsValidityCheck(); + setTextAsOfLastFormControlChangeEvent(value); } void HTMLTextAreaElement::setValueCommon(const String& value) @@ -429,6 +431,13 @@ void HTMLTextAreaElement::setRows(int rows) setAttribute(rowsAttr, String::number(rows)); } +bool HTMLTextAreaElement::lastChangeWasUserEdit() const +{ + if (!renderer()) + return false; + return toRenderTextControl(renderer())->lastChangeWasUserEdit(); +} + bool HTMLTextAreaElement::shouldUseInputMethod() const { return true; diff --git a/Source/WebCore/html/HTMLTextAreaElement.h b/Source/WebCore/html/HTMLTextAreaElement.h index 21b5880..40193a0 100644 --- a/Source/WebCore/html/HTMLTextAreaElement.h +++ b/Source/WebCore/html/HTMLTextAreaElement.h @@ -55,7 +55,9 @@ public: void setCols(int); void setRows(int); - + + bool lastChangeWasUserEdit() const; + void cacheSelection(int s, int e) { m_cachedSelectionStart = s; m_cachedSelectionEnd = e; }; private: diff --git a/Source/WebCore/html/HTMLTitleElement.cpp b/Source/WebCore/html/HTMLTitleElement.cpp index 776c37c..78c8b6a 100644 --- a/Source/WebCore/html/HTMLTitleElement.cpp +++ b/Source/WebCore/html/HTMLTitleElement.cpp @@ -46,7 +46,7 @@ PassRefPtr HTMLTitleElement::create(const QualifiedName& tagNa void HTMLTitleElement::insertedIntoDocument() { HTMLElement::insertedIntoDocument(); - document()->setTitle(m_title, this); + document()->setTitleElement(m_title, this); } void HTMLTitleElement::removedFromDocument() @@ -57,12 +57,9 @@ void HTMLTitleElement::removedFromDocument() void HTMLTitleElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) { - m_title = ""; - for (Node* c = firstChild(); c != 0; c = c->nextSibling()) - if (c->nodeType() == TEXT_NODE || c->nodeType() == CDATA_SECTION_NODE) - m_title += c->nodeValue(); + m_title = text(); if (inDocument()) - document()->setTitle(m_title, this); + document()->setTitleElement(m_title, this); HTMLElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); } diff --git a/Source/WebCore/html/NumberInputType.cpp b/Source/WebCore/html/NumberInputType.cpp index 3397248..af30345 100644 --- a/Source/WebCore/html/NumberInputType.cpp +++ b/Source/WebCore/html/NumberInputType.cpp @@ -223,8 +223,9 @@ String NumberInputType::visibleValue() const if (currentValue.isEmpty()) return currentValue; double doubleValue = numeric_limits::quiet_NaN(); - parseToDoubleForNumberType(currentValue, &doubleValue); - String localized = formatLocalizedNumber(doubleValue); + unsigned decimalPlace; + parseToDoubleForNumberTypeWithDecimalPlaces(currentValue, &doubleValue, &decimalPlace); + String localized = formatLocalizedNumber(doubleValue, decimalPlace); return localized.isEmpty() ? currentValue : localized; } diff --git a/Source/WebCore/html/RangeInputType.cpp b/Source/WebCore/html/RangeInputType.cpp index be7e0c6..cbec740 100644 --- a/Source/WebCore/html/RangeInputType.cpp +++ b/Source/WebCore/html/RangeInputType.cpp @@ -261,7 +261,7 @@ void RangeInputType::minOrMaxAttributeChanged() void RangeInputType::valueChanged() { - element()->shadowRoot()->setNeedsStyleRecalc(); + toSliderThumbElement(element()->shadowRoot())->setPositionFromValue(); } String RangeInputType::fallbackValue() diff --git a/Source/WebCore/html/ValidationMessage.cpp b/Source/WebCore/html/ValidationMessage.cpp index 70aa02d..59a1467 100644 --- a/Source/WebCore/html/ValidationMessage.cpp +++ b/Source/WebCore/html/ValidationMessage.cpp @@ -31,11 +31,15 @@ #include "config.h" #include "ValidationMessage.h" +#include "CSSPropertyNames.h" #include "CSSStyleSelector.h" +#include "CSSValueKeywords.h" #include "FormAssociatedElement.h" #include "HTMLBRElement.h" #include "HTMLNames.h" +#include "Page.h" #include "RenderObject.h" +#include "Settings.h" #include "Text.h" #include @@ -90,8 +94,13 @@ void ValidationMessage::setMessageDOMAndStartTimer(Timer*) } } - m_timer.set(new Timer(this, &ValidationMessage::deleteBubbleTree)); - m_timer->startOneShot(max(5.0, m_message.length() / 20.0)); + int magnification = doc->page() ? doc->page()->settings()->validationMessageTimerMaginification() : -1; + if (magnification <= 0) + m_timer.clear(); + else { + m_timer.set(new Timer(this, &ValidationMessage::deleteBubbleTree)); + m_timer->startOneShot(max(5.0, static_cast(m_message.length()) * magnification / 1000)); + } } class ElementWithPseudoId : public HTMLElement { @@ -116,6 +125,9 @@ void ValidationMessage::buildBubbleTree(Timer*) HTMLElement* host = toHTMLElement(m_element); Document* doc = host->document(); m_bubble = ElementWithPseudoId::create(doc, "-webkit-validation-bubble"); + // Need to force position:absolute because RenderMenuList doesn't assume it + // contains non-absolute or non-fixed renderers as children. + m_bubble->getInlineStyleDecl()->setProperty(CSSPropertyPosition, CSSValueAbsolute); ExceptionCode ec = 0; // FIXME: We need a way to host multiple shadow roots in a single node, or // to inherit an existing shadow tree. @@ -124,8 +136,9 @@ void ValidationMessage::buildBubbleTree(Timer*) else host->setShadowRoot(m_bubble); - m_bubble->appendChild(ElementWithPseudoId::create(doc, "-webkit-validation-bubble-top-outer-arrow"), ec); - m_bubble->appendChild(ElementWithPseudoId::create(doc, "-webkit-validation-bubble-top-inner-arrow"), ec); + RefPtr clipper = ElementWithPseudoId::create(doc, "-webkit-validation-bubble-arrow-clipper"); + clipper->appendChild(ElementWithPseudoId::create(doc, "-webkit-validation-bubble-arrow"), ec); + m_bubble->appendChild(clipper.release(), ec); m_bubbleMessage = ElementWithPseudoId::create(doc, "-webkit-validation-bubble-message"); m_bubble->appendChild(m_bubbleMessage, ec); diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp b/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp index a549782..f5ff078 100644 --- a/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp +++ b/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp @@ -146,7 +146,7 @@ CanvasRenderingContext2D::~CanvasRenderingContext2D() bool CanvasRenderingContext2D::isAccelerated() const { #if USE(IOSURFACE_CANVAS_BACKING_STORE) - return true; + return canvas()->document()->page()->settings()->canvasUsesAcceleratedDrawing(); #elif ENABLE(ACCELERATED_2D_CANVAS) return m_context3D; #else diff --git a/Source/WebCore/html/canvas/WebGLContextAttributes.cpp b/Source/WebCore/html/canvas/WebGLContextAttributes.cpp index 6a47ea9..e36e04e 100644 --- a/Source/WebCore/html/canvas/WebGLContextAttributes.cpp +++ b/Source/WebCore/html/canvas/WebGLContextAttributes.cpp @@ -107,6 +107,16 @@ void WebGLContextAttributes::setPremultipliedAlpha(bool premultipliedAlpha) m_attrs.premultipliedAlpha = premultipliedAlpha; } +bool WebGLContextAttributes::preserveDrawingBuffer() const +{ + return m_attrs.preserveDrawingBuffer; +} + +void WebGLContextAttributes::setPreserveDrawingBuffer(bool preserveDrawingBuffer) +{ + m_attrs.preserveDrawingBuffer = preserveDrawingBuffer; +} + GraphicsContext3D::Attributes WebGLContextAttributes::attributes() const { return m_attrs; diff --git a/Source/WebCore/html/canvas/WebGLContextAttributes.h b/Source/WebCore/html/canvas/WebGLContextAttributes.h index a108605..5391a2b 100644 --- a/Source/WebCore/html/canvas/WebGLContextAttributes.h +++ b/Source/WebCore/html/canvas/WebGLContextAttributes.h @@ -65,6 +65,11 @@ class WebGLContextAttributes : public CanvasContextAttributes { bool premultipliedAlpha() const; void setPremultipliedAlpha(bool premultipliedAlpha); + // Whether or not to preserve the drawing buffer after presentation to the + // screen; default=false + bool preserveDrawingBuffer() const; + void setPreserveDrawingBuffer(bool); + // Fetches a copy of the attributes stored in this object in a // form that can be used to initialize a GraphicsContext3D. GraphicsContext3D::Attributes attributes() const; diff --git a/Source/WebCore/html/canvas/WebGLContextAttributes.idl b/Source/WebCore/html/canvas/WebGLContextAttributes.idl index 0fa0c2c..56da1c6 100644 --- a/Source/WebCore/html/canvas/WebGLContextAttributes.idl +++ b/Source/WebCore/html/canvas/WebGLContextAttributes.idl @@ -34,5 +34,6 @@ module html { attribute boolean stencil; attribute boolean antialias; attribute boolean premultipliedAlpha; + attribute boolean preserveDrawingBuffer; }; } diff --git a/Source/WebCore/html/canvas/WebGLRenderingContext.cpp b/Source/WebCore/html/canvas/WebGLRenderingContext.cpp index cc7a23b..aa40a64 100644 --- a/Source/WebCore/html/canvas/WebGLRenderingContext.cpp +++ b/Source/WebCore/html/canvas/WebGLRenderingContext.cpp @@ -412,6 +412,13 @@ void WebGLRenderingContext::initializeNewContext() m_stencilFuncRefBack = 0; m_stencilFuncMask = 0xFFFFFFFF; m_stencilFuncMaskBack = 0xFFFFFFFF; + m_layerCleared = false; + + m_clearColor[0] = m_clearColor[1] = m_clearColor[2] = m_clearColor[3] = 0; + m_scissorEnabled = false; + m_clearDepth = 1; + m_clearStencil = 0; + m_colorMask[0] = m_colorMask[1] = m_colorMask[2] = m_colorMask[3] = true; GC3Dint numCombinedTextureImageUnits = 0; m_context->getIntegerv(GraphicsContext3D::MAX_COMBINED_TEXTURE_IMAGE_UNITS, &numCombinedTextureImageUnits); @@ -472,6 +479,10 @@ WebGLRenderingContext::~WebGLRenderingContext() void WebGLRenderingContext::markContextChanged() { + if (m_framebufferBinding) + return; + m_context->markContextChanged(); + m_layerCleared = false; #if USE(ACCELERATED_COMPOSITING) RenderBox* renderBox = canvas()->renderBox(); if (renderBox && renderBox->hasLayer() && renderBox->layer()->hasAcceleratedCompositing()) @@ -486,15 +497,81 @@ void WebGLRenderingContext::markContextChanged() m_markedCanvasDirty = true; } +bool WebGLRenderingContext::clearIfComposited(GC3Dbitfield mask) +{ + if (isContextLost()) + return false; + + RefPtr contextAttributes = getContextAttributes(); + + if (!m_context->layerComposited() || m_layerCleared + || m_attributes.preserveDrawingBuffer || m_framebufferBinding) + return false; + + // Determine if it's possible to combine the clear the user asked for and this clear. + bool combinedClear = mask && !m_scissorEnabled; + + m_context->disable(GraphicsContext3D::SCISSOR_TEST); + if (combinedClear && (mask & GraphicsContext3D::COLOR_BUFFER_BIT)) + m_context->clearColor(m_colorMask[0] ? m_clearColor[0] : 0, + m_colorMask[1] ? m_clearColor[1] : 0, + m_colorMask[2] ? m_clearColor[2] : 0, + m_colorMask[3] ? m_clearColor[3] : 0); + else + m_context->clearColor(0, 0, 0, 0); + m_context->colorMask(true, true, true, true); + if (contextAttributes->depth() && (!combinedClear || !(mask & GraphicsContext3D::DEPTH_BUFFER_BIT))) + m_context->clearDepth(1.0f); + if (contextAttributes->stencil() && (!combinedClear || !(mask & GraphicsContext3D::STENCIL_BUFFER_BIT))) + m_context->clearStencil(0); + GC3Dbitfield clearMask = GraphicsContext3D::COLOR_BUFFER_BIT; + if (contextAttributes->depth()) + clearMask |= GraphicsContext3D::DEPTH_BUFFER_BIT; + if (contextAttributes->stencil()) + clearMask |= GraphicsContext3D::STENCIL_BUFFER_BIT; + m_context->clear(clearMask); + + // Restore the state that the context set. + if (m_scissorEnabled) + m_context->enable(GraphicsContext3D::SCISSOR_TEST); + m_context->clearColor(m_clearColor[0], m_clearColor[1], + m_clearColor[2], m_clearColor[3]); + m_context->colorMask(m_colorMask[0], m_colorMask[1], + m_colorMask[2], m_colorMask[3]); + m_context->clearDepth(m_clearDepth); + m_context->clearStencil(m_clearStencil); + m_layerCleared = true; + + return combinedClear; +} + +void WebGLRenderingContext::markLayerComposited() +{ + m_context->markLayerComposited(); +} + void WebGLRenderingContext::paintRenderingResultsToCanvas() { - if (!m_markedCanvasDirty) + // Until the canvas is written to by the application, the clear that + // happened after it was composited should be ignored by the compositor. + if (m_context->layerComposited() && !m_attributes.preserveDrawingBuffer) + canvas()->makePresentationCopy(); + else + canvas()->clearPresentationCopy(); + clearIfComposited(); + if (!m_markedCanvasDirty && !m_layerCleared) return; canvas()->clearCopiedImage(); m_markedCanvasDirty = false; m_context->paintRenderingResultsToCanvas(this); } +PassRefPtr WebGLRenderingContext::paintRenderingResultsToImageData() +{ + clearIfComposited(); + return m_context->paintRenderingResultsToImageData(); +} + bool WebGLRenderingContext::paintsIntoCanvasBuffer() const { return m_context->paintsIntoCanvasBuffer(); @@ -885,7 +962,8 @@ void WebGLRenderingContext::clear(GC3Dbitfield mask) m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION); return; } - m_context->clear(mask); + if (!clearIfComposited(mask)) + m_context->clear(mask); cleanupAfterGraphicsCall(true); } @@ -901,6 +979,10 @@ void WebGLRenderingContext::clearColor(GC3Dfloat r, GC3Dfloat g, GC3Dfloat b, GC b = 0; if (isnan(a)) a = 1; + m_clearColor[0] = r; + m_clearColor[1] = g; + m_clearColor[2] = b; + m_clearColor[3] = a; m_context->clearColor(r, g, b, a); cleanupAfterGraphicsCall(false); } @@ -909,6 +991,7 @@ void WebGLRenderingContext::clearDepth(GC3Dfloat depth) { if (isContextLost()) return; + m_clearDepth = depth; m_context->clearDepth(depth); cleanupAfterGraphicsCall(false); } @@ -917,6 +1000,7 @@ void WebGLRenderingContext::clearStencil(GC3Dint s) { if (isContextLost()) return; + m_clearStencil = s; m_context->clearStencil(s); cleanupAfterGraphicsCall(false); } @@ -925,6 +1009,10 @@ void WebGLRenderingContext::colorMask(GC3Dboolean red, GC3Dboolean green, GC3Dbo { if (isContextLost()) return; + m_colorMask[0] = red; + m_colorMask[1] = green; + m_colorMask[2] = blue; + m_colorMask[3] = alpha; m_context->colorMask(red, green, blue, alpha); cleanupAfterGraphicsCall(false); } @@ -959,6 +1047,7 @@ void WebGLRenderingContext::copyTexImage2D(GC3Denum target, GC3Dint level, GC3De m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION); return; } + clearIfComposited(); if (isResourceSafe()) m_context->copyTexImage2D(target, level, internalformat, x, y, width, height, border); else { @@ -1002,6 +1091,7 @@ void WebGLRenderingContext::copyTexSubImage2D(GC3Denum target, GC3Dint level, GC m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION); return; } + clearIfComposited(); if (isResourceSafe()) m_context->copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); else { @@ -1234,6 +1324,8 @@ void WebGLRenderingContext::disable(GC3Denum cap) { if (isContextLost() || !validateCapability(cap)) return; + if (cap == GraphicsContext3D::SCISSOR_TEST) + m_scissorEnabled = false; m_context->disable(cap); cleanupAfterGraphicsCall(false); } @@ -1479,6 +1571,8 @@ void WebGLRenderingContext::drawArrays(GC3Denum mode, GC3Dint first, GC3Dsizei c return; } + clearIfComposited(); + bool vertexAttrib0Simulated = false; if (!isGLES2Compliant()) vertexAttrib0Simulated = simulateVertexAttrib0(first + count - 1); @@ -1550,6 +1644,7 @@ void WebGLRenderingContext::drawElements(GC3Denum mode, GC3Dsizei count, GC3Denu m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION); return; } + clearIfComposited(); bool vertexAttrib0Simulated = false; if (!isGLES2Compliant()) { @@ -1571,6 +1666,8 @@ void WebGLRenderingContext::enable(GC3Denum cap) { if (isContextLost() || !validateCapability(cap)) return; + if (cap == GraphicsContext3D::SCISSOR_TEST) + m_scissorEnabled = true; m_context->enable(cap); cleanupAfterGraphicsCall(false); } @@ -1597,7 +1694,7 @@ void WebGLRenderingContext::finish() if (isContextLost()) return; m_context->finish(); - cleanupAfterGraphicsCall(true); + cleanupAfterGraphicsCall(false); } void WebGLRenderingContext::flush() @@ -1605,7 +1702,7 @@ void WebGLRenderingContext::flush() if (isContextLost()) return; m_context->flush(); - cleanupAfterGraphicsCall(true); + cleanupAfterGraphicsCall(false); } void WebGLRenderingContext::framebufferRenderbuffer(GC3Denum target, GC3Denum attachment, GC3Denum renderbuffertarget, WebGLRenderbuffer* buffer, ExceptionCode& ec) @@ -2752,6 +2849,7 @@ void WebGLRenderingContext::readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); return; } + clearIfComposited(); void* data = pixels->baseAddress(); m_context->readPixels(x, y, width, height, format, type, data); #if OS(DARWIN) @@ -3062,8 +3160,12 @@ void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum return; } checkOrigin(canvas); - texImage2DImpl(target, level, internalformat, format, type, canvas->copiedImage(), - m_unpackFlipY, m_unpackPremultiplyAlpha, ec); + RefPtr imageData = canvas->getImageData(); + if (imageData) + texImage2D(target, level, internalformat, format, type, imageData.get(), ec); + else + texImage2DImpl(target, level, internalformat, format, type, canvas->copiedImage(), + m_unpackFlipY, m_unpackPremultiplyAlpha, ec); } #if ENABLE(VIDEO) @@ -3252,8 +3354,12 @@ void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Din return; } checkOrigin(canvas); - texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas->copiedImage(), - m_unpackFlipY, m_unpackPremultiplyAlpha, ec); + RefPtr imageData = canvas->getImageData(); + if (imageData) + texSubImage2D(target, level, xoffset, yoffset, format, type, imageData.get(), ec); + else + texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas->copiedImage(), + m_unpackFlipY, m_unpackPremultiplyAlpha, ec); } #if ENABLE(VIDEO) diff --git a/Source/WebCore/html/canvas/WebGLRenderingContext.h b/Source/WebCore/html/canvas/WebGLRenderingContext.h index 13145c8..f716efb 100644 --- a/Source/WebCore/html/canvas/WebGLRenderingContext.h +++ b/Source/WebCore/html/canvas/WebGLRenderingContext.h @@ -285,7 +285,9 @@ public: void reshape(int width, int height); + void markLayerComposited(); virtual void paintRenderingResultsToCanvas(); + virtual PassRefPtr paintRenderingResultsToImageData(); void removeObject(WebGLObject*); @@ -443,6 +445,13 @@ public: bool m_contextLost; GraphicsContext3D::Attributes m_attributes; + bool m_layerCleared; + GC3Dfloat m_clearColor[4]; + bool m_scissorEnabled; + GC3Dfloat m_clearDepth; + GC3Dint m_clearStencil; + GC3Dboolean m_colorMask[4]; + long m_stencilBits; GC3Duint m_stencilMask, m_stencilMaskBack; GC3Dint m_stencilFuncRef, m_stencilFuncRefBack; // Note that these are the user specified values, not the internal clamped value. @@ -469,6 +478,11 @@ public: WebGLGetInfo getWebGLFloatArrayParameter(GC3Denum); WebGLGetInfo getWebGLIntArrayParameter(GC3Denum); + // Clear the backbuffer if it was composited since the last operation. + // clearMask is set to the bitfield of any clear that would happen anyway at this time + // and the function returns true if that clear is now unnecessary. + bool clearIfComposited(GC3Dbitfield clearMask = 0); + void texImage2DBase(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, void* pixels, ExceptionCode&); diff --git a/Source/WebCore/html/parser/HTMLDocumentParser.cpp b/Source/WebCore/html/parser/HTMLDocumentParser.cpp index e79a97a..88db3c2 100644 --- a/Source/WebCore/html/parser/HTMLDocumentParser.cpp +++ b/Source/WebCore/html/parser/HTMLDocumentParser.cpp @@ -26,6 +26,7 @@ #include "config.h" #include "HTMLDocumentParser.h" +#include "ContentSecurityPolicy.h" #include "DocumentFragment.h" #include "Element.h" #include "Frame.h" @@ -216,6 +217,13 @@ bool HTMLDocumentParser::canTakeNextToken(SynchronousMode mode, PumpSession& ses // The parser will pause itself when waiting on a script to load or run. if (m_treeBuilder->isPaused()) { + if (mode == AllowYield) + m_parserScheduler->checkForYieldBeforeScript(session); + + // If we don't run the script, we cannot allow the next token to be taken. + if (session.needsYield) + return false; + // If we're paused waiting for a script, we try to execute scripts before continuing. bool shouldContinueParsing = runScriptsForPausedTreeBuilder(); m_treeBuilder->setPaused(!shouldContinueParsing); @@ -242,7 +250,6 @@ bool HTMLDocumentParser::canTakeNextToken(SynchronousMode mode, PumpSession& ses void HTMLDocumentParser::pumpTokenizer(SynchronousMode mode) { ASSERT(!isStopped()); - ASSERT(!m_treeBuilder->isPaused()); ASSERT(!isScheduledForResume()); // ASSERT that this object is both attached to the Document and protected. ASSERT(refCount() >= 2); @@ -485,11 +492,6 @@ void HTMLDocumentParser::stopWatchingForLoad(CachedResource* cachedScript) cachedScript->removeClient(this); } -bool HTMLDocumentParser::shouldLoadExternalScriptFromSrc(const AtomicString& srcValue) -{ - return document()->contentSecurityPolicy()->canLoadExternalScriptFromSrc(srcValue); -} - void HTMLDocumentParser::notifyFinished(CachedResource* cachedResource) { // pumpTokenizer can cause this parser to be detached from the Document, diff --git a/Source/WebCore/html/parser/HTMLDocumentParser.h b/Source/WebCore/html/parser/HTMLDocumentParser.h index 4bc33e4..a016cf3 100644 --- a/Source/WebCore/html/parser/HTMLDocumentParser.h +++ b/Source/WebCore/html/parser/HTMLDocumentParser.h @@ -108,7 +108,6 @@ private: // HTMLScriptRunnerHost virtual void watchForLoad(CachedResource*); virtual void stopWatchingForLoad(CachedResource*); - virtual bool shouldLoadExternalScriptFromSrc(const AtomicString&); virtual HTMLInputStream& inputStream() { return m_input; } // CachedResourceClient diff --git a/Source/WebCore/html/parser/HTMLElementStack.cpp b/Source/WebCore/html/parser/HTMLElementStack.cpp index 6f5f9ed..a4a7383 100644 --- a/Source/WebCore/html/parser/HTMLElementStack.cpp +++ b/Source/WebCore/html/parser/HTMLElementStack.cpp @@ -50,7 +50,7 @@ inline bool isNumberedHeaderElement(ContainerNode* node) || node->hasTagName(h6Tag); } -inline bool isRootMarker(ContainerNode* node) +inline bool isRootNode(ContainerNode* node) { return node->nodeType() == Node::DOCUMENT_FRAGMENT_NODE || node->hasTagName(htmlTag); @@ -74,7 +74,7 @@ inline bool isScopeMarker(ContainerNode* node) || node->hasTagName(SVGNames::foreignObjectTag) || node->hasTagName(SVGNames::descTag) || node->hasTagName(SVGNames::titleTag) - || isRootMarker(node); + || isRootNode(node); } inline bool isListItemScopeMarker(ContainerNode* node) @@ -87,7 +87,7 @@ inline bool isListItemScopeMarker(ContainerNode* node) inline bool isTableScopeMarker(ContainerNode* node) { return node->hasTagName(tableTag) - || isRootMarker(node); + || isRootNode(node); } inline bool isTableBodyScopeMarker(ContainerNode* node) @@ -95,26 +95,26 @@ inline bool isTableBodyScopeMarker(ContainerNode* node) return node->hasTagName(tbodyTag) || node->hasTagName(tfootTag) || node->hasTagName(theadTag) - || isRootMarker(node); + || isRootNode(node); } inline bool isTableRowScopeMarker(ContainerNode* node) { return node->hasTagName(trTag) - || isRootMarker(node); + || isRootNode(node); } -inline bool isForeignContentScopeMarker(Element* element) +inline bool isForeignContentScopeMarker(ContainerNode* node) { - return element->hasTagName(MathMLNames::miTag) - || element->hasTagName(MathMLNames::moTag) - || element->hasTagName(MathMLNames::mnTag) - || element->hasTagName(MathMLNames::msTag) - || element->hasTagName(MathMLNames::mtextTag) - || element->hasTagName(SVGNames::foreignObjectTag) - || element->hasTagName(SVGNames::descTag) - || element->hasTagName(SVGNames::titleTag) - || element->namespaceURI() == HTMLNames::xhtmlNamespaceURI; + return node->hasTagName(MathMLNames::miTag) + || node->hasTagName(MathMLNames::moTag) + || node->hasTagName(MathMLNames::mnTag) + || node->hasTagName(MathMLNames::msTag) + || node->hasTagName(MathMLNames::mtextTag) + || node->hasTagName(SVGNames::foreignObjectTag) + || node->hasTagName(SVGNames::descTag) + || node->hasTagName(SVGNames::titleTag) + || isInHTMLNamespace(node); } inline bool isButtonScopeMarker(ContainerNode* node) @@ -275,7 +275,7 @@ void HTMLElementStack::popUntilTableRowScopeMarker() void HTMLElementStack::popUntilForeignContentScopeMarker() { - while (!isForeignContentScopeMarker(top())) + while (!isForeignContentScopeMarker(topNode())) pop(); } @@ -434,10 +434,10 @@ bool inScopeCommon(HTMLElementStack::ElementRecord* top, const AtomicString& tar bool HTMLElementStack::hasOnlyHTMLElementsInScope() const { for (ElementRecord* record = m_top.get(); record; record = record->next()) { - Element* element = record->element(); - if (element->namespaceURI() != xhtmlNamespaceURI) + ContainerNode* node = record->node(); + if (!isInHTMLNamespace(node)) return false; - if (isScopeMarker(element)) + if (isScopeMarker(node)) return true; } ASSERT_NOT_REACHED(); // is always on the stack and is a scope marker. @@ -460,10 +460,10 @@ bool HTMLElementStack::hasNumberedHeaderElementInScope() const bool HTMLElementStack::inScope(Element* targetElement) const { for (ElementRecord* pos = m_top.get(); pos; pos = pos->next()) { - Element* element = pos->element(); - if (element == targetElement) + ContainerNode* node = pos->node(); + if (node == targetElement) return true; - if (isScopeMarker(element)) + if (isScopeMarker(node)) return false; } ASSERT_NOT_REACHED(); // is always on the stack and is a scope marker. diff --git a/Source/WebCore/html/parser/HTMLElementStack.h b/Source/WebCore/html/parser/HTMLElementStack.h index a710932..fd0e494 100644 --- a/Source/WebCore/html/parser/HTMLElementStack.h +++ b/Source/WebCore/html/parser/HTMLElementStack.h @@ -28,6 +28,7 @@ #define HTMLElementStack_h #include "Element.h" +#include "HTMLNames.h" #include #include #include @@ -167,6 +168,15 @@ private: Element* m_headElement; Element* m_bodyElement; }; + +inline bool isInHTMLNamespace(Node* node) +{ + // A DocumentFragment takes the place of the document element when parsing + // fragments and should be considered in the HTML namespace. + return node->namespaceURI() == HTMLNames::xhtmlNamespaceURI + || node->nodeType() == Node::DOCUMENT_FRAGMENT_NODE; +} + } // namespace WebCore diff --git a/Source/WebCore/html/parser/HTMLParserScheduler.cpp b/Source/WebCore/html/parser/HTMLParserScheduler.cpp index c4525c8..393c4be 100644 --- a/Source/WebCore/html/parser/HTMLParserScheduler.cpp +++ b/Source/WebCore/html/parser/HTMLParserScheduler.cpp @@ -86,6 +86,16 @@ void HTMLParserScheduler::continueNextChunkTimerFired(Timer m_parser->resumeParsingAfterYield(); } +void HTMLParserScheduler::checkForYieldBeforeScript(PumpSession& session) +{ + // If we've never painted before and a layout is pending, yield prior to running + // scripts to give the page a chance to paint earlier. + Document* document = m_parser->document(); + bool needsFirstPaint = document->view() && !document->view()->hasEverPainted(); + if (needsFirstPaint && document->isLayoutTimerActive()) + session.needsYield = true; +} + void HTMLParserScheduler::scheduleForResume() { m_continueNextChunkTimer.startOneShot(0); diff --git a/Source/WebCore/html/parser/HTMLParserScheduler.h b/Source/WebCore/html/parser/HTMLParserScheduler.h index 9aa12eb..730b52b 100644 --- a/Source/WebCore/html/parser/HTMLParserScheduler.h +++ b/Source/WebCore/html/parser/HTMLParserScheduler.h @@ -70,6 +70,7 @@ public: } ++session.processedTokens; } + void checkForYieldBeforeScript(PumpSession&); void scheduleForResume(); bool isScheduledForResume() const { return m_isSuspendedWithActiveTimer || m_continueNextChunkTimer.isActive(); } diff --git a/Source/WebCore/html/parser/HTMLPreloadScanner.cpp b/Source/WebCore/html/parser/HTMLPreloadScanner.cpp index d23542f..5514597 100644 --- a/Source/WebCore/html/parser/HTMLPreloadScanner.cpp +++ b/Source/WebCore/html/parser/HTMLPreloadScanner.cpp @@ -30,6 +30,7 @@ #include "CachedResourceLoader.h" #include "Document.h" +#include "InputType.h" #include "HTMLDocumentParser.h" #include "HTMLTokenizer.h" #include "HTMLLinkElement.h" @@ -50,13 +51,17 @@ public: : m_tagName(token.name().data(), token.name().size()) , m_linkIsStyleSheet(false) , m_linkMediaAttributeIsScreen(true) + , m_inputIsImage(false) { processAttributes(token.attributes()); } void processAttributes(const HTMLToken::AttributeList& attributes) { - if (m_tagName != scriptTag && m_tagName != imgTag && m_tagName != linkTag) + if (m_tagName != imgTag + && m_tagName != inputTag + && m_tagName != linkTag + && m_tagName != scriptTag) return; for (HTMLToken::AttributeList::const_iterator iter = attributes.begin(); @@ -77,6 +82,11 @@ public: m_linkIsStyleSheet = relAttributeIsStyleSheet(attributeValue); else if (attributeName == mediaAttr) m_linkMediaAttributeIsScreen = linkMediaAttributeIsScreen(attributeValue); + } else if (m_tagName == inputTag) { + if (attributeName == srcAttr) + setUrlToLoad(attributeValue); + else if (attributeName == typeAttr) + m_inputIsImage = equalIgnoringCase(attributeValue, InputTypeNames::image()); } } } @@ -87,7 +97,7 @@ public: HTMLLinkElement::tokenizeRelAttribute(attributeValue, rel); return rel.m_isStyleSheet && !rel.m_isAlternate && !rel.m_isIcon && !rel.m_isDNSPrefetch; } - + static bool linkMediaAttributeIsScreen(const String& attributeValue) { if (attributeValue.isEmpty()) @@ -118,7 +128,7 @@ public: CachedResourceLoader* cachedResourceLoader = document->cachedResourceLoader(); if (m_tagName == scriptTag) cachedResourceLoader->preload(CachedResource::Script, m_urlToLoad, m_charset, scanningBody); - else if (m_tagName == imgTag) + else if (m_tagName == imgTag || (m_tagName == inputTag && m_inputIsImage)) cachedResourceLoader->preload(CachedResource::ImageResource, m_urlToLoad, String(), scanningBody); else if (m_tagName == linkTag && m_linkIsStyleSheet && m_linkMediaAttributeIsScreen) cachedResourceLoader->preload(CachedResource::CSSStyleSheet, m_urlToLoad, m_charset, scanningBody); @@ -132,6 +142,7 @@ private: String m_charset; bool m_linkIsStyleSheet; bool m_linkMediaAttributeIsScreen; + bool m_inputIsImage; }; } // namespace diff --git a/Source/WebCore/html/parser/HTMLScriptRunnerHost.h b/Source/WebCore/html/parser/HTMLScriptRunnerHost.h index 5b40a931..454bc6f 100644 --- a/Source/WebCore/html/parser/HTMLScriptRunnerHost.h +++ b/Source/WebCore/html/parser/HTMLScriptRunnerHost.h @@ -44,8 +44,6 @@ public: // Implementors must call cachedResource->removeClient() immediately. virtual void stopWatchingForLoad(CachedResource*) = 0; - // Implementors can block certain script loads (for XSSAuditor, etc.) - virtual bool shouldLoadExternalScriptFromSrc(const AtomicString&) = 0; virtual HTMLInputStream& inputStream() = 0; }; diff --git a/Source/WebCore/html/parser/HTMLToken.h b/Source/WebCore/html/parser/HTMLToken.h index aa16ab2..49ec312 100644 --- a/Source/WebCore/html/parser/HTMLToken.h +++ b/Source/WebCore/html/parser/HTMLToken.h @@ -398,27 +398,7 @@ public: case HTMLToken::EndTag: { m_selfClosing = token.selfClosing(); m_name = AtomicString(token.name().data(), token.name().size()); - const HTMLToken::AttributeList& attributes = token.attributes(); - for (HTMLToken::AttributeList::const_iterator iter = attributes.begin(); - iter != attributes.end(); ++iter) { - if (!iter->m_name.isEmpty()) { - String name(iter->m_name.data(), iter->m_name.size()); - String value(iter->m_value.data(), iter->m_value.size()); - ASSERT(iter->m_nameRange.m_start); - ASSERT(iter->m_nameRange.m_end); - ASSERT(iter->m_valueRange.m_start); - ASSERT(iter->m_valueRange.m_end); - RefPtr mappedAttribute = Attribute::createMapped(name, value); - if (!m_attributes) { - m_attributes = NamedNodeMap::create(); - // Reserving capacity here improves the parser - // benchmark. It might be worth experimenting with - // the constant to see where the optimal point is. - m_attributes->reserveInitialCapacity(10); - } - m_attributes->insertAttribute(mappedAttribute.release(), false); - } - } + initializeAttributes(token.attributes()); break; } case HTMLToken::Comment: @@ -513,6 +493,8 @@ public: private: HTMLToken::Type m_type; + void initializeAttributes(const HTMLToken::AttributeList& attributes); + bool usesName() const { return m_type == HTMLToken::StartTag || m_type == HTMLToken::EndTag || m_type == HTMLToken::DOCTYPE; @@ -548,6 +530,30 @@ private: RefPtr m_attributes; }; +inline void AtomicHTMLToken::initializeAttributes(const HTMLToken::AttributeList& attributes) +{ + size_t size = attributes.size(); + if (!size) + return; + + m_attributes = NamedNodeMap::create(); + m_attributes->reserveInitialCapacity(size); + for (size_t i = 0; i < size; ++i) { + const HTMLToken::Attribute& attribute = attributes[i]; + if (attribute.m_name.isEmpty()) + continue; + + ASSERT(attribute.m_nameRange.m_start); + ASSERT(attribute.m_nameRange.m_end); + ASSERT(attribute.m_valueRange.m_start); + ASSERT(attribute.m_valueRange.m_end); + + String name(attribute.m_name.data(), attribute.m_name.size()); + String value(attribute.m_value.data(), attribute.m_value.size()); + m_attributes->insertAttribute(Attribute::createMapped(name, value), false); + } +} + } #endif diff --git a/Source/WebCore/html/parser/HTMLTreeBuilder.cpp b/Source/WebCore/html/parser/HTMLTreeBuilder.cpp index 8f9e3e1..6db09de 100644 --- a/Source/WebCore/html/parser/HTMLTreeBuilder.cpp +++ b/Source/WebCore/html/parser/HTMLTreeBuilder.cpp @@ -125,7 +125,7 @@ bool isSpecialNode(Node* node) return true; if (node->nodeType() == Node::DOCUMENT_FRAGMENT_NODE) return true; - if (node->namespaceURI() != xhtmlNamespaceURI) + if (!isInHTMLNamespace(node)) return false; const AtomicString& tagName = node->localName(); return tagName == addressTag @@ -445,7 +445,7 @@ void HTMLTreeBuilder::constructTreeFromAtomicToken(AtomicHTMLToken& token) // the U+0000 characters into replacement characters has compatibility // problems. m_parser->tokenizer()->setForceNullCharacterReplacement(m_insertionMode == TextMode || m_insertionMode == InForeignContentMode); - m_parser->tokenizer()->setShouldAllowCDATA(m_insertionMode == InForeignContentMode && m_tree.currentNode()->namespaceURI() != xhtmlNamespaceURI); + m_parser->tokenizer()->setShouldAllowCDATA(m_insertionMode == InForeignContentMode && !isInHTMLNamespace(m_tree.currentNode())); } void HTMLTreeBuilder::processToken(AtomicHTMLToken& token) @@ -984,7 +984,7 @@ void HTMLTreeBuilder::processStartTagForInBody(AtomicHTMLToken& token) adjustMathMLAttributes(token); adjustForeignAttributes(token); m_tree.insertForeignElement(token, MathMLNames::mathmlNamespaceURI); - if (m_insertionMode != InForeignContentMode) + if (m_insertionMode != InForeignContentMode && !token.selfClosing()) setInsertionMode(InForeignContentMode); return; } @@ -993,7 +993,7 @@ void HTMLTreeBuilder::processStartTagForInBody(AtomicHTMLToken& token) adjustSVGAttributes(token); adjustForeignAttributes(token); m_tree.insertForeignElement(token, SVGNames::svgNamespaceURI); - if (m_insertionMode != InForeignContentMode) + if (m_insertionMode != InForeignContentMode && !token.selfClosing()) setInsertionMode(InForeignContentMode); return; } @@ -1125,7 +1125,7 @@ bool shouldProcessForeignContentUsingInBodyInsertionMode(AtomicHTMLToken& token, || currentElement->hasTagName(SVGNames::descTag) || currentElement->hasTagName(SVGNames::titleTag)) return true; - return currentElement->namespaceURI() == HTMLNames::xhtmlNamespaceURI; + return isInHTMLNamespace(currentElement); } } @@ -1451,7 +1451,7 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken& token) processStartTag(token); break; case InForeignContentMode: { - if (shouldProcessForeignContentUsingInBodyInsertionMode(token, m_tree.currentElement())) { + if (shouldProcessForeignContentUsingInBodyInsertionMode(token, m_tree.currentNode())) { processForeignContentUsingInBodyModeAndResetMode(token); return; } @@ -2297,7 +2297,7 @@ void HTMLTreeBuilder::processEndTag(AtomicHTMLToken& token) notImplemented(); return; } - if (m_tree.currentNode()->namespaceURI() != xhtmlNamespaceURI) { + if (!isInHTMLNamespace(m_tree.currentNode())) { // FIXME: This code just wants an Element* iterator, instead of an ElementRecord* HTMLElementStack::ElementRecord* nodeRecord = m_tree.openElements()->topRecord(); if (!nodeRecord->node()->hasLocalName(token.name())) @@ -2310,12 +2310,7 @@ void HTMLTreeBuilder::processEndTag(AtomicHTMLToken& token) } nodeRecord = nodeRecord->next(); - if (nodeRecord->node()->nodeType() == Node::DOCUMENT_FRAGMENT_NODE) { - ASSERT(isParsingFragment()); - break; - } - - if (nodeRecord->node()->namespaceURI() == xhtmlNamespaceURI) + if (isInHTMLNamespace(nodeRecord->node())) break; } } diff --git a/Source/WebCore/html/shadow/MediaControls.cpp b/Source/WebCore/html/shadow/MediaControls.cpp index 61a3684..20f1abb 100644 --- a/Source/WebCore/html/shadow/MediaControls.cpp +++ b/Source/WebCore/html/shadow/MediaControls.cpp @@ -52,12 +52,10 @@ namespace WebCore { using namespace HTMLNames; -static const double cTimeUpdateRepeatDelay = 0.2; static const double cOpacityAnimationRepeatDelay = 0.05; MediaControls::MediaControls(HTMLMediaElement* mediaElement) : m_mediaElement(mediaElement) - , m_timeUpdateTimer(this, &MediaControls::timeUpdateTimerFired) , m_opacityAnimationTimer(this, &MediaControls::opacityAnimationTimerFired) , m_opacityAnimationStartTime(0) , m_opacityAnimationDuration(0) @@ -70,6 +68,137 @@ MediaControls::MediaControls(HTMLMediaElement* mediaElement) { } +// FIXME: This will turn into the standard element factory method once shadow DOM conversion is complete. +// (see https://bugs.webkit.org/show_bug.cgi?id=53020) +PassRefPtr MediaControls::create(HTMLMediaElement* mediaElement) +{ + ASSERT(!m_panel); + ASSERT(!m_muteButton); + ASSERT(!m_playButton); + ASSERT(!m_returnToRealtimeButton); + ASSERT(!m_statusDisplay); + ASSERT(!m_timelineContainer); + ASSERT(!m_currentTimeDisplay); + ASSERT(!m_timeline); + ASSERT(!m_timeRemainingDisplay); + ASSERT(!m_seekBackButton); + ASSERT(!m_seekForwardButton); + ASSERT(!m_toggleClosedCaptionsButton); + ASSERT(!m_fullscreenButton); + ASSERT(!m_muteButton); + ASSERT(!m_volumeSliderContainer); + ASSERT(!m_volumeSlider); + ASSERT(!m_volumeSliderMuteButton); + ASSERT(!m_fullScreenMinVolumeButton); + ASSERT(!m_fullScreenMaxVolumeButton); + ASSERT(!m_fullScreenVolumeSlider); + + RefPtr controls = MediaControlShadowRootElement::create(mediaElement); + + m_panel = MediaControlPanelElement::create(mediaElement); + + m_rewindButton = MediaControlRewindButtonElement::create(mediaElement); + m_rewindButton->attachToParent(m_panel.get()); + + m_playButton = MediaControlPlayButtonElement::create(mediaElement); + m_playButton->attachToParent(m_panel.get()); + + m_returnToRealtimeButton = MediaControlReturnToRealtimeButtonElement::create(mediaElement); + m_returnToRealtimeButton->attachToParent(m_panel.get()); + + m_statusDisplay = MediaControlStatusDisplayElement::create(mediaElement); + m_statusDisplay->attachToParent(m_panel.get()); + + m_timelineContainer = MediaControlTimelineContainerElement::create(mediaElement); + + m_currentTimeDisplay = MediaControlCurrentTimeDisplayElement::create(mediaElement); + m_currentTimeDisplay->attachToParent(m_timelineContainer.get()); + + m_timeline = MediaControlTimelineElement::create(mediaElement); + m_timeline->attachToParent(m_timelineContainer.get()); + + m_timeRemainingDisplay = MediaControlTimeRemainingDisplayElement::create(mediaElement); + m_timeRemainingDisplay->attachToParent(m_timelineContainer.get()); + + m_timelineContainer->attachToParent(m_panel.get()); + + m_seekBackButton = MediaControlSeekBackButtonElement::create(mediaElement); + m_seekBackButton->attachToParent(m_panel.get()); + + m_seekForwardButton = MediaControlSeekForwardButtonElement::create(mediaElement); + m_seekForwardButton->attachToParent(m_panel.get()); + + m_toggleClosedCaptionsButton = MediaControlToggleClosedCaptionsButtonElement::create(mediaElement); + m_toggleClosedCaptionsButton->attachToParent(m_panel.get()); + + m_fullscreenButton = MediaControlFullscreenButtonElement::create(mediaElement); + m_fullscreenButton->attachToParent(m_panel.get()); + + m_muteButton = MediaControlPanelMuteButtonElement::create(mediaElement); + m_muteButton->attachToParent(m_panel.get()); + + m_volumeSliderContainer = MediaControlVolumeSliderContainerElement::create(mediaElement); + + m_volumeSlider = MediaControlVolumeSliderElement::create(mediaElement); + m_volumeSlider->attachToParent(m_volumeSliderContainer.get()); + + m_volumeSliderMuteButton = MediaControlVolumeSliderMuteButtonElement::create(mediaElement); + m_volumeSliderMuteButton->attachToParent(m_volumeSliderContainer.get()); + + m_volumeSliderContainer->attachToParent(m_panel.get()); + + // FIXME: These controls, and others, should be created dynamically when needed, instead of + // always created. + m_fullScreenMinVolumeButton = MediaControlFullscreenVolumeMinButtonElement::create(mediaElement); + m_fullScreenMinVolumeButton->attachToParent(m_panel.get()); + + m_fullScreenVolumeSlider = MediaControlFullscreenVolumeSliderElement::create(mediaElement); + m_fullScreenVolumeSlider->attachToParent(m_panel.get()); + + m_fullScreenMaxVolumeButton = MediaControlFullscreenVolumeMaxButtonElement::create(mediaElement); + m_fullScreenMaxVolumeButton->attachToParent(m_panel.get()); + + m_panel->attachToParent(controls.get()); + return controls.release(); +} + +void MediaControls::reset() +{ + update(); +} + +void MediaControls::playbackProgressed() +{ + if (m_timeline) + m_timeline->update(false); + updateTimeDisplay(); +} + +void MediaControls::playbackStarted() +{ + playbackProgressed(); +} + +void MediaControls::playbackStopped() +{ + playbackProgressed(); +} + +void MediaControls::changedMute() +{ + update(); +} + +void MediaControls::changedVolume() +{ + update(); +} + +void MediaControls::changedClosedCaptionsVisibility() +{ + update(); +} + void MediaControls::updateStyle() { if (!m_controlsShadowRoot) @@ -109,6 +238,12 @@ void MediaControls::updateStyle() m_volumeSliderMuteButton->updateStyle(); if (m_volumeSlider) m_volumeSlider->updateStyle(); + if (m_fullScreenMinVolumeButton) + m_fullScreenMinVolumeButton->updateStyle(); + if (m_fullScreenVolumeSlider) + m_fullScreenVolumeSlider->updateStyle(); + if (m_fullScreenMaxVolumeButton) + m_fullScreenMaxVolumeButton->updateStyle(); } void MediaControls::destroy() @@ -151,46 +286,19 @@ void MediaControls::update() m_volumeSliderMuteButton = 0; m_controlsShadowRoot = 0; m_toggleClosedCaptionsButton = 0; + m_fullScreenMinVolumeButton = 0; + m_fullScreenVolumeSlider = 0; + m_fullScreenMaxVolumeButton = 0; } m_opacityAnimationTo = 1.0f; m_opacityAnimationTimer.stop(); - m_timeUpdateTimer.stop(); return; } if (!m_controlsShadowRoot) { - createControlsShadowRoot(); - createPanel(); - if (m_panel) { - createRewindButton(); - createPlayButton(); - createReturnToRealtimeButton(); - createStatusDisplay(); - createTimelineContainer(); - if (m_timelineContainer) { - createCurrentTimeDisplay(); - createTimeline(); - createTimeRemainingDisplay(); - } - createSeekBackButton(); - createSeekForwardButton(); - createToggleClosedCaptionsButton(); - createFullscreenButton(); - createMuteButton(); - createVolumeSliderContainer(); - if (m_volumeSliderContainer) { - createVolumeSlider(); - createVolumeSliderMuteButton(); - } - m_panel->attach(); - } - } - - if (media->canPlay()) { - if (m_timeUpdateTimer.isActive()) - m_timeUpdateTimer.stop(); - } else if (media->renderer()->style()->visibility() == VISIBLE && m_timeline && m_timeline->renderer() && m_timeline->renderer()->style()->display() != NONE) { - m_timeUpdateTimer.startRepeating(cTimeUpdateRepeatDelay); + m_controlsShadowRoot = create(m_mediaElement); + m_mediaElement->renderer()->addChild(m_controlsShadowRoot->renderer()); + m_panel->attach(); } if (m_panel) { @@ -232,148 +340,16 @@ void MediaControls::update() m_volumeSlider->update(); if (m_volumeSliderMuteButton) m_volumeSliderMuteButton->update(); - + if (m_fullScreenMinVolumeButton) + m_fullScreenMinVolumeButton->update(); + if (m_fullScreenVolumeSlider) + m_fullScreenVolumeSlider->update(); + if (m_fullScreenMaxVolumeButton) + m_fullScreenMaxVolumeButton->update(); updateTimeDisplay(); updateControlVisibility(); } -void MediaControls::createControlsShadowRoot() -{ - ASSERT(!m_controlsShadowRoot); - m_controlsShadowRoot = MediaControlShadowRootElement::create(m_mediaElement); - m_mediaElement->renderer()->addChild(m_controlsShadowRoot->renderer()); -} - -void MediaControls::createPanel() -{ - ASSERT(!m_panel); - m_panel = MediaControlPanelElement::create(m_mediaElement); - m_panel->attachToParent(m_controlsShadowRoot.get()); -} - -void MediaControls::createMuteButton() -{ - ASSERT(!m_muteButton); - m_muteButton = MediaControlPanelMuteButtonElement::create(m_mediaElement); - m_muteButton->attachToParent(m_panel.get()); -} - -void MediaControls::createPlayButton() -{ - ASSERT(!m_playButton); - m_playButton = MediaControlPlayButtonElement::create(m_mediaElement); - m_playButton->attachToParent(m_panel.get()); -} - -void MediaControls::createSeekBackButton() -{ - ASSERT(!m_seekBackButton); - m_seekBackButton = MediaControlSeekBackButtonElement::create(m_mediaElement); - m_seekBackButton->attachToParent(m_panel.get()); -} - -void MediaControls::createSeekForwardButton() -{ - ASSERT(!m_seekForwardButton); - m_seekForwardButton = MediaControlSeekForwardButtonElement::create(m_mediaElement); - m_seekForwardButton->attachToParent(m_panel.get()); -} - -void MediaControls::createRewindButton() -{ - ASSERT(!m_rewindButton); - m_rewindButton = MediaControlRewindButtonElement::create(m_mediaElement); - m_rewindButton->attachToParent(m_panel.get()); -} - -void MediaControls::createReturnToRealtimeButton() -{ - ASSERT(!m_returnToRealtimeButton); - m_returnToRealtimeButton = MediaControlReturnToRealtimeButtonElement::create(m_mediaElement); - m_returnToRealtimeButton->attachToParent(m_panel.get()); -} - -void MediaControls::createToggleClosedCaptionsButton() -{ - ASSERT(!m_toggleClosedCaptionsButton); - m_toggleClosedCaptionsButton = MediaControlToggleClosedCaptionsButtonElement::create(m_mediaElement); - m_toggleClosedCaptionsButton->attachToParent(m_panel.get()); -} - -void MediaControls::createStatusDisplay() -{ - ASSERT(!m_statusDisplay); - m_statusDisplay = MediaControlStatusDisplayElement::create(m_mediaElement); - m_statusDisplay->attachToParent(m_panel.get()); -} - -void MediaControls::createTimelineContainer() -{ - ASSERT(!m_timelineContainer); - m_timelineContainer = MediaControlTimelineContainerElement::create(m_mediaElement); - m_timelineContainer->attachToParent(m_panel.get()); -} - -void MediaControls::createTimeline() -{ - ASSERT(!m_timeline); - m_timeline = MediaControlTimelineElement::create(m_mediaElement); - m_timeline->setAttribute(precisionAttr, "float"); - m_timeline->attachToParent(m_timelineContainer.get()); -} - -void MediaControls::createVolumeSliderContainer() -{ - ASSERT(!m_volumeSliderContainer); - m_volumeSliderContainer = MediaControlVolumeSliderContainerElement::create(m_mediaElement); - m_volumeSliderContainer->attachToParent(m_panel.get()); -} - -void MediaControls::createVolumeSlider() -{ - ASSERT(!m_volumeSlider); - m_volumeSlider = MediaControlVolumeSliderElement::create(m_mediaElement); - m_volumeSlider->setAttribute(precisionAttr, "float"); - m_volumeSlider->setAttribute(maxAttr, "1"); - m_volumeSlider->setAttribute(valueAttr, String::number(m_mediaElement->volume())); - m_volumeSlider->attachToParent(m_volumeSliderContainer.get()); -} - -void MediaControls::createVolumeSliderMuteButton() -{ - ASSERT(!m_volumeSliderMuteButton); - m_volumeSliderMuteButton = MediaControlVolumeSliderMuteButtonElement::create(m_mediaElement); - m_volumeSliderMuteButton->attachToParent(m_volumeSliderContainer.get()); -} - -void MediaControls::createCurrentTimeDisplay() -{ - ASSERT(!m_currentTimeDisplay); - m_currentTimeDisplay = MediaControlCurrentTimeDisplayElement::create(m_mediaElement); - m_currentTimeDisplay->attachToParent(m_timelineContainer.get()); -} - -void MediaControls::createTimeRemainingDisplay() -{ - ASSERT(!m_timeRemainingDisplay); - m_timeRemainingDisplay = MediaControlTimeRemainingDisplayElement::create(m_mediaElement); - m_timeRemainingDisplay->attachToParent(m_timelineContainer.get()); -} - -void MediaControls::createFullscreenButton() -{ - ASSERT(!m_fullscreenButton); - m_fullscreenButton = MediaControlFullscreenButtonElement::create(m_mediaElement); - m_fullscreenButton->attachToParent(m_panel.get()); -} - -void MediaControls::timeUpdateTimerFired(Timer*) -{ - if (m_timeline) - m_timeline->update(false); - updateTimeDisplay(); -} - void MediaControls::updateTimeDisplay() { ASSERT(m_mediaElement->renderer()); @@ -480,13 +456,6 @@ void MediaControls::updateVolumeSliderContainer(bool visible) return; RefPtr s = m_volumeSliderContainer->styleForElement(); - int height = s->height().isPercent() ? 0 : s->height().value(); - int width = s->width().isPercent() ? 0 : s->width().value(); - IntPoint offset = m_mediaElement->document()->page()->theme()->volumeSliderOffsetFromMuteButton(m_muteButton->renderBox(), IntSize(width, height)); - int x = offset.x() + m_muteButton->renderBox()->offsetLeft(); - int y = offset.y() + m_muteButton->renderBox()->offsetTop(); - - m_volumeSliderContainer->setPosition(x, y); m_volumeSliderContainer->setVisible(true); m_volumeSliderContainer->update(); m_volumeSlider->update(); @@ -588,6 +557,7 @@ void MediaControls::forwardEvent(Event* event) #endif } +<<<<<<< HEAD // We want the timeline slider to be at least 100 pixels wide. static const int minWidthToDisplayTimeDisplays = 16 + 16 + 45 + 100 + 45 + 16 + 1; @@ -612,6 +582,8 @@ void MediaControls::updateLastTouch() } #endif +======= +>>>>>>> webkit.org at r82507 } #endif diff --git a/Source/WebCore/html/shadow/MediaControls.h b/Source/WebCore/html/shadow/MediaControls.h index a4fbbd6..726573e 100644 --- a/Source/WebCore/html/shadow/MediaControls.h +++ b/Source/WebCore/html/shadow/MediaControls.h @@ -53,6 +53,9 @@ class MediaControlStatusDisplayElement; class MediaControlTimelineContainerElement; class MediaControlVolumeSliderContainerElement; class MediaControlElement; +class MediaControlFullscreenVolumeMinButtonElement; +class MediaControlFullscreenVolumeSliderElement; +class MediaControlFullscreenVolumeMaxButtonElement; class MediaPlayer; class RenderBox; @@ -62,12 +65,21 @@ class MediaControls { public: MediaControls(HTMLMediaElement*); + void reset(); + + void playbackProgressed(); + void playbackStarted(); + void playbackStopped(); + + void changedMute(); + void changedVolume(); + void changedClosedCaptionsVisibility(); + void destroy(); void update(); void updateStyle(); void forwardEvent(Event*); void updateTimeDisplay(); - void updateTimeDisplayVisibility(); // FIXME: This is temporary to allow RenderMedia::layout tweak the position of controls. // Once shadow DOM refactoring is complete, the tweaking will be in MediaControlsShadowRoot and this accessor will no longer be necessary. @@ -78,27 +90,7 @@ public: #endif private: - void createControlsShadowRoot(); - void destroyControlsShadowRoot(); - void createPanel(); - void createMuteButton(); - void createPlayButton(); - void createSeekBackButton(); - void createSeekForwardButton(); - void createRewindButton(); - void createReturnToRealtimeButton(); - void createToggleClosedCaptionsButton(); - void createStatusDisplay(); - void createTimelineContainer(); - void createTimeline(); - void createVolumeSliderContainer(); - void createVolumeSlider(); - void createVolumeSliderMuteButton(); - void createCurrentTimeDisplay(); - void createTimeRemainingDisplay(); - void createFullscreenButton(); - - void timeUpdateTimerFired(Timer*); + PassRefPtr create(HTMLMediaElement*); void updateControlVisibility(); void changeOpacity(HTMLElement*, float opacity); @@ -125,9 +117,11 @@ private: RefPtr m_currentTimeDisplay; RefPtr m_timeRemainingDisplay; RefPtr m_statusDisplay; + RefPtr m_fullScreenMinVolumeButton; + RefPtr m_fullScreenVolumeSlider; + RefPtr m_fullScreenMaxVolumeButton; HTMLMediaElement* m_mediaElement; - Timer m_timeUpdateTimer; Timer m_opacityAnimationTimer; double m_opacityAnimationStartTime; diff --git a/Source/WebCore/html/shadow/SliderThumbElement.cpp b/Source/WebCore/html/shadow/SliderThumbElement.cpp index 2c049cb..d1aa15e 100644 --- a/Source/WebCore/html/shadow/SliderThumbElement.cpp +++ b/Source/WebCore/html/shadow/SliderThumbElement.cpp @@ -56,6 +56,8 @@ namespace WebCore { class RenderSliderThumb : public RenderBlock { public: RenderSliderThumb(Node*); + +private: virtual void layout(); }; @@ -85,6 +87,16 @@ void RenderSliderThumb::layout() RenderBlock::layout(); } +void SliderThumbElement::setPositionFromValue() +{ + // Since today the code to calculate position is in the RenderSlider layout + // path, we don't actually update the value here. Instead, we poke at the + // renderer directly to trigger layout. + // FIXME: Move the logic of positioning the thumb here. + if (renderer()) + renderer()->setNeedsLayout(true); +} + RenderObject* SliderThumbElement::createRenderer(RenderArena* arena, RenderStyle*) { return new (arena) RenderSliderThumb(this); @@ -92,11 +104,11 @@ RenderObject* SliderThumbElement::createRenderer(RenderArena* arena, RenderStyle void SliderThumbElement::dragFrom(const IntPoint& point) { - setPosition(point); + setPositionFromPoint(point); startDragging(); } -void SliderThumbElement::setPosition(const IntPoint& point) +void SliderThumbElement::setPositionFromPoint(const IntPoint& point) { HTMLInputElement* input = static_cast(shadowHost()); ASSERT(input); @@ -212,6 +224,7 @@ void SliderThumbElement::defaultEventHandler(Event* event) #endif ) { if (m_inDragMode) +<<<<<<< HEAD #if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS) { if (event->isMouseEvent()) { @@ -233,6 +246,9 @@ void SliderThumbElement::defaultEventHandler(Event* event) } #endif +======= + setPositionFromPoint(mouseEvent->absoluteLocation()); +>>>>>>> webkit.org at r82507 return; } diff --git a/Source/WebCore/html/shadow/SliderThumbElement.h b/Source/WebCore/html/shadow/SliderThumbElement.h index 7c4c179..9414ac4 100644 --- a/Source/WebCore/html/shadow/SliderThumbElement.h +++ b/Source/WebCore/html/shadow/SliderThumbElement.h @@ -49,6 +49,7 @@ public: static PassRefPtr create(Document*); bool inDragMode() const { return m_inDragMode; } + void setPositionFromValue(); void dragFrom(const IntPoint&); virtual void defaultEventHandler(Event*); @@ -60,7 +61,7 @@ private: virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); void startDragging(); void stopDragging(); - void setPosition(const IntPoint&); + void setPositionFromPoint(const IntPoint&); FloatPoint m_offsetToThumb; bool m_inDragMode; -- cgit v1.1