diff options
Diffstat (limited to 'WebCore/html')
-rw-r--r-- | WebCore/html/HTMLFormControlElement.cpp | 35 | ||||
-rw-r--r-- | WebCore/html/HTMLFormControlElement.h | 10 | ||||
-rw-r--r-- | WebCore/html/HTMLFormElement.cpp | 2 | ||||
-rw-r--r-- | WebCore/html/HTMLImageElement.cpp | 2 | ||||
-rw-r--r-- | WebCore/html/HTMLInputElement.cpp | 97 | ||||
-rw-r--r-- | WebCore/html/HTMLMediaElement.cpp | 69 | ||||
-rw-r--r-- | WebCore/html/HTMLMediaElement.h | 16 | ||||
-rw-r--r-- | WebCore/html/HTMLMediaElement.idl | 13 | ||||
-rw-r--r-- | WebCore/html/HTMLTextAreaElement.cpp | 7 | ||||
-rw-r--r-- | WebCore/html/HTMLVideoElement.cpp | 37 | ||||
-rw-r--r-- | WebCore/html/HTMLVideoElement.h | 6 | ||||
-rw-r--r-- | WebCore/html/HTMLVideoElement.idl | 8 | ||||
-rw-r--r-- | WebCore/html/canvas/CanvasRenderingContext2D.cpp | 24 | ||||
-rw-r--r-- | WebCore/html/canvas/CanvasRenderingContext2D.h | 4 |
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. |