summaryrefslogtreecommitdiffstats
path: root/WebCore/html
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/html')
-rw-r--r--WebCore/html/HTMLFormControlElement.cpp35
-rw-r--r--WebCore/html/HTMLFormControlElement.h10
-rw-r--r--WebCore/html/HTMLFormElement.cpp2
-rw-r--r--WebCore/html/HTMLImageElement.cpp2
-rw-r--r--WebCore/html/HTMLInputElement.cpp97
-rw-r--r--WebCore/html/HTMLMediaElement.cpp69
-rw-r--r--WebCore/html/HTMLMediaElement.h16
-rw-r--r--WebCore/html/HTMLMediaElement.idl13
-rw-r--r--WebCore/html/HTMLTextAreaElement.cpp7
-rw-r--r--WebCore/html/HTMLVideoElement.cpp37
-rw-r--r--WebCore/html/HTMLVideoElement.h6
-rw-r--r--WebCore/html/HTMLVideoElement.idl8
-rw-r--r--WebCore/html/canvas/CanvasRenderingContext2D.cpp24
-rw-r--r--WebCore/html/canvas/CanvasRenderingContext2D.h4
14 files changed, 197 insertions, 133 deletions
diff --git a/WebCore/html/HTMLFormControlElement.cpp b/WebCore/html/HTMLFormControlElement.cpp
index eb25c40..6f24e0c 100644
--- a/WebCore/html/HTMLFormControlElement.cpp
+++ b/WebCore/html/HTMLFormControlElement.cpp
@@ -52,6 +52,7 @@ using namespace HTMLNames;
HTMLFormControlElement::HTMLFormControlElement(const QualifiedName& tagName, Document* doc, HTMLFormElement* f)
: HTMLElement(tagName, doc)
, m_form(f)
+ , m_hasName(false)
, m_disabled(false)
, m_readOnly(false)
, m_required(false)
@@ -89,8 +90,9 @@ ValidityState* HTMLFormControlElement::validity()
void HTMLFormControlElement::parseMappedAttribute(MappedAttribute *attr)
{
+ bool oldWillValidate = willValidate();
if (attr->name() == nameAttr)
- setNeedsStyleRecalc();
+ m_hasName = !attr->isEmpty();
else if (attr->name() == disabledAttr) {
bool oldDisabled = m_disabled;
m_disabled = !attr->isNull();
@@ -114,6 +116,8 @@ void HTMLFormControlElement::parseMappedAttribute(MappedAttribute *attr)
setNeedsStyleRecalc();
} else
HTMLElement::parseMappedAttribute(attr);
+ if (oldWillValidate != willValidate())
+ setNeedsWillValidateCheck();
}
void HTMLFormControlElement::attach()
@@ -149,9 +153,10 @@ void HTMLFormControlElement::insertedIntoTree(bool deep)
// setting a form, we will already have a non-null value for m_form,
// and so we don't need to do anything.
m_form = findFormAncestor();
- if (m_form)
+ if (m_form) {
m_form->registerFormElement(this);
- else
+ setNeedsWillValidateCheck();
+ } else
document()->checkedRadioButtons().addButton(this);
}
@@ -178,11 +183,19 @@ void HTMLFormControlElement::removedFromTree(bool deep)
if (m_form && !(parser && parser->isHandlingResidualStyleAcrossBlocks()) && findRoot(this) != findRoot(m_form)) {
m_form->removeFormElement(this);
m_form = 0;
+ setNeedsWillValidateCheck();
}
HTMLElement::removedFromTree(deep);
}
+void HTMLFormControlElement::formDestroyed()
+{
+ if (m_form)
+ setNeedsWillValidateCheck();
+ m_form = 0;
+}
+
const AtomicString& HTMLFormControlElement::formControlName() const
{
const AtomicString& n = getAttribute(nameAttr);
@@ -199,11 +212,6 @@ void HTMLFormControlElement::dispatchFormControlChangeEvent()
dispatchEvent(Event::create(eventNames().changeEvent, true, false));
}
-bool HTMLFormControlElement::disabled() const
-{
- return m_disabled;
-}
-
void HTMLFormControlElement::setDisabled(bool b)
{
setAttribute(disabledAttr, b ? "" : 0);
@@ -297,7 +305,7 @@ bool HTMLFormControlElement::willValidate() const
// The control does not have a repetition template as an ancestor.
// The control does not have a datalist element as an ancestor.
// The control is not an output element.
- return form() && !name().isEmpty() && !disabled() && !isReadOnlyFormControl();
+ return m_form && m_hasName && !m_disabled && !m_readOnly;
}
String HTMLFormControlElement::validationMessage()
@@ -305,6 +313,12 @@ String HTMLFormControlElement::validationMessage()
return validity()->validationMessage();
}
+void HTMLFormControlElement::setNeedsWillValidateCheck()
+{
+ setNeedsStyleRecalc();
+ // FIXME: Show/hide a validation message.
+}
+
bool HTMLFormControlElement::checkValidity()
{
if (willValidate() && !isValidFormControlElement()) {
@@ -315,12 +329,13 @@ bool HTMLFormControlElement::checkValidity()
return true;
}
-void HTMLFormControlElement::updateValidity()
+void HTMLFormControlElement::setNeedsValidityCheck()
{
if (willValidate()) {
// Update style for pseudo classes such as :valid :invalid.
setNeedsStyleRecalc();
}
+ // FIXME: show/hide a validation message.
}
void HTMLFormControlElement::setCustomValidity(const String& error)
diff --git a/WebCore/html/HTMLFormControlElement.h b/WebCore/html/HTMLFormControlElement.h
index 358546b..117087b 100644
--- a/WebCore/html/HTMLFormControlElement.h
+++ b/WebCore/html/HTMLFormControlElement.h
@@ -63,7 +63,7 @@ public:
virtual void dispatchFormControlChangeEvent();
- bool disabled() const;
+ bool disabled() const { return m_disabled; }
void setDisabled(bool);
virtual bool supportsFocus() const;
@@ -109,19 +109,22 @@ public:
virtual bool willValidate() const;
String validationMessage();
bool checkValidity();
- void updateValidity();
+ // This must be called when a validation constraint or control value is changed.
+ void setNeedsValidityCheck();
void setCustomValidity(const String&);
virtual bool valueMissing() const { return false; }
virtual bool patternMismatch() const { return false; }
virtual bool tooLong() const { return false; }
- void formDestroyed() { m_form = 0; }
+ void formDestroyed();
virtual void dispatchFocusEvent();
virtual void dispatchBlurEvent();
protected:
void removeFromForm();
+ // This must be called any time the result of willValidate() has changed.
+ void setNeedsWillValidateCheck();
private:
virtual HTMLFormElement* virtualForm() const;
@@ -130,6 +133,7 @@ private:
HTMLFormElement* m_form;
OwnPtr<ValidityState> m_validityState;
+ bool m_hasName : 1;
bool m_disabled : 1;
bool m_readOnly : 1;
bool m_required : 1;
diff --git a/WebCore/html/HTMLFormElement.cpp b/WebCore/html/HTMLFormElement.cpp
index bf25bf6..2f88894 100644
--- a/WebCore/html/HTMLFormElement.cpp
+++ b/WebCore/html/HTMLFormElement.cpp
@@ -524,11 +524,13 @@ bool HTMLFormElement::isURLAttribute(Attribute* attr) const
void HTMLFormElement::registerImgElement(HTMLImageElement* e)
{
+ ASSERT(imgElements.find(e) == notFound);
imgElements.append(e);
}
void HTMLFormElement::removeImgElement(HTMLImageElement* e)
{
+ ASSERT(imgElements.find(e) != notFound);
removeFromVector(imgElements, e);
}
diff --git a/WebCore/html/HTMLImageElement.cpp b/WebCore/html/HTMLImageElement.cpp
index 34646ad..4592461 100644
--- a/WebCore/html/HTMLImageElement.cpp
+++ b/WebCore/html/HTMLImageElement.cpp
@@ -54,6 +54,8 @@ HTMLImageElement::HTMLImageElement(const QualifiedName& tagName, Document* doc,
HTMLImageElement::~HTMLImageElement()
{
+ if (m_form)
+ m_form->removeImgElement(this);
}
bool HTMLImageElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
diff --git a/WebCore/html/HTMLInputElement.cpp b/WebCore/html/HTMLInputElement.cpp
index 5567fe2..79f8c14 100644
--- a/WebCore/html/HTMLInputElement.cpp
+++ b/WebCore/html/HTMLInputElement.cpp
@@ -83,12 +83,20 @@ static const double numberDefaultStep = 1.0;
static const double numberStepScaleFactor = 1.0;
// Constant values for minimum().
static const double dateDefaultMinimum = -12219292800000.0; // This means 1582-10-15T00:00Z.
+static const double dateTimeDefaultMinimum = -12219292800000.0; // ditto.
+static const double monthDefaultMinimum = (1582.0 - 1970) * 12 + 10 - 1; // 1582-10
static const double numberDefaultMinimum = -DBL_MAX;
static const double rangeDefaultMinimum = 0.0;
+static const double timeDefaultMinimum = 0.0; // 00:00:00.000
+static const double weekDefaultMinimum = -12212380800000.0; // 1583-01-03, the first Monday of 1583.
// Constant values for maximum().
static const double dateDefaultMaximum = DBL_MAX;
+static const double dateTimeDefaultMaximum = DBL_MAX;
+static const double monthDefaultMaximum = DBL_MAX;
static const double numberDefaultMaximum = DBL_MAX;
static const double rangeDefaultMaximum = 100.0;
+static const double timeDefaultMaximum = 86399999.0; // 23:59:59.999
+static const double weekDefaultMaximum = DBL_MAX;
HTMLInputElement::HTMLInputElement(const QualifiedName& tagName, Document* doc, HTMLFormElement* f)
: HTMLTextFormControlElement(tagName, doc, f)
@@ -274,22 +282,24 @@ bool HTMLInputElement::rangeUnderflow() const
const double nan = numeric_limits<double>::quiet_NaN();
switch (inputType()) {
case DATE:
+ case DATETIME:
+ case DATETIMELOCAL:
+ case MONTH:
case NUMBER:
- case RANGE: {
+ case RANGE:
+ case TIME:
+ case WEEK: {
double doubleValue = parseToDouble(value(), nan);
return isfinite(doubleValue) && doubleValue < minimum();
}
case BUTTON:
case CHECKBOX:
case COLOR:
- case DATETIME:
- case DATETIMELOCAL:
case EMAIL:
case FILE:
case HIDDEN:
case IMAGE:
case ISINDEX:
- case MONTH:
case PASSWORD:
case RADIO:
case RESET:
@@ -297,9 +307,7 @@ bool HTMLInputElement::rangeUnderflow() const
case SUBMIT:
case TELEPHONE:
case TEXT:
- case TIME:
case URL:
- case WEEK:
break;
}
return false;
@@ -310,22 +318,24 @@ bool HTMLInputElement::rangeOverflow() const
const double nan = numeric_limits<double>::quiet_NaN();
switch (inputType()) {
case DATE:
+ case DATETIME:
+ case DATETIMELOCAL:
+ case MONTH:
case NUMBER:
- case RANGE: {
+ case RANGE:
+ case TIME:
+ case WEEK: {
double doubleValue = parseToDouble(value(), nan);
return isfinite(doubleValue) && doubleValue > maximum();
}
case BUTTON:
case CHECKBOX:
case COLOR:
- case DATETIME:
- case DATETIMELOCAL:
case EMAIL:
case FILE:
case HIDDEN:
case IMAGE:
case ISINDEX:
- case MONTH:
case PASSWORD:
case RADIO:
case RESET:
@@ -333,9 +343,7 @@ bool HTMLInputElement::rangeOverflow() const
case SUBMIT:
case TELEPHONE:
case TEXT:
- case TIME:
case URL:
- case WEEK:
break;
}
return false;
@@ -346,21 +354,27 @@ double HTMLInputElement::minimum() const
switch (inputType()) {
case DATE:
return parseToDouble(getAttribute(minAttr), dateDefaultMinimum);
+ case DATETIME:
+ case DATETIMELOCAL:
+ return parseToDouble(getAttribute(minAttr), dateTimeDefaultMinimum);
+ case MONTH:
+ return parseToDouble(getAttribute(minAttr), monthDefaultMinimum);
case NUMBER:
return parseToDouble(getAttribute(minAttr), numberDefaultMinimum);
case RANGE:
return parseToDouble(getAttribute(minAttr), rangeDefaultMinimum);
+ case TIME:
+ return parseToDouble(getAttribute(minAttr), timeDefaultMinimum);
+ case WEEK:
+ return parseToDouble(getAttribute(minAttr), weekDefaultMinimum);
case BUTTON:
case CHECKBOX:
case COLOR:
- case DATETIME:
- case DATETIMELOCAL:
case EMAIL:
case FILE:
case HIDDEN:
case IMAGE:
case ISINDEX:
- case MONTH:
case PASSWORD:
case RADIO:
case RESET:
@@ -368,9 +382,7 @@ double HTMLInputElement::minimum() const
case SUBMIT:
case TELEPHONE:
case TEXT:
- case TIME:
case URL:
- case WEEK:
break;
}
ASSERT_NOT_REACHED();
@@ -382,6 +394,11 @@ double HTMLInputElement::maximum() const
switch (inputType()) {
case DATE:
return parseToDouble(getAttribute(maxAttr), dateDefaultMaximum);
+ case DATETIME:
+ case DATETIMELOCAL:
+ return parseToDouble(getAttribute(maxAttr), dateTimeDefaultMaximum);
+ case MONTH:
+ return parseToDouble(getAttribute(maxAttr), monthDefaultMaximum);
case NUMBER:
return parseToDouble(getAttribute(maxAttr), numberDefaultMaximum);
case RANGE: {
@@ -393,17 +410,18 @@ double HTMLInputElement::maximum() const
max = std::max(min, rangeDefaultMaximum);
return max;
}
+ case TIME:
+ return parseToDouble(getAttribute(maxAttr), timeDefaultMaximum);
+ case WEEK:
+ return parseToDouble(getAttribute(maxAttr), weekDefaultMaximum);
case BUTTON:
case CHECKBOX:
case COLOR:
- case DATETIME:
- case DATETIMELOCAL:
case EMAIL:
case FILE:
case HIDDEN:
case IMAGE:
case ISINDEX:
- case MONTH:
case PASSWORD:
case RADIO:
case RESET:
@@ -411,9 +429,7 @@ double HTMLInputElement::maximum() const
case SUBMIT:
case TELEPHONE:
case TEXT:
- case TIME:
case URL:
- case WEEK:
break;
}
ASSERT_NOT_REACHED();
@@ -704,6 +720,7 @@ void HTMLInputElement::setInputType(const String& t)
// type change, otherwise a JavaScript programmer would be able to set a text
// field's value to something like /etc/passwd and then change it to a file field.
if (inputType() != newType) {
+ bool oldWillValidate = willValidate();
if (newType == FILE && m_haveType)
// Set the attribute back to the old value.
// Useful in case we were called from inside parseMappedAttribute.
@@ -760,8 +777,10 @@ void HTMLInputElement::setInputType(const String& t)
checkedRadioButtons(this).addButton(this);
}
+ setNeedsValidityCheck();
+ if (oldWillValidate != willValidate())
+ setNeedsWillValidateCheck();
InputElement::notifyFormStateChanged(this);
- updateValidity();
}
m_haveType = true;
@@ -983,17 +1002,18 @@ void HTMLInputElement::parseMappedAttribute(MappedAttribute *attr)
if (m_data.value().isNull())
setNeedsStyleRecalc();
setFormControlValueMatchesRenderer(false);
- updateValidity();
+ setNeedsValidityCheck();
} else if (attr->name() == checkedAttr) {
m_defaultChecked = !attr->isNull();
if (m_useDefaultChecked) {
setChecked(m_defaultChecked);
m_useDefaultChecked = true;
}
- updateValidity();
- } else if (attr->name() == maxlengthAttr)
+ setNeedsValidityCheck();
+ } else if (attr->name() == maxlengthAttr) {
InputElement::parseMaxLengthAttribute(m_data, this, this, attr);
- else if (attr->name() == sizeAttr)
+ setNeedsValidityCheck();
+ } else if (attr->name() == sizeAttr)
InputElement::parseSizeAttribute(m_data, this, attr);
else if (attr->name() == altAttr) {
if (renderer() && inputType() == IMAGE)
@@ -1037,15 +1057,16 @@ void HTMLInputElement::parseMappedAttribute(MappedAttribute *attr)
attach();
}
setNeedsStyleRecalc();
- } else if (attr->name() == autosaveAttr ||
- attr->name() == incrementalAttr ||
- attr->name() == minAttr ||
- attr->name() == maxAttr ||
- attr->name() == multipleAttr ||
- attr->name() == precisionAttr)
+ } else if (attr->name() == autosaveAttr
+ || attr->name() == incrementalAttr)
setNeedsStyleRecalc();
- else if (attr->name() == patternAttr)
- updateValidity();
+ else if (attr->name() == minAttr
+ || attr->name() == maxAttr
+ || attr->name() == multipleAttr
+ || attr->name() == patternAttr
+ || attr->name() == precisionAttr
+ || attr->name() == stepAttr)
+ setNeedsValidityCheck();
#if ENABLE(DATALIST)
else if (attr->name() == listAttr)
m_hasNonEmptyList = !attr->isEmpty();
@@ -1491,7 +1512,7 @@ void HTMLInputElement::setValue(const String& value, bool sendChangeEvent)
dispatchFormControlChangeEvent();
InputElement::notifyFormStateChanged(this);
- updateValidity();
+ setNeedsValidityCheck();
}
double HTMLInputElement::parseToDouble(const String& src, double defaultValue) const
@@ -1765,7 +1786,7 @@ void HTMLInputElement::setValueFromRenderer(const String& value)
m_data.setSuggestedValue(String());
updatePlaceholderVisibility(false);
InputElement::setValueFromRenderer(m_data, this, this, value);
- updateValidity();
+ setNeedsValidityCheck();
}
void HTMLInputElement::setFileListFromRenderer(const Vector<String>& paths)
@@ -1777,7 +1798,7 @@ void HTMLInputElement::setFileListFromRenderer(const Vector<String>& paths)
setFormControlValueMatchesRenderer(true);
InputElement::notifyFormStateChanged(this);
- updateValidity();
+ setNeedsValidityCheck();
}
bool HTMLInputElement::storesValueSeparateFromAttribute() const
diff --git a/WebCore/html/HTMLMediaElement.cpp b/WebCore/html/HTMLMediaElement.cpp
index 5cd0157..279aac7 100644
--- a/WebCore/html/HTMLMediaElement.cpp
+++ b/WebCore/html/HTMLMediaElement.cpp
@@ -270,7 +270,7 @@ void HTMLMediaElement::insertedIntoDocument()
void HTMLMediaElement::removedFromDocument()
{
if (m_networkState > NETWORK_EMPTY)
- pause();
+ pause(processingUserGesture());
if (m_isFullscreen)
exitFullscreen();
HTMLElement::removedFromDocument();
@@ -421,9 +421,9 @@ String HTMLMediaElement::canPlayType(const String& mimeType) const
return canPlay;
}
-void HTMLMediaElement::load(ExceptionCode& ec)
+void HTMLMediaElement::load(bool isUserGesture, ExceptionCode& ec)
{
- if (m_restrictions & RequireUserGestureForLoadRestriction && !processingUserGesture())
+ if (m_restrictions & RequireUserGestureForLoadRestriction && !isUserGesture)
ec = INVALID_STATE_ERR;
else {
prepareForLoad();
@@ -1120,9 +1120,9 @@ void HTMLMediaElement::setAutobuffer(bool b)
setBooleanAttribute(autobufferAttr, b);
}
-void HTMLMediaElement::play()
+void HTMLMediaElement::play(bool isUserGesture)
{
- if (m_restrictions & RequireUserGestureForRateChangeRestriction && !processingUserGesture())
+ if (m_restrictions & RequireUserGestureForRateChangeRestriction && !isUserGesture)
return;
playInternal();
@@ -1155,9 +1155,9 @@ void HTMLMediaElement::playInternal()
updatePlayState();
}
-void HTMLMediaElement::pause()
+void HTMLMediaElement::pause(bool isUserGesture)
{
- if (m_restrictions & RequireUserGestureForRateChangeRestriction && !processingUserGesture())
+ if (m_restrictions & RequireUserGestureForRateChangeRestriction && !isUserGesture)
return;
pauseInternal();
@@ -1235,7 +1235,15 @@ void HTMLMediaElement::setMuted(bool muted)
{
if (m_muted != muted) {
m_muted = muted;
- updateVolume();
+ // Avoid recursion when the player reports volume changes.
+ if (!processingMediaPlayerCallback()) {
+ if (m_player && m_player->supportsMuting()) {
+ m_player->setMuted(m_muted);
+ if (renderer())
+ renderer()->updateFromElement();
+ } else
+ updateVolume();
+ }
scheduleEvent(eventNames().volumechangeEvent);
}
}
@@ -1257,7 +1265,7 @@ void HTMLMediaElement::beginScrubbing()
// Because a media element stays in non-paused state when it reaches end, playback resumes
// when the slider is dragged from the end to another position unless we pause first. Do
// a "hard pause" so an event is generated, since we want to stay paused after scrubbing finishes.
- pause();
+ pause(processingUserGesture());
} else {
// Not at the end but we still want to pause playback so the media engine doesn't try to
// continue playing during scrubbing. Pause without generating an event as we will
@@ -1444,10 +1452,20 @@ void HTMLMediaElement::mediaPlayerTimeChanged(MediaPlayer*)
void HTMLMediaElement::mediaPlayerVolumeChanged(MediaPlayer*)
{
beginProcessingMediaPlayerCallback();
+ if (m_player)
+ m_volume = m_player->volume();
updateVolume();
endProcessingMediaPlayerCallback();
}
+void HTMLMediaElement::mediaPlayerMuteChanged(MediaPlayer*)
+{
+ beginProcessingMediaPlayerCallback();
+ if (m_player)
+ setMuted(m_player->muted());
+ endProcessingMediaPlayerCallback();
+}
+
void HTMLMediaElement::mediaPlayerDurationChanged(MediaPlayer*)
{
beginProcessingMediaPlayerCallback();
@@ -1743,7 +1761,7 @@ void HTMLMediaElement::documentDidBecomeActive()
// MEDIA_ERR_ABORTED while the abortEvent is being sent, but cleared immediately afterwards).
// This behavior is not specified but it seems like a sensible thing to do.
ExceptionCode ec;
- load(ec);
+ load(processingUserGesture(), ec);
}
if (renderer())
@@ -1860,37 +1878,6 @@ PlatformMedia HTMLMediaElement::platformMedia() const
return m_player ? m_player->platformMedia() : NoPlatformMedia;
}
-void HTMLMediaElement::webkitEnterFullScreen(ExceptionCode& ec)
-{
- if (m_isFullscreen)
- return;
-
- // Generate an exception if this isn't called in response to a user gesture, or if the
- // element does not support fullscreen.
- if (!processingUserGesture() || !supportsFullscreen()) {
- ec = INVALID_STATE_ERR;
- return;
- }
-
- enterFullscreen();
-}
-
-void HTMLMediaElement::webkitExitFullScreen()
-{
- if (m_isFullscreen)
- exitFullscreen();
-}
-
-bool HTMLMediaElement::webkitSupportsFullscreen()
-{
- return supportsFullscreen();
-}
-
-bool HTMLMediaElement::webkitDisplayingFullscreen()
-{
- return m_isFullscreen;
-}
-
bool HTMLMediaElement::hasClosedCaptions() const
{
return m_player && m_player->hasClosedCaptions();
diff --git a/WebCore/html/HTMLMediaElement.h b/WebCore/html/HTMLMediaElement.h
index 9ee2c25..45a41c6 100644
--- a/WebCore/html/HTMLMediaElement.h
+++ b/WebCore/html/HTMLMediaElement.h
@@ -102,7 +102,7 @@ public:
void setAutobuffer(bool);
PassRefPtr<TimeRanges> buffered() const;
- void load(ExceptionCode&);
+ void load(bool isUserGesture, ExceptionCode&);
String canPlayType(const String& mimeType) const;
// ready state
@@ -129,14 +129,8 @@ public:
void setAutoplay(bool b);
bool loop() const;
void setLoop(bool b);
- void play();
- void pause();
-
-// fullscreen
- void webkitEnterFullScreen(ExceptionCode&);
- void webkitExitFullScreen();
- bool webkitSupportsFullscreen();
- bool webkitDisplayingFullscreen();
+ void play(bool isUserGesture);
+ void pause(bool isUserGesture);
// captions
bool webkitHasClosedCaptions() const;
@@ -177,6 +171,8 @@ public:
bool closedCaptionsVisible() const;
void setClosedCaptionsVisible(bool);
+ bool processingUserGesture() const;
+
protected:
float getTimeOffsetAttribute(const QualifiedName&, float valueOnError) const;
void setTimeOffsetAttribute(const QualifiedName&, float value);
@@ -196,6 +192,7 @@ private: // MediaPlayerClient
virtual void mediaPlayerReadyStateChanged(MediaPlayer*);
virtual void mediaPlayerTimeChanged(MediaPlayer*);
virtual void mediaPlayerVolumeChanged(MediaPlayer*);
+ virtual void mediaPlayerMuteChanged(MediaPlayer*);
virtual void mediaPlayerDurationChanged(MediaPlayer*);
virtual void mediaPlayerRateChanged(MediaPlayer*);
virtual void mediaPlayerSawUnsupportedTracks(MediaPlayer*);
@@ -246,7 +243,6 @@ private:
void prepareForLoad();
- bool processingUserGesture() const;
bool processingMediaPlayerCallback() const { return m_processingMediaPlayerCallback > 0; }
void beginProcessingMediaPlayerCallback() { ++m_processingMediaPlayerCallback; }
void endProcessingMediaPlayerCallback() { ASSERT(m_processingMediaPlayerCallback); --m_processingMediaPlayerCallback; }
diff --git a/WebCore/html/HTMLMediaElement.idl b/WebCore/html/HTMLMediaElement.idl
index 1097e55..46a2b86 100644
--- a/WebCore/html/HTMLMediaElement.idl
+++ b/WebCore/html/HTMLMediaElement.idl
@@ -42,7 +42,7 @@ interface [Conditional=VIDEO] HTMLMediaElement : HTMLElement {
attribute boolean autobuffer;
readonly attribute TimeRanges buffered;
- void load()
+ [NeedsUserGestureCheck] void load()
raises (DOMException);
DOMString canPlayType(in DOMString type);
@@ -68,8 +68,8 @@ interface [Conditional=VIDEO] HTMLMediaElement : HTMLElement {
readonly attribute boolean ended;
attribute boolean autoplay;
attribute boolean loop;
- void play();
- void pause();
+ [NeedsUserGestureCheck] void play();
+ [NeedsUserGestureCheck] void pause();
// controls
attribute boolean controls;
@@ -80,13 +80,6 @@ interface [Conditional=VIDEO] HTMLMediaElement : HTMLElement {
// WebKit extensions
attribute boolean webkitPreservesPitch;
- readonly attribute boolean webkitSupportsFullscreen;
- readonly attribute boolean webkitDisplayingFullscreen;
-
- void webkitEnterFullScreen()
- raises (DOMException);
- void webkitExitFullScreen();
-
readonly attribute boolean webkitHasClosedCaptions;
attribute boolean webkitClosedCaptionsVisible;
};
diff --git a/WebCore/html/HTMLTextAreaElement.cpp b/WebCore/html/HTMLTextAreaElement.cpp
index 7159cc7..f74040d 100644
--- a/WebCore/html/HTMLTextAreaElement.cpp
+++ b/WebCore/html/HTMLTextAreaElement.cpp
@@ -154,7 +154,9 @@ void HTMLTextAreaElement::parseMappedAttribute(MappedAttribute* attr)
} else if (attr->name() == alignAttr) {
// Don't map 'align' attribute. This matches what Firefox, Opera and IE do.
// See http://bugs.webkit.org/show_bug.cgi?id=7075
- } else
+ } else if (attr->name() == maxlengthAttr)
+ setNeedsValidityCheck();
+ else
HTMLTextFormControlElement::parseMappedAttribute(attr);
}
@@ -305,9 +307,8 @@ void HTMLTextAreaElement::setValue(const String& value)
setSelectionRange(endOfString, endOfString);
}
- setNeedsStyleRecalc();
+ setNeedsValidityCheck();
notifyFormStateChanged(this);
- updateValidity();
}
String HTMLTextAreaElement::defaultValue() const
diff --git a/WebCore/html/HTMLVideoElement.cpp b/WebCore/html/HTMLVideoElement.cpp
index 1fae354..be8f884 100644
--- a/WebCore/html/HTMLVideoElement.cpp
+++ b/WebCore/html/HTMLVideoElement.cpp
@@ -33,6 +33,7 @@
#include "CSSHelper.h"
#include "CSSPropertyNames.h"
#include "Document.h"
+#include "ExceptionCode.h"
#include "HTMLImageLoader.h"
#include "HTMLNames.h"
#include "MappedAttribute.h"
@@ -197,8 +198,6 @@ void HTMLVideoElement::updatePosterImage()
void HTMLVideoElement::paint(GraphicsContext* context, const IntRect& destRect)
{
- // FIXME: We should also be able to paint the poster image.
-
MediaPlayer* player = HTMLMediaElement::player();
if (!player)
return;
@@ -209,8 +208,6 @@ void HTMLVideoElement::paint(GraphicsContext* context, const IntRect& destRect)
void HTMLVideoElement::paintCurrentFrameInContext(GraphicsContext* context, const IntRect& destRect)
{
- // FIXME: We should also be able to paint the poster image.
-
MediaPlayer* player = HTMLMediaElement::player();
if (!player)
return;
@@ -227,5 +224,37 @@ bool HTMLVideoElement::hasAvailableVideoFrame() const
return m_player->hasAvailableVideoFrame();
}
+void HTMLVideoElement::webkitEnterFullScreen(bool isUserGesture, ExceptionCode& ec)
+{
+ if (m_isFullscreen)
+ return;
+
+ // Generate an exception if this isn't called in response to a user gesture, or if the
+ // element does not support fullscreen.
+ if (!isUserGesture || !supportsFullscreen()) {
+ ec = INVALID_STATE_ERR;
+ return;
+ }
+
+ enterFullscreen();
+}
+
+void HTMLVideoElement::webkitExitFullScreen()
+{
+ if (m_isFullscreen)
+ exitFullscreen();
+}
+
+bool HTMLVideoElement::webkitSupportsFullscreen()
+{
+ return supportsFullscreen();
+}
+
+bool HTMLVideoElement::webkitDisplayingFullscreen()
+{
+ return m_isFullscreen;
+}
+
+
}
#endif
diff --git a/WebCore/html/HTMLVideoElement.h b/WebCore/html/HTMLVideoElement.h
index 834ec4c..a5c005c 100644
--- a/WebCore/html/HTMLVideoElement.h
+++ b/WebCore/html/HTMLVideoElement.h
@@ -64,6 +64,12 @@ public:
const KURL& poster() const { return m_posterURL; }
void setPoster(const String&);
+// fullscreen
+ void webkitEnterFullScreen(bool isUserGesture, ExceptionCode&);
+ void webkitExitFullScreen();
+ bool webkitSupportsFullscreen();
+ bool webkitDisplayingFullscreen();
+
void updatePosterImage();
bool shouldDisplayPosterImage() const { return m_shouldDisplayPosterImage; }
diff --git a/WebCore/html/HTMLVideoElement.idl b/WebCore/html/HTMLVideoElement.idl
index f43bf82..c4764ac 100644
--- a/WebCore/html/HTMLVideoElement.idl
+++ b/WebCore/html/HTMLVideoElement.idl
@@ -30,5 +30,13 @@ module html {
readonly attribute unsigned long videoWidth;
readonly attribute unsigned long videoHeight;
attribute [ConvertNullToNullString] DOMString poster;
+
+ readonly attribute boolean webkitSupportsFullscreen;
+ readonly attribute boolean webkitDisplayingFullscreen;
+
+ [NeedsUserGestureCheck] void webkitEnterFullScreen()
+ raises (DOMException);
+ void webkitExitFullScreen();
+
};
}
diff --git a/WebCore/html/canvas/CanvasRenderingContext2D.cpp b/WebCore/html/canvas/CanvasRenderingContext2D.cpp
index 1e09534..8add19c 100644
--- a/WebCore/html/canvas/CanvasRenderingContext2D.cpp
+++ b/WebCore/html/canvas/CanvasRenderingContext2D.cpp
@@ -30,7 +30,7 @@
#include "config.h"
#include "CanvasRenderingContext2D.h"
-#include "TransformationMatrix.h"
+#include "AffineTransform.h"
#include "CSSParser.h"
#include "CachedImage.h"
#include "CanvasGradient.h"
@@ -357,7 +357,7 @@ void CanvasRenderingContext2D::scale(float sx, float sy)
if (!isfinite(sx) | !isfinite(sy))
return;
- TransformationMatrix newTransform = state().m_transform;
+ AffineTransform newTransform = state().m_transform;
newTransform.scaleNonUniform(sx, sy);
if (!newTransform.isInvertible()) {
state().m_invertibleCTM = false;
@@ -366,7 +366,7 @@ void CanvasRenderingContext2D::scale(float sx, float sy)
state().m_transform = newTransform;
c->scale(FloatSize(sx, sy));
- m_path.transform(TransformationMatrix().scaleNonUniform(1.0/sx, 1.0/sy));
+ m_path.transform(AffineTransform().scaleNonUniform(1.0 / sx, 1.0 / sy));
}
void CanvasRenderingContext2D::rotate(float angleInRadians)
@@ -380,7 +380,7 @@ void CanvasRenderingContext2D::rotate(float angleInRadians)
if (!isfinite(angleInRadians))
return;
- TransformationMatrix newTransform = state().m_transform;
+ AffineTransform newTransform = state().m_transform;
newTransform.rotate(angleInRadians / piDouble * 180.0);
if (!newTransform.isInvertible()) {
state().m_invertibleCTM = false;
@@ -389,7 +389,7 @@ void CanvasRenderingContext2D::rotate(float angleInRadians)
state().m_transform = newTransform;
c->rotate(angleInRadians);
- m_path.transform(TransformationMatrix().rotate(-angleInRadians / piDouble * 180.0));
+ m_path.transform(AffineTransform().rotate(-angleInRadians / piDouble * 180.0));
}
void CanvasRenderingContext2D::translate(float tx, float ty)
@@ -403,7 +403,7 @@ void CanvasRenderingContext2D::translate(float tx, float ty)
if (!isfinite(tx) | !isfinite(ty))
return;
- TransformationMatrix newTransform = state().m_transform;
+ AffineTransform newTransform = state().m_transform;
newTransform.translate(tx, ty);
if (!newTransform.isInvertible()) {
state().m_invertibleCTM = false;
@@ -412,7 +412,7 @@ void CanvasRenderingContext2D::translate(float tx, float ty)
state().m_transform = newTransform;
c->translate(tx, ty);
- m_path.transform(TransformationMatrix().translate(-tx, -ty));
+ m_path.transform(AffineTransform().translate(-tx, -ty));
}
void CanvasRenderingContext2D::transform(float m11, float m12, float m21, float m22, float dx, float dy)
@@ -427,8 +427,8 @@ void CanvasRenderingContext2D::transform(float m11, float m12, float m21, float
!isfinite(m12) | !isfinite(m22) | !isfinite(dy))
return;
- TransformationMatrix transform(m11, m12, m21, m22, dx, dy);
- TransformationMatrix newTransform = transform * state().m_transform;
+ AffineTransform transform(m11, m12, m21, m22, dx, dy);
+ AffineTransform newTransform = transform * state().m_transform;
if (!newTransform.isInvertible()) {
state().m_invertibleCTM = false;
return;
@@ -449,7 +449,7 @@ void CanvasRenderingContext2D::setTransform(float m11, float m12, float m21, flo
!isfinite(m12) | !isfinite(m22) | !isfinite(dy))
return;
- TransformationMatrix ctm = state().m_transform;
+ AffineTransform ctm = state().m_transform;
if (!ctm.isInvertible())
return;
c->concatCTM(c->getCTM().inverse());
@@ -708,7 +708,7 @@ bool CanvasRenderingContext2D::isPointInPath(const float x, const float y)
return false;
FloatPoint point(x, y);
- TransformationMatrix ctm = state().m_transform;
+ AffineTransform ctm = state().m_transform;
FloatPoint transformedPoint = ctm.inverse().mapPoint(point);
return m_path.contains(transformedPoint);
}
@@ -1241,7 +1241,7 @@ void CanvasRenderingContext2D::willDraw(const FloatRect& r, unsigned options)
FloatRect dirtyRect = r;
if (options & CanvasWillDrawApplyTransform) {
- TransformationMatrix ctm = state().m_transform;
+ AffineTransform ctm = state().m_transform;
dirtyRect = ctm.mapRect(r);
}
diff --git a/WebCore/html/canvas/CanvasRenderingContext2D.h b/WebCore/html/canvas/CanvasRenderingContext2D.h
index 283f92c..553ffd2 100644
--- a/WebCore/html/canvas/CanvasRenderingContext2D.h
+++ b/WebCore/html/canvas/CanvasRenderingContext2D.h
@@ -26,8 +26,8 @@
#ifndef CanvasRenderingContext2D_h
#define CanvasRenderingContext2D_h
+#include "AffineTransform.h"
#include "CanvasRenderingContext.h"
-#include "TransformationMatrix.h"
#include "FloatSize.h"
#include "Font.h"
#include "GraphicsTypes.h"
@@ -218,7 +218,7 @@ namespace WebCore {
String m_shadowColor;
float m_globalAlpha;
CompositeOperator m_globalComposite;
- TransformationMatrix m_transform;
+ AffineTransform m_transform;
bool m_invertibleCTM;
// Text state.