summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/html
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2011-05-25 19:08:45 +0100
committerSteve Block <steveblock@google.com>2011-06-08 13:51:31 +0100
commit2bde8e466a4451c7319e3a072d118917957d6554 (patch)
tree28f4a1b869a513e565c7760d0e6a06e7cf1fe95a /Source/WebCore/html
parent6939c99b71d9372d14a0c74a772108052e8c48c8 (diff)
downloadexternal_webkit-2bde8e466a4451c7319e3a072d118917957d6554.zip
external_webkit-2bde8e466a4451c7319e3a072d118917957d6554.tar.gz
external_webkit-2bde8e466a4451c7319e3a072d118917957d6554.tar.bz2
Merge WebKit at r82507: Initial merge by git
Change-Id: I60ce9d780725b58b45e54165733a8ffee23b683e
Diffstat (limited to 'Source/WebCore/html')
-rw-r--r--Source/WebCore/html/CollectionCache.h2
-rw-r--r--Source/WebCore/html/FormAssociatedElement.cpp2
-rw-r--r--Source/WebCore/html/HTMLAnchorElement.cpp10
-rw-r--r--Source/WebCore/html/HTMLAnchorElement.idl1
-rw-r--r--Source/WebCore/html/HTMLAreaElement.cpp2
-rw-r--r--Source/WebCore/html/HTMLAreaElement.idl1
-rw-r--r--Source/WebCore/html/HTMLAttributeNames.in1
-rw-r--r--Source/WebCore/html/HTMLBodyElement.cpp2
-rw-r--r--Source/WebCore/html/HTMLCanvasElement.cpp68
-rw-r--r--Source/WebCore/html/HTMLCanvasElement.h5
-rw-r--r--Source/WebCore/html/HTMLCollection.cpp2
-rw-r--r--Source/WebCore/html/HTMLDetailsElement.cpp91
-rw-r--r--Source/WebCore/html/HTMLDetailsElement.h14
-rw-r--r--Source/WebCore/html/HTMLElement.cpp37
-rw-r--r--Source/WebCore/html/HTMLElement.h5
-rw-r--r--Source/WebCore/html/HTMLEmbedElement.cpp10
-rw-r--r--Source/WebCore/html/HTMLFormControlElement.cpp17
-rw-r--r--Source/WebCore/html/HTMLFormControlElement.h7
-rw-r--r--Source/WebCore/html/HTMLFormElement.cpp7
-rw-r--r--Source/WebCore/html/HTMLFrameElementBase.cpp7
-rw-r--r--Source/WebCore/html/HTMLFrameElementBase.h3
-rw-r--r--Source/WebCore/html/HTMLFrameSetElement.cpp30
-rw-r--r--Source/WebCore/html/HTMLFrameSetElement.h10
-rw-r--r--Source/WebCore/html/HTMLInputElement.cpp19
-rw-r--r--Source/WebCore/html/HTMLInputElement.h4
-rw-r--r--Source/WebCore/html/HTMLLinkElement.cpp39
-rw-r--r--Source/WebCore/html/HTMLLinkElement.h1
-rw-r--r--Source/WebCore/html/HTMLMediaElement.cpp70
-rw-r--r--Source/WebCore/html/HTMLMediaElement.h12
-rw-r--r--Source/WebCore/html/HTMLObjectElement.cpp11
-rw-r--r--Source/WebCore/html/HTMLPlugInElement.cpp2
-rw-r--r--Source/WebCore/html/HTMLPlugInImageElement.cpp10
-rw-r--r--Source/WebCore/html/HTMLPlugInImageElement.h11
-rw-r--r--Source/WebCore/html/HTMLScriptElement.cpp18
-rw-r--r--Source/WebCore/html/HTMLScriptElement.h4
-rw-r--r--Source/WebCore/html/HTMLScriptElement.idl2
-rw-r--r--Source/WebCore/html/HTMLSelectElement.cpp5
-rw-r--r--Source/WebCore/html/HTMLSummaryElement.cpp7
-rw-r--r--Source/WebCore/html/HTMLSummaryElement.h2
-rw-r--r--Source/WebCore/html/HTMLTextAreaElement.cpp9
-rw-r--r--Source/WebCore/html/HTMLTextAreaElement.h4
-rw-r--r--Source/WebCore/html/HTMLTitleElement.cpp9
-rw-r--r--Source/WebCore/html/NumberInputType.cpp5
-rw-r--r--Source/WebCore/html/RangeInputType.cpp2
-rw-r--r--Source/WebCore/html/ValidationMessage.cpp21
-rw-r--r--Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp2
-rw-r--r--Source/WebCore/html/canvas/WebGLContextAttributes.cpp10
-rw-r--r--Source/WebCore/html/canvas/WebGLContextAttributes.h5
-rw-r--r--Source/WebCore/html/canvas/WebGLContextAttributes.idl1
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderingContext.cpp122
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderingContext.h14
-rw-r--r--Source/WebCore/html/parser/HTMLDocumentParser.cpp14
-rw-r--r--Source/WebCore/html/parser/HTMLDocumentParser.h1
-rw-r--r--Source/WebCore/html/parser/HTMLElementStack.cpp44
-rw-r--r--Source/WebCore/html/parser/HTMLElementStack.h10
-rw-r--r--Source/WebCore/html/parser/HTMLParserScheduler.cpp10
-rw-r--r--Source/WebCore/html/parser/HTMLParserScheduler.h1
-rw-r--r--Source/WebCore/html/parser/HTMLPreloadScanner.cpp17
-rw-r--r--Source/WebCore/html/parser/HTMLScriptRunnerHost.h2
-rw-r--r--Source/WebCore/html/parser/HTMLToken.h48
-rw-r--r--Source/WebCore/html/parser/HTMLTreeBuilder.cpp21
-rw-r--r--Source/WebCore/html/shadow/MediaControls.cpp332
-rw-r--r--Source/WebCore/html/shadow/MediaControls.h40
-rw-r--r--Source/WebCore/html/shadow/SliderThumbElement.cpp20
-rw-r--r--Source/WebCore/html/shadow/SliderThumbElement.h3
65 files changed, 890 insertions, 428 deletions
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<AtomicStringImpl*, Vector<Element*>*> 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<MouseEvent*>(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<HTMLMapElement*>(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<WebGLRenderingContext*>(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> imageData = getImageData();
+
+ if (imageData)
+ return ImageDataToDataURL(*imageData, lowercaseMimeType, quality);
+#endif
+
+ makeRenderingResultsAvailable();
+
return buffer()->toDataURL(lowercaseMimeType, quality);
}
+PassRefPtr<ImageData> HTMLCanvasElement::getImageData()
+{
+ if (!m_context || !m_context->is3d())
+ return 0;
+
+#if ENABLE(WEBGL)
+ WebGLRenderingContext* ctx = static_cast<WebGLRenderingContext*>(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<ImageData> 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<ImageBuffer> m_imageBuffer;
+ mutable RefPtr<Image> m_presentedImage;
mutable RefPtr<Image> 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<HTMLDocument*>(m_base->document())->domTreeVersion();
+ uint64_t docversion = static_cast<HTMLDocument*>(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> 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 <summary> 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<MouseEvent*>(event);
+ if (mouseEvent->button() != LeftButton)
+ return;
+
+ RenderDetails* renderDetails = static_cast<RenderDetails*>(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<HTMLDetailsElement> 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<HTMLDocument*>(document())->addNamedItem(m_name);
@@ -233,8 +237,6 @@ void HTMLEmbedElement::insertedIntoDocument()
static_cast<HTMLObjectElement*>(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<int>::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<Range> 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<RefPtr<FormAssociatedElement> > 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<HTMLFormElement> 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<HTMLFrameSetElement*>(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<MouseEvent*>(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<HTMLFrameSetElement> 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<Document> 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<Document> 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<HTMLLinkElement>* 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<HTMLLinkElement>*);
#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<HTMLMediaElement>*)
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<HTMLMediaElement>*)
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<HTMLMediaElement> m_loadTimer;
Timer<HTMLMediaElement> m_asyncEventTimer;
Timer<HTMLMediaElement> 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<String>& paramNames, Vector<S
// if we know that resource points to a plug-in.
if (url.isEmpty() && !urlParameter.isEmpty()) {
SubframeLoader* loader = document()->frame()->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<HTMLDocument*>(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> 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> 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<double>::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 <wtf/PassOwnPtr.h>
@@ -90,8 +94,13 @@ void ValidationMessage::setMessageDOMAndStartTimer(Timer<ValidationMessage>*)
}
}
- m_timer.set(new Timer<ValidationMessage>(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<ValidationMessage>(this, &ValidationMessage::deleteBubbleTree));
+ m_timer->startOneShot(max(5.0, static_cast<double>(m_message.length()) * magnification / 1000));
+ }
}
class ElementWithPseudoId : public HTMLElement {
@@ -116,6 +125,9 @@ void ValidationMessage::buildBubbleTree(Timer<ValidationMessage>*)
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<ValidationMessage>*)
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<HTMLElement> 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<WebGLContextAttributes> 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<ImageData> 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> 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> 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<ImageData> 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(); // <html> 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(); // <html> 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 <wtf/Forward.h>
#include <wtf/Noncopyable.h>
#include <wtf/OwnPtr.h>
@@ -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<HTMLParserScheduler>
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<Attribute> 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<NamedNodeMap> 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<MediaControlShadowRootElement> 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<MediaControlShadowRootElement> 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. <http://webkit.org/b/57163>
+ 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<MediaControls>*)
-{
- 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<RenderStyle> 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<MediaControls>*);
+ PassRefPtr<MediaControlShadowRootElement> create(HTMLMediaElement*);
void updateControlVisibility();
void changeOpacity(HTMLElement*, float opacity);
@@ -125,9 +117,11 @@ private:
RefPtr<MediaControlTimeDisplayElement> m_currentTimeDisplay;
RefPtr<MediaControlTimeDisplayElement> m_timeRemainingDisplay;
RefPtr<MediaControlStatusDisplayElement> m_statusDisplay;
+ RefPtr<MediaControlFullscreenVolumeMinButtonElement> m_fullScreenMinVolumeButton;
+ RefPtr<MediaControlFullscreenVolumeSliderElement> m_fullScreenVolumeSlider;
+ RefPtr<MediaControlFullscreenVolumeMaxButtonElement> m_fullScreenMaxVolumeButton;
HTMLMediaElement* m_mediaElement;
- Timer<MediaControls> m_timeUpdateTimer;
Timer<MediaControls> 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<HTMLInputElement*>(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<SliderThumbElement> 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;