diff options
Diffstat (limited to 'Source/WebCore/html/shadow')
16 files changed, 2537 insertions, 86 deletions
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 |