summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/html
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2011-06-02 12:07:03 +0100
committerBen Murdoch <benm@google.com>2011-06-10 10:47:21 +0100
commit2daae5fd11344eaa88a0d92b0f6d65f8d2255c00 (patch)
treee4964fbd1cb70599f7718ff03e50ea1dab33890b /Source/WebCore/html
parent87bdf0060a247bfbe668342b87e0874182e0ffa9 (diff)
downloadexternal_webkit-2daae5fd11344eaa88a0d92b0f6d65f8d2255c00.zip
external_webkit-2daae5fd11344eaa88a0d92b0f6d65f8d2255c00.tar.gz
external_webkit-2daae5fd11344eaa88a0d92b0f6d65f8d2255c00.tar.bz2
Merge WebKit at r84325: Initial merge by git.
Change-Id: Ic1a909300ecc0a13ddc6b4e784371d2ac6e3d59b
Diffstat (limited to 'Source/WebCore/html')
-rw-r--r--Source/WebCore/html/FormAssociatedElement.h1
-rw-r--r--Source/WebCore/html/HTMLAttributeNames.in5
-rw-r--r--Source/WebCore/html/HTMLCanvasElement.cpp33
-rw-r--r--Source/WebCore/html/HTMLCanvasElement.h6
-rw-r--r--Source/WebCore/html/HTMLDetailsElement.cpp112
-rw-r--r--Source/WebCore/html/HTMLDetailsElement.h14
-rw-r--r--Source/WebCore/html/HTMLElement.cpp43
-rw-r--r--Source/WebCore/html/HTMLElement.h7
-rw-r--r--Source/WebCore/html/HTMLFormControlElement.cpp6
-rw-r--r--Source/WebCore/html/HTMLFormControlElement.h1
-rw-r--r--Source/WebCore/html/HTMLFormElement.cpp70
-rw-r--r--Source/WebCore/html/HTMLFormElement.h5
-rw-r--r--Source/WebCore/html/HTMLFormElement.idl3
-rw-r--r--Source/WebCore/html/HTMLFrameOwnerElement.cpp5
-rw-r--r--Source/WebCore/html/HTMLFrameOwnerElement.h2
-rw-r--r--Source/WebCore/html/HTMLInputElement.cpp15
-rw-r--r--Source/WebCore/html/HTMLInputElement.h1
-rw-r--r--Source/WebCore/html/HTMLKeygenElement.cpp24
-rw-r--r--Source/WebCore/html/HTMLKeygenElement.h3
-rw-r--r--Source/WebCore/html/HTMLLinkElement.cpp36
-rw-r--r--Source/WebCore/html/HTMLLinkElement.h4
-rw-r--r--Source/WebCore/html/HTMLMediaElement.cpp131
-rw-r--r--Source/WebCore/html/HTMLMediaElement.h11
-rw-r--r--Source/WebCore/html/HTMLMeterElement.cpp45
-rw-r--r--Source/WebCore/html/HTMLMeterElement.h14
-rw-r--r--Source/WebCore/html/HTMLObjectElement.cpp16
-rw-r--r--Source/WebCore/html/HTMLObjectElement.h1
-rw-r--r--Source/WebCore/html/HTMLOutputElement.h1
-rw-r--r--Source/WebCore/html/HTMLProgressElement.cpp28
-rw-r--r--Source/WebCore/html/HTMLProgressElement.h10
-rw-r--r--Source/WebCore/html/HTMLSelectElement.h1
-rw-r--r--Source/WebCore/html/HTMLSummaryElement.cpp43
-rw-r--r--Source/WebCore/html/HTMLSummaryElement.h8
-rw-r--r--Source/WebCore/html/HTMLTagNames.in2
-rw-r--r--Source/WebCore/html/HTMLTextAreaElement.cpp16
-rw-r--r--Source/WebCore/html/HTMLTextAreaElement.h1
-rw-r--r--Source/WebCore/html/HTMLTitleElement.cpp16
-rw-r--r--Source/WebCore/html/HTMLTitleElement.h5
-rw-r--r--Source/WebCore/html/HTMLTrackElement.cpp128
-rw-r--r--Source/WebCore/html/HTMLTrackElement.h62
-rw-r--r--Source/WebCore/html/HTMLTrackElement.idl36
-rw-r--r--Source/WebCore/html/HTMLVideoElement.cpp7
-rw-r--r--Source/WebCore/html/HTMLVideoElement.h2
-rw-r--r--Source/WebCore/html/InputType.cpp3
-rw-r--r--Source/WebCore/html/RangeInputType.cpp14
-rw-r--r--Source/WebCore/html/RangeInputType.h7
-rw-r--r--Source/WebCore/html/ValidationMessage.cpp16
-rw-r--r--Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp148
-rw-r--r--Source/WebCore/html/canvas/CanvasRenderingContext2D.h12
-rw-r--r--Source/WebCore/html/canvas/CanvasStyle.cpp6
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderingContext.cpp38
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderingContext.h3
-rw-r--r--Source/WebCore/html/parser/CSSPreloadScanner.cpp39
-rw-r--r--Source/WebCore/html/parser/CSSPreloadScanner.h3
-rw-r--r--Source/WebCore/html/parser/HTMLDocumentParser.cpp31
-rw-r--r--Source/WebCore/html/parser/HTMLDocumentParser.h2
-rw-r--r--Source/WebCore/html/parser/HTMLParserScheduler.h14
-rw-r--r--Source/WebCore/html/parser/HTMLScriptRunner.cpp5
-rw-r--r--Source/WebCore/html/parser/HTMLScriptRunnerHost.h4
-rw-r--r--Source/WebCore/html/shadow/DetailsMarkerControl.cpp70
-rw-r--r--Source/WebCore/html/shadow/DetailsMarkerControl.h (renamed from Source/WebCore/html/shadow/ProgressBarValueElement.h)40
-rw-r--r--Source/WebCore/html/shadow/MediaControlElements.cpp980
-rw-r--r--Source/WebCore/html/shadow/MediaControlElements.h462
-rw-r--r--Source/WebCore/html/shadow/MediaControlRootElement.cpp446
-rw-r--r--Source/WebCore/html/shadow/MediaControlRootElement.h133
-rw-r--r--Source/WebCore/html/shadow/MediaControls.cpp19
-rw-r--r--Source/WebCore/html/shadow/MediaControls.h90
-rw-r--r--Source/WebCore/html/shadow/MeterShadowElement.cpp103
-rw-r--r--Source/WebCore/html/shadow/MeterShadowElement.h86
-rw-r--r--Source/WebCore/html/shadow/ProgressShadowElement.cpp81
-rw-r--r--Source/WebCore/html/shadow/ProgressShadowElement.h87
-rw-r--r--Source/WebCore/html/shadow/SliderThumbElement.cpp8
-rw-r--r--Source/WebCore/html/shadow/SliderThumbElement.h2
-rw-r--r--Source/WebCore/html/shadow/TextControlInnerElements.cpp9
-rw-r--r--Source/WebCore/html/shadow/TextControlInnerElements.h7
75 files changed, 3452 insertions, 496 deletions
diff --git a/Source/WebCore/html/FormAssociatedElement.h b/Source/WebCore/html/FormAssociatedElement.h
index aa5abd9..7f3e9ac 100644
--- a/Source/WebCore/html/FormAssociatedElement.h
+++ b/Source/WebCore/html/FormAssociatedElement.h
@@ -46,7 +46,6 @@ public:
virtual bool isFormControlElement() const = 0;
virtual bool isEnumeratable() const = 0;
- virtual bool isResettable() const = 0;
const AtomicString& name() const { return formControlName(); }
diff --git a/Source/WebCore/html/HTMLAttributeNames.in b/Source/WebCore/html/HTMLAttributeNames.in
index 3a6fea4..5e0fe7b 100644
--- a/Source/WebCore/html/HTMLAttributeNames.in
+++ b/Source/WebCore/html/HTMLAttributeNames.in
@@ -85,6 +85,7 @@ coords
data
datetime
declare
+default
defer
dir
direction
@@ -118,6 +119,7 @@ incremental
indeterminate
ismap
keytype
+kind
label
lang
language
@@ -178,8 +180,6 @@ onerror
onfocus
onfocusin
onfocusout
-onformchange
-onforminput
onhashchange
oninput
oninvalid
@@ -276,6 +276,7 @@ x-webkit-speech
x-webkit-grammar
spellcheck
src
+srclang
standby
start
step
diff --git a/Source/WebCore/html/HTMLCanvasElement.cpp b/Source/WebCore/html/HTMLCanvasElement.cpp
index 67d1caa..1747273 100644
--- a/Source/WebCore/html/HTMLCanvasElement.cpp
+++ b/Source/WebCore/html/HTMLCanvasElement.cpp
@@ -175,7 +175,7 @@ CanvasRenderingContext* HTMLCanvasElement::getContext(const String& type, Canvas
#if ENABLE(WEBGL)
Settings* settings = document()->settings();
if (settings && settings->webGLEnabled()
-#if !PLATFORM(CHROMIUM)
+#if !PLATFORM(CHROMIUM) && !PLATFORM(GTK)
&& settings->acceleratedCompositingEnabled()
#endif
) {
@@ -318,27 +318,6 @@ void HTMLCanvasElement::clearPresentationCopy()
m_presentedImage.clear();
}
-void HTMLCanvasElement::attach()
-{
- HTMLElement::attach();
-
- if (m_context && m_context->is2d()) {
- CanvasRenderingContext2D* ctx = static_cast<CanvasRenderingContext2D*>(m_context.get());
- ctx->updateFont();
- }
-}
-
-void HTMLCanvasElement::recalcStyle(StyleChange change)
-{
- HTMLElement::recalcStyle(change);
-
- // Update font if needed.
- if (change == Force && m_context && m_context->is2d()) {
- CanvasRenderingContext2D* ctx = static_cast<CanvasRenderingContext2D*>(m_context.get());
- ctx->updateFont();
- }
-}
-
void HTMLCanvasElement::setSurfaceSize(const IntSize& size)
{
m_size = size;
@@ -363,8 +342,12 @@ String HTMLCanvasElement::toDataURL(const String& mimeType, const double* qualit
if (mimeType.isNull() || !MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(lowercaseMimeType))
lowercaseMimeType = "image/png";
+<<<<<<< HEAD
#if PLATFORM(CG) || (USE(SKIA) && !PLATFORM(ANDROID))
// FIXME: Consider using this code path on Android. http://b/4572024
+=======
+#if USE(CG) || USE(SKIA)
+>>>>>>> WebKit.org at r84325
// Try to get ImageData first, as that may avoid lossy conversions.
RefPtr<ImageData> imageData = getImageData();
@@ -460,10 +443,8 @@ void HTMLCanvasElement::createImageBuffer() const
m_imageBuffer->context()->setImageInterpolationQuality(DefaultInterpolationQuality);
#if USE(JSC)
- if (hasCachedDOMNodeWrapperUnchecked(document(), const_cast<HTMLCanvasElement*>(this))) {
- JSC::JSLock lock(JSC::SilenceAssertionsOnly);
- scriptExecutionContext()->globalData()->heap.reportExtraMemoryCost(m_imageBuffer->dataSize());
- }
+ JSC::JSLock lock(JSC::SilenceAssertionsOnly);
+ scriptExecutionContext()->globalData()->heap.reportExtraMemoryCost(m_imageBuffer->dataSize());
#endif
}
diff --git a/Source/WebCore/html/HTMLCanvasElement.h b/Source/WebCore/html/HTMLCanvasElement.h
index 6fdd222..9eab209 100644
--- a/Source/WebCore/html/HTMLCanvasElement.h
+++ b/Source/WebCore/html/HTMLCanvasElement.h
@@ -34,7 +34,7 @@
#if PLATFORM(CHROMIUM) || PLATFORM(QT)
#define DefaultInterpolationQuality InterpolationMedium
-#elif PLATFORM(CG)
+#elif USE(CG)
#define DefaultInterpolationQuality InterpolationLow
#else
#define DefaultInterpolationQuality InterpolationDefault
@@ -150,10 +150,6 @@ private:
virtual void parseMappedAttribute(Attribute*);
virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
- virtual void attach();
-
- virtual void recalcStyle(StyleChange);
-
void reset();
void createImageBuffer() const;
diff --git a/Source/WebCore/html/HTMLDetailsElement.cpp b/Source/WebCore/html/HTMLDetailsElement.cpp
index f9c2f6c..b41f5dd 100644
--- a/Source/WebCore/html/HTMLDetailsElement.cpp
+++ b/Source/WebCore/html/HTMLDetailsElement.cpp
@@ -21,11 +21,12 @@
#include "config.h"
#include "HTMLDetailsElement.h"
-#include "Frame.h"
#include "HTMLNames.h"
+#include "HTMLSummaryElement.h"
+#include "LocalizedStrings.h"
#include "MouseEvent.h"
-#include "PlatformMouseEvent.h"
#include "RenderDetails.h"
+#include "Text.h"
namespace WebCore {
@@ -49,48 +50,76 @@ RenderObject* HTMLDetailsElement::createRenderer(RenderArena* arena, RenderStyle
return new (arena) RenderDetails(this);
}
-void HTMLDetailsElement::findMainSummary()
+Node* HTMLDetailsElement::findSummaryFor(ContainerNode* container)
{
- m_mainSummary = 0;
+ for (Node* child = container->firstChild(); child; child = child->nextSibling()) {
+ if (child->hasTagName(summaryTag))
+ return child;
+ }
- for (Node* child = firstChild(); child; child = child->nextSibling()) {
- if (child->hasTagName(summaryTag)) {
- m_mainSummary = child;
- break;
- }
+ return 0;
+}
+
+Node* HTMLDetailsElement::findMainSummary()
+{
+ Node* found = findSummaryFor(this);
+ if (found) {
+ removeShadowRoot();
+ return found;
}
+
+ createShadowSubtree();
+ found = findSummaryFor(shadowRoot());
+ ASSERT(found);
+ return found;
+}
+
+void HTMLDetailsElement::refreshMainSummary(RefreshRenderer refreshRenderer)
+{
+ RefPtr<Node> oldSummary = m_mainSummary;
+ m_mainSummary = findMainSummary();
+
+ if (oldSummary == m_mainSummary || !attached())
+ return;
+
+ if (oldSummary && oldSummary->parentNodeForRenderingAndStyle()) {
+ oldSummary->detach();
+ oldSummary->attach();
+ }
+
+ if (refreshRenderer == RefreshRendererAllowed) {
+ m_mainSummary->detach();
+ m_mainSummary->attach();
+ }
+}
+
+void HTMLDetailsElement::createShadowSubtree()
+{
+ if (shadowRoot())
+ return;
+
+ RefPtr<HTMLSummaryElement> defaultSummary = HTMLSummaryElement::create(summaryTag, document());
+ ExceptionCode ec = 0;
+ defaultSummary->appendChild(Text::create(document(), defaultDetailsSummaryText()), ec);
+ ensureShadowRoot()->appendChild(defaultSummary, ec, true);
}
+
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();
- }
- }
- }
+ // 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.
+ if (!changedByParser)
+ refreshMainSummary(childCountDelta < 0 ? RefreshRendererAllowed : RefreshRendererSupressed);
}
void HTMLDetailsElement::finishParsingChildren()
{
HTMLElement::finishParsingChildren();
- findMainSummary();
- if (attached() && m_mainSummary && !m_mainSummary->renderer()) {
- m_mainSummary->detach();
- m_mainSummary->attach();
- }
+ refreshMainSummary(RefreshRendererAllowed);
}
void HTMLDetailsElement::parseMappedAttribute(Attribute* attr)
@@ -111,26 +140,9 @@ bool HTMLDetailsElement::childShouldCreateRenderer(Node* child) const
return m_isOpen || child == m_mainSummary;
}
-void HTMLDetailsElement::defaultEventHandler(Event* event)
+void HTMLDetailsElement::toggleOpen()
{
- 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();
- }
+ setAttribute(openAttr, m_isOpen ? nullAtom : emptyAtom);
}
}
diff --git a/Source/WebCore/html/HTMLDetailsElement.h b/Source/WebCore/html/HTMLDetailsElement.h
index 45a9035..70ae9c6 100644
--- a/Source/WebCore/html/HTMLDetailsElement.h
+++ b/Source/WebCore/html/HTMLDetailsElement.h
@@ -29,19 +29,29 @@ class HTMLDetailsElement : public HTMLElement {
public:
static PassRefPtr<HTMLDetailsElement> create(const QualifiedName& tagName, Document* document);
Node* mainSummary() const { return m_mainSummary; }
+ void toggleOpen();
private:
+ enum RefreshRenderer {
+ RefreshRendererAllowed,
+ RefreshRendererSupressed,
+ };
+
HTMLDetailsElement(const QualifiedName&, Document*);
virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
virtual void childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta);
virtual void finishParsingChildren();
+ virtual bool canHaveLightChildRendererWithShadow() const { return true; }
void parseMappedAttribute(Attribute*);
bool childShouldCreateRenderer(Node*) const;
- void defaultEventHandler(Event*);
- void findMainSummary();
+ Node* findSummaryFor(ContainerNode*);
+ Node* findMainSummary();
+ void refreshMainSummary(RefreshRenderer);
+
+ void createShadowSubtree();
Node* m_mainSummary;
bool m_isOpen;
diff --git a/Source/WebCore/html/HTMLElement.cpp b/Source/WebCore/html/HTMLElement.cpp
index e3b5043..b2b57a2 100644
--- a/Source/WebCore/html/HTMLElement.cpp
+++ b/Source/WebCore/html/HTMLElement.cpp
@@ -194,10 +194,6 @@ void HTMLElement::parseMappedAttribute(Attribute* attr)
setAttributeEventListener(eventNames().focusinEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == onfocusoutAttr) {
setAttributeEventListener(eventNames().focusoutEvent, createAttributeEventListener(this, attr));
- } else if (attr->name() == onformchangeAttr) {
- setAttributeEventListener(eventNames().formchangeEvent, createAttributeEventListener(this, attr));
- } else if (attr->name() == onforminputAttr) {
- setAttributeEventListener(eventNames().forminputEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == onblurAttr) {
setAttributeEventListener(eventNames().blurEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == onkeydownAttr) {
@@ -657,11 +653,6 @@ bool HTMLElement::supportsFocus() const
return Element::supportsFocus() || (rendererIsEditable() && parentNode() && !parentNode()->rendererIsEditable());
}
-bool HTMLElement::isContentEditable() const
-{
- return rendererIsEditable();
-}
-
String HTMLElement::contentEditable() const
{
const AtomicString& value = fastGetAttribute(contenteditableAttr);
@@ -819,40 +810,6 @@ HTMLFormElement* HTMLElement::virtualForm() const
return findFormAncestor();
}
-HTMLFormElement* HTMLElement::shadowAncestorOwnerForm()
-{
- Node* ancestorNode = shadowAncestorNode();
- if (!ancestorNode)
- return form();
-
- if (!ancestorNode->isHTMLElement())
- return 0;
- HTMLElement* ancestorHTML = toHTMLElement(ancestorNode);
- if (!ancestorHTML)
- return 0;
- return ancestorHTML->form();
-}
-
-void HTMLElement::dispatchChangeEvents()
-{
- RefPtr<HTMLElement> protector(this);
- RefPtr<HTMLFormElement> ownerForm(shadowAncestorOwnerForm());
-
- Node::dispatchChangeEvents();
- if (ownerForm)
- ownerForm->dispatchFormChange();
-}
-
-void HTMLElement::dispatchInputEvents()
-{
- RefPtr<HTMLElement> protector(this);
- RefPtr<HTMLFormElement> ownerForm(shadowAncestorOwnerForm());
-
- Node::dispatchInputEvents();
- if (ownerForm)
- ownerForm->dispatchFormInput();
-}
-
static void setHasDirAutoFlagRecursively(Node* firstNode, bool flag, Node* lastNode = 0)
{
firstNode->setSelfOrAncestorHasDirAutoAttribute(flag);
diff --git a/Source/WebCore/html/HTMLElement.h b/Source/WebCore/html/HTMLElement.h
index 077b1c3..5a5fdfb 100644
--- a/Source/WebCore/html/HTMLElement.h
+++ b/Source/WebCore/html/HTMLElement.h
@@ -57,8 +57,6 @@ public:
virtual bool supportsFocus() const;
- bool isContentEditable() const;
-
String contentEditable() const;
void setContentEditable(const String&, ExceptionCode&);
@@ -83,9 +81,6 @@ public:
HTMLFormElement* findFormAncestor() const;
- virtual void dispatchChangeEvents();
- virtual void dispatchInputEvents();
-
TextDirection directionalityIfhasDirAutoAttribute(bool& isAuto) const;
protected:
@@ -108,8 +103,6 @@ private:
Node* insertAdjacent(const String& where, Node* newChild, ExceptionCode&);
PassRefPtr<DocumentFragment> textToFragment(const String&, ExceptionCode&);
- HTMLFormElement* shadowAncestorOwnerForm();
-
void dirAttributeChanged(Attribute*);
void adjustDirectionalityIfNeededAfterChildAttributeChanged(Element* child);
void calculateAndAdjustDirectionality();
diff --git a/Source/WebCore/html/HTMLFormControlElement.cpp b/Source/WebCore/html/HTMLFormControlElement.cpp
index af061fe..87f4e4d 100644
--- a/Source/WebCore/html/HTMLFormControlElement.cpp
+++ b/Source/WebCore/html/HTMLFormControlElement.cpp
@@ -201,14 +201,14 @@ void HTMLFormControlElement::setChangedSinceLastFormControlChangeEvent(bool chan
void HTMLFormControlElement::dispatchFormControlChangeEvent()
{
- HTMLElement::dispatchChangeEvents();
+ HTMLElement::dispatchChangeEvent();
setChangedSinceLastFormControlChangeEvent(false);
}
void HTMLFormControlElement::dispatchFormControlInputEvent()
{
setChangedSinceLastFormControlChangeEvent(true);
- HTMLElement::dispatchInputEvents();
+ HTMLElement::dispatchInputEvent();
}
void HTMLFormControlElement::setDisabled(bool b)
@@ -638,7 +638,7 @@ void HTMLTextFormControlElement::select()
void HTMLTextFormControlElement::dispatchFormControlChangeEvent()
{
if (m_textAsOfLastFormControlChangeEvent != value()) {
- HTMLElement::dispatchChangeEvents();
+ HTMLElement::dispatchChangeEvent();
setTextAsOfLastFormControlChangeEvent(value());
}
setChangedSinceLastFormControlChangeEvent(false);
diff --git a/Source/WebCore/html/HTMLFormControlElement.h b/Source/WebCore/html/HTMLFormControlElement.h
index ede3299..884ace0 100644
--- a/Source/WebCore/html/HTMLFormControlElement.h
+++ b/Source/WebCore/html/HTMLFormControlElement.h
@@ -63,7 +63,6 @@ public:
virtual bool isFocusable() const;
virtual bool isEnumeratable() const { return false; }
- virtual bool isResettable() const { return false; }
// Determines whether or not a control will be automatically focused.
virtual bool autofocus() const;
diff --git a/Source/WebCore/html/HTMLFormElement.cpp b/Source/WebCore/html/HTMLFormElement.cpp
index f051ea1..cfea3d8 100644
--- a/Source/WebCore/html/HTMLFormElement.cpp
+++ b/Source/WebCore/html/HTMLFormElement.cpp
@@ -236,17 +236,11 @@ bool HTMLFormElement::validateInteractively(Event* event)
FormAssociatedElement* unhandledAssociatedElement = unhandledInvalidControls[i].get();
HTMLElement* unhandled = toHTMLElement(unhandledAssociatedElement);
if (unhandled->isFocusable() && unhandled->inDocument()) {
- RefPtr<Document> originalDocument(unhandled->document());
unhandled->scrollIntoViewIfNeeded(false);
- // scrollIntoViewIfNeeded() dispatches events, so the state
- // of 'unhandled' might be changed so it's no longer focusable or
- // moved to another document.
- if (unhandled->isFocusable() && unhandled->inDocument() && originalDocument == unhandled->document()) {
- unhandled->focus();
- if (unhandled->isFormControlElement())
- static_cast<HTMLFormControlElement*>(unhandled)->updateVisibleValidationMessage();
- break;
- }
+ unhandled->focus();
+ if (unhandled->isFormControlElement())
+ static_cast<HTMLFormControlElement*>(unhandled)->updateVisibleValidationMessage();
+ break;
}
}
// Warn about all of unfocusable controls.
@@ -417,7 +411,7 @@ unsigned HTMLFormElement::formElementIndexWithFormAttribute(Element* element)
// Compares the position of the form element and the inserted element.
// Updates the indeces in order to the relation of the position:
unsigned short position = compareDocumentPosition(element);
- if (position & DOCUMENT_POSITION_CONTAINS)
+ if (position & (DOCUMENT_POSITION_CONTAINS | DOCUMENT_POSITION_CONTAINED_BY))
++m_associatedElementsAfterIndex;
else if (position & DOCUMENT_POSITION_PRECEDING) {
++m_associatedElementsBeforeIndex;
@@ -488,18 +482,15 @@ void HTMLFormElement::removeFormElement(FormAssociatedElement* e)
{
if (e->isFormControlElement())
m_checkedRadioButtons.removeButton(static_cast<HTMLFormControlElement*>(e));
- HTMLElement* element = toHTMLElement(e);
- if (element->fastHasAttribute(formAttr)) {
- unsigned index;
- for (index = 0; index < m_associatedElements.size(); ++index)
- if (m_associatedElements[index] == e)
- break;
- ASSERT(index < m_associatedElements.size());
- if (index < m_associatedElementsBeforeIndex)
- --m_associatedElementsBeforeIndex;
- if (index < m_associatedElementsAfterIndex)
- --m_associatedElementsAfterIndex;
- } else
+ unsigned index;
+ for (index = 0; index < m_associatedElements.size(); ++index) {
+ if (m_associatedElements[index] == e)
+ break;
+ }
+ ASSERT(index < m_associatedElements.size());
+ if (index < m_associatedElementsBeforeIndex)
+ --m_associatedElementsBeforeIndex;
+ if (index < m_associatedElementsAfterIndex)
--m_associatedElementsAfterIndex;
removeFromVector(m_associatedElements, e);
}
@@ -593,39 +584,6 @@ bool HTMLFormElement::checkValidity()
return !checkInvalidControlsAndCollectUnhandled(controls);
}
-void HTMLFormElement::broadcastFormEvent(const AtomicString& eventName)
-{
- RefPtr<HTMLFormElement> protector(this);
- // Copy m_associatedElements because event handlers called from
- // formElement->dispatchEvent() might change m_associatedElements.
- Vector<RefPtr<FormAssociatedElement> > elements;
- elements.reserveCapacity(m_associatedElements.size());
- for (unsigned i = 0; i < m_associatedElements.size(); ++i) {
- if (!m_associatedElements[i]->isResettable())
- continue;
- elements.append(m_associatedElements[i]);
- }
-
- for (unsigned i = 0; i < elements.size(); ++i) {
- // We can assume a resettable control is always a HTMLFormControlElement.
- // FIXME: We should handle resettable non-HTMLFormControlElements maybe in the future.
- ASSERT(elements[i]->isFormControlElement());
- HTMLFormControlElement* formElement = static_cast<HTMLFormControlElement*>(elements[i].get());
- if (!formElement->dispatchEvent(Event::create(eventName, false, false)))
- continue;
- }
-}
-
-void HTMLFormElement::dispatchFormInput()
-{
- broadcastFormEvent(eventNames().forminputEvent);
-}
-
-void HTMLFormElement::dispatchFormChange()
-{
- broadcastFormEvent(eventNames().formchangeEvent);
-}
-
bool HTMLFormElement::checkInvalidControlsAndCollectUnhandled(Vector<RefPtr<FormAssociatedElement> >& unhandledInvalidControls)
{
RefPtr<HTMLFormElement> protector(this);
diff --git a/Source/WebCore/html/HTMLFormElement.h b/Source/WebCore/html/HTMLFormElement.h
index f723533..3100f67 100644
--- a/Source/WebCore/html/HTMLFormElement.h
+++ b/Source/WebCore/html/HTMLFormElement.h
@@ -114,9 +114,6 @@ public:
const Vector<FormAssociatedElement*>& associatedElements() const { return m_associatedElements; }
- void dispatchFormInput();
- void dispatchFormChange();
-
private:
HTMLFormElement(const QualifiedName&, Document*);
@@ -148,8 +145,6 @@ private:
// are any invalid controls in this form.
bool checkInvalidControlsAndCollectUnhandled(Vector<RefPtr<FormAssociatedElement> >&);
- void broadcastFormEvent(const AtomicString&);
-
friend class HTMLFormCollection;
typedef HashMap<RefPtr<AtomicStringImpl>, RefPtr<HTMLFormControlElement> > AliasMap;
diff --git a/Source/WebCore/html/HTMLFormElement.idl b/Source/WebCore/html/HTMLFormElement.idl
index 3e9e46d..e9759e2 100644
--- a/Source/WebCore/html/HTMLFormElement.idl
+++ b/Source/WebCore/html/HTMLFormElement.idl
@@ -43,9 +43,6 @@ module html {
#endif
void reset();
boolean checkValidity();
-
- void dispatchFormInput();
- void dispatchFormChange();
};
}
diff --git a/Source/WebCore/html/HTMLFrameOwnerElement.cpp b/Source/WebCore/html/HTMLFrameOwnerElement.cpp
index 2a7b610..a217881 100644
--- a/Source/WebCore/html/HTMLFrameOwnerElement.cpp
+++ b/Source/WebCore/html/HTMLFrameOwnerElement.cpp
@@ -89,6 +89,11 @@ void HTMLFrameOwnerElement::setSandboxFlags(SandboxFlags flags)
frame->loader()->ownerElementSandboxFlagsChanged();
}
+bool HTMLFrameOwnerElement::isKeyboardFocusable(KeyboardEvent* event) const
+{
+ return m_contentFrame && HTMLElement::isKeyboardFocusable(event);
+}
+
#if ENABLE(SVG)
SVGDocument* HTMLFrameOwnerElement::getSVGDocument(ExceptionCode& ec) const
{
diff --git a/Source/WebCore/html/HTMLFrameOwnerElement.h b/Source/WebCore/html/HTMLFrameOwnerElement.h
index f784f4f..de9d153 100644
--- a/Source/WebCore/html/HTMLFrameOwnerElement.h
+++ b/Source/WebCore/html/HTMLFrameOwnerElement.h
@@ -66,7 +66,7 @@ private:
friend class Frame;
virtual bool isFrameOwnerElement() const { return true; }
- virtual bool isKeyboardFocusable(KeyboardEvent*) const { return m_contentFrame; }
+ virtual bool isKeyboardFocusable(KeyboardEvent*) const;
Frame* m_contentFrame;
SandboxFlags m_sandboxFlags;
diff --git a/Source/WebCore/html/HTMLInputElement.cpp b/Source/WebCore/html/HTMLInputElement.cpp
index 7ae6ad9..83e8c7d 100644
--- a/Source/WebCore/html/HTMLInputElement.cpp
+++ b/Source/WebCore/html/HTMLInputElement.cpp
@@ -443,6 +443,7 @@ void HTMLInputElement::setType(const String& type)
void HTMLInputElement::updateType()
{
+<<<<<<< HEAD
const AtomicString& typeString = fastGetAttribute(typeAttr);
OwnPtr<InputType> newType = InputType::create(this, typeString);
@@ -450,19 +451,21 @@ void HTMLInputElement::updateType()
if (newType->isPasswordField() && document()->focusedNode() == this)
PlatformBridge::updateTextfield(document()->view(), this, true, String());
#endif
+=======
+ OwnPtr<InputType> newType = InputType::create(this, fastGetAttribute(typeAttr));
+ bool hadType = m_hasType;
+ m_hasType = true;
+ if (m_inputType->formControlType() == newType->formControlType())
+ return;
+>>>>>>> WebKit.org at r84325
- if (m_hasType && !newType->canChangeFromAnotherType()) {
+ if (hadType && !newType->canChangeFromAnotherType()) {
// Set the attribute back to the old value.
// Useful in case we were called from inside parseMappedAttribute.
setAttribute(typeAttr, type());
return;
}
- m_hasType = true;
-
- if (m_inputType->formControlType() == newType->formControlType())
- return;
-
checkedRadioButtons().removeButton(this);
bool wasAttached = attached();
diff --git a/Source/WebCore/html/HTMLInputElement.h b/Source/WebCore/html/HTMLInputElement.h
index f2c2625..2a98b13 100644
--- a/Source/WebCore/html/HTMLInputElement.h
+++ b/Source/WebCore/html/HTMLInputElement.h
@@ -215,7 +215,6 @@ private:
virtual bool isKeyboardFocusable(KeyboardEvent*) const;
virtual bool isMouseFocusable() const;
virtual bool isEnumeratable() const;
- virtual bool isResettable() const { return true; }
virtual void updateFocusAppearance(bool restorePreviousSelection);
virtual void aboutToUnload();
virtual bool shouldUseInputMethod() const;
diff --git a/Source/WebCore/html/HTMLKeygenElement.cpp b/Source/WebCore/html/HTMLKeygenElement.cpp
index b90335e..29c9deb 100644
--- a/Source/WebCore/html/HTMLKeygenElement.cpp
+++ b/Source/WebCore/html/HTMLKeygenElement.cpp
@@ -32,6 +32,7 @@
#include "HTMLSelectElement.h"
#include "HTMLOptionElement.h"
#include "SSLKeyGenerator.h"
+#include "ShadowRoot.h"
#include "Text.h"
#include <wtf/StdLibExtras.h>
@@ -67,15 +68,18 @@ inline HTMLKeygenElement::HTMLKeygenElement(const QualifiedName& tagName, Docume
ASSERT(hasTagName(keygenTag));
// Create a select element with one option element for each key size.
- RefPtr<HTMLSelectElement> select = KeygenSelectElement::create(document);
Vector<String> keys;
getSupportedKeySizes(keys);
+
+ RefPtr<HTMLSelectElement> select = KeygenSelectElement::create(document);
+ ExceptionCode ec = 0;
for (size_t i = 0; i < keys.size(); ++i) {
RefPtr<HTMLOptionElement> option = HTMLOptionElement::create(document, this->form());
- select->parserAddChild(option);
- option->parserAddChild(Text::create(document, keys[i]));
+ select->appendChild(option, ec);
+ option->appendChild(Text::create(document, keys[i]), ec);
}
- setShadowRoot(select);
+
+ ensureShadowRoot()->appendChild(select, ec);
}
PassRefPtr<HTMLKeygenElement> HTMLKeygenElement::create(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
@@ -87,7 +91,7 @@ void HTMLKeygenElement::parseMappedAttribute(Attribute* attr)
{
// Reflect disabled attribute on the shadow select element
if (attr->name() == disabledAttr)
- selectShadow()->setAttribute(attr->name(), attr->value());
+ shadowSelect()->setAttribute(attr->name(), attr->value());
if (attr->name() == challengeAttr)
m_challenge = attr->value();
@@ -102,7 +106,7 @@ bool HTMLKeygenElement::appendFormData(FormDataList& encoded_values, bool)
// Only RSA is supported at this time.
if (!m_keyType.isNull() && !equalIgnoringCase(m_keyType, "rsa"))
return false;
- String value = signedPublicKeyAndChallengeString(selectShadow()->selectedIndex(), m_challenge, document()->baseURL());
+ String value = signedPublicKeyAndChallengeString(shadowSelect()->selectedIndex(), m_challenge, document()->baseURL());
if (value.isNull())
return false;
encoded_values.appendData(name(), value.utf8());
@@ -117,12 +121,14 @@ const AtomicString& HTMLKeygenElement::formControlType() const
void HTMLKeygenElement::reset()
{
- static_cast<HTMLFormControlElement*>(selectShadow())->reset();
+ static_cast<HTMLFormControlElement*>(shadowSelect())->reset();
}
-HTMLSelectElement* HTMLKeygenElement::selectShadow()
+HTMLSelectElement* HTMLKeygenElement::shadowSelect() const
{
- return static_cast<HTMLSelectElement*>(shadowRoot());
+ Node* shadow = shadowRoot();
+ ASSERT(shadow);
+ return shadow ? static_cast<HTMLSelectElement*>(shadow->firstChild()) : 0;
}
} // namespace
diff --git a/Source/WebCore/html/HTMLKeygenElement.h b/Source/WebCore/html/HTMLKeygenElement.h
index a7a8a64..88782c8 100644
--- a/Source/WebCore/html/HTMLKeygenElement.h
+++ b/Source/WebCore/html/HTMLKeygenElement.h
@@ -49,10 +49,9 @@ private:
virtual bool isEnumeratable() const { return true; }
- virtual bool isResettable() const { return true; }
virtual void reset();
- HTMLSelectElement* selectShadow();
+ HTMLSelectElement* shadowSelect() const;
AtomicString m_challenge;
AtomicString m_keyType;
diff --git a/Source/WebCore/html/HTMLLinkElement.cpp b/Source/WebCore/html/HTMLLinkElement.cpp
index 67262d9..7cbf38b 100644
--- a/Source/WebCore/html/HTMLLinkElement.cpp
+++ b/Source/WebCore/html/HTMLLinkElement.cpp
@@ -26,6 +26,7 @@
#include "Attribute.h"
#include "CachedCSSStyleSheet.h"
+#include "CachedResource.h"
#include "CachedResourceLoader.h"
#include "CSSStyleSelector.h"
#include "Document.h"
@@ -78,8 +79,8 @@ HTMLLinkElement::~HTMLLinkElement()
}
#if ENABLE(LINK_PREFETCH)
- if (m_cachedLinkPrefetch)
- m_cachedLinkPrefetch->removeClient(this);
+ if (m_cachedLinkResource)
+ m_cachedLinkResource->removeClient(this);
#endif
}
@@ -163,6 +164,7 @@ void HTMLLinkElement::tokenizeRelAttribute(const AtomicString& rel, RelAttribute
relAttribute.m_isDNSPrefetch = false;
#if ENABLE(LINK_PREFETCH)
relAttribute.m_isLinkPrefetch = false;
+ relAttribute.m_isLinkSubresource = false;
#endif
#ifdef ANDROID_APPLE_TOUCH_ICON
relAttribute.m_isTouchIcon = false;
@@ -180,10 +182,6 @@ void HTMLLinkElement::tokenizeRelAttribute(const AtomicString& rel, RelAttribute
#endif
else if (equalIgnoringCase(rel, "dns-prefetch"))
relAttribute.m_isDNSPrefetch = true;
-#if ENABLE(LINK_PREFETCH)
- else if (equalIgnoringCase(rel, "prefetch"))
- relAttribute.m_isLinkPrefetch = true;
-#endif
else if (equalIgnoringCase(rel, "alternate stylesheet") || equalIgnoringCase(rel, "stylesheet alternate")) {
relAttribute.m_isStyleSheet = true;
relAttribute.m_isAlternate = true;
@@ -201,6 +199,12 @@ void HTMLLinkElement::tokenizeRelAttribute(const AtomicString& rel, RelAttribute
relAttribute.m_isAlternate = true;
else if (equalIgnoringCase(*it, "icon"))
relAttribute.m_isIcon = true;
+#if ENABLE(LINK_PREFETCH)
+ else if (equalIgnoringCase(*it, "prefetch"))
+ relAttribute.m_isLinkPrefetch = true;
+ else if (equalIgnoringCase(*it, "subresource"))
+ relAttribute.m_isLinkSubresource = true;
+#endif
}
}
}
@@ -250,12 +254,16 @@ void HTMLLinkElement::process()
}
#if ENABLE(LINK_PREFETCH)
- if (m_relAttribute.m_isLinkPrefetch && m_url.isValid() && document()->frame()) {
+ if ((m_relAttribute.m_isLinkPrefetch || m_relAttribute.m_isLinkSubresource) && m_url.isValid() && document()->frame()) {
if (!checkBeforeLoadEvent())
return;
- m_cachedLinkPrefetch = document()->cachedResourceLoader()->requestLinkPrefetch(m_url);
- if (m_cachedLinkPrefetch)
- m_cachedLinkPrefetch->addClient(this);
+ ResourceLoadPriority priority = ResourceLoadPriorityUnresolved;
+ if (m_relAttribute.m_isLinkSubresource)
+ priority = ResourceLoadPriorityLow;
+
+ m_cachedLinkResource = document()->cachedResourceLoader()->requestLinkResource(m_url, priority);
+ if (m_cachedLinkResource)
+ m_cachedLinkResource->addClient(this);
}
#endif
@@ -427,19 +435,19 @@ bool HTMLLinkElement::isLoading() const
void HTMLLinkElement::onloadTimerFired(Timer<HTMLLinkElement>* timer)
{
ASSERT_UNUSED(timer, timer == &m_onloadTimer);
- if (m_cachedLinkPrefetch->errorOccurred())
+ if (m_cachedLinkResource->errorOccurred())
dispatchEvent(Event::create(eventNames().errorEvent, false, false));
else
dispatchEvent(Event::create(eventNames().loadEvent, false, false));
- m_cachedLinkPrefetch->removeClient(this);
- m_cachedLinkPrefetch = 0;
+ m_cachedLinkResource->removeClient(this);
+ m_cachedLinkResource = 0;
}
void HTMLLinkElement::notifyFinished(CachedResource* resource)
{
m_onloadTimer.startOneShot(0);
- ASSERT(m_cachedLinkPrefetch.get() == resource);
+ ASSERT(m_cachedLinkResource.get() == resource);
}
#endif
diff --git a/Source/WebCore/html/HTMLLinkElement.h b/Source/WebCore/html/HTMLLinkElement.h
index d31feeb..f602d38 100644
--- a/Source/WebCore/html/HTMLLinkElement.h
+++ b/Source/WebCore/html/HTMLLinkElement.h
@@ -48,6 +48,7 @@ public:
#endif
#if ENABLE(LINK_PREFETCH)
bool m_isLinkPrefetch;
+ bool m_isLinkSubresource;
#endif
RelAttribute()
@@ -57,6 +58,7 @@ public:
, m_isDNSPrefetch(false)
#if ENABLE(LINK_PREFETCH)
, m_isLinkPrefetch(false)
+ , m_isLinkSubresource(false)
#endif
{
}
@@ -138,7 +140,7 @@ private:
CachedResourceHandle<CachedCSSStyleSheet> m_cachedSheet;
RefPtr<CSSStyleSheet> m_sheet;
#if ENABLE(LINK_PREFETCH)
- CachedResourceHandle<CachedResource> m_cachedLinkPrefetch;
+ CachedResourceHandle<CachedResource> m_cachedLinkResource;
Timer<HTMLLinkElement> m_onloadTimer;
#endif
KURL m_url;
diff --git a/Source/WebCore/html/HTMLMediaElement.cpp b/Source/WebCore/html/HTMLMediaElement.cpp
index 29c0cb8..5505343 100644
--- a/Source/WebCore/html/HTMLMediaElement.cpp
+++ b/Source/WebCore/html/HTMLMediaElement.cpp
@@ -33,6 +33,7 @@
#include "ChromeClient.h"
#include "ClientRect.h"
#include "ClientRectList.h"
+#include "ContentSecurityPolicy.h"
#include "ContentType.h"
#include "CSSPropertyNames.h"
#include "CSSValueKeywords.h"
@@ -54,12 +55,14 @@
#include "MediaList.h"
#include "MediaPlayer.h"
#include "MediaQueryEvaluator.h"
+#include "MouseEvent.h"
#include "MIMETypeRegistry.h"
#include "Page.h"
#include "RenderVideo.h"
#include "RenderView.h"
#include "ScriptEventListener.h"
#include "Settings.h"
+#include "ShadowRoot.h"
#include "TimeRanges.h"
#include <limits>
#include <wtf/CurrentTime.h>
@@ -161,6 +164,7 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document* docum
, m_sendProgressEvents(true)
, m_isFullscreen(false)
, m_closedCaptionsVisible(false)
+ , m_mouseOver(false)
#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
, m_needWidgetUpdate(false)
#endif
@@ -223,12 +227,14 @@ void HTMLMediaElement::attributeChanged(Attribute* attr, bool preserveDecls)
}
else if (attrName == controlsAttr) {
#if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
- if (!isVideo() && attached() && (controls() != (renderer() != 0))) {
- detach();
- attach();
- }
- if (hasMediaControls())
- mediaControls()->reset();
+ if (controls()) {
+ if (!hasMediaControls()) {
+ ensureMediaControls();
+ mediaControls()->reset();
+ }
+ mediaControls()->show();
+ } else if (hasMediaControls())
+ mediaControls()->hide();
#else
if (m_player)
m_player->setControls(controls());
@@ -743,6 +749,9 @@ bool HTMLMediaElement::isSafeToLoadURL(const KURL& url, InvalidSourceAction acti
return false;
}
+ if (!document()->contentSecurityPolicy()->allowMediaFromSource(url))
+ return false;
+
return true;
}
@@ -900,6 +909,8 @@ void HTMLMediaElement::setNetworkState(MediaPlayer::NetworkState state)
noneSupported();
updateDisplayState();
+ if (hasMediaControls())
+ mediaControls()->reportedError();
return;
}
@@ -929,6 +940,9 @@ void HTMLMediaElement::setNetworkState(MediaPlayer::NetworkState state)
m_networkState = NETWORK_IDLE;
m_completelyLoaded = true;
}
+
+ if (hasMediaControls())
+ mediaControls()->changedNetworkState();
}
void HTMLMediaElement::mediaPlayerReadyStateChanged(MediaPlayer*)
@@ -978,6 +992,8 @@ void HTMLMediaElement::setReadyState(MediaPlayer::ReadyState state)
if (m_readyState >= HAVE_METADATA && oldState < HAVE_METADATA) {
scheduleEvent(eventNames().durationchangeEvent);
scheduleEvent(eventNames().loadedmetadataEvent);
+ if (hasMediaControls())
+ mediaControls()->loadedMetadata();
if (renderer())
renderer()->updateFromElement();
m_player->seek(0);
@@ -1491,6 +1507,10 @@ bool HTMLMediaElement::controls() const
if (isVideo() && document()->page() && document()->page()->chrome()->requiresFullscreenForVideoPlayback())
return true;
+ // Always show controls when in full screen mode.
+ if (isFullscreen())
+ return true;
+
return hasAttribute(controlsAttr);
}
@@ -1605,9 +1625,11 @@ void HTMLMediaElement::playbackProgressTimerFired(Timer<HTMLMediaElement>*)
return;
scheduleTimeupdateEvent(true);
- if (hasMediaControls())
+ if (hasMediaControls()) {
+ if (!m_mouseOver && controls())
+ mediaControls()->makeTransparent();
mediaControls()->playbackProgressed();
-
+ }
// FIXME: deal with cue ranges here
}
@@ -1997,13 +2019,26 @@ void HTMLMediaElement::mediaPlayerRenderingModeChanged(MediaPlayer*)
void HTMLMediaElement::mediaPlayerEngineUpdated(MediaPlayer*)
{
- beginProcessingMediaPlayerCallback();
LOG(Media, "HTMLMediaElement::mediaPlayerEngineUpdated");
+ beginProcessingMediaPlayerCallback();
if (renderer())
renderer()->updateFromElement();
endProcessingMediaPlayerCallback();
}
+void HTMLMediaElement::mediaPlayerFirstVideoFrameAvailable(MediaPlayer*)
+{
+ LOG(Media, "HTMLMediaElement::mediaPlayerFirstVideoFrameAvailable");
+ beginProcessingMediaPlayerCallback();
+ if (displayMode() == PosterWaitingForVideo) {
+ setDisplayMode(Video);
+#if USE(ACCELERATED_COMPOSITING)
+ mediaPlayerRenderingModeChanged(m_player.get());
+#endif
+ }
+ endProcessingMediaPlayerCallback();
+}
+
PassRefPtr<TimeRanges> HTMLMediaElement::buffered() const
{
if (!m_player)
@@ -2148,9 +2183,11 @@ void HTMLMediaElement::updatePlayState()
if (!m_isFullscreen && isVideo() && document() && document()->page() && document()->page()->chrome()->requiresFullscreenForVideoPlayback())
enterFullscreen();
- // Set rate before calling play in case the rate was set before the media engine was setup.
- // The media engine should just stash the rate since it isn't already playing.
+ // Set rate, muted before calling play in case they were set before the media engine was setup.
+ // The media engine should just stash the rate and muted values since it isn't already playing.
m_player->setRate(m_playbackRate);
+ m_player->setMuted(m_muted);
+
m_player->play();
}
@@ -2323,10 +2360,18 @@ void HTMLMediaElement::defaultEventHandler(Event* event)
if (widget)
widget->handleEvent(event);
#else
- if (hasMediaControls())
- mediaControls()->forwardEvent(event);
- if (event->defaultHandled())
- return;
+ if (event->isMouseEvent()) {
+ MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
+ if (mouseEvent->relatedTarget() != this) {
+ if (event->type() == eventNames().mouseoverEvent) {
+ m_mouseOver = true;
+ if (hasMediaControls() && controls() && !canPlay())
+ mediaControls()->makeOpaque();
+ } else if (event->type() == eventNames().mouseoutEvent)
+ m_mouseOver = false;
+ }
+ }
+
HTMLElement::defaultEventHandler(event);
#endif
}
@@ -2459,9 +2504,16 @@ bool HTMLMediaElement::isFullscreen() const
void HTMLMediaElement::enterFullscreen()
{
LOG(Media, "HTMLMediaElement::enterFullscreen");
-
+#if ENABLE(FULLSCREEN_API)
+ if (document() && document()->settings() && document()->settings()->fullScreenEnabled()) {
+ webkitRequestFullScreen(0);
+ return;
+ }
+#endif
ASSERT(!m_isFullscreen);
m_isFullscreen = true;
+ if (hasMediaControls())
+ mediaControls()->enteredFullscreen();
if (document() && document()->page()) {
document()->page()->chrome()->client()->enterFullscreenForNode(this);
scheduleEvent(eventNames().webkitbeginfullscreenEvent);
@@ -2471,9 +2523,17 @@ void HTMLMediaElement::enterFullscreen()
void HTMLMediaElement::exitFullscreen()
{
LOG(Media, "HTMLMediaElement::exitFullscreen");
-
+#if ENABLE(FULLSCREEN_API)
+ if (document() && document()->settings() && document()->settings()->fullScreenEnabled()) {
+ if (document()->webkitIsFullScreen() && document()->webkitCurrentFullScreenElement() == this)
+ document()->webkitCancelFullScreen();
+ return;
+ }
+#endif
ASSERT(m_isFullscreen);
m_isFullscreen = false;
+ if (hasMediaControls())
+ mediaControls()->exitedFullscreen();
if (document() && document()->page()) {
if (document()->page()->chrome()->requiresFullscreenForVideoPlayback())
pauseInternal();
@@ -2606,15 +2666,44 @@ void HTMLMediaElement::privateBrowsingStateDidChange()
MediaControls* HTMLMediaElement::mediaControls()
{
- ASSERT(renderer());
- return toRenderMedia(renderer())->controls();
+ if (!shadowRoot())
+ return 0;
+
+ Node* node = shadowRoot()->firstChild();
+ ASSERT(node->isHTMLElement());
+ return static_cast<MediaControls*>(node);
+}
+
+bool HTMLMediaElement::hasMediaControls()
+{
+ return shadowRoot();
+}
+
+void HTMLMediaElement::ensureMediaControls()
+{
+ if (hasMediaControls())
+ return;
+
+ ExceptionCode ec;
+ ensureShadowRoot()->appendChild(MediaControls::create(this), ec);
}
-bool HTMLMediaElement::hasMediaControls() const
+void* HTMLMediaElement::preDispatchEventHandler(Event* event)
{
- return renderer() && renderer()->isMedia();
+ if (event && event->type() == eventNames().webkitfullscreenchangeEvent) {
+ if (controls()) {
+ if (!hasMediaControls()) {
+ ensureMediaControls();
+ mediaControls()->reset();
+ }
+ mediaControls()->show();
+ } else if (hasMediaControls())
+ mediaControls()->hide();
+ }
+ return 0;
}
+
}
#endif
diff --git a/Source/WebCore/html/HTMLMediaElement.h b/Source/WebCore/html/HTMLMediaElement.h
index ea958fa..604cdf8 100644
--- a/Source/WebCore/html/HTMLMediaElement.h
+++ b/Source/WebCore/html/HTMLMediaElement.h
@@ -212,7 +212,7 @@ protected:
virtual void willMoveToNewOwnerDocument();
virtual void didMoveToNewOwnerDocument();
- enum DisplayMode { Unknown, None, Poster, Video };
+ enum DisplayMode { Unknown, None, Poster, PosterWaitingForVideo, Video };
DisplayMode displayMode() const { return m_displayMode; }
virtual void setDisplayMode(DisplayMode mode) { m_displayMode = mode; }
@@ -257,6 +257,7 @@ private:
virtual void mediaPlayerRenderingModeChanged(MediaPlayer*);
#endif
virtual void mediaPlayerEngineUpdated(MediaPlayer*);
+ virtual void mediaPlayerFirstVideoFrameAvailable(MediaPlayer*);
void loadTimerFired(Timer<HTMLMediaElement>*);
void asyncEventTimerFired(Timer<HTMLMediaElement>*);
@@ -323,7 +324,10 @@ private:
void invalidateCachedTime();
void refreshCachedTime() const;
- bool hasMediaControls() const;
+ bool hasMediaControls();
+ void ensureMediaControls();
+
+ virtual void* preDispatchEventHandler(Event*);
Timer<HTMLMediaElement> m_loadTimer;
Timer<HTMLMediaElement> m_asyncEventTimer;
@@ -331,7 +335,7 @@ private:
Timer<HTMLMediaElement> m_playbackProgressTimer;
Vector<RefPtr<Event> > m_pendingEvents;
RefPtr<TimeRanges> m_playedTimeRanges;
-
+
float m_playbackRate;
float m_defaultPlaybackRate;
bool m_webkitPreservesPitch;
@@ -404,6 +408,7 @@ private:
bool m_isFullscreen : 1;
bool m_closedCaptionsVisible : 1;
+ bool m_mouseOver : 1;
#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
bool m_needWidgetUpdate : 1;
diff --git a/Source/WebCore/html/HTMLMeterElement.cpp b/Source/WebCore/html/HTMLMeterElement.cpp
index 2ebf57e..88b1622 100644
--- a/Source/WebCore/html/HTMLMeterElement.cpp
+++ b/Source/WebCore/html/HTMLMeterElement.cpp
@@ -29,7 +29,9 @@
#include "HTMLFormElement.h"
#include "HTMLNames.h"
#include "HTMLParserIdioms.h"
+#include "MeterShadowElement.h"
#include "RenderMeter.h"
+#include "ShadowRoot.h"
#include <wtf/StdLibExtras.h>
namespace WebCore {
@@ -42,9 +44,15 @@ HTMLMeterElement::HTMLMeterElement(const QualifiedName& tagName, Document* docum
ASSERT(hasTagName(meterTag));
}
+HTMLMeterElement::~HTMLMeterElement()
+{
+}
+
PassRefPtr<HTMLMeterElement> HTMLMeterElement::create(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
{
- return adoptRef(new HTMLMeterElement(tagName, document, form));
+ RefPtr<HTMLMeterElement> meter = adoptRef(new HTMLMeterElement(tagName, document, form));
+ meter->createShadowSubtree();
+ return meter;
}
RenderObject* HTMLMeterElement::createRenderer(RenderArena* arena, RenderStyle*)
@@ -60,18 +68,16 @@ const AtomicString& HTMLMeterElement::formControlType() const
void HTMLMeterElement::parseMappedAttribute(Attribute* attribute)
{
- if (attribute->name() == valueAttr || attribute->name() == minAttr || attribute->name() == maxAttr || attribute->name() == lowAttr || attribute->name() == highAttr || attribute->name() == optimumAttr) {
- if (renderer())
- renderer()->updateFromElement();
- } else
+ if (attribute->name() == valueAttr || attribute->name() == minAttr || attribute->name() == maxAttr || attribute->name() == lowAttr || attribute->name() == highAttr || attribute->name() == optimumAttr)
+ didElementStateChange();
+ else
HTMLFormControlElement::parseMappedAttribute(attribute);
}
void HTMLMeterElement::attach()
{
HTMLFormControlElement::attach();
- if (renderer())
- renderer()->updateFromElement();
+ didElementStateChange();
}
double HTMLMeterElement::min() const
@@ -203,5 +209,30 @@ HTMLMeterElement::GaugeRegion HTMLMeterElement::gaugeRegion() const
return GaugeRegionSuboptimal;
}
+double HTMLMeterElement::valueRatio() const
+{
+ double min = this->min();
+ double max = this->max();
+ double value = this->value();
+
+ if (max <= min)
+ return 0;
+ return (value - min) / (max - min);
+}
+
+void HTMLMeterElement::didElementStateChange()
+{
+ m_value->setWidthPercentage(valueRatio()*100);
+}
+
+void HTMLMeterElement::createShadowSubtree()
+{
+ RefPtr<MeterBarElement> bar = MeterBarElement::create(document());
+ m_value = MeterValueElement::create(document());
+ ExceptionCode ec = 0;
+ bar->appendChild(m_value, ec);
+ ensureShadowRoot()->appendChild(bar, ec);
+}
+
} // namespace
#endif
diff --git a/Source/WebCore/html/HTMLMeterElement.h b/Source/WebCore/html/HTMLMeterElement.h
index d5038e0..5ce1193 100644
--- a/Source/WebCore/html/HTMLMeterElement.h
+++ b/Source/WebCore/html/HTMLMeterElement.h
@@ -26,6 +26,8 @@
namespace WebCore {
+class MeterValueElement;
+
class HTMLMeterElement : public HTMLFormControlElement {
public:
static PassRefPtr<HTMLMeterElement> create(const QualifiedName&, Document*, HTMLFormElement*);
@@ -54,19 +56,23 @@ public:
double optimum() const;
void setOptimum(double, ExceptionCode&);
+ double valueRatio() const;
GaugeRegion gaugeRegion() const;
+
private:
HTMLMeterElement(const QualifiedName&, Document*, HTMLFormElement*);
+ virtual ~HTMLMeterElement();
virtual bool recalcWillValidate() const { return false; }
-
virtual const AtomicString& formControlType() const;
-
virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
-
virtual void parseMappedAttribute(Attribute*);
-
virtual void attach();
+
+ void didElementStateChange();
+ void createShadowSubtree();
+
+ RefPtr<MeterValueElement> m_value;
};
} // namespace
diff --git a/Source/WebCore/html/HTMLObjectElement.cpp b/Source/WebCore/html/HTMLObjectElement.cpp
index 4f4d0a1..f5f0083 100644
--- a/Source/WebCore/html/HTMLObjectElement.cpp
+++ b/Source/WebCore/html/HTMLObjectElement.cpp
@@ -236,17 +236,19 @@ bool HTMLObjectElement::hasFallbackContent() const
return false;
}
-inline bool HTMLObjectElement::hasValidClassId()
+bool HTMLObjectElement::hasValidClassId()
{
+#if PLATFORM(QT)
+ if (equalIgnoringCase(serviceType(), "application/x-qt-plugin") || equalIgnoringCase(serviceType(), "application/x-qt-styled-widget"))
+ return true;
+#endif
+
+ if (MIMETypeRegistry::isJavaAppletMIMEType(serviceType()) && classId().startsWith("java:", false))
+ return true;
+
// HTML5 says that fallback content should be rendered if a non-empty
// classid is specified for which the UA can't find a suitable plug-in.
- // WebKit supports no classids, with the exception of Qt plug-ins, which use
- // classid to specify which QObject to load.
-#if PLATFORM(QT)
- return classId().isEmpty() || equalIgnoringCase(serviceType(), "application/x-qt-plugin") || equalIgnoringCase(serviceType(), "application/x-qt-styled-widget");
-#else
return classId().isEmpty();
-#endif
}
// FIXME: This should be unified with HTMLEmbedElement::updateWidget and
diff --git a/Source/WebCore/html/HTMLObjectElement.h b/Source/WebCore/html/HTMLObjectElement.h
index 82d63f7..b929ad5 100644
--- a/Source/WebCore/html/HTMLObjectElement.h
+++ b/Source/WebCore/html/HTMLObjectElement.h
@@ -50,7 +50,6 @@ public:
virtual bool isFormControlElement() const { return false; }
virtual bool isEnumeratable() const { return true; }
- virtual bool isResettable() const { return false; }
virtual bool appendFormData(FormDataList&, bool);
// Implementations of constraint validation API.
diff --git a/Source/WebCore/html/HTMLOutputElement.h b/Source/WebCore/html/HTMLOutputElement.h
index 4c5c684..83ecee2 100644
--- a/Source/WebCore/html/HTMLOutputElement.h
+++ b/Source/WebCore/html/HTMLOutputElement.h
@@ -56,7 +56,6 @@ private:
virtual void parseMappedAttribute(Attribute*);
virtual const AtomicString& formControlType() const;
virtual bool isEnumeratable() const { return true; }
- virtual bool isResettable() const { return true; }
virtual void childrenChanged(bool createdByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
virtual void reset();
diff --git a/Source/WebCore/html/HTMLProgressElement.cpp b/Source/WebCore/html/HTMLProgressElement.cpp
index cab0429..710f7e4 100644
--- a/Source/WebCore/html/HTMLProgressElement.cpp
+++ b/Source/WebCore/html/HTMLProgressElement.cpp
@@ -30,23 +30,33 @@
#include "HTMLFormElement.h"
#include "HTMLNames.h"
#include "HTMLParserIdioms.h"
-#include "ProgressBarValueElement.h"
+#include "ProgressShadowElement.h"
#include "RenderProgress.h"
+#include "ShadowRoot.h"
#include <wtf/StdLibExtras.h>
namespace WebCore {
using namespace HTMLNames;
+const double HTMLProgressElement::IndeterminatePosition = -1;
+const double HTMLProgressElement::InvalidPosition = -2;
+
HTMLProgressElement::HTMLProgressElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
: HTMLFormControlElement(tagName, document, form)
{
ASSERT(hasTagName(progressTag));
}
+HTMLProgressElement::~HTMLProgressElement()
+{
+}
+
PassRefPtr<HTMLProgressElement> HTMLProgressElement::create(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
{
- return adoptRef(new HTMLProgressElement(tagName, document, form));
+ RefPtr<HTMLProgressElement> progress = adoptRef(new HTMLProgressElement(tagName, document, form));
+ progress->createShadowSubtree();
+ return progress;
}
RenderObject* HTMLProgressElement::createRenderer(RenderArena* arena, RenderStyle*)
@@ -72,7 +82,6 @@ void HTMLProgressElement::parseMappedAttribute(Attribute* attribute)
void HTMLProgressElement::attach()
{
- createShadowSubtreeIfNeeded();
HTMLFormControlElement::attach();
didElementStateChange();
}
@@ -117,21 +126,24 @@ void HTMLProgressElement::setMax(double max, ExceptionCode& ec)
double HTMLProgressElement::position() const
{
if (!hasAttribute(valueAttr))
- return -1;
+ return HTMLProgressElement::IndeterminatePosition;
return value() / max();
}
void HTMLProgressElement::didElementStateChange()
{
+ m_value->setWidthPercentage(position()*100);
if (renderer())
renderer()->updateFromElement();
}
-void HTMLProgressElement::createShadowSubtreeIfNeeded()
+void HTMLProgressElement::createShadowSubtree()
{
- if (shadowRoot())
- return;
- setShadowRoot(ProgressBarValueElement::create(document()).get());
+ RefPtr<ProgressBarElement> bar = ProgressBarElement::create(document());
+ m_value = ProgressValueElement::create(document());
+ ExceptionCode ec = 0;
+ bar->appendChild(m_value, ec);
+ ensureShadowRoot()->appendChild(bar, ec);
}
} // namespace
diff --git a/Source/WebCore/html/HTMLProgressElement.h b/Source/WebCore/html/HTMLProgressElement.h
index a0db966..42109f7 100644
--- a/Source/WebCore/html/HTMLProgressElement.h
+++ b/Source/WebCore/html/HTMLProgressElement.h
@@ -26,8 +26,13 @@
namespace WebCore {
+class ProgressValueElement;
+
class HTMLProgressElement : public HTMLFormControlElement {
public:
+ static const double IndeterminatePosition;
+ static const double InvalidPosition;
+
static PassRefPtr<HTMLProgressElement> create(const QualifiedName&, Document*, HTMLFormElement*);
double value() const;
@@ -40,6 +45,7 @@ public:
private:
HTMLProgressElement(const QualifiedName&, Document*, HTMLFormElement*);
+ virtual ~HTMLProgressElement();
virtual bool recalcWillValidate() const { return false; }
@@ -52,7 +58,9 @@ private:
virtual void attach();
void didElementStateChange();
- void createShadowSubtreeIfNeeded();
+ void createShadowSubtree();
+
+ RefPtr<ProgressValueElement> m_value;
};
} // namespace
diff --git a/Source/WebCore/html/HTMLSelectElement.h b/Source/WebCore/html/HTMLSelectElement.h
index 837675c..e6e1bec 100644
--- a/Source/WebCore/html/HTMLSelectElement.h
+++ b/Source/WebCore/html/HTMLSelectElement.h
@@ -107,7 +107,6 @@ private:
virtual bool canStartSelection() const { return false; }
virtual bool isEnumeratable() const { return true; }
- virtual bool isResettable() const { return true; }
virtual bool saveFormControlState(String& value) const;
virtual void restoreFormControlState(const String&);
diff --git a/Source/WebCore/html/HTMLSummaryElement.cpp b/Source/WebCore/html/HTMLSummaryElement.cpp
index 9c2222a..1a1fefc 100644
--- a/Source/WebCore/html/HTMLSummaryElement.cpp
+++ b/Source/WebCore/html/HTMLSummaryElement.cpp
@@ -21,8 +21,11 @@
#include "config.h"
#include "HTMLSummaryElement.h"
+#include "DetailsMarkerControl.h"
#include "HTMLDetailsElement.h"
#include "HTMLNames.h"
+#include "MouseEvent.h"
+#include "PlatformMouseEvent.h"
#include "RenderSummary.h"
namespace WebCore {
@@ -31,7 +34,9 @@ using namespace HTMLNames;
PassRefPtr<HTMLSummaryElement> HTMLSummaryElement::create(const QualifiedName& tagName, Document* document)
{
- return adoptRef(new HTMLSummaryElement(tagName, document));
+ RefPtr<HTMLSummaryElement> result = adoptRef(new HTMLSummaryElement(tagName, document));
+ result->createShadowSubtree();
+ return result;
}
HTMLSummaryElement::HTMLSummaryElement(const QualifiedName& tagName, Document* document)
@@ -45,4 +50,40 @@ RenderObject* HTMLSummaryElement::createRenderer(RenderArena* arena, RenderStyle
return new (arena) RenderSummary(this);
}
+void HTMLSummaryElement::createShadowSubtree()
+{
+ ExceptionCode ec = 0;
+ ensureShadowRoot()->appendChild(DetailsMarkerControl::create(document()), ec, true);
+}
+
+HTMLDetailsElement* HTMLSummaryElement::detailsElement() const
+{
+ Element* mayDetails = toElement(parentNodeForRenderingAndStyle());
+ if (!mayDetails || !mayDetails->hasTagName(detailsTag))
+ return 0;
+ return static_cast<HTMLDetailsElement*>(mayDetails);
+}
+
+bool HTMLSummaryElement::isMainSummary() const
+{
+ if (HTMLDetailsElement* details = detailsElement())
+ return details->mainSummary() == this;
+ return 0;
+}
+
+void HTMLSummaryElement::defaultEventHandler(Event* event)
+{
+ HTMLElement::defaultEventHandler(event);
+ if (!isMainSummary() || !renderer() || !renderer()->isSummary() || !event->isMouseEvent() || event->type() != eventNames().clickEvent || event->defaultHandled())
+ return;
+
+ MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
+ if (mouseEvent->button() != LeftButton)
+ return;
+
+ if (HTMLDetailsElement* details = detailsElement())
+ details->toggleOpen();
+ event->setDefaultHandled();
+}
+
}
diff --git a/Source/WebCore/html/HTMLSummaryElement.h b/Source/WebCore/html/HTMLSummaryElement.h
index 1a93ee9..7e3766a 100644
--- a/Source/WebCore/html/HTMLSummaryElement.h
+++ b/Source/WebCore/html/HTMLSummaryElement.h
@@ -25,14 +25,22 @@
namespace WebCore {
+class HTMLDetailsElement;
+
class HTMLSummaryElement : public HTMLElement {
public:
static PassRefPtr<HTMLSummaryElement> create(const QualifiedName&, Document*);
+ bool isMainSummary() const;
private:
HTMLSummaryElement(const QualifiedName&, Document*);
virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
+ virtual void defaultEventHandler(Event*);
+ virtual void createShadowSubtree();
+ virtual bool canHaveLightChildRendererWithShadow() const { return true; }
+
+ HTMLDetailsElement* detailsElement() const;
};
}
diff --git a/Source/WebCore/html/HTMLTagNames.in b/Source/WebCore/html/HTMLTagNames.in
index bea63e4..0bf4ff9 100644
--- a/Source/WebCore/html/HTMLTagNames.in
+++ b/Source/WebCore/html/HTMLTagNames.in
@@ -126,7 +126,7 @@ th interfaceName=HTMLTableCellElement
thead interfaceName=HTMLTableSectionElement
title
tr interfaceName=HTMLTableRowElement
-track interfaceName=HTMLElement
+track wrapperOnlyIfMediaIsAvailable, conditional=VIDEO_TRACK
tt interfaceName=HTMLElement
u interfaceName=HTMLElement
ul interfaceName=HTMLUListElement
diff --git a/Source/WebCore/html/HTMLTextAreaElement.cpp b/Source/WebCore/html/HTMLTextAreaElement.cpp
index c8ec9ab..5b12a14 100644
--- a/Source/WebCore/html/HTMLTextAreaElement.cpp
+++ b/Source/WebCore/html/HTMLTextAreaElement.cpp
@@ -108,7 +108,8 @@ void HTMLTextAreaElement::restoreFormControlState(const String& state)
void HTMLTextAreaElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
{
- setNonDirtyValue(defaultValue());
+ if (!m_isDirty)
+ setNonDirtyValue(defaultValue());
HTMLElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
}
@@ -347,12 +348,6 @@ String HTMLTextAreaElement::defaultValue() const
value += static_cast<Text*>(n)->data();
}
- UChar firstCharacter = value[0];
- if (firstCharacter == '\r' && value[1] == '\n')
- value.remove(0, 2);
- else if (firstCharacter == '\r' || firstCharacter == '\n')
- value.remove(0, 1);
-
return value;
}
@@ -371,17 +366,14 @@ void HTMLTextAreaElement::setDefaultValue(const String& defaultValue)
removeChild(textNodes[i].get(), ec);
// Normalize line endings.
- // Add an extra line break if the string starts with one, since
- // the code to read default values from the DOM strips the leading one.
String value = defaultValue;
value.replace("\r\n", "\n");
value.replace('\r', '\n');
- if (value[0] == '\n')
- value = "\n" + value;
insertBefore(document()->createTextNode(value), firstChild(), ec);
- setNonDirtyValue(value);
+ if (!m_isDirty)
+ setNonDirtyValue(value);
}
int HTMLTextAreaElement::maxLength() const
diff --git a/Source/WebCore/html/HTMLTextAreaElement.h b/Source/WebCore/html/HTMLTextAreaElement.h
index 40193a0..1ab8ba7 100644
--- a/Source/WebCore/html/HTMLTextAreaElement.h
+++ b/Source/WebCore/html/HTMLTextAreaElement.h
@@ -82,7 +82,6 @@ private:
virtual void defaultEventHandler(Event*);
virtual bool isEnumeratable() const { return true; }
- virtual bool isResettable() const { return true; }
virtual const AtomicString& formControlType() const;
diff --git a/Source/WebCore/html/HTMLTitleElement.cpp b/Source/WebCore/html/HTMLTitleElement.cpp
index 78c8b6a..b046c7b 100644
--- a/Source/WebCore/html/HTMLTitleElement.cpp
+++ b/Source/WebCore/html/HTMLTitleElement.cpp
@@ -25,6 +25,7 @@
#include "Document.h"
#include "HTMLNames.h"
+#include "RenderStyle.h"
#include "Text.h"
namespace WebCore {
@@ -33,7 +34,6 @@ using namespace HTMLNames;
inline HTMLTitleElement::HTMLTitleElement(const QualifiedName& tagName, Document* document)
: HTMLElement(tagName, document)
- , m_title("")
{
ASSERT(hasTagName(titleTag));
}
@@ -57,7 +57,7 @@ void HTMLTitleElement::removedFromDocument()
void HTMLTitleElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
{
- m_title = text();
+ m_title = textWithDirection();
if (inDocument())
document()->setTitleElement(m_title, this);
HTMLElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
@@ -71,10 +71,20 @@ String HTMLTitleElement::text() const
if (n->isTextNode())
val += static_cast<Text*>(n)->data();
}
-
+
return val;
}
+StringWithDirection HTMLTitleElement::textWithDirection()
+{
+ TextDirection direction = LTR;
+ if (RenderStyle* style = computedStyle())
+ direction = style->direction();
+ else if (RefPtr<RenderStyle> style = styleForRenderer())
+ direction = style->direction();
+ return StringWithDirection(text(), direction);
+}
+
void HTMLTitleElement::setText(const String &value)
{
ExceptionCode ec = 0;
diff --git a/Source/WebCore/html/HTMLTitleElement.h b/Source/WebCore/html/HTMLTitleElement.h
index 8b90f56..6920997 100644
--- a/Source/WebCore/html/HTMLTitleElement.h
+++ b/Source/WebCore/html/HTMLTitleElement.h
@@ -23,6 +23,7 @@
#define HTMLTitleElement_h
#include "HTMLElement.h"
+#include "StringWithDirection.h"
namespace WebCore {
@@ -33,6 +34,8 @@ public:
String text() const;
void setText(const String&);
+ StringWithDirection textWithDirection();
+
private:
HTMLTitleElement(const QualifiedName&, Document*);
@@ -40,7 +43,7 @@ private:
virtual void removedFromDocument();
virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
- String m_title;
+ StringWithDirection m_title;
};
} //namespace
diff --git a/Source/WebCore/html/HTMLTrackElement.cpp b/Source/WebCore/html/HTMLTrackElement.cpp
new file mode 100644
index 0000000..63f2788
--- /dev/null
+++ b/Source/WebCore/html/HTMLTrackElement.cpp
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(VIDEO_TRACK)
+#include "HTMLTrackElement.h"
+
+#include "HTMLMediaElement.h"
+#include "HTMLNames.h"
+#include "Logging.h"
+
+using namespace std;
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLTrackElement::HTMLTrackElement(const QualifiedName& tagName, Document* document)
+ : HTMLElement(tagName, document)
+{
+ LOG(Media, "HTMLTrackElement::HTMLTrackElement - %p", this);
+ ASSERT(hasTagName(trackTag));
+}
+
+PassRefPtr<HTMLTrackElement> HTMLTrackElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLTrackElement(tagName, document));
+}
+
+void HTMLTrackElement::insertedIntoTree(bool deep)
+{
+ HTMLElement::insertedIntoTree(deep);
+ if (parentNode() && (parentNode()->hasTagName(audioTag) || parentNode()->hasTagName(videoTag))) {
+ // TODO(annacc):
+ // static_cast<HTMLMediaElement*>(parentNode())->trackWasAdded(this);
+ }
+}
+
+void HTMLTrackElement::willRemove()
+{
+ if (parentNode() && (parentNode()->hasTagName(audioTag) || parentNode()->hasTagName(videoTag))) {
+ // TODO(annacc):
+ // static_cast<HTMLMediaElement*>(parentNode())->trackWillBeRemoved(this);
+ }
+ HTMLElement::willRemove();
+}
+
+KURL HTMLTrackElement::src() const
+{
+ return document()->completeURL(getAttribute(srcAttr));
+}
+
+void HTMLTrackElement::setSrc(const String& url)
+{
+ setAttribute(srcAttr, url);
+}
+
+String HTMLTrackElement::kind() const
+{
+ return getAttribute(kindAttr);
+}
+
+void HTMLTrackElement::setKind(const String& kind)
+{
+ setAttribute(kindAttr, kind);
+}
+
+String HTMLTrackElement::srclang() const
+{
+ return getAttribute(srclangAttr);
+}
+
+void HTMLTrackElement::setSrclang(const String& srclang)
+{
+ setAttribute(srclangAttr, srclang);
+}
+
+String HTMLTrackElement::label() const
+{
+ return getAttribute(labelAttr);
+}
+
+void HTMLTrackElement::setLabel(const String& label)
+{
+ setAttribute(labelAttr, label);
+}
+
+bool HTMLTrackElement::isDefault() const
+{
+ return hasAttribute(defaultAttr);
+}
+
+void HTMLTrackElement::setIsDefault(bool isDefault)
+{
+ setBooleanAttribute(defaultAttr, isDefault);
+}
+
+bool HTMLTrackElement::isURLAttribute(Attribute* attribute) const
+{
+ return attribute->name() == srcAttr;
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/html/HTMLTrackElement.h b/Source/WebCore/html/HTMLTrackElement.h
new file mode 100644
index 0000000..4697e02
--- /dev/null
+++ b/Source/WebCore/html/HTMLTrackElement.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HTMLTrackElement_h
+#define HTMLTrackElement_h
+
+#if ENABLE(VIDEO_TRACK)
+
+#include "HTMLElement.h"
+
+namespace WebCore {
+
+class HTMLTrackElement : public HTMLElement {
+public:
+ static PassRefPtr<HTMLTrackElement> create(const QualifiedName&, Document*);
+
+ KURL src() const;
+ String kind() const;
+ String srclang() const;
+ String label() const;
+
+ bool isDefault() const;
+ void setKind(const String&);
+ void setSrc(const String&);
+ void setSrclang(const String&);
+ void setLabel(const String&);
+ void setIsDefault(bool);
+
+private:
+ HTMLTrackElement(const QualifiedName&, Document*);
+
+ virtual void insertedIntoTree(bool);
+ virtual void willRemove();
+ virtual bool isURLAttribute(Attribute*) const;
+};
+
+}
+
+#endif
+#endif
diff --git a/Source/WebCore/html/HTMLTrackElement.idl b/Source/WebCore/html/HTMLTrackElement.idl
new file mode 100644
index 0000000..309f0f0
--- /dev/null
+++ b/Source/WebCore/html/HTMLTrackElement.idl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module html {
+interface [Conditional=VIDEO_TRACK] HTMLTrackElement : HTMLElement {
+ attribute [Reflect, URL] DOMString src;
+ attribute DOMString kind;
+ attribute DOMString srclang;
+ attribute DOMString label;
+ attribute [Reflect=default] boolean isDefault;
+
+ // readonly attribute TextTrack track;
+};
+}
diff --git a/Source/WebCore/html/HTMLVideoElement.cpp b/Source/WebCore/html/HTMLVideoElement.cpp
index 4ddcdfe..5b7f42d 100644
--- a/Source/WebCore/html/HTMLVideoElement.cpp
+++ b/Source/WebCore/html/HTMLVideoElement.cpp
@@ -129,6 +129,11 @@ bool HTMLVideoElement::supportsFullscreen() const
return false;
// Check with the platform client.
+#if ENABLE(FULLSCREEN_API)
+ if (page->chrome()->client()->supportsFullScreenForElement(this, false))
+ return true;
+#endif
+
return page->chrome()->client()->supportsFullscreenForNode(this);
}
@@ -183,7 +188,7 @@ void HTMLVideoElement::setDisplayMode(DisplayMode mode)
if (oldMode != Video && player())
player()->prepareForRendering();
if (!hasAvailableVideoFrame())
- mode = Poster;
+ mode = PosterWaitingForVideo;
}
} else if (oldMode != Video && player())
player()->prepareForRendering();
diff --git a/Source/WebCore/html/HTMLVideoElement.h b/Source/WebCore/html/HTMLVideoElement.h
index 714fcaa..57b70ea 100644
--- a/Source/WebCore/html/HTMLVideoElement.h
+++ b/Source/WebCore/html/HTMLVideoElement.h
@@ -64,7 +64,7 @@ public:
// Used by canvas to gain raw pixel access
void paintCurrentFrameInContext(GraphicsContext*, const IntRect&);
- bool shouldDisplayPosterImage() const { return displayMode() == Poster; }
+ bool shouldDisplayPosterImage() const { return displayMode() == Poster || displayMode() == PosterWaitingForVideo; }
private:
HTMLVideoElement(const QualifiedName&, Document*);
diff --git a/Source/WebCore/html/InputType.cpp b/Source/WebCore/html/InputType.cpp
index d944909..9756313 100644
--- a/Source/WebCore/html/InputType.cpp
+++ b/Source/WebCore/html/InputType.cpp
@@ -55,6 +55,7 @@
#include "RenderObject.h"
#include "ResetInputType.h"
#include "SearchInputType.h"
+#include "ShadowRoot.h"
#include "SubmitInputType.h"
#include "TelephoneInputType.h"
#include "TextInputType.h"
@@ -365,7 +366,7 @@ void InputType::createShadowSubtree()
void InputType::destroyShadowSubtree()
{
- element()->setShadowRoot(0);
+ element()->removeShadowRoot();
}
double InputType::parseToDouble(const String&, double defaultValue) const
diff --git a/Source/WebCore/html/RangeInputType.cpp b/Source/WebCore/html/RangeInputType.cpp
index cbec740..22e7f8e 100644
--- a/Source/WebCore/html/RangeInputType.cpp
+++ b/Source/WebCore/html/RangeInputType.cpp
@@ -39,6 +39,7 @@
#include "MouseEvent.h"
#include "PlatformMouseEvent.h"
#include "RenderSlider.h"
+#include "ShadowRoot.h"
#include "SliderThumbElement.h"
#include "StepRange.h"
#include <limits>
@@ -152,7 +153,7 @@ void RangeInputType::handleMouseDownEvent(MouseEvent* event)
if (event->button() != LeftButton || event->target() != element())
return;
- if (SliderThumbElement* thumb = toSliderThumbElement(element()->shadowRoot()))
+ if (SliderThumbElement* thumb = shadowSliderThumb())
thumb->dragFrom(event->absoluteLocation());
}
@@ -216,7 +217,8 @@ void RangeInputType::handleTouchStartEvent(TouchEvent* touchEvent)
void RangeInputType::createShadowSubtree()
{
- element()->setShadowRoot(SliderThumbElement::create(element()->document()));
+ ExceptionCode ec = 0;
+ element()->ensureShadowRoot()->appendChild(SliderThumbElement::create(element()->document()), ec);
}
RenderObject* RangeInputType::createRenderer(RenderArena* arena, RenderStyle*) const
@@ -261,7 +263,7 @@ void RangeInputType::minOrMaxAttributeChanged()
void RangeInputType::valueChanged()
{
- toSliderThumbElement(element()->shadowRoot())->setPositionFromValue();
+ shadowSliderThumb()->setPositionFromValue();
}
String RangeInputType::fallbackValue()
@@ -285,4 +287,10 @@ bool RangeInputType::shouldRespectListAttribute()
return true;
}
+SliderThumbElement* RangeInputType::shadowSliderThumb() const
+{
+ Node* shadow = element()->shadowRoot();
+ return shadow ? toSliderThumbElement(shadow->firstChild()) : 0;
+}
+
} // namespace WebCore
diff --git a/Source/WebCore/html/RangeInputType.h b/Source/WebCore/html/RangeInputType.h
index ac89d02..b7af291 100644
--- a/Source/WebCore/html/RangeInputType.h
+++ b/Source/WebCore/html/RangeInputType.h
@@ -35,6 +35,8 @@
namespace WebCore {
+class SliderThumbElement;
+
class RangeInputType : public InputType {
public:
static PassOwnPtr<InputType> create(HTMLInputElement*);
@@ -67,9 +69,14 @@ private:
virtual String fallbackValue();
virtual String sanitizeValue(const String& proposedValue);
virtual bool shouldRespectListAttribute();
+<<<<<<< HEAD
#if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS)
virtual void handleTouchStartEvent(TouchEvent*);
#endif
+=======
+
+ SliderThumbElement* shadowSliderThumb() const;
+>>>>>>> WebKit.org at r84325
};
} // namespace WebCore
diff --git a/Source/WebCore/html/ValidationMessage.cpp b/Source/WebCore/html/ValidationMessage.cpp
index 59a1467..48912d7 100644
--- a/Source/WebCore/html/ValidationMessage.cpp
+++ b/Source/WebCore/html/ValidationMessage.cpp
@@ -40,6 +40,7 @@
#include "Page.h"
#include "RenderObject.h"
#include "Settings.h"
+#include "ShadowRoot.h"
#include "Text.h"
#include <wtf/PassOwnPtr.h>
@@ -129,12 +130,7 @@ void ValidationMessage::buildBubbleTree(Timer<ValidationMessage>*)
// 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.
- if (host->shadowRoot())
- host->shadowRoot()->appendChild(m_bubble.get(), ec);
- else
- host->setShadowRoot(m_bubble);
+ host->ensureShadowRoot()->appendChild(m_bubble.get(), ec);
RefPtr<HTMLElement> clipper = ElementWithPseudoId::create(doc, "-webkit-validation-bubble-arrow-clipper");
clipper->appendChild(ElementWithPseudoId::create(doc, "-webkit-validation-bubble-arrow"), ec);
@@ -161,12 +157,8 @@ void ValidationMessage::deleteBubbleTree(Timer<ValidationMessage>*)
if (m_bubble) {
m_bubbleMessage = 0;
HTMLElement* host = toHTMLElement(m_element);
- if (m_bubble->isShadowRoot())
- host->setShadowRoot(0);
- else {
- ExceptionCode ec;
- host->shadowRoot()->removeChild(m_bubble.get(), ec);
- }
+ ExceptionCode ec;
+ host->shadowRoot()->removeChild(m_bubble.get(), ec);
m_bubble = 0;
}
m_message = String();
diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp b/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp
index f5ff078..ab6427e 100644
--- a/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp
+++ b/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp
@@ -133,7 +133,11 @@ CanvasRenderingContext2D::CanvasRenderingContext2D(HTMLCanvasElement* canvas, bo
m_context3D = p->sharedGraphicsContext3D();
if (m_context3D) {
m_drawingBuffer = m_context3D->graphicsContext3D()->createDrawingBuffer(IntSize(canvas->width(), canvas->height()));
- c->setSharedGraphicsContext3D(m_context3D.get(), m_drawingBuffer.get(), IntSize(canvas->width(), canvas->height()));
+ if (!m_drawingBuffer) {
+ c->setSharedGraphicsContext3D(0, 0, IntSize());
+ m_context3D.clear();
+ } else
+ c->setSharedGraphicsContext3D(m_context3D.get(), m_drawingBuffer.get(), IntSize(canvas->width(), canvas->height()));
}
}
#endif
@@ -146,7 +150,8 @@ CanvasRenderingContext2D::~CanvasRenderingContext2D()
bool CanvasRenderingContext2D::isAccelerated() const
{
#if USE(IOSURFACE_CANVAS_BACKING_STORE)
- return canvas()->document()->page()->settings()->canvasUsesAcceleratedDrawing();
+ ImageBuffer* buffer = canvas()->buffer();
+ return buffer ? buffer->isAccelerated() : false;
#elif ENABLE(ACCELERATED_2D_CANVAS)
return m_context3D;
#else
@@ -172,13 +177,18 @@ void CanvasRenderingContext2D::reset()
#if ENABLE(ACCELERATED_2D_CANVAS)
if (GraphicsContext* c = drawingContext()) {
if (m_context3D && m_drawingBuffer) {
- m_drawingBuffer->reset(IntSize(canvas()->width(), canvas()->height()));
- c->setSharedGraphicsContext3D(m_context3D.get(), m_drawingBuffer.get(), IntSize(canvas()->width(), canvas()->height()));
+ if (m_drawingBuffer->reset(IntSize(canvas()->width(), canvas()->height()))) {
+ c->setSharedGraphicsContext3D(m_context3D.get(), m_drawingBuffer.get(), IntSize(canvas()->width(), canvas()->height()));
#if USE(ACCELERATED_COMPOSITING)
- RenderBox* renderBox = canvas()->renderBox();
- if (renderBox && renderBox->hasLayer() && renderBox->layer()->hasAcceleratedCompositing())
- renderBox->layer()->contentChanged(RenderLayer::CanvasChanged);
+ RenderBox* renderBox = canvas()->renderBox();
+ if (renderBox && renderBox->hasLayer() && renderBox->layer()->hasAcceleratedCompositing())
+ renderBox->layer()->contentChanged(RenderLayer::CanvasChanged);
#endif
+ } else {
+ c->setSharedGraphicsContext3D(0, 0, IntSize());
+ m_drawingBuffer.clear();
+ m_context3D.clear();
+ }
}
}
#endif
@@ -203,6 +213,83 @@ CanvasRenderingContext2D::State::State()
{
}
+CanvasRenderingContext2D::State::State(const State& other)
+ : FontSelectorClient()
+{
+ m_unparsedStrokeColor = other.m_unparsedStrokeColor;
+ m_unparsedFillColor = other.m_unparsedFillColor;
+ m_strokeStyle = other.m_strokeStyle;
+ m_fillStyle = other.m_fillStyle;
+ m_lineWidth = other.m_lineWidth;
+ m_lineCap = other.m_lineCap;
+ m_lineJoin = other.m_lineJoin;
+ m_miterLimit = other.m_miterLimit;
+ m_shadowOffset = other.m_shadowOffset;
+ m_shadowBlur = other.m_shadowBlur;
+ m_shadowColor = other.m_shadowColor;
+ m_globalAlpha = other.m_globalAlpha;
+ m_globalComposite = other.m_globalComposite;
+ m_transform = other.m_transform;
+ m_invertibleCTM = other.m_invertibleCTM;
+ m_textAlign = other.m_textAlign;
+ m_textBaseline = other.m_textBaseline;
+ m_unparsedFont = other.m_unparsedFont;
+ m_font = other.m_font;
+ m_realizedFont = other.m_realizedFont;
+
+ if (m_realizedFont)
+ m_font.fontSelector()->registerForInvalidationCallbacks(this);
+}
+
+CanvasRenderingContext2D::State& CanvasRenderingContext2D::State::operator=(const State& other)
+{
+ if (this == &other)
+ return *this;
+
+ if (m_realizedFont)
+ m_font.fontSelector()->unregisterForInvalidationCallbacks(this);
+
+ m_unparsedStrokeColor = other.m_unparsedStrokeColor;
+ m_unparsedFillColor = other.m_unparsedFillColor;
+ m_strokeStyle = other.m_strokeStyle;
+ m_fillStyle = other.m_fillStyle;
+ m_lineWidth = other.m_lineWidth;
+ m_lineCap = other.m_lineCap;
+ m_lineJoin = other.m_lineJoin;
+ m_miterLimit = other.m_miterLimit;
+ m_shadowOffset = other.m_shadowOffset;
+ m_shadowBlur = other.m_shadowBlur;
+ m_shadowColor = other.m_shadowColor;
+ m_globalAlpha = other.m_globalAlpha;
+ m_globalComposite = other.m_globalComposite;
+ m_transform = other.m_transform;
+ m_invertibleCTM = other.m_invertibleCTM;
+ m_textAlign = other.m_textAlign;
+ m_textBaseline = other.m_textBaseline;
+ m_unparsedFont = other.m_unparsedFont;
+ m_font = other.m_font;
+ m_realizedFont = other.m_realizedFont;
+
+ if (m_realizedFont)
+ m_font.fontSelector()->registerForInvalidationCallbacks(this);
+
+ return *this;
+}
+
+CanvasRenderingContext2D::State::~State()
+{
+ if (m_realizedFont)
+ m_font.fontSelector()->unregisterForInvalidationCallbacks(this);
+}
+
+void CanvasRenderingContext2D::State::fontsNeedUpdate(FontSelector* fontSelector)
+{
+ ASSERT_ARG(fontSelector, fontSelector == m_font.fontSelector());
+ ASSERT(m_realizedFont);
+
+ m_font.update(fontSelector);
+}
+
void CanvasRenderingContext2D::save()
{
ASSERT(m_stateStack.size() >= 1);
@@ -959,7 +1046,7 @@ void CanvasRenderingContext2D::strokeRect(float x, float y, float width, float h
didDraw(boundingRect);
}
-#if PLATFORM(CG)
+#if USE(CG)
static inline CGSize adjustedShadowSize(CGFloat width, CGFloat height)
{
// Work around <rdar://problem/5539388> by ensuring that shadow offsets will get truncated
@@ -1063,7 +1150,7 @@ void CanvasRenderingContext2D::setShadow(float width, float height, float blur,
GraphicsContext* dc = drawingContext();
if (!dc)
return;
-#if PLATFORM(CG)
+#if USE(CG)
const CGFloat components[5] = { c, m, y, k, a };
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceCMYK();
CGColorRef shadowColor = CGColorCreate(colorSpace, components);
@@ -1150,8 +1237,12 @@ void CanvasRenderingContext2D::drawImage(HTMLImageElement* image,
drawImage(image, FloatRect(sx, sy, sw, sh), FloatRect(dx, dy, dw, dh), ec);
}
-void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, const FloatRect& srcRect, const FloatRect& dstRect,
- ExceptionCode& ec)
+void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, const FloatRect& srcRect, const FloatRect& dstRect, ExceptionCode& ec)
+{
+ drawImage(image, srcRect, dstRect, state().m_globalComposite, ec);
+}
+
+void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, const FloatRect& srcRect, const FloatRect& dstRect, const CompositeOperator& op, ExceptionCode& ec)
{
if (!image) {
ec = TYPE_MISMATCH_ERR;
@@ -1193,7 +1284,7 @@ void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, const FloatRec
FloatRect sourceRect = c->roundToDevicePixels(normalizedSrcRect);
FloatRect destRect = c->roundToDevicePixels(normalizedDstRect);
- c->drawImage(cachedImage->image(), ColorSpaceDeviceRGB, destRect, sourceRect, state().m_globalComposite);
+ c->drawImage(cachedImage->image(), ColorSpaceDeviceRGB, destRect, sourceRect, op);
didDraw(destRect);
}
@@ -1352,34 +1443,17 @@ void CanvasRenderingContext2D::drawImage(HTMLVideoElement* video, const FloatRec
}
#endif
-// FIXME: Why isn't this just another overload of drawImage? Why have a different name?
void CanvasRenderingContext2D::drawImageFromRect(HTMLImageElement* image,
float sx, float sy, float sw, float sh,
float dx, float dy, float dw, float dh,
const String& compositeOperation)
{
- if (!image)
- return;
-
- CachedImage* cachedImage = image->cachedImage();
- if (!cachedImage)
- return;
-
- checkOrigin(image);
-
- GraphicsContext* c = drawingContext();
- if (!c)
- return;
- if (!state().m_invertibleCTM)
- return;
-
CompositeOperator op;
if (!parseCompositeOperator(compositeOperation, op))
op = CompositeSourceOver;
- FloatRect destRect = FloatRect(dx, dy, dw, dh);
- c->drawImage(cachedImage->image(), ColorSpaceDeviceRGB, destRect, FloatRect(sx, sy, sw, sh), op);
- didDraw(destRect);
+ ExceptionCode ec;
+ drawImage(image, FloatRect(sx, sy, sw, sh), FloatRect(dx, dy, dw, dh), op, ec);
}
void CanvasRenderingContext2D::setAlpha(float alpha)
@@ -1680,15 +1754,7 @@ void CanvasRenderingContext2D::setFont(const String& newFont)
state().m_font = newStyle->font();
state().m_font.update(styleSelector->fontSelector());
state().m_realizedFont = true;
-}
-
-void CanvasRenderingContext2D::updateFont()
-{
- if (!state().m_realizedFont)
- return;
-
- const Font& font = state().m_font;
- font.update(font.fontSelector());
+ styleSelector->fontSelector()->registerForInvalidationCallbacks(&state());
}
String CanvasRenderingContext2D::textAlign() const
@@ -1825,7 +1891,7 @@ void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, flo
if (!fill)
textRect.inflate(c->strokeThickness() / 2);
-#if PLATFORM(CG)
+#if USE(CG)
CanvasStyle* drawStyle = fill ? state().m_fillStyle.get() : state().m_strokeStyle.get();
if (drawStyle->canvasGradient() || drawStyle->canvasPattern()) {
// FIXME: The rect is not big enough for miters on stroked text.
diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext2D.h b/Source/WebCore/html/canvas/CanvasRenderingContext2D.h
index 206744e..fbaec9e 100644
--- a/Source/WebCore/html/canvas/CanvasRenderingContext2D.h
+++ b/Source/WebCore/html/canvas/CanvasRenderingContext2D.h
@@ -37,7 +37,7 @@
#include <wtf/Vector.h>
-#if PLATFORM(CG)
+#if USE(CG)
#include <ApplicationServices/ApplicationServices.h>
#endif
@@ -175,6 +175,7 @@ public:
void drawImage(HTMLCanvasElement*, float x, float y, float width, float height, ExceptionCode&);
void drawImage(HTMLCanvasElement*, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, ExceptionCode&);
void drawImage(HTMLCanvasElement*, const FloatRect& srcRect, const FloatRect& dstRect, ExceptionCode&);
+ void drawImage(HTMLImageElement*, const FloatRect& srcRect, const FloatRect& dstRect, const CompositeOperator&, ExceptionCode&);
#if ENABLE(VIDEO)
void drawImage(HTMLVideoElement*, float x, float y, ExceptionCode&);
void drawImage(HTMLVideoElement*, float x, float y, float width, float height, ExceptionCode&);
@@ -204,7 +205,6 @@ public:
String font() const;
void setFont(const String&);
- void updateFont();
String textAlign() const;
void setTextAlign(const String&);
@@ -228,8 +228,14 @@ public:
#endif
private:
- struct State {
+ struct State : FontSelectorClient {
State();
+ virtual ~State();
+
+ State(const State&);
+ State& operator=(const State&);
+
+ virtual void fontsNeedUpdate(FontSelector*);
String m_unparsedStrokeColor;
String m_unparsedFillColor;
diff --git a/Source/WebCore/html/canvas/CanvasStyle.cpp b/Source/WebCore/html/canvas/CanvasStyle.cpp
index ee8567c..3aee6e8 100644
--- a/Source/WebCore/html/canvas/CanvasStyle.cpp
+++ b/Source/WebCore/html/canvas/CanvasStyle.cpp
@@ -38,7 +38,7 @@
#include <wtf/Assertions.h>
#include <wtf/PassRefPtr.h>
-#if PLATFORM(CG)
+#if USE(CG)
#include <CoreGraphics/CGContext.h>
#endif
@@ -238,7 +238,7 @@ void CanvasStyle::applyStrokeColor(GraphicsContext* context)
case CMYKA: {
// FIXME: Do this through platform-independent GraphicsContext API.
// We'll need a fancier Color abstraction to support CMYKA correctly
-#if PLATFORM(CG)
+#if USE(CG)
CGContextSetCMYKStrokeColor(context->platformContext(), m_cmyka.c, m_cmyka.m, m_cmyka.y, m_cmyka.k, m_cmyka.a);
#elif PLATFORM(QT)
QPen currentPen = context->platformContext()->pen();
@@ -275,7 +275,7 @@ void CanvasStyle::applyFillColor(GraphicsContext* context)
case CMYKA: {
// FIXME: Do this through platform-independent GraphicsContext API.
// We'll need a fancier Color abstraction to support CMYKA correctly
-#if PLATFORM(CG)
+#if USE(CG)
CGContextSetCMYKFillColor(context->platformContext(), m_cmyka.c, m_cmyka.m, m_cmyka.y, m_cmyka.k, m_cmyka.a);
#elif PLATFORM(QT)
QBrush currentBrush = context->platformContext()->brush();
diff --git a/Source/WebCore/html/canvas/WebGLRenderingContext.cpp b/Source/WebCore/html/canvas/WebGLRenderingContext.cpp
index aa40a64..933d37f 100644
--- a/Source/WebCore/html/canvas/WebGLRenderingContext.cpp
+++ b/Source/WebCore/html/canvas/WebGLRenderingContext.cpp
@@ -458,14 +458,14 @@ void WebGLRenderingContext::setupFlags()
ASSERT(m_context);
m_isGLES2Compliant = m_context->isGLES2Compliant();
- m_isErrorGeneratedOnOutOfBoundsAccesses = m_context->getExtensions()->supports("GL_CHROMIUM_strict_attribs");
- m_isResourceSafe = m_context->getExtensions()->supports("GL_CHROMIUM_resource_safe");
+ m_isErrorGeneratedOnOutOfBoundsAccesses = m_context->getExtensions()->isEnabled("GL_CHROMIUM_strict_attribs");
+ m_isResourceSafe = m_context->getExtensions()->isEnabled("GL_CHROMIUM_resource_safe");
if (m_isGLES2Compliant) {
- m_isGLES2NPOTStrict = !m_context->getExtensions()->supports("GL_OES_texture_npot");
- m_isDepthStencilSupported = m_context->getExtensions()->supports("GL_OES_packed_depth_stencil");
+ m_isGLES2NPOTStrict = !m_context->getExtensions()->isEnabled("GL_OES_texture_npot");
+ m_isDepthStencilSupported = m_context->getExtensions()->isEnabled("GL_OES_packed_depth_stencil");
} else {
- m_isGLES2NPOTStrict = !m_context->getExtensions()->supports("GL_ARB_texture_non_power_of_two");
- m_isDepthStencilSupported = m_context->getExtensions()->supports("GL_EXT_packed_depth_stencil");
+ m_isGLES2NPOTStrict = !m_context->getExtensions()->isEnabled("GL_ARB_texture_non_power_of_two");
+ m_isDepthStencilSupported = m_context->getExtensions()->isEnabled("GL_EXT_packed_depth_stencil");
}
}
@@ -502,12 +502,12 @@ 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;
+ RefPtr<WebGLContextAttributes> contextAttributes = getContextAttributes();
+
// Determine if it's possible to combine the clear the user asked for and this clear.
bool combinedClear = mask && !m_scissorEnabled;
@@ -3140,10 +3140,8 @@ void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum
ec = 0;
if (isContextLost())
return;
- if (!image || !image->cachedImage()) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ if (!validateHTMLImageElement(image))
return;
- }
checkOrigin(image);
texImage2DImpl(target, level, internalformat, format, type, image->cachedImage()->image(),
m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
@@ -3334,10 +3332,8 @@ void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Din
ec = 0;
if (isContextLost())
return;
- if (!image || !image->cachedImage()) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ if (!validateHTMLImageElement(image))
return;
- }
checkOrigin(image);
texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image->cachedImage()->image(),
m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
@@ -4613,6 +4609,20 @@ WebGLBuffer* WebGLRenderingContext::validateBufferDataParameters(GC3Denum target
return 0;
}
+bool WebGLRenderingContext::validateHTMLImageElement(HTMLImageElement* image)
+{
+ if (!image || !image->cachedImage()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return false;
+ }
+ const KURL& url = image->cachedImage()->response().url();
+ if (url.isNull() || url.isEmpty() || !url.isValid()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return false;
+ }
+ return true;
+}
+
void WebGLRenderingContext::vertexAttribfImpl(GC3Duint index, GC3Dsizei expectedSize, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2, GC3Dfloat v3)
{
if (isContextLost())
diff --git a/Source/WebCore/html/canvas/WebGLRenderingContext.h b/Source/WebCore/html/canvas/WebGLRenderingContext.h
index f716efb..23c147d 100644
--- a/Source/WebCore/html/canvas/WebGLRenderingContext.h
+++ b/Source/WebCore/html/canvas/WebGLRenderingContext.h
@@ -590,6 +590,9 @@ public:
// Return the current bound buffer to target, or 0 if parameters are invalid.
WebGLBuffer* validateBufferDataParameters(GC3Denum target, GC3Denum usage);
+ // Helper function for tex{Sub}Image2D to make sure image is ready.
+ bool validateHTMLImageElement(HTMLImageElement*);
+
// Helper functions for vertexAttribNf{v}.
void vertexAttribfImpl(GC3Duint index, GC3Dsizei expectedSize, GC3Dfloat, GC3Dfloat, GC3Dfloat, GC3Dfloat);
void vertexAttribfvImpl(GC3Duint index, Float32Array*, GC3Dsizei expectedSize);
diff --git a/Source/WebCore/html/parser/CSSPreloadScanner.cpp b/Source/WebCore/html/parser/CSSPreloadScanner.cpp
index 23364f9..3c23b9f 100644
--- a/Source/WebCore/html/parser/CSSPreloadScanner.cpp
+++ b/Source/WebCore/html/parser/CSSPreloadScanner.cpp
@@ -54,7 +54,7 @@ void CSSPreloadScanner::scan(const HTMLToken& token, bool scanningBody)
m_scanningBody = scanningBody;
const HTMLToken::DataVector& characters = token.characters();
- for (HTMLToken::DataVector::const_iterator iter = characters.begin(); iter != characters.end(); ++iter)
+ for (HTMLToken::DataVector::const_iterator iter = characters.begin(); iter != characters.end() && m_state != DoneParsingImportRules; ++iter)
tokenize(*iter);
}
@@ -64,10 +64,14 @@ inline void CSSPreloadScanner::tokenize(UChar c)
// Searching for other types of resources is probably low payoff.
switch (m_state) {
case Initial:
+ if (isHTMLSpace(c))
+ break;
if (c == '@')
m_state = RuleStart;
else if (c == '/')
m_state = MaybeComment;
+ else
+ m_state = DoneParsingImportRules;
break;
case MaybeComment:
if (c == '*')
@@ -80,10 +84,10 @@ inline void CSSPreloadScanner::tokenize(UChar c)
m_state = MaybeCommentEnd;
break;
case MaybeCommentEnd:
+ if (c == '*')
+ break;
if (c == '/')
m_state = Initial;
- else if (c == '*')
- ;
else
m_state = Comment;
break;
@@ -106,9 +110,11 @@ inline void CSSPreloadScanner::tokenize(UChar c)
break;
case AfterRule:
if (isHTMLSpace(c))
- ;
- else if (c == ';')
+ break;
+ if (c == ';')
m_state = Initial;
+ else if (c == '{')
+ m_state = DoneParsingImportRules;
else {
m_state = RuleValue;
m_ruleValue.append(c);
@@ -117,23 +123,26 @@ inline void CSSPreloadScanner::tokenize(UChar c)
case RuleValue:
if (isHTMLSpace(c))
m_state = AfterRuleValue;
- else if (c == ';') {
+ else if (c == ';')
emitRule();
- m_state = Initial;
- } else
+ else
m_ruleValue.append(c);
break;
case AfterRuleValue:
if (isHTMLSpace(c))
- ;
- else if (c == ';') {
+ break;
+ if (c == ';')
emitRule();
- m_state = Initial;
- } else {
+ else if (c == '{')
+ m_state = DoneParsingImportRules;
+ else {
// FIXME: media rules
m_state = Initial;
}
break;
+ case DoneParsingImportRules:
+ ASSERT_NOT_REACHED();
+ break;
}
}
@@ -187,7 +196,11 @@ void CSSPreloadScanner::emitRule()
String value = parseCSSStringOrURL(m_ruleValue.data(), m_ruleValue.size());
if (!value.isEmpty())
m_document->cachedResourceLoader()->preload(CachedResource::CSSStyleSheet, value, String(), m_scanningBody);
- }
+ m_state = Initial;
+ } else if (equalIgnoringCase("charset", m_rule.data(), m_rule.size()))
+ m_state = Initial;
+ else
+ m_state = DoneParsingImportRules;
m_rule.clear();
m_ruleValue.clear();
}
diff --git a/Source/WebCore/html/parser/CSSPreloadScanner.h b/Source/WebCore/html/parser/CSSPreloadScanner.h
index fae95a1..e45fa2d 100644
--- a/Source/WebCore/html/parser/CSSPreloadScanner.h
+++ b/Source/WebCore/html/parser/CSSPreloadScanner.h
@@ -53,7 +53,8 @@ private:
Rule,
AfterRule,
RuleValue,
- AfterRuleValue
+ AfterRuleValue,
+ DoneParsingImportRules,
};
inline void tokenize(UChar c);
diff --git a/Source/WebCore/html/parser/HTMLDocumentParser.cpp b/Source/WebCore/html/parser/HTMLDocumentParser.cpp
index 88db3c2..7519699 100644
--- a/Source/WebCore/html/parser/HTMLDocumentParser.cpp
+++ b/Source/WebCore/html/parser/HTMLDocumentParser.cpp
@@ -40,7 +40,6 @@
#include "InspectorInstrumentation.h"
#include "NestingLevelIncrementer.h"
#include "Settings.h"
-#include <wtf/CurrentTime.h>
#ifdef ANDROID_INSTRUMENT
#include "TimeCounter.h"
@@ -331,6 +330,14 @@ void HTMLDocumentParser::insert(const SegmentedString& source)
excludedLineNumberSource.setExcludeLineNumbers();
m_input.insertAtCurrentInsertionPoint(excludedLineNumberSource);
pumpTokenizerIfPossible(ForceSynchronous);
+
+ if (isWaitingForScripts()) {
+ // Check the document.write() output with a separate preload scanner as
+ // the main scanner can't deal with insertions.
+ HTMLPreloadScanner preloadScanner(document());
+ preloadScanner.appendToEnd(source);
+ preloadScanner.scan();
+ }
endIfDelayed();
}
@@ -344,9 +351,19 @@ void HTMLDocumentParser::append(const SegmentedString& source)
// but we need to ensure it isn't deleted yet.
RefPtr<HTMLDocumentParser> protect(this);
+ if (m_preloadScanner) {
+ if (m_input.current().isEmpty() && !isWaitingForScripts()) {
+ // We have parsed until the end of the current input and so are now moving ahead of the preload scanner.
+ // Clear the scanner so we know to scan starting from the current input point if we block again.
+ m_preloadScanner.clear();
+ } else {
+ m_preloadScanner->appendToEnd(source);
+ if (isWaitingForScripts())
+ m_preloadScanner->scan();
+ }
+ }
+
m_input.appendToEnd(source);
- if (m_preloadScanner)
- m_preloadScanner->appendToEnd(source);
if (inPumpSession()) {
// We've gotten data off the network in a nested write.
@@ -473,7 +490,6 @@ void HTMLDocumentParser::resumeParsingAfterScriptExecution()
ASSERT(!inScriptExecution());
ASSERT(!m_treeBuilder->isPaused());
- m_preloadScanner.clear();
pumpTokenizerIfPossible(AllowYield);
endIfDelayed();
}
@@ -491,6 +507,13 @@ void HTMLDocumentParser::stopWatchingForLoad(CachedResource* cachedScript)
{
cachedScript->removeClient(this);
}
+
+void HTMLDocumentParser::appendCurrentInputStreamToPreloadScannerAndScan()
+{
+ ASSERT(m_preloadScanner);
+ m_preloadScanner->appendToEnd(m_input.current());
+ m_preloadScanner->scan();
+}
void HTMLDocumentParser::notifyFinished(CachedResource* cachedResource)
{
diff --git a/Source/WebCore/html/parser/HTMLDocumentParser.h b/Source/WebCore/html/parser/HTMLDocumentParser.h
index a016cf3..d482a3d 100644
--- a/Source/WebCore/html/parser/HTMLDocumentParser.h
+++ b/Source/WebCore/html/parser/HTMLDocumentParser.h
@@ -109,6 +109,8 @@ private:
virtual void watchForLoad(CachedResource*);
virtual void stopWatchingForLoad(CachedResource*);
virtual HTMLInputStream& inputStream() { return m_input; }
+ virtual bool hasPreloadScanner() const { return m_preloadScanner.get(); }
+ virtual void appendCurrentInputStreamToPreloadScannerAndScan();
// CachedResourceClient
virtual void notifyFinished(CachedResource*);
diff --git a/Source/WebCore/html/parser/HTMLParserScheduler.h b/Source/WebCore/html/parser/HTMLParserScheduler.h
index 730b52b..b0e2e85 100644
--- a/Source/WebCore/html/parser/HTMLParserScheduler.h
+++ b/Source/WebCore/html/parser/HTMLParserScheduler.h
@@ -26,6 +26,8 @@
#ifndef HTMLParserScheduler_h
#define HTMLParserScheduler_h
+#include <limits.h>
+
#include "NestingLevelIncrementer.h"
#include "Timer.h"
#include <wtf/CurrentTime.h>
@@ -39,8 +41,11 @@ class PumpSession : public NestingLevelIncrementer {
public:
PumpSession(unsigned& nestingLevel)
: NestingLevelIncrementer(nestingLevel)
- , processedTokens(0)
- , startTime(currentTime())
+ // Setting processedTokens to INT_MAX causes us to check for yields
+ // after any token during any parse where yielding is allowed.
+ // At that time we'll initialize startTime.
+ , processedTokens(INT_MAX)
+ , startTime(0)
, needsYield(false)
{
}
@@ -63,6 +68,11 @@ public:
void checkForYieldBeforeToken(PumpSession& session)
{
if (session.processedTokens > m_parserChunkSize) {
+ // currentTime() can be expensive. By delaying, we avoided calling
+ // currentTime() when constructing non-yielding PumpSessions.
+ if (!session.startTime)
+ session.startTime = currentTime();
+
session.processedTokens = 0;
double elapsedTime = currentTime() - session.startTime;
if (elapsedTime > m_parserTimeLimit)
diff --git a/Source/WebCore/html/parser/HTMLScriptRunner.cpp b/Source/WebCore/html/parser/HTMLScriptRunner.cpp
index 99fff5e..7312334 100644
--- a/Source/WebCore/html/parser/HTMLScriptRunner.cpp
+++ b/Source/WebCore/html/parser/HTMLScriptRunner.cpp
@@ -169,12 +169,17 @@ bool HTMLScriptRunner::execute(PassRefPtr<Element> scriptElement, const TextPosi
ASSERT(scriptElement);
// FIXME: If scripting is disabled, always just return true;
+ bool hadPreloadScanner = m_host->hasPreloadScanner();
+
// Try to execute the script given to us.
runScript(scriptElement.get(), scriptStartPosition);
if (haveParsingBlockingScript()) {
if (m_scriptNestingLevel)
return false; // Block the parser. Unwind to the outermost HTMLScriptRunner::execute before continuing parsing.
+ // If preload scanner got created, it is missing the source after the current insertion point. Append it and scan.
+ if (!hadPreloadScanner && m_host->hasPreloadScanner())
+ m_host->appendCurrentInputStreamToPreloadScannerAndScan();
if (!executeParsingBlockingScripts())
return false; // We still have a parsing blocking script, block the parser.
}
diff --git a/Source/WebCore/html/parser/HTMLScriptRunnerHost.h b/Source/WebCore/html/parser/HTMLScriptRunnerHost.h
index 454bc6f..1f22896 100644
--- a/Source/WebCore/html/parser/HTMLScriptRunnerHost.h
+++ b/Source/WebCore/html/parser/HTMLScriptRunnerHost.h
@@ -45,6 +45,10 @@ public:
virtual void stopWatchingForLoad(CachedResource*) = 0;
virtual HTMLInputStream& inputStream() = 0;
+
+ virtual bool hasPreloadScanner() const = 0;
+ virtual void appendCurrentInputStreamToPreloadScannerAndScan() = 0;
+
};
}
diff --git a/Source/WebCore/html/shadow/DetailsMarkerControl.cpp b/Source/WebCore/html/shadow/DetailsMarkerControl.cpp
new file mode 100644
index 0000000..e8c6d6e
--- /dev/null
+++ b/Source/WebCore/html/shadow/DetailsMarkerControl.cpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DetailsMarkerControl.h"
+
+#include "HTMLNames.h"
+#include "HTMLSummaryElement.h"
+#include "RenderDetailsMarker.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+DetailsMarkerControl::DetailsMarkerControl(Document* document)
+ : HTMLDivElement(divTag, document)
+{
+}
+
+RenderObject* DetailsMarkerControl::createRenderer(RenderArena* arena, RenderStyle*)
+{
+ return new (arena) RenderDetailsMarker(this);
+}
+
+bool DetailsMarkerControl::rendererIsNeeded(RenderStyle* style)
+{
+ return summaryElement()->isMainSummary() && HTMLDivElement::rendererIsNeeded(style);
+}
+
+const AtomicString& DetailsMarkerControl::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, pseudId, ("-webkit-details-marker"));
+ return pseudId;
+}
+
+HTMLSummaryElement* DetailsMarkerControl::summaryElement()
+{
+ Node* node = this->shadowAncestorNode();
+ ASSERT(!node || toElement(node)->hasTagName(summaryTag));
+ return static_cast<HTMLSummaryElement*>(node);
+}
+
+}
diff --git a/Source/WebCore/html/shadow/ProgressBarValueElement.h b/Source/WebCore/html/shadow/DetailsMarkerControl.h
index 22f4e57..3c5b09d 100644
--- a/Source/WebCore/html/shadow/ProgressBarValueElement.h
+++ b/Source/WebCore/html/shadow/DetailsMarkerControl.h
@@ -1,6 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
- * Copyright (C) 2010 Google Inc. All rights reserved.
+ * Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -29,43 +28,32 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef ProgressBarValueElement_h
-#define ProgressBarValueElement_h
+#ifndef DetailsMarkerControl_h
+#define DetailsMarkerControl_h
#include "HTMLDivElement.h"
-#include "HTMLNames.h"
-#include "RenderProgress.h"
#include <wtf/Forward.h>
namespace WebCore {
-class ProgressBarValueElement : public HTMLDivElement {
+class HTMLSummaryElement;
+
+class DetailsMarkerControl : public HTMLDivElement {
public:
- ProgressBarValueElement(Document* document)
- : HTMLDivElement(HTMLNames::divTag, document)
- {
- }
+ DetailsMarkerControl(Document*);
+ static PassRefPtr<DetailsMarkerControl> create(Document*);
- virtual const AtomicString& shadowPseudoId() const;
+private:
virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
- static PassRefPtr<ProgressBarValueElement> create(Document*);
+ virtual bool rendererIsNeeded(RenderStyle*);
+ virtual const AtomicString& shadowPseudoId() const;
+ HTMLSummaryElement* summaryElement();
};
-inline const AtomicString& ProgressBarValueElement::shadowPseudoId() const
-{
- DEFINE_STATIC_LOCAL(AtomicString, pseudId, ("-webkit-progress-bar-value"));
- return pseudId;
-}
-
-inline RenderObject* ProgressBarValueElement::createRenderer(RenderArena* arena, RenderStyle*)
-{
- return new (arena) RenderProgressBarValuePart(this);
-}
-
-inline PassRefPtr<ProgressBarValueElement> ProgressBarValueElement::create(Document* document)
+inline PassRefPtr<DetailsMarkerControl> DetailsMarkerControl::create(Document* document)
{
- return adoptRef(new ProgressBarValueElement(document));
+ return adoptRef(new DetailsMarkerControl(document));
}
}
diff --git a/Source/WebCore/html/shadow/MediaControlElements.cpp b/Source/WebCore/html/shadow/MediaControlElements.cpp
new file mode 100644
index 0000000..68b301e
--- /dev/null
+++ b/Source/WebCore/html/shadow/MediaControlElements.cpp
@@ -0,0 +1,980 @@
+/*
+ * Copyright (C) 2008, 2009, 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(VIDEO)
+
+#include "MediaControlElements.h"
+
+#include "CSSStyleSelector.h"
+#include "EventNames.h"
+#include "FloatConversion.h"
+#include "Frame.h"
+#include "HTMLNames.h"
+#include "LocalizedStrings.h"
+#include "MediaControls.h"
+#include "MouseEvent.h"
+#include "Page.h"
+#include "RenderFlexibleBox.h"
+#include "RenderMedia.h"
+#include "RenderSlider.h"
+#include "RenderTheme.h"
+#include "RenderView.h"
+#include "Settings.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+HTMLMediaElement* toParentMediaElement(RenderObject* o)
+{
+ Node* node = o->node();
+ Node* mediaNode = node ? node->shadowAncestorNode() : 0;
+ if (!mediaNode || (!mediaNode->hasTagName(HTMLNames::videoTag) && !mediaNode->hasTagName(HTMLNames::audioTag)))
+ return 0;
+
+ return static_cast<HTMLMediaElement*>(mediaNode);
+}
+
+// FIXME: These constants may need to be tweaked to better match the seeking in the QuickTime plug-in.
+static const float cSeekRepeatDelay = 0.1f;
+static const float cStepTime = 0.07f;
+static const float cSeekTime = 0.2f;
+
+// ----------------------------
+
+MediaControlElement::MediaControlElement(HTMLMediaElement* mediaElement)
+ : HTMLDivElement(divTag, mediaElement->document())
+ , m_mediaElement(mediaElement)
+{
+}
+
+static const String& displayString()
+{
+ DEFINE_STATIC_LOCAL(String, s, ("display"));
+ return s;
+}
+
+void MediaControlElement::show()
+{
+ ExceptionCode ec;
+ // FIXME: Make more efficient <http://webkit.org/b/58157>
+ style()->removeProperty(displayString(), ec);
+}
+
+void MediaControlElement::hide()
+{
+ ExceptionCode ec;
+ // FIXME: Make more efficient <http://webkit.org/b/58157>
+ DEFINE_STATIC_LOCAL(String, none, ("none"));
+ style()->setProperty(displayString(), none, ec);
+}
+
+// ----------------------------
+
+inline MediaControlPanelElement::MediaControlPanelElement(HTMLMediaElement* mediaElement)
+ : MediaControlElement(mediaElement)
+{
+}
+
+PassRefPtr<MediaControlPanelElement> MediaControlPanelElement::create(HTMLMediaElement* mediaElement)
+{
+ return adoptRef(new MediaControlPanelElement(mediaElement));
+}
+
+MediaControlElementType MediaControlPanelElement::displayType() const
+{
+ return MediaControlsPanel;
+}
+
+const AtomicString& MediaControlPanelElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-panel"));
+ return id;
+}
+
+// ----------------------------
+
+inline MediaControlTimelineContainerElement::MediaControlTimelineContainerElement(HTMLMediaElement* mediaElement)
+ : MediaControlElement(mediaElement)
+{
+}
+
+PassRefPtr<MediaControlTimelineContainerElement> MediaControlTimelineContainerElement::create(HTMLMediaElement* mediaElement)
+{
+ RefPtr<MediaControlTimelineContainerElement> element = adoptRef(new MediaControlTimelineContainerElement(mediaElement));
+ element->hide();
+ return element.release();
+}
+
+MediaControlElementType MediaControlTimelineContainerElement::displayType() const
+{
+ return MediaTimelineContainer;
+}
+
+const AtomicString& MediaControlTimelineContainerElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-timeline-container"));
+ return id;
+}
+
+// ----------------------------
+
+class RenderMediaVolumeSliderContainer : public RenderBlock {
+public:
+ RenderMediaVolumeSliderContainer(Node*);
+
+private:
+ virtual void layout();
+};
+
+RenderMediaVolumeSliderContainer::RenderMediaVolumeSliderContainer(Node* node)
+ : RenderBlock(node)
+{
+}
+
+void RenderMediaVolumeSliderContainer::layout()
+{
+ RenderBlock::layout();
+ if (style()->display() == NONE || !previousSibling() || !previousSibling()->isBox())
+ return;
+
+ RenderBox* buttonBox = toRenderBox(previousSibling());
+
+ if (view())
+ view()->disableLayoutState();
+
+ IntPoint offset = theme()->volumeSliderOffsetFromMuteButton(buttonBox, IntSize(width(), height()));
+ setX(offset.x() + buttonBox->offsetLeft());
+ setY(offset.y() + buttonBox->offsetTop());
+
+ if (view())
+ view()->enableLayoutState();
+}
+
+inline MediaControlVolumeSliderContainerElement::MediaControlVolumeSliderContainerElement(HTMLMediaElement* mediaElement)
+ : MediaControlElement(mediaElement)
+{
+}
+
+PassRefPtr<MediaControlVolumeSliderContainerElement> MediaControlVolumeSliderContainerElement::create(HTMLMediaElement* mediaElement)
+{
+ RefPtr<MediaControlVolumeSliderContainerElement> element = adoptRef(new MediaControlVolumeSliderContainerElement(mediaElement));
+ element->hide();
+ return element.release();
+}
+
+RenderObject* MediaControlVolumeSliderContainerElement::createRenderer(RenderArena* arena, RenderStyle*)
+{
+ return new (arena) RenderMediaVolumeSliderContainer(this);
+}
+
+void MediaControlVolumeSliderContainerElement::defaultEventHandler(Event* event)
+{
+ if (!event->isMouseEvent() || event->type() != eventNames().mouseoutEvent)
+ return;
+
+ // Poor man's mouseleave event detection.
+ MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
+ if (!mouseEvent->relatedTarget() || !mouseEvent->relatedTarget()->toNode())
+ return;
+
+ if (this->containsIncludingShadowDOM(mouseEvent->relatedTarget()->toNode()))
+ return;
+
+ hide();
+}
+
+
+MediaControlElementType MediaControlVolumeSliderContainerElement::displayType() const
+{
+ return MediaVolumeSliderContainer;
+}
+
+const AtomicString& MediaControlVolumeSliderContainerElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-volume-slider-container"));
+ return id;
+}
+
+// ----------------------------
+
+inline MediaControlStatusDisplayElement::MediaControlStatusDisplayElement(HTMLMediaElement* mediaElement)
+ : MediaControlElement(mediaElement)
+ , m_stateBeingDisplayed(Nothing)
+{
+}
+
+PassRefPtr<MediaControlStatusDisplayElement> MediaControlStatusDisplayElement::create(HTMLMediaElement* mediaElement)
+{
+ RefPtr<MediaControlStatusDisplayElement> element = adoptRef(new MediaControlStatusDisplayElement(mediaElement));
+ element->hide();
+ return element.release();
+}
+
+void MediaControlStatusDisplayElement::update()
+{
+ // Get the new state that we'll have to display.
+ StateBeingDisplayed newStateToDisplay = Nothing;
+
+ if (mediaElement()->readyState() != HTMLMediaElement::HAVE_ENOUGH_DATA && !mediaElement()->currentSrc().isEmpty())
+ newStateToDisplay = Loading;
+ else if (mediaElement()->movieLoadType() == MediaPlayer::LiveStream)
+ newStateToDisplay = LiveBroadcast;
+
+ if (newStateToDisplay == m_stateBeingDisplayed)
+ return;
+
+ ExceptionCode e;
+
+ if (m_stateBeingDisplayed == Nothing)
+ show();
+ else if (newStateToDisplay == Nothing)
+ hide();
+
+ m_stateBeingDisplayed = newStateToDisplay;
+
+ switch (m_stateBeingDisplayed) {
+ case Nothing:
+ setInnerText("", e);
+ break;
+ case Loading:
+ setInnerText(mediaElementLoadingStateText(), e);
+ break;
+ case LiveBroadcast:
+ setInnerText(mediaElementLiveBroadcastStateText(), e);
+ break;
+ }
+}
+
+MediaControlElementType MediaControlStatusDisplayElement::displayType() const
+{
+ return MediaStatusDisplay;
+}
+
+const AtomicString& MediaControlStatusDisplayElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-status-display"));
+ return id;
+}
+
+// ----------------------------
+
+MediaControlInputElement::MediaControlInputElement(HTMLMediaElement* mediaElement, MediaControlElementType displayType)
+ : HTMLInputElement(inputTag, mediaElement->document(), 0, false)
+ , m_mediaElement(mediaElement)
+ , m_displayType(displayType)
+{
+}
+
+void MediaControlInputElement::show()
+{
+ ExceptionCode ec;
+ style()->removeProperty(displayString(), ec);
+}
+
+void MediaControlInputElement::hide()
+{
+ ExceptionCode ec;
+ DEFINE_STATIC_LOCAL(String, none, ("none"));
+ style()->setProperty(displayString(), none, ec);
+}
+
+
+void MediaControlInputElement::setDisplayType(MediaControlElementType displayType)
+{
+ if (displayType == m_displayType)
+ return;
+
+ m_displayType = displayType;
+ if (RenderObject* object = renderer())
+ object->repaint();
+}
+
+// ----------------------------
+
+inline MediaControlMuteButtonElement::MediaControlMuteButtonElement(HTMLMediaElement* mediaElement, MediaControlElementType displayType)
+ : MediaControlInputElement(mediaElement, displayType)
+{
+}
+
+void MediaControlMuteButtonElement::defaultEventHandler(Event* event)
+{
+ if (event->type() == eventNames().clickEvent) {
+ mediaElement()->setMuted(!mediaElement()->muted());
+ event->setDefaultHandled();
+ }
+
+ HTMLInputElement::defaultEventHandler(event);
+}
+
+void MediaControlMuteButtonElement::changedMute()
+{
+ updateDisplayType();
+}
+
+void MediaControlMuteButtonElement::updateDisplayType()
+{
+ setDisplayType(mediaElement()->muted() ? MediaUnMuteButton : MediaMuteButton);
+}
+
+// ----------------------------
+
+inline MediaControlPanelMuteButtonElement::MediaControlPanelMuteButtonElement(HTMLMediaElement* mediaElement, MediaControls* controls)
+ : MediaControlMuteButtonElement(mediaElement, MediaMuteButton)
+ , m_controls(controls)
+{
+}
+
+PassRefPtr<MediaControlPanelMuteButtonElement> MediaControlPanelMuteButtonElement::create(HTMLMediaElement* mediaElement, MediaControls* controls)
+{
+ ASSERT(controls);
+
+ RefPtr<MediaControlPanelMuteButtonElement> button = adoptRef(new MediaControlPanelMuteButtonElement(mediaElement, controls));
+ button->setType("button");
+ return button.release();
+}
+
+void MediaControlPanelMuteButtonElement::defaultEventHandler(Event* event)
+{
+ if (event->type() == eventNames().mouseoverEvent)
+ m_controls->showVolumeSlider();
+
+ MediaControlMuteButtonElement::defaultEventHandler(event);
+}
+
+const AtomicString& MediaControlPanelMuteButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-mute-button"));
+ return id;
+}
+
+// ----------------------------
+
+inline MediaControlVolumeSliderMuteButtonElement::MediaControlVolumeSliderMuteButtonElement(HTMLMediaElement* mediaElement)
+ : MediaControlMuteButtonElement(mediaElement, MediaMuteButton)
+{
+}
+
+PassRefPtr<MediaControlVolumeSliderMuteButtonElement> MediaControlVolumeSliderMuteButtonElement::create(HTMLMediaElement* mediaElement)
+{
+ RefPtr<MediaControlVolumeSliderMuteButtonElement> button = adoptRef(new MediaControlVolumeSliderMuteButtonElement(mediaElement));
+ button->setType("button");
+ return button.release();
+}
+
+const AtomicString& MediaControlVolumeSliderMuteButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-volume-slider-mute-button"));
+ return id;
+}
+
+// ----------------------------
+
+inline MediaControlPlayButtonElement::MediaControlPlayButtonElement(HTMLMediaElement* mediaElement)
+ : MediaControlInputElement(mediaElement, MediaPlayButton)
+{
+}
+
+PassRefPtr<MediaControlPlayButtonElement> MediaControlPlayButtonElement::create(HTMLMediaElement* mediaElement)
+{
+ RefPtr<MediaControlPlayButtonElement> button = adoptRef(new MediaControlPlayButtonElement(mediaElement));
+ button->setType("button");
+ return button.release();
+}
+
+void MediaControlPlayButtonElement::defaultEventHandler(Event* event)
+{
+ if (event->type() == eventNames().clickEvent) {
+ mediaElement()->togglePlayState();
+ updateDisplayType();
+ event->setDefaultHandled();
+ }
+ HTMLInputElement::defaultEventHandler(event);
+}
+
+void MediaControlPlayButtonElement::updateDisplayType()
+{
+ setDisplayType(mediaElement()->canPlay() ? MediaPlayButton : MediaPauseButton);
+}
+
+const AtomicString& MediaControlPlayButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-play-button"));
+ return id;
+}
+
+// ----------------------------
+
+inline MediaControlSeekButtonElement::MediaControlSeekButtonElement(HTMLMediaElement* mediaElement, MediaControlElementType displayType)
+ : MediaControlInputElement(mediaElement, displayType)
+ , m_seeking(false)
+ , m_capturing(false)
+ , m_seekTimer(this, &MediaControlSeekButtonElement::seekTimerFired)
+{
+}
+
+void MediaControlSeekButtonElement::defaultEventHandler(Event* event)
+{
+ if (event->type() == eventNames().mousedownEvent) {
+ if (Frame* frame = document()->frame()) {
+ m_capturing = true;
+ frame->eventHandler()->setCapturingMouseEventsNode(this);
+ }
+ mediaElement()->pause(event->fromUserGesture());
+ m_seekTimer.startRepeating(cSeekRepeatDelay);
+ event->setDefaultHandled();
+ } else if (event->type() == eventNames().mouseupEvent) {
+ if (m_capturing)
+ if (Frame* frame = document()->frame()) {
+ m_capturing = false;
+ frame->eventHandler()->setCapturingMouseEventsNode(0);
+ }
+ ExceptionCode ec;
+ if (m_seeking || m_seekTimer.isActive()) {
+ if (!m_seeking) {
+ float stepTime = isForwardButton() ? cStepTime : -cStepTime;
+ mediaElement()->setCurrentTime(mediaElement()->currentTime() + stepTime, ec);
+ }
+ m_seekTimer.stop();
+ m_seeking = false;
+ event->setDefaultHandled();
+ }
+ }
+ HTMLInputElement::defaultEventHandler(event);
+}
+
+void MediaControlSeekButtonElement::seekTimerFired(Timer<MediaControlSeekButtonElement>*)
+{
+ ExceptionCode ec;
+ m_seeking = true;
+ float seekTime = isForwardButton() ? cSeekTime : -cSeekTime;
+ mediaElement()->setCurrentTime(mediaElement()->currentTime() + seekTime, ec);
+}
+
+void MediaControlSeekButtonElement::detach()
+{
+ if (m_capturing) {
+ if (Frame* frame = document()->frame())
+ frame->eventHandler()->setCapturingMouseEventsNode(0);
+ }
+ MediaControlInputElement::detach();
+}
+
+// ----------------------------
+
+inline MediaControlSeekForwardButtonElement::MediaControlSeekForwardButtonElement(HTMLMediaElement* mediaElement)
+ : MediaControlSeekButtonElement(mediaElement, MediaSeekForwardButton)
+{
+}
+
+PassRefPtr<MediaControlSeekForwardButtonElement> MediaControlSeekForwardButtonElement::create(HTMLMediaElement* mediaElement)
+{
+ RefPtr<MediaControlSeekForwardButtonElement> button = adoptRef(new MediaControlSeekForwardButtonElement(mediaElement));
+ button->setType("button");
+ return button.release();
+}
+
+const AtomicString& MediaControlSeekForwardButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-seek-forward-button"));
+ return id;
+}
+
+// ----------------------------
+
+inline MediaControlSeekBackButtonElement::MediaControlSeekBackButtonElement(HTMLMediaElement* mediaElement)
+ : MediaControlSeekButtonElement(mediaElement, MediaSeekBackButton)
+{
+}
+
+PassRefPtr<MediaControlSeekBackButtonElement> MediaControlSeekBackButtonElement::create(HTMLMediaElement* mediaElement)
+{
+ RefPtr<MediaControlSeekBackButtonElement> button = adoptRef(new MediaControlSeekBackButtonElement(mediaElement));
+ button->setType("button");
+ return button.release();
+}
+
+const AtomicString& MediaControlSeekBackButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-seek-back-button"));
+ return id;
+}
+
+// ----------------------------
+
+inline MediaControlRewindButtonElement::MediaControlRewindButtonElement(HTMLMediaElement* element)
+ : MediaControlInputElement(element, MediaRewindButton)
+{
+}
+
+PassRefPtr<MediaControlRewindButtonElement> MediaControlRewindButtonElement::create(HTMLMediaElement* mediaElement)
+{
+ RefPtr<MediaControlRewindButtonElement> button = adoptRef(new MediaControlRewindButtonElement(mediaElement));
+ button->setType("button");
+ return button.release();
+}
+
+void MediaControlRewindButtonElement::defaultEventHandler(Event* event)
+{
+ if (event->type() == eventNames().clickEvent) {
+ mediaElement()->rewind(30);
+ event->setDefaultHandled();
+ }
+ HTMLInputElement::defaultEventHandler(event);
+}
+
+const AtomicString& MediaControlRewindButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-rewind-button"));
+ return id;
+}
+
+// ----------------------------
+
+inline MediaControlReturnToRealtimeButtonElement::MediaControlReturnToRealtimeButtonElement(HTMLMediaElement* mediaElement)
+ : MediaControlInputElement(mediaElement, MediaReturnToRealtimeButton)
+{
+}
+
+PassRefPtr<MediaControlReturnToRealtimeButtonElement> MediaControlReturnToRealtimeButtonElement::create(HTMLMediaElement* mediaElement)
+{
+ RefPtr<MediaControlReturnToRealtimeButtonElement> button = adoptRef(new MediaControlReturnToRealtimeButtonElement(mediaElement));
+ button->setType("button");
+ button->hide();
+ return button.release();
+}
+
+void MediaControlReturnToRealtimeButtonElement::defaultEventHandler(Event* event)
+{
+ if (event->type() == eventNames().clickEvent) {
+ mediaElement()->returnToRealtime();
+ event->setDefaultHandled();
+ }
+ HTMLInputElement::defaultEventHandler(event);
+}
+
+const AtomicString& MediaControlReturnToRealtimeButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-return-to-realtime-button"));
+ return id;
+}
+
+// ----------------------------
+
+inline MediaControlToggleClosedCaptionsButtonElement::MediaControlToggleClosedCaptionsButtonElement(HTMLMediaElement* mediaElement)
+ : MediaControlInputElement(mediaElement, MediaShowClosedCaptionsButton)
+{
+}
+
+PassRefPtr<MediaControlToggleClosedCaptionsButtonElement> MediaControlToggleClosedCaptionsButtonElement::create(HTMLMediaElement* mediaElement)
+{
+ RefPtr<MediaControlToggleClosedCaptionsButtonElement> button = adoptRef(new MediaControlToggleClosedCaptionsButtonElement(mediaElement));
+ button->setType("button");
+ button->hide();
+ return button.release();
+}
+
+void MediaControlToggleClosedCaptionsButtonElement::defaultEventHandler(Event* event)
+{
+ if (event->type() == eventNames().clickEvent) {
+ mediaElement()->setClosedCaptionsVisible(!mediaElement()->closedCaptionsVisible());
+ setChecked(mediaElement()->closedCaptionsVisible());
+ updateDisplayType();
+ event->setDefaultHandled();
+ }
+
+ HTMLInputElement::defaultEventHandler(event);
+}
+
+void MediaControlToggleClosedCaptionsButtonElement::updateDisplayType()
+{
+ setDisplayType(mediaElement()->closedCaptionsVisible() ? MediaHideClosedCaptionsButton : MediaShowClosedCaptionsButton);
+}
+
+const AtomicString& MediaControlToggleClosedCaptionsButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-toggle-closed-captions-button"));
+ return id;
+}
+
+// ----------------------------
+
+MediaControlTimelineElement::MediaControlTimelineElement(HTMLMediaElement* mediaElement, MediaControls* controls)
+ : MediaControlInputElement(mediaElement, MediaSlider)
+ , m_controls(controls)
+{
+}
+
+PassRefPtr<MediaControlTimelineElement> MediaControlTimelineElement::create(HTMLMediaElement* mediaElement, MediaControls* controls)
+{
+ ASSERT(controls);
+
+ RefPtr<MediaControlTimelineElement> timeline = adoptRef(new MediaControlTimelineElement(mediaElement, controls));
+ timeline->setType("range");
+ timeline->setAttribute(precisionAttr, "float");
+ return timeline.release();
+}
+
+void MediaControlTimelineElement::defaultEventHandler(Event* event)
+{
+ // Left button is 0. Rejects mouse events not from left button.
+ if (event->isMouseEvent() && static_cast<MouseEvent*>(event)->button())
+ return;
+
+ if (!attached())
+ return;
+
+ if (event->type() == eventNames().mousedownEvent)
+ mediaElement()->beginScrubbing();
+
+ MediaControlInputElement::defaultEventHandler(event);
+
+ if (event->type() == eventNames().mouseoverEvent || event->type() == eventNames().mouseoutEvent || event->type() == eventNames().mousemoveEvent)
+ return;
+
+ float time = narrowPrecisionToFloat(value().toDouble());
+ if (time != mediaElement()->currentTime()) {
+ // FIXME: This is fired 3 times on every click. We should not be doing that <http:/webkit.org/b/58160>.
+ ExceptionCode ec;
+ mediaElement()->setCurrentTime(time, ec);
+ }
+
+ RenderSlider* slider = toRenderSlider(renderer());
+<<<<<<< HEAD:Source/WebCore/rendering/MediaControlElements.cpp
+ if (slider && slider->inDragMode()) {
+ toRenderMedia(mediaElement()->renderer())->controls()->updateTimeDisplay();
+#if PLATFORM(ANDROID)
+ toRenderMedia(mediaElement()->renderer())->controls()->updateLastTouch();
+#endif
+ }
+=======
+ if (slider && slider->inDragMode())
+ m_controls->updateTimeDisplay();
+>>>>>>> WebKit.org at r84325:Source/WebCore/html/shadow/MediaControlElements.cpp
+
+ if (event->type() == eventNames().mouseupEvent)
+ mediaElement()->endScrubbing();
+}
+
+void MediaControlTimelineElement::setPosition(float currentTime)
+{
+ setValue(String::number(currentTime));
+}
+
+void MediaControlTimelineElement::setDuration(float duration)
+{
+ setAttribute(maxAttr, String::number(isfinite(duration) ? duration : 0));
+}
+
+
+const AtomicString& MediaControlTimelineElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-timeline"));
+ return id;
+}
+
+// ----------------------------
+
+inline MediaControlVolumeSliderElement::MediaControlVolumeSliderElement(HTMLMediaElement* mediaElement)
+ : MediaControlInputElement(mediaElement, MediaVolumeSlider)
+{
+}
+
+PassRefPtr<MediaControlVolumeSliderElement> MediaControlVolumeSliderElement::create(HTMLMediaElement* mediaElement)
+{
+ RefPtr<MediaControlVolumeSliderElement> slider = adoptRef(new MediaControlVolumeSliderElement(mediaElement));
+ slider->setType("range");
+ slider->setAttribute(precisionAttr, "float");
+ slider->setAttribute(maxAttr, "1");
+ slider->setAttribute(valueAttr, String::number(mediaElement->volume()));
+ return slider.release();
+}
+
+void MediaControlVolumeSliderElement::defaultEventHandler(Event* event)
+{
+ // Left button is 0. Rejects mouse events not from left button.
+ if (event->isMouseEvent() && static_cast<MouseEvent*>(event)->button())
+ return;
+
+ if (!attached())
+ return;
+
+ MediaControlInputElement::defaultEventHandler(event);
+
+ if (event->type() == eventNames().mouseoverEvent || event->type() == eventNames().mouseoutEvent || event->type() == eventNames().mousemoveEvent)
+ return;
+
+ float volume = narrowPrecisionToFloat(value().toDouble());
+ if (volume != mediaElement()->volume()) {
+ ExceptionCode ec = 0;
+ mediaElement()->setVolume(volume, ec);
+ ASSERT(!ec);
+ }
+}
+
+void MediaControlVolumeSliderElement::setVolume(float volume)
+{
+ if (value().toFloat() != volume)
+ setValue(String::number(volume));
+}
+
+const AtomicString& MediaControlVolumeSliderElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-volume-slider"));
+ return id;
+}
+
+// ----------------------------
+
+inline MediaControlFullscreenVolumeSliderElement::MediaControlFullscreenVolumeSliderElement(HTMLMediaElement* mediaElement)
+ : MediaControlVolumeSliderElement(mediaElement)
+{
+}
+
+PassRefPtr<MediaControlFullscreenVolumeSliderElement> MediaControlFullscreenVolumeSliderElement::create(HTMLMediaElement* mediaElement)
+{
+ RefPtr<MediaControlFullscreenVolumeSliderElement> slider = adoptRef(new MediaControlFullscreenVolumeSliderElement(mediaElement));
+ slider->setType("range");
+ slider->setAttribute(precisionAttr, "float");
+ slider->setAttribute(maxAttr, "1");
+ slider->setAttribute(valueAttr, String::number(mediaElement->volume()));
+ return slider.release();
+}
+
+const AtomicString& MediaControlFullscreenVolumeSliderElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-fullscreen-volume-slider"));
+ return id;
+}
+
+// ----------------------------
+
+inline MediaControlFullscreenButtonElement::MediaControlFullscreenButtonElement(HTMLMediaElement* mediaElement, MediaControls* controls)
+ : MediaControlInputElement(mediaElement, MediaFullscreenButton)
+ , m_controls(controls)
+{
+}
+
+PassRefPtr<MediaControlFullscreenButtonElement> MediaControlFullscreenButtonElement::create(HTMLMediaElement* mediaElement, MediaControls* controls)
+{
+ ASSERT(controls);
+
+ RefPtr<MediaControlFullscreenButtonElement> button = adoptRef(new MediaControlFullscreenButtonElement(mediaElement, controls));
+ button->setType("button");
+ button->hide();
+ return button.release();
+}
+
+void MediaControlFullscreenButtonElement::defaultEventHandler(Event* event)
+{
+ if (event->type() == eventNames().clickEvent) {
+#if ENABLE(FULLSCREEN_API)
+ // Only use the new full screen API if the fullScreenEnabled setting has
+ // been explicitly enabled. Otherwise, use the old fullscreen API. This
+ // allows apps which embed a WebView to retain the existing full screen
+ // video implementation without requiring them to implement their own full
+ // screen behavior.
+ if (document()->settings() && document()->settings()->fullScreenEnabled()) {
+ if (document()->webkitIsFullScreen() && document()->webkitCurrentFullScreenElement() == mediaElement()) {
+ document()->webkitCancelFullScreen();
+ m_controls->exitedFullscreen();
+ } else {
+ mediaElement()->webkitRequestFullScreen(0);
+ m_controls->enteredFullscreen();
+ }
+ } else
+#endif
+ mediaElement()->enterFullscreen();
+ event->setDefaultHandled();
+ }
+ HTMLInputElement::defaultEventHandler(event);
+}
+
+const AtomicString& MediaControlFullscreenButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-fullscreen-button"));
+ return id;
+}
+
+// ----------------------------
+
+inline MediaControlFullscreenVolumeMinButtonElement::MediaControlFullscreenVolumeMinButtonElement(HTMLMediaElement* mediaElement)
+ : MediaControlInputElement(mediaElement, MediaUnMuteButton)
+{
+}
+
+PassRefPtr<MediaControlFullscreenVolumeMinButtonElement> MediaControlFullscreenVolumeMinButtonElement::create(HTMLMediaElement* mediaElement)
+{
+ RefPtr<MediaControlFullscreenVolumeMinButtonElement> button = adoptRef(new MediaControlFullscreenVolumeMinButtonElement(mediaElement));
+ button->setType("button");
+ return button.release();
+}
+
+void MediaControlFullscreenVolumeMinButtonElement::defaultEventHandler(Event* event)
+{
+ if (event->type() == eventNames().clickEvent) {
+ ExceptionCode code = 0;
+ mediaElement()->setVolume(0, code);
+ event->setDefaultHandled();
+ }
+ HTMLInputElement::defaultEventHandler(event);
+}
+
+const AtomicString& MediaControlFullscreenVolumeMinButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-fullscreen-volume-min-button"));
+ return id;
+}
+
+// ----------------------------
+
+inline MediaControlFullscreenVolumeMaxButtonElement::MediaControlFullscreenVolumeMaxButtonElement(HTMLMediaElement* mediaElement)
+: MediaControlInputElement(mediaElement, MediaMuteButton)
+{
+}
+
+PassRefPtr<MediaControlFullscreenVolumeMaxButtonElement> MediaControlFullscreenVolumeMaxButtonElement::create(HTMLMediaElement* mediaElement)
+{
+ RefPtr<MediaControlFullscreenVolumeMaxButtonElement> button = adoptRef(new MediaControlFullscreenVolumeMaxButtonElement(mediaElement));
+ button->setType("button");
+ return button.release();
+}
+
+void MediaControlFullscreenVolumeMaxButtonElement::defaultEventHandler(Event* event)
+{
+ if (event->type() == eventNames().clickEvent) {
+ ExceptionCode code = 0;
+ mediaElement()->setVolume(1, code);
+ event->setDefaultHandled();
+ }
+ HTMLInputElement::defaultEventHandler(event);
+}
+
+const AtomicString& MediaControlFullscreenVolumeMaxButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-fullscreen-volume-max-button"));
+ return id;
+}
+
+// ----------------------------
+
+class RenderMediaControlTimeDisplay : public RenderFlexibleBox {
+public:
+ RenderMediaControlTimeDisplay(Node*);
+
+private:
+ virtual void layout();
+};
+
+RenderMediaControlTimeDisplay::RenderMediaControlTimeDisplay(Node* node)
+ : RenderFlexibleBox(node)
+{
+}
+
+// We want the timeline slider to be at least 100 pixels wide.
+// FIXME: Eliminate hard-coded widths altogether.
+static const int minWidthToDisplayTimeDisplays = 45 + 100 + 45;
+
+void RenderMediaControlTimeDisplay::layout()
+{
+ RenderFlexibleBox::layout();
+ RenderBox* timelineContainerBox = parentBox();
+ while (timelineContainerBox && timelineContainerBox->isAnonymous())
+ timelineContainerBox = timelineContainerBox->parentBox();
+
+ if (timelineContainerBox && timelineContainerBox->width() < minWidthToDisplayTimeDisplays)
+ setWidth(0);
+}
+
+inline MediaControlTimeDisplayElement::MediaControlTimeDisplayElement(HTMLMediaElement* mediaElement)
+ : MediaControlElement(mediaElement)
+ , m_currentValue(0)
+{
+}
+
+void MediaControlTimeDisplayElement::setCurrentValue(float time)
+{
+ m_currentValue = time;
+}
+
+RenderObject* MediaControlTimeDisplayElement::createRenderer(RenderArena* arena, RenderStyle*)
+{
+ return new (arena) RenderMediaControlTimeDisplay(this);
+}
+
+// ----------------------------
+
+PassRefPtr<MediaControlTimeRemainingDisplayElement> MediaControlTimeRemainingDisplayElement::create(HTMLMediaElement* mediaElement)
+{
+ return adoptRef(new MediaControlTimeRemainingDisplayElement(mediaElement));
+}
+
+MediaControlTimeRemainingDisplayElement::MediaControlTimeRemainingDisplayElement(HTMLMediaElement* mediaElement)
+ : MediaControlTimeDisplayElement(mediaElement)
+{
+}
+
+MediaControlElementType MediaControlTimeRemainingDisplayElement::displayType() const
+{
+ return MediaTimeRemainingDisplay;
+}
+
+const AtomicString& MediaControlTimeRemainingDisplayElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-time-remaining-display"));
+ return id;
+}
+
+// ----------------------------
+
+PassRefPtr<MediaControlCurrentTimeDisplayElement> MediaControlCurrentTimeDisplayElement::create(HTMLMediaElement* mediaElement)
+{
+ return adoptRef(new MediaControlCurrentTimeDisplayElement(mediaElement));
+}
+
+MediaControlCurrentTimeDisplayElement::MediaControlCurrentTimeDisplayElement(HTMLMediaElement* mediaElement)
+ : MediaControlTimeDisplayElement(mediaElement)
+{
+}
+
+MediaControlElementType MediaControlCurrentTimeDisplayElement::displayType() const
+{
+ return MediaCurrentTimeDisplay;
+}
+
+const AtomicString& MediaControlCurrentTimeDisplayElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-current-time-display"));
+ return id;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(VIDEO)
diff --git a/Source/WebCore/html/shadow/MediaControlElements.h b/Source/WebCore/html/shadow/MediaControlElements.h
new file mode 100644
index 0000000..db3158b
--- /dev/null
+++ b/Source/WebCore/html/shadow/MediaControlElements.h
@@ -0,0 +1,462 @@
+/*
+ * Copyright (C) 2008, 2009, 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef MediaControlElements_h
+#define MediaControlElements_h
+
+#if ENABLE(VIDEO)
+
+#include "HTMLDivElement.h"
+#include "HTMLInputElement.h"
+#include "HTMLMediaElement.h"
+#include "RenderBlock.h"
+
+// These are the shadow elements used in RenderMedia
+
+namespace WebCore {
+
+class Event;
+class Frame;
+class MediaControls;
+
+// Must match WebKitSystemInterface.h
+enum MediaControlElementType {
+ MediaFullscreenButton = 0,
+ MediaMuteButton,
+ MediaPlayButton,
+ MediaSeekBackButton,
+ MediaSeekForwardButton,
+ MediaSlider,
+ MediaSliderThumb,
+ MediaRewindButton,
+ MediaReturnToRealtimeButton,
+ MediaShowClosedCaptionsButton,
+ MediaHideClosedCaptionsButton,
+ MediaUnMuteButton,
+ MediaPauseButton,
+ MediaTimelineContainer,
+ MediaCurrentTimeDisplay,
+ MediaTimeRemainingDisplay,
+ MediaStatusDisplay,
+ MediaControlsPanel,
+ MediaVolumeSliderContainer,
+ MediaVolumeSlider,
+ MediaVolumeSliderThumb,
+ MediaVolumeSliderMuteButton,
+};
+
+HTMLMediaElement* toParentMediaElement(RenderObject*);
+
+// ----------------------------
+
+class MediaControlElement : public HTMLDivElement {
+public:
+ void hide();
+ void show();
+
+ virtual MediaControlElementType displayType() const = 0;
+
+ HTMLMediaElement* mediaElement() const { return m_mediaElement; }
+
+protected:
+ MediaControlElement(HTMLMediaElement*);
+
+private:
+ virtual bool isMediaControlElement() const { return true; }
+
+ HTMLMediaElement* m_mediaElement;
+};
+
+// ----------------------------
+
+class MediaControlPanelElement : public MediaControlElement {
+public:
+ static PassRefPtr<MediaControlPanelElement> create(HTMLMediaElement*);
+
+private:
+ MediaControlPanelElement(HTMLMediaElement*);
+ virtual MediaControlElementType displayType() const;
+ virtual const AtomicString& shadowPseudoId() const;
+};
+
+// ----------------------------
+
+class MediaControlTimelineContainerElement : public MediaControlElement {
+public:
+ static PassRefPtr<MediaControlTimelineContainerElement> create(HTMLMediaElement*);
+
+private:
+ MediaControlTimelineContainerElement(HTMLMediaElement*);
+ virtual const AtomicString& shadowPseudoId() const;
+
+ virtual MediaControlElementType displayType() const;
+};
+
+// ----------------------------
+
+class MediaControlVolumeSliderContainerElement : public MediaControlElement {
+public:
+ static PassRefPtr<MediaControlVolumeSliderContainerElement> create(HTMLMediaElement*);
+
+private:
+ MediaControlVolumeSliderContainerElement(HTMLMediaElement*);
+ virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
+ virtual void defaultEventHandler(Event*);
+ virtual MediaControlElementType displayType() const;
+ virtual const AtomicString& shadowPseudoId() const;
+};
+
+// ----------------------------
+
+class MediaControlStatusDisplayElement : public MediaControlElement {
+public:
+ static PassRefPtr<MediaControlStatusDisplayElement> create(HTMLMediaElement*);
+
+ void update();
+
+private:
+ MediaControlStatusDisplayElement(HTMLMediaElement*);
+
+ virtual MediaControlElementType displayType() const;
+ virtual const AtomicString& shadowPseudoId() const;
+
+ enum StateBeingDisplayed { Nothing, Loading, LiveBroadcast };
+ StateBeingDisplayed m_stateBeingDisplayed;
+};
+
+// ----------------------------
+
+class MediaControlInputElement : public HTMLInputElement {
+public:
+ void hide();
+ void show();
+
+ MediaControlElementType displayType() const { return m_displayType; }
+
+ HTMLMediaElement* mediaElement() const { return m_mediaElement; }
+
+protected:
+ MediaControlInputElement(HTMLMediaElement*, MediaControlElementType);
+
+ void setDisplayType(MediaControlElementType);
+
+private:
+ virtual bool isMediaControlElement() const { return true; }
+
+ virtual void updateDisplayType() { }
+
+ HTMLMediaElement* m_mediaElement;
+ MediaControlElementType m_displayType;
+};
+
+// ----------------------------
+
+class MediaControlMuteButtonElement : public MediaControlInputElement {
+public:
+ void changedMute();
+
+protected:
+ MediaControlMuteButtonElement(HTMLMediaElement*, MediaControlElementType);
+ virtual void defaultEventHandler(Event*);
+
+
+private:
+ virtual void updateDisplayType();
+};
+
+// ----------------------------
+
+class MediaControlPanelMuteButtonElement : public MediaControlMuteButtonElement {
+public:
+ static PassRefPtr<MediaControlPanelMuteButtonElement> create(HTMLMediaElement*, MediaControls*);
+
+private:
+ MediaControlPanelMuteButtonElement(HTMLMediaElement*, MediaControls*);
+
+ virtual void defaultEventHandler(Event*);
+ virtual const AtomicString& shadowPseudoId() const;
+
+ MediaControls* m_controls;
+};
+
+// ----------------------------
+
+class MediaControlVolumeSliderMuteButtonElement : public MediaControlMuteButtonElement {
+public:
+ static PassRefPtr<MediaControlVolumeSliderMuteButtonElement> create(HTMLMediaElement*);
+
+private:
+ MediaControlVolumeSliderMuteButtonElement(HTMLMediaElement*);
+
+ virtual const AtomicString& shadowPseudoId() const;
+};
+
+
+// ----------------------------
+
+class MediaControlPlayButtonElement : public MediaControlInputElement {
+public:
+ static PassRefPtr<MediaControlPlayButtonElement> create(HTMLMediaElement*);
+
+ virtual void defaultEventHandler(Event*);
+ virtual void updateDisplayType();
+
+private:
+ MediaControlPlayButtonElement(HTMLMediaElement*);
+
+ virtual const AtomicString& shadowPseudoId() const;
+};
+
+// ----------------------------
+
+class MediaControlSeekButtonElement : public MediaControlInputElement {
+public:
+ virtual void defaultEventHandler(Event*);
+
+protected:
+ MediaControlSeekButtonElement(HTMLMediaElement*, MediaControlElementType);
+
+private:
+ virtual bool isForwardButton() const = 0;
+
+ virtual void detach();
+ void seekTimerFired(Timer<MediaControlSeekButtonElement>*);
+
+ bool m_seeking;
+ bool m_capturing;
+ Timer<MediaControlSeekButtonElement> m_seekTimer;
+};
+
+// ----------------------------
+
+class MediaControlSeekForwardButtonElement : public MediaControlSeekButtonElement {
+public:
+ static PassRefPtr<MediaControlSeekForwardButtonElement> create(HTMLMediaElement*);
+
+private:
+ MediaControlSeekForwardButtonElement(HTMLMediaElement*);
+
+ virtual bool isForwardButton() const { return true; }
+ virtual const AtomicString& shadowPseudoId() const;
+};
+
+// ----------------------------
+
+class MediaControlSeekBackButtonElement : public MediaControlSeekButtonElement {
+public:
+ static PassRefPtr<MediaControlSeekBackButtonElement> create(HTMLMediaElement*);
+
+private:
+ MediaControlSeekBackButtonElement(HTMLMediaElement*);
+
+ virtual bool isForwardButton() const { return false; }
+ virtual const AtomicString& shadowPseudoId() const;
+};
+
+// ----------------------------
+
+class MediaControlRewindButtonElement : public MediaControlInputElement {
+public:
+ static PassRefPtr<MediaControlRewindButtonElement> create(HTMLMediaElement*);
+
+ virtual void defaultEventHandler(Event*);
+
+private:
+ MediaControlRewindButtonElement(HTMLMediaElement*);
+
+ virtual const AtomicString& shadowPseudoId() const;
+};
+
+// ----------------------------
+
+class MediaControlReturnToRealtimeButtonElement : public MediaControlInputElement {
+public:
+ static PassRefPtr<MediaControlReturnToRealtimeButtonElement> create(HTMLMediaElement*);
+
+ virtual void defaultEventHandler(Event*);
+
+private:
+ MediaControlReturnToRealtimeButtonElement(HTMLMediaElement*);
+
+ virtual const AtomicString& shadowPseudoId() const;
+};
+
+// ----------------------------
+
+class MediaControlToggleClosedCaptionsButtonElement : public MediaControlInputElement {
+public:
+ static PassRefPtr<MediaControlToggleClosedCaptionsButtonElement> create(HTMLMediaElement*);
+
+ virtual void defaultEventHandler(Event*);
+ virtual void updateDisplayType();
+
+private:
+ MediaControlToggleClosedCaptionsButtonElement(HTMLMediaElement*);
+
+ virtual const AtomicString& shadowPseudoId() const;
+};
+
+// ----------------------------
+
+class MediaControlTimelineElement : public MediaControlInputElement {
+public:
+ static PassRefPtr<MediaControlTimelineElement> create(HTMLMediaElement*, MediaControls*);
+
+ virtual void defaultEventHandler(Event*);
+ void setPosition(float);
+ void setDuration(float);
+
+private:
+ MediaControlTimelineElement(HTMLMediaElement*, MediaControls*);
+
+ virtual const AtomicString& shadowPseudoId() const;
+
+ MediaControls* m_controls;
+};
+
+// ----------------------------
+
+class MediaControlVolumeSliderElement : public MediaControlInputElement {
+public:
+ static PassRefPtr<MediaControlVolumeSliderElement> create(HTMLMediaElement*);
+
+ virtual void defaultEventHandler(Event*);
+ void setVolume(float);
+
+protected:
+ MediaControlVolumeSliderElement(HTMLMediaElement*);
+
+private:
+ virtual const AtomicString& shadowPseudoId() const;
+};
+
+// ----------------------------
+
+class MediaControlFullscreenButtonElement : public MediaControlInputElement {
+public:
+ static PassRefPtr<MediaControlFullscreenButtonElement> create(HTMLMediaElement*, MediaControls*);
+
+ virtual void defaultEventHandler(Event*);
+
+private:
+ MediaControlFullscreenButtonElement(HTMLMediaElement*, MediaControls*);
+
+ virtual const AtomicString& shadowPseudoId() const;
+
+ MediaControls* m_controls;
+};
+
+// ----------------------------
+
+class MediaControlFullscreenVolumeSliderElement : public MediaControlVolumeSliderElement {
+public:
+ static PassRefPtr<MediaControlFullscreenVolumeSliderElement> create(HTMLMediaElement*);
+
+private:
+ MediaControlFullscreenVolumeSliderElement(HTMLMediaElement*);
+
+ virtual const AtomicString& shadowPseudoId() const;
+};
+
+// ----------------------------
+
+class MediaControlFullscreenVolumeMinButtonElement : public MediaControlInputElement {
+public:
+ static PassRefPtr<MediaControlFullscreenVolumeMinButtonElement> create(HTMLMediaElement*);
+
+ virtual void defaultEventHandler(Event*);
+
+private:
+ MediaControlFullscreenVolumeMinButtonElement(HTMLMediaElement*);
+
+ virtual const AtomicString& shadowPseudoId() const;
+};
+
+// ----------------------------
+
+class MediaControlFullscreenVolumeMaxButtonElement : public MediaControlInputElement {
+public:
+ static PassRefPtr<MediaControlFullscreenVolumeMaxButtonElement> create(HTMLMediaElement*);
+
+ virtual void defaultEventHandler(Event*);
+
+private:
+ MediaControlFullscreenVolumeMaxButtonElement(HTMLMediaElement*);
+
+ virtual const AtomicString& shadowPseudoId() const;
+};
+
+// ----------------------------
+
+class MediaControlTimeDisplayElement : public MediaControlElement {
+public:
+ void setCurrentValue(float);
+ float currentValue() const { return m_currentValue; }
+
+protected:
+ MediaControlTimeDisplayElement(HTMLMediaElement*);
+
+private:
+ virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
+
+ float m_currentValue;
+};
+
+// ----------------------------
+
+class MediaControlTimeRemainingDisplayElement : public MediaControlTimeDisplayElement {
+public:
+ static PassRefPtr<MediaControlTimeRemainingDisplayElement> create(HTMLMediaElement*);
+
+private:
+ MediaControlTimeRemainingDisplayElement(HTMLMediaElement*);
+
+ virtual MediaControlElementType displayType() const;
+ virtual const AtomicString& shadowPseudoId() const;
+};
+
+// ----------------------------
+
+class MediaControlCurrentTimeDisplayElement : public MediaControlTimeDisplayElement {
+public:
+ static PassRefPtr<MediaControlCurrentTimeDisplayElement> create(HTMLMediaElement*);
+
+private:
+ MediaControlCurrentTimeDisplayElement(HTMLMediaElement*);
+
+ virtual MediaControlElementType displayType() const;
+ virtual const AtomicString& shadowPseudoId() const;
+};
+
+// ----------------------------
+
+} // namespace WebCore
+
+#endif // ENABLE(VIDEO)
+
+#endif // MediaControlElements_h
diff --git a/Source/WebCore/html/shadow/MediaControlRootElement.cpp b/Source/WebCore/html/shadow/MediaControlRootElement.cpp
new file mode 100644
index 0000000..23a25f5
--- /dev/null
+++ b/Source/WebCore/html/shadow/MediaControlRootElement.cpp
@@ -0,0 +1,446 @@
+/*
+ * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(VIDEO)
+#include "MediaControlRootElement.h"
+
+#include "MediaControlElements.h"
+#include "Page.h"
+#include "RenderTheme.h"
+
+using namespace std;
+
+namespace WebCore {
+
+MediaControlRootElement::MediaControlRootElement(HTMLMediaElement* mediaElement)
+ : MediaControls(mediaElement)
+ , m_mediaElement(mediaElement)
+ , m_rewindButton(0)
+ , m_playButton(0)
+ , m_returnToRealTimeButton(0)
+ , m_statusDisplay(0)
+ , m_currentTimeDisplay(0)
+ , m_timeline(0)
+ , m_timeRemainingDisplay(0)
+ , m_timelineContainer(0)
+ , m_seekBackButton(0)
+ , m_seekForwardButton(0)
+ , m_toggleClosedCaptionsButton(0)
+ , m_panelMuteButton(0)
+ , m_volumeSlider(0)
+ , m_volumeSliderMuteButton(0)
+ , m_volumeSliderContainer(0)
+ , m_fullScreenButton(0)
+ , m_fullScreenMinVolumeButton(0)
+ , m_fullScreenVolumeSlider(0)
+ , m_fullScreenMaxVolumeButton(0)
+ , m_panel(0)
+ , m_opaque(true)
+{
+}
+
+PassRefPtr<MediaControls> MediaControls::create(HTMLMediaElement* mediaElement)
+{
+ return MediaControlRootElement::create(mediaElement);
+}
+
+PassRefPtr<MediaControlRootElement> MediaControlRootElement::create(HTMLMediaElement* mediaElement)
+{
+ if (!mediaElement->document()->page())
+ return 0;
+
+ RefPtr<MediaControlRootElement> controls = adoptRef(new MediaControlRootElement(mediaElement));
+
+ RefPtr<MediaControlPanelElement> panel = MediaControlPanelElement::create(mediaElement);
+
+ ExceptionCode ec;
+
+ RefPtr<MediaControlRewindButtonElement> rewindButton = MediaControlRewindButtonElement::create(mediaElement);
+ controls->m_rewindButton = rewindButton.get();
+ panel->appendChild(rewindButton.release(), ec, true);
+ if (ec)
+ return 0;
+
+ RefPtr<MediaControlPlayButtonElement> playButton = MediaControlPlayButtonElement::create(mediaElement);
+ controls->m_playButton = playButton.get();
+ panel->appendChild(playButton.release(), ec, true);
+ if (ec)
+ return 0;
+
+ RefPtr<MediaControlReturnToRealtimeButtonElement> returnToRealtimeButton = MediaControlReturnToRealtimeButtonElement::create(mediaElement);
+ controls->m_returnToRealTimeButton = returnToRealtimeButton.get();
+ panel->appendChild(returnToRealtimeButton.release(), ec, true);
+ if (ec)
+ return 0;
+
+ if (mediaElement->document()->page()->theme()->usesMediaControlStatusDisplay()) {
+ RefPtr<MediaControlStatusDisplayElement> statusDisplay = MediaControlStatusDisplayElement::create(mediaElement);
+ controls->m_statusDisplay = statusDisplay.get();
+ panel->appendChild(statusDisplay.release(), ec, true);
+ if (ec)
+ return 0;
+ }
+
+ RefPtr<MediaControlTimelineContainerElement> timelineContainer = MediaControlTimelineContainerElement::create(mediaElement);
+
+ RefPtr<MediaControlCurrentTimeDisplayElement> currentTimeDisplay = MediaControlCurrentTimeDisplayElement::create(mediaElement);
+ controls->m_currentTimeDisplay = currentTimeDisplay.get();
+ timelineContainer->appendChild(currentTimeDisplay.release(), ec, true);
+ if (ec)
+ return 0;
+
+ RefPtr<MediaControlTimelineElement> timeline = MediaControlTimelineElement::create(mediaElement, controls.get());
+ controls->m_timeline = timeline.get();
+ timelineContainer->appendChild(timeline.release(), ec, true);
+ if (ec)
+ return 0;
+
+ RefPtr<MediaControlTimeRemainingDisplayElement> timeRemainingDisplay = MediaControlTimeRemainingDisplayElement::create(mediaElement);
+ controls->m_timeRemainingDisplay = timeRemainingDisplay.get();
+ timelineContainer->appendChild(timeRemainingDisplay.release(), ec, true);
+ if (ec)
+ return 0;
+
+ controls->m_timelineContainer = timelineContainer.get();
+ panel->appendChild(timelineContainer.release(), ec, true);
+ if (ec)
+ return 0;
+
+ // FIXME: Only create when needed <http://webkit.org/b/57163>
+ RefPtr<MediaControlSeekBackButtonElement> seekBackButton = MediaControlSeekBackButtonElement::create(mediaElement);
+ controls->m_seekBackButton = seekBackButton.get();
+ panel->appendChild(seekBackButton.release(), ec, true);
+ if (ec)
+ return 0;
+
+ // FIXME: Only create when needed <http://webkit.org/b/57163>
+ RefPtr<MediaControlSeekForwardButtonElement> seekForwardButton = MediaControlSeekForwardButtonElement::create(mediaElement);
+ controls->m_seekForwardButton = seekForwardButton.get();
+ panel->appendChild(seekForwardButton.release(), ec, true);
+ if (ec)
+ return 0;
+
+ if (mediaElement->document()->page()->theme()->supportsClosedCaptioning()) {
+ RefPtr<MediaControlToggleClosedCaptionsButtonElement> toggleClosedCaptionsButton = MediaControlToggleClosedCaptionsButtonElement::create(mediaElement);
+ controls->m_toggleClosedCaptionsButton = toggleClosedCaptionsButton.get();
+ panel->appendChild(toggleClosedCaptionsButton.release(), ec, true);
+ if (ec)
+ return 0;
+ }
+
+ // FIXME: Only create when needed <http://webkit.org/b/57163>
+ RefPtr<MediaControlFullscreenButtonElement> fullScreenButton = MediaControlFullscreenButtonElement::create(mediaElement, controls.get());
+ controls->m_fullScreenButton = fullScreenButton.get();
+ panel->appendChild(fullScreenButton.release(), ec, true);
+
+ RefPtr<MediaControlPanelMuteButtonElement> panelMuteButton = MediaControlPanelMuteButtonElement::create(mediaElement, controls.get());
+ controls->m_panelMuteButton = panelMuteButton.get();
+ panel->appendChild(panelMuteButton.release(), ec, true);
+ if (ec)
+ return 0;
+
+ if (mediaElement->document()->page()->theme()->usesMediaControlVolumeSlider()) {
+ RefPtr<MediaControlVolumeSliderContainerElement> volumeSliderContainer = MediaControlVolumeSliderContainerElement::create(mediaElement);
+
+ RefPtr<MediaControlVolumeSliderElement> slider = MediaControlVolumeSliderElement::create(mediaElement);
+ controls->m_volumeSlider = slider.get();
+ volumeSliderContainer->appendChild(slider.release(), ec, true);
+ if (ec)
+ return 0;
+
+ RefPtr<MediaControlVolumeSliderMuteButtonElement> volumeSliderMuteButton = MediaControlVolumeSliderMuteButtonElement::create(mediaElement);
+ controls->m_volumeSliderMuteButton = volumeSliderMuteButton.get();
+ volumeSliderContainer->appendChild(volumeSliderMuteButton.release(), ec, true);
+ if (ec)
+ return 0;
+
+ controls->m_volumeSliderContainer = volumeSliderContainer.get();
+ panel->appendChild(volumeSliderContainer.release(), ec, true);
+ if (ec)
+ return 0;
+ }
+
+ // FIXME: Only create when needed <http://webkit.org/b/57163>
+ RefPtr<MediaControlFullscreenVolumeMinButtonElement> fullScreenMinVolumeButton = MediaControlFullscreenVolumeMinButtonElement::create(mediaElement);
+ controls->m_fullScreenMinVolumeButton = fullScreenMinVolumeButton.get();
+ panel->appendChild(fullScreenMinVolumeButton.release(), ec, true);
+ if (ec)
+ return 0;
+
+ RefPtr<MediaControlFullscreenVolumeSliderElement> fullScreenVolumeSlider = MediaControlFullscreenVolumeSliderElement::create(mediaElement);
+ controls->m_fullScreenVolumeSlider = fullScreenVolumeSlider.get();
+ panel->appendChild(fullScreenVolumeSlider.release(), ec, true);
+ if (ec)
+ return 0;
+
+ RefPtr<MediaControlFullscreenVolumeMaxButtonElement> fullScreenMaxVolumeButton = MediaControlFullscreenVolumeMaxButtonElement::create(mediaElement);
+ controls->m_fullScreenMaxVolumeButton = fullScreenMaxVolumeButton.get();
+ panel->appendChild(fullScreenMaxVolumeButton.release(), ec, true);
+ if (ec)
+ return 0;
+
+ controls->m_panel = panel.get();
+ controls->appendChild(panel.release(), ec, true);
+ if (ec)
+ return 0;
+
+ return controls.release();
+}
+
+void MediaControlRootElement::show()
+{
+ m_panel->show();
+}
+
+void MediaControlRootElement::hide()
+{
+ m_panel->hide();
+}
+
+static const String& webkitTransitionString()
+{
+ DEFINE_STATIC_LOCAL(String, s, ("-webkit-transition"));
+ return s;
+}
+
+static const String& opacityString()
+{
+ DEFINE_STATIC_LOCAL(String, s, ("opacity"));
+ return s;
+}
+
+void MediaControlRootElement::makeOpaque()
+{
+ if (m_opaque)
+ return;
+
+ DEFINE_STATIC_LOCAL(String, transitionValue, ());
+ if (transitionValue.isNull())
+ transitionValue = String::format("opacity %.1gs", document()->page()->theme()->mediaControlsFadeInDuration());
+ DEFINE_STATIC_LOCAL(String, opacityValue, ("1"));
+
+ ExceptionCode ec;
+ // FIXME: Make more efficient <http://webkit.org/b/58157>
+ m_panel->style()->setProperty(webkitTransitionString(), transitionValue, ec);
+ m_panel->style()->setProperty(opacityString(), opacityValue, ec);
+ m_opaque = true;
+}
+
+void MediaControlRootElement::makeTransparent()
+{
+ if (!m_opaque)
+ return;
+
+ DEFINE_STATIC_LOCAL(String, transitionValue, ());
+ if (transitionValue.isNull())
+ transitionValue = String::format("opacity %.1gs", document()->page()->theme()->mediaControlsFadeOutDuration());
+ DEFINE_STATIC_LOCAL(String, opacityValue, ("0"));
+
+ ExceptionCode ec;
+ // FIXME: Make more efficient <http://webkit.org/b/58157>
+ m_panel->style()->setProperty(webkitTransitionString(), transitionValue, ec);
+ m_panel->style()->setProperty(opacityString(), opacityValue, ec);
+ m_opaque = false;
+}
+
+void MediaControlRootElement::reset()
+{
+ Page* page = document()->page();
+ if (!page)
+ return;
+
+ changedNetworkState();
+
+ if (m_mediaElement->supportsFullscreen())
+ m_fullScreenButton->show();
+ else
+ m_fullScreenButton->hide();
+
+ float duration = m_mediaElement->duration();
+ if (isfinite(duration) || page->theme()->hasOwnDisabledStateHandlingFor(MediaSliderPart)) {
+ m_timeline->setDuration(duration);
+ m_timelineContainer->show();
+ m_timeline->setPosition(m_mediaElement->currentTime());
+ updateTimeDisplay();
+ } else
+ m_timelineContainer->hide();
+
+ if (m_mediaElement->hasAudio() || page->theme()->hasOwnDisabledStateHandlingFor(MediaMuteButtonPart))
+ m_panelMuteButton->show();
+ else
+ m_panelMuteButton->hide();
+
+ if (m_volumeSlider)
+ m_volumeSlider->setVolume(m_mediaElement->volume());
+
+ if (m_toggleClosedCaptionsButton) {
+ if (m_mediaElement->hasClosedCaptions())
+ m_toggleClosedCaptionsButton->show();
+ else
+ m_toggleClosedCaptionsButton->hide();
+ }
+
+ if (m_mediaElement->movieLoadType() != MediaPlayer::LiveStream) {
+ m_returnToRealTimeButton->hide();
+ m_rewindButton->show();
+ } else {
+ m_returnToRealTimeButton->show();
+ m_rewindButton->hide();
+ }
+
+ makeOpaque();
+}
+
+void MediaControlRootElement::playbackStarted()
+{
+ m_playButton->updateDisplayType();
+ m_timeline->setPosition(m_mediaElement->currentTime());
+ updateTimeDisplay();
+}
+
+void MediaControlRootElement::playbackProgressed()
+{
+ m_timeline->setPosition(m_mediaElement->currentTime());
+ updateTimeDisplay();
+}
+
+void MediaControlRootElement::playbackStopped()
+{
+ m_playButton->updateDisplayType();
+ m_timeline->setPosition(m_mediaElement->currentTime());
+ updateTimeDisplay();
+ makeOpaque();
+}
+
+void MediaControlRootElement::updateTimeDisplay()
+{
+ float now = m_mediaElement->currentTime();
+ float duration = m_mediaElement->duration();
+
+ Page* page = document()->page();
+ if (!page)
+ return;
+
+ // Allow the theme to format the time.
+ ExceptionCode ec;
+ m_currentTimeDisplay->setInnerText(page->theme()->formatMediaControlsCurrentTime(now, duration), ec);
+ m_currentTimeDisplay->setCurrentValue(now);
+ m_timeRemainingDisplay->setInnerText(page->theme()->formatMediaControlsRemainingTime(now, duration), ec);
+ m_timeRemainingDisplay->setCurrentValue(now - duration);
+}
+
+void MediaControlRootElement::reportedError()
+{
+ Page* page = document()->page();
+ if (!page)
+ return;
+
+ if (!page->theme()->hasOwnDisabledStateHandlingFor(MediaSliderPart))
+ m_timelineContainer->hide();
+
+ if (!page->theme()->hasOwnDisabledStateHandlingFor(MediaMuteButtonPart))
+ m_panelMuteButton->hide();
+
+ m_fullScreenButton->hide();
+
+ if (m_volumeSliderContainer)
+ m_volumeSliderContainer->hide();
+ if (m_toggleClosedCaptionsButton && !page->theme()->hasOwnDisabledStateHandlingFor(MediaToggleClosedCaptionsButtonPart))
+ m_toggleClosedCaptionsButton->hide();
+}
+
+void MediaControlRootElement::changedNetworkState()
+{
+ if (m_statusDisplay)
+ m_statusDisplay->update();
+}
+
+void MediaControlRootElement::loadedMetadata()
+{
+ if (m_statusDisplay)
+ m_statusDisplay->hide();
+
+ reset();
+}
+
+void MediaControlRootElement::changedClosedCaptionsVisibility()
+{
+ if (m_toggleClosedCaptionsButton)
+ m_toggleClosedCaptionsButton->updateDisplayType();
+}
+
+void MediaControlRootElement::changedMute()
+{
+ m_panelMuteButton->changedMute();
+ if (m_volumeSliderMuteButton)
+ m_volumeSliderMuteButton->changedMute();
+}
+
+void MediaControlRootElement::changedVolume()
+{
+ if (m_volumeSlider)
+ m_volumeSlider->setVolume(m_mediaElement->volume());
+}
+
+void MediaControlRootElement::enteredFullscreen()
+{
+ if (m_mediaElement->movieLoadType() == MediaPlayer::LiveStream || m_mediaElement->movieLoadType() == MediaPlayer::StoredStream) {
+ m_seekBackButton->hide();
+ m_seekForwardButton->hide();
+ } else
+ m_rewindButton->hide();
+}
+
+void MediaControlRootElement::exitedFullscreen()
+{
+ // "show" actually means removal of display:none style, so we are just clearing styles
+ // when exiting fullscreen.
+ // FIXME: Clarify naming of show/hide <http://webkit.org/b/58157>
+ m_rewindButton->show();
+ m_seekBackButton->show();
+ m_seekForwardButton->show();
+}
+
+void MediaControlRootElement::showVolumeSlider()
+{
+ if (!m_mediaElement->hasAudio())
+ return;
+
+ if (m_volumeSliderContainer)
+ m_volumeSliderContainer->show();
+}
+
+const AtomicString& MediaControlRootElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls"));
+ return id;
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/html/shadow/MediaControlRootElement.h b/Source/WebCore/html/shadow/MediaControlRootElement.h
new file mode 100644
index 0000000..8c6d3ec
--- /dev/null
+++ b/Source/WebCore/html/shadow/MediaControlRootElement.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef MediaControlRootElement_h
+#define MediaControlRootElement_h
+
+#if ENABLE(VIDEO)
+
+#include "MediaControls.h"
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class HTMLInputElement;
+class HTMLMediaElement;
+class Event;
+class MediaControlPanelMuteButtonElement;
+class MediaControlPlayButtonElement;
+class MediaControlSeekButtonElement;
+class MediaControlRewindButtonElement;
+class MediaControlReturnToRealtimeButtonElement;
+class MediaControlToggleClosedCaptionsButtonElement;
+class MediaControlCurrentTimeDisplayElement;
+class MediaControlTimelineElement;
+class MediaControlTimeRemainingDisplayElement;
+class MediaControlVolumeSliderElement;
+class MediaControlFullscreenButtonElement;
+class MediaControlTimeDisplayElement;
+class MediaControlStatusDisplayElement;
+class MediaControlTimelineContainerElement;
+class MediaControlSeekBackButtonElement;
+class MediaControlSeekForwardButtonElement;
+class MediaControlMuteButtonElement;
+class MediaControlVolumeSliderElement;
+class MediaControlVolumeSliderMuteButtonElement;
+class MediaControlVolumeSliderContainerElement;
+class MediaControlFullscreenVolumeMinButtonElement;
+class MediaControlFullscreenVolumeSliderElement;
+class MediaControlFullscreenVolumeMaxButtonElement;
+class MediaControlPanelElement;
+class MediaPlayer;
+
+class RenderBox;
+class RenderMedia;
+
+class MediaControlRootElement : public MediaControls {
+public:
+ static PassRefPtr<MediaControlRootElement> create(HTMLMediaElement*);
+
+ // MediaControls implementation.
+ void show();
+ void hide();
+ void makeOpaque();
+ void makeTransparent();
+
+ void reset();
+
+ void playbackProgressed();
+ void playbackStarted();
+ void playbackStopped();
+
+ void changedMute();
+ void changedVolume();
+
+ void enteredFullscreen();
+ void exitedFullscreen();
+
+ void reportedError();
+ void changedNetworkState();
+ void loadedMetadata();
+ void changedClosedCaptionsVisibility();
+
+ void showVolumeSlider();
+ void updateTimeDisplay();
+
+private:
+ MediaControlRootElement(HTMLMediaElement*);
+
+ virtual const AtomicString& shadowPseudoId() const;
+
+ HTMLMediaElement* m_mediaElement;
+
+ MediaControlRewindButtonElement* m_rewindButton;
+ MediaControlPlayButtonElement* m_playButton;
+ MediaControlReturnToRealtimeButtonElement* m_returnToRealTimeButton;
+ MediaControlStatusDisplayElement* m_statusDisplay;
+ MediaControlCurrentTimeDisplayElement* m_currentTimeDisplay;
+ MediaControlTimelineElement* m_timeline;
+ MediaControlTimeRemainingDisplayElement* m_timeRemainingDisplay;
+ MediaControlTimelineContainerElement* m_timelineContainer;
+ MediaControlSeekBackButtonElement* m_seekBackButton;
+ MediaControlSeekForwardButtonElement* m_seekForwardButton;
+ MediaControlToggleClosedCaptionsButtonElement* m_toggleClosedCaptionsButton;
+ MediaControlPanelMuteButtonElement* m_panelMuteButton;
+ MediaControlVolumeSliderElement* m_volumeSlider;
+ MediaControlVolumeSliderMuteButtonElement* m_volumeSliderMuteButton;
+ MediaControlVolumeSliderContainerElement* m_volumeSliderContainer;
+ MediaControlFullscreenButtonElement* m_fullScreenButton;
+ MediaControlFullscreenVolumeMinButtonElement* m_fullScreenMinVolumeButton;
+ MediaControlFullscreenVolumeSliderElement* m_fullScreenVolumeSlider;
+ MediaControlFullscreenVolumeMaxButtonElement* m_fullScreenMaxVolumeButton;
+ MediaControlPanelElement* m_panel;
+
+ bool m_opaque;
+};
+
+}
+
+#endif
+#endif
diff --git a/Source/WebCore/html/shadow/MediaControls.cpp b/Source/WebCore/html/shadow/MediaControls.cpp
index 04bdce4..690d1ce 100644
--- a/Source/WebCore/html/shadow/MediaControls.cpp
+++ b/Source/WebCore/html/shadow/MediaControls.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -27,11 +27,13 @@
#include "config.h"
#if ENABLE(VIDEO)
+
#include "MediaControls.h"
-#include "EventNames.h"
-#include "FloatConversion.h"
+#include "HTMLDivElement.h"
+#include "HTMLMediaElement.h"
#include "HTMLNames.h"
+<<<<<<< HEAD
#include "MediaControlElements.h"
#include "MouseEvent.h"
#include "Page.h"
@@ -47,14 +49,13 @@
using namespace std;
+=======
+>>>>>>> WebKit.org at r84325
namespace WebCore {
-using namespace HTMLNames;
-
-static const double cOpacityAnimationRepeatDelay = 0.05;
-
MediaControls::MediaControls(HTMLMediaElement* mediaElement)
+<<<<<<< HEAD
: m_mediaElement(mediaElement)
, m_opacityAnimationTimer(this, &MediaControls::opacityAnimationTimerFired)
, m_opacityAnimationStartTime(0)
@@ -555,6 +556,10 @@ void MediaControls::forwardEvent(Event* event)
}
}
#endif
+=======
+ : HTMLDivElement(HTMLNames::divTag, mediaElement->document())
+{
+>>>>>>> WebKit.org at r84325
}
#if PLATFORM(ANDROID)
diff --git a/Source/WebCore/html/shadow/MediaControls.h b/Source/WebCore/html/shadow/MediaControls.h
index 726573e..a14b359 100644
--- a/Source/WebCore/html/shadow/MediaControls.h
+++ b/Source/WebCore/html/shadow/MediaControls.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -29,76 +29,59 @@
#if ENABLE(VIDEO)
-#include "Timer.h"
-#include <wtf/RefPtr.h>
+#include "HTMLDivElement.h"
namespace WebCore {
-class HTMLElement;
-class HTMLInputElement;
class HTMLMediaElement;
-class Event;
-class MediaControlMuteButtonElement;
-class MediaControlPlayButtonElement;
-class MediaControlSeekButtonElement;
-class MediaControlShadowRootElement;
-class MediaControlRewindButtonElement;
-class MediaControlReturnToRealtimeButtonElement;
-class MediaControlToggleClosedCaptionsButtonElement;
-class MediaControlTimelineElement;
-class MediaControlVolumeSliderElement;
-class MediaControlFullscreenButtonElement;
-class MediaControlTimeDisplayElement;
-class MediaControlStatusDisplayElement;
-class MediaControlTimelineContainerElement;
-class MediaControlVolumeSliderContainerElement;
-class MediaControlElement;
-class MediaControlFullscreenVolumeMinButtonElement;
-class MediaControlFullscreenVolumeSliderElement;
-class MediaControlFullscreenVolumeMaxButtonElement;
-class MediaPlayer;
-
-class RenderBox;
-class RenderMedia;
-
-class MediaControls {
-public:
- MediaControls(HTMLMediaElement*);
- void reset();
+class MediaControls : public HTMLDivElement {
+ public:
+ virtual ~MediaControls() {}
- void playbackProgressed();
- void playbackStarted();
- void playbackStopped();
+ // This function is to be implemented in your port-specific media
+ // controls implementation.
+ static PassRefPtr<MediaControls> create(HTMLMediaElement*);
- void changedMute();
- void changedVolume();
- void changedClosedCaptionsVisibility();
+ virtual void show() = 0;
+ virtual void hide() = 0;
+ virtual void makeOpaque() = 0;
+ virtual void makeTransparent() = 0;
- void destroy();
- void update();
- void updateStyle();
- void forwardEvent(Event*);
- void updateTimeDisplay();
+ virtual void reset() = 0;
- // 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.
- RenderBox* renderBox();
+ virtual void playbackProgressed() = 0;
+ virtual void playbackStarted() = 0;
+ virtual void playbackStopped() = 0;
+<<<<<<< HEAD
#if PLATFORM(ANDROID)
void updateLastTouch();
#endif
private:
PassRefPtr<MediaControlShadowRootElement> create(HTMLMediaElement*);
+=======
+ virtual void changedMute() = 0;
+ virtual void changedVolume() = 0;
+>>>>>>> WebKit.org at r84325
+
+ virtual void enteredFullscreen() = 0;
+ virtual void exitedFullscreen() = 0;
+
+ virtual void reportedError() = 0;
+ virtual void changedNetworkState() = 0;
+ virtual void loadedMetadata() = 0;
+ virtual void changedClosedCaptionsVisibility() = 0;
- void updateControlVisibility();
- void changeOpacity(HTMLElement*, float opacity);
- void opacityAnimationTimerFired(Timer<MediaControls>*);
+ virtual void showVolumeSlider() = 0;
+ virtual void updateTimeDisplay() = 0;
- void updateVolumeSliderContainer(bool visible);
+protected:
+ MediaControls(HTMLMediaElement*);
private:
+<<<<<<< HEAD
RefPtr<MediaControlShadowRootElement> m_controlsShadowRoot;
RefPtr<MediaControlElement> m_panel;
RefPtr<MediaControlMuteButtonElement> m_muteButton;
@@ -134,10 +117,13 @@ private:
#if PLATFORM(ANDROID)
double m_lastTouch;
#endif
+=======
+ MediaControls();
+>>>>>>> WebKit.org at r84325
};
-
}
#endif
+
#endif
diff --git a/Source/WebCore/html/shadow/MeterShadowElement.cpp b/Source/WebCore/html/shadow/MeterShadowElement.cpp
new file mode 100644
index 0000000..a5eb70b
--- /dev/null
+++ b/Source/WebCore/html/shadow/MeterShadowElement.cpp
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#if ENABLE(METER_TAG)
+#include "MeterShadowElement.h"
+
+#include "CSSMutableStyleDeclaration.h"
+#include "CSSPropertyNames.h"
+#include "HTMLMeterElement.h"
+#include "HTMLNames.h"
+#include "RenderMeter.h"
+#include "RenderTheme.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+MeterShadowElement::MeterShadowElement(Document* document)
+ : HTMLDivElement(HTMLNames::divTag, document)
+{
+}
+
+HTMLMeterElement* MeterShadowElement::meterElement() const
+{
+ Node* node = const_cast<MeterShadowElement*>(this)->shadowAncestorNode();
+ ASSERT(!node || meterTag == toElement(node)->tagQName());
+ return static_cast<HTMLMeterElement*>(node);
+}
+
+bool MeterShadowElement::rendererIsNeeded(RenderStyle* style)
+{
+ RenderMeter* meterRenderer = toRenderMeter(meterElement()->renderer());
+ return meterRenderer && !meterRenderer->theme()->supportsMeter(meterRenderer->style()->appearance()) && HTMLDivElement::rendererIsNeeded(style);
+}
+
+const AtomicString& MeterBarElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, pseudId, ("-webkit-meter-bar"));
+ return pseudId;
+}
+
+
+const AtomicString& MeterValueElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, optimumPseudId, ("-webkit-meter-optimum-value"));
+ DEFINE_STATIC_LOCAL(AtomicString, suboptimumPseudId, ("-webkit-meter-suboptimum-value"));
+ DEFINE_STATIC_LOCAL(AtomicString, evenLessGoodPseudId, ("-webkit-meter-even-less-good-value"));
+
+ HTMLMeterElement* meter = meterElement();
+ if (!meter)
+ return optimumPseudId;
+
+ switch (meter->gaugeRegion()) {
+ case HTMLMeterElement::GaugeRegionOptimum:
+ return optimumPseudId;
+ case HTMLMeterElement::GaugeRegionSuboptimal:
+ return suboptimumPseudId;
+ case HTMLMeterElement::GaugeRegionEvenLessGood:
+ return evenLessGoodPseudId;
+ default:
+ ASSERT_NOT_REACHED();
+ return optimumPseudId;
+ }
+}
+
+void MeterValueElement::setWidthPercentage(double width)
+{
+ getInlineStyleDecl()->setProperty(CSSPropertyWidth, width, CSSPrimitiveValue::CSS_PERCENTAGE);
+}
+
+
+}
+
+#endif
+
diff --git a/Source/WebCore/html/shadow/MeterShadowElement.h b/Source/WebCore/html/shadow/MeterShadowElement.h
new file mode 100644
index 0000000..93626df
--- /dev/null
+++ b/Source/WebCore/html/shadow/MeterShadowElement.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef MeterShadowElement_h
+#define MeterShadowElement_h
+
+#include "HTMLDivElement.h"
+#include <wtf/Forward.h>
+
+namespace WebCore {
+
+class HTMLMeterElement;
+
+class MeterShadowElement : public HTMLDivElement {
+public:
+ MeterShadowElement(Document*);
+ HTMLMeterElement* meterElement() const;
+
+private:
+ virtual bool rendererIsNeeded(RenderStyle*);
+};
+
+class MeterBarElement : public MeterShadowElement {
+public:
+ MeterBarElement(Document* document)
+ : MeterShadowElement(document)
+ {
+ }
+
+ static PassRefPtr<MeterBarElement> create(Document*);
+ virtual const AtomicString& shadowPseudoId() const;
+};
+
+inline PassRefPtr<MeterBarElement> MeterBarElement::create(Document* document)
+{
+ return adoptRef(new MeterBarElement(document));
+}
+
+
+class MeterValueElement : public MeterShadowElement {
+public:
+ MeterValueElement(Document* document)
+ : MeterShadowElement(document)
+ {
+ }
+
+ virtual const AtomicString& shadowPseudoId() const;
+ static PassRefPtr<MeterValueElement> create(Document*);
+ void setWidthPercentage(double);
+};
+
+inline PassRefPtr<MeterValueElement> MeterValueElement::create(Document* document)
+{
+ return adoptRef(new MeterValueElement(document));
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/html/shadow/ProgressShadowElement.cpp b/Source/WebCore/html/shadow/ProgressShadowElement.cpp
new file mode 100644
index 0000000..1cedd0d
--- /dev/null
+++ b/Source/WebCore/html/shadow/ProgressShadowElement.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#if ENABLE(PROGRESS_TAG)
+#include "ProgressShadowElement.h"
+
+#include "HTMLNames.h"
+#include "HTMLProgressElement.h"
+#include "RenderObject.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+ProgressShadowElement::ProgressShadowElement(Document* document)
+ : HTMLDivElement(HTMLNames::divTag, document)
+{
+}
+
+HTMLProgressElement* ProgressShadowElement::progressElement() const
+{
+ Node* node = const_cast<ProgressShadowElement*>(this)->shadowAncestorNode();
+ ASSERT(!node || progressTag == toElement(node)->tagQName());
+ return static_cast<HTMLProgressElement*>(node);
+}
+
+bool ProgressShadowElement::rendererIsNeeded(RenderStyle* style)
+{
+ RenderObject* progressRenderer = progressElement()->renderer();
+ return progressRenderer && !progressRenderer->style()->hasAppearance() && HTMLDivElement::rendererIsNeeded(style);
+}
+
+const AtomicString& ProgressBarElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, pseudId, ("-webkit-progress-bar"));
+ return pseudId;
+}
+
+
+const AtomicString& ProgressValueElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, pseudId, ("-webkit-progress-value"));
+ return pseudId;
+}
+
+void ProgressValueElement::setWidthPercentage(double width)
+{
+ getInlineStyleDecl()->setProperty(CSSPropertyWidth, width, CSSPrimitiveValue::CSS_PERCENTAGE);
+}
+
+}
+#endif
+
diff --git a/Source/WebCore/html/shadow/ProgressShadowElement.h b/Source/WebCore/html/shadow/ProgressShadowElement.h
new file mode 100644
index 0000000..a106bf8
--- /dev/null
+++ b/Source/WebCore/html/shadow/ProgressShadowElement.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ProgressShadowElement_h
+#define ProgressShadowElement_h
+
+#include "HTMLDivElement.h"
+#include <wtf/Forward.h>
+
+namespace WebCore {
+
+class HTMLProgressElement;
+
+class ProgressShadowElement : public HTMLDivElement {
+public:
+ ProgressShadowElement(Document*);
+ HTMLProgressElement* progressElement() const;
+
+private:
+ virtual bool rendererIsNeeded(RenderStyle*);
+};
+
+class ProgressBarElement : public ProgressShadowElement {
+public:
+ ProgressBarElement(Document* document)
+ : ProgressShadowElement(document)
+ {
+ }
+
+ static PassRefPtr<ProgressBarElement> create(Document*);
+ virtual const AtomicString& shadowPseudoId() const;
+};
+
+inline PassRefPtr<ProgressBarElement> ProgressBarElement::create(Document* document)
+{
+ return adoptRef(new ProgressBarElement(document));
+}
+
+
+class ProgressValueElement : public ProgressShadowElement {
+public:
+ ProgressValueElement(Document* document)
+ : ProgressShadowElement(document)
+ {
+ }
+
+ virtual const AtomicString& shadowPseudoId() const;
+ static PassRefPtr<ProgressValueElement> create(Document*);
+ void setWidthPercentage(double);
+};
+
+inline PassRefPtr<ProgressValueElement> ProgressValueElement::create(Document* document)
+{
+ return adoptRef(new ProgressValueElement(document));
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/html/shadow/SliderThumbElement.cpp b/Source/WebCore/html/shadow/SliderThumbElement.cpp
index 6a6e901..e68ab00 100644
--- a/Source/WebCore/html/shadow/SliderThumbElement.cpp
+++ b/Source/WebCore/html/shadow/SliderThumbElement.cpp
@@ -110,7 +110,7 @@ void SliderThumbElement::dragFrom(const IntPoint& point)
void SliderThumbElement::setPositionFromPoint(const IntPoint& point)
{
- HTMLInputElement* input = static_cast<HTMLInputElement*>(shadowHost());
+ HTMLInputElement* input = hostInput();
ASSERT(input);
if (!input->renderer() || !renderer())
@@ -260,6 +260,12 @@ void SliderThumbElement::detach()
HTMLDivElement::detach();
}
+HTMLInputElement* SliderThumbElement::hostInput()
+{
+ ASSERT(parentNode());
+ return static_cast<HTMLInputElement*>(parentNode()->shadowHost());
+}
+
const AtomicString& SliderThumbElement::shadowPseudoId() const
{
DEFINE_STATIC_LOCAL(AtomicString, sliderThumb, ("-webkit-slider-thumb"));
diff --git a/Source/WebCore/html/shadow/SliderThumbElement.h b/Source/WebCore/html/shadow/SliderThumbElement.h
index 9414ac4..2fa60cb 100644
--- a/Source/WebCore/html/shadow/SliderThumbElement.h
+++ b/Source/WebCore/html/shadow/SliderThumbElement.h
@@ -41,6 +41,7 @@
namespace WebCore {
class HTMLElement;
+class HTMLInputElement;
class Event;
class FloatPoint;
@@ -62,6 +63,7 @@ private:
void startDragging();
void stopDragging();
void setPositionFromPoint(const IntPoint&);
+ HTMLInputElement* hostInput();
FloatPoint m_offsetToThumb;
bool m_inDragMode;
diff --git a/Source/WebCore/html/shadow/TextControlInnerElements.cpp b/Source/WebCore/html/shadow/TextControlInnerElements.cpp
index 968c5e4..00fc667 100644
--- a/Source/WebCore/html/shadow/TextControlInnerElements.cpp
+++ b/Source/WebCore/html/shadow/TextControlInnerElements.cpp
@@ -393,6 +393,12 @@ void InputFieldSpeechButtonElement::defaultEventHandler(Event* event)
// here, we take a temporary reference.
RefPtr<HTMLInputElement> input(static_cast<HTMLInputElement*>(shadowAncestorNode()));
+ if (input->disabled() || input->isReadOnlyFormControl()) {
+ if (!event->defaultHandled())
+ HTMLDivElement::defaultEventHandler(event);
+ return;
+ }
+
// On mouse down, select the text and set focus.
if (event->type() == eventNames().mousedownEvent && event->isMouseEvent() && static_cast<MouseEvent*>(event)->button() == LeftButton) {
if (renderer() && renderer()->visibleToHitTesting()) {
@@ -471,6 +477,9 @@ void InputFieldSpeechButtonElement::setRecognitionResult(int, const SpeechInputR
// remove the input element from DOM. To make sure it remains valid until we finish our work
// here, we take a temporary reference.
RefPtr<HTMLInputElement> input(static_cast<HTMLInputElement*>(shadowAncestorNode()));
+ if (input->disabled() || input->isReadOnlyFormControl())
+ return;
+
RefPtr<InputFieldSpeechButtonElement> holdRefButton(this);
input->setValue(results.isEmpty() ? "" : results[0]->utterance());
input->dispatchEvent(SpeechInputEvent::create(eventNames().webkitspeechchangeEvent, results));
diff --git a/Source/WebCore/html/shadow/TextControlInnerElements.h b/Source/WebCore/html/shadow/TextControlInnerElements.h
index 4ba7857..2340970 100644
--- a/Source/WebCore/html/shadow/TextControlInnerElements.h
+++ b/Source/WebCore/html/shadow/TextControlInnerElements.h
@@ -133,6 +133,7 @@ public:
virtual void detach();
virtual void defaultEventHandler(Event*);
+ virtual bool isInputFieldSpeechButtonElement() const { return true; }
SpeechInputState state() const { return m_state; }
// SpeechInputListener methods.
@@ -151,6 +152,12 @@ private:
SpeechInputResultArray m_results;
};
+inline InputFieldSpeechButtonElement* toInputFieldSpeechButtonElement(Element* element)
+{
+ ASSERT(!element || element->isInputFieldSpeechButtonElement());
+ return static_cast<InputFieldSpeechButtonElement*>(element);
+}
+
#endif // ENABLE(INPUT_SPEECH)
} // namespace