Changeset 100159 in webkit


Ignore:
Timestamp:
Nov 14, 2011 9:55:16 AM (12 years ago)
Author:
jer.noble@apple.com
Message:

Implement MediaController.
https://bugs.webkit.org/show_bug.cgi?id=71408

Reviewed by Eric Carlson.

Source/JavaScriptCore:

Change the definition of WTF_USE_COREAUDIO to exclude Windows completely, as
CoreAudioClock.h is not available there.

  • wtf/Platform.h:

Source/WebCore:

Tests: media/media-controller-playback.html

media/media-controller.html

Adds support for the MediaController DOM object, and the mediagroup and mediacontroller
HTMLMediaElement attributes.

MediaController is an DOM object which synchronizes playback of multiple HTMLMediaElements. It can
either be created by a page script and assigned to a HTMLMediaElement using the controller property,
or all HTMLMediaElements with identical mediagroup attributes will have a MediaController assigned
automatically.

Add an abstract interface implemented by both MediaController and HTMLMediaElement.

  • html/MediaControllerInterface.h: Added.

(WebCore::MediaControllerInterface::~MediaControllerInterface):

Add the MediaController object and IDL.

  • html/MediaController.cpp: Added.

(mediaGroupToMediaControllerMap):
(MediaController::mediaControllerForMediaGroup):
(MediaController::create):
(MediaController::MediaController):
(MediaController::~MediaController):
(MediaController::addMediaElement):
(MediaController::removeMediaElement):
(MediaController::containsMediaElement):
(MediaController::buffered):
(MediaController::seekable):
(MediaController::played):
(MediaController::duration):
(MediaController::currentTime):
(MediaController::setCurrentTime):
(MediaController::play):
(MediaController::pause):
(MediaController::setDefaultPlaybackRate):
(MediaController::setPlaybackRate):
(MediaController::setVolume):
(MediaController::setMuted):
(MediaController::reportControllerState):
(MediaController::updateReadyState):
(MediaController::updatePlaybackState):
(MediaController::updateMediaElements):
(MediaController::scheduleEvent):
(MediaController::asyncEventTimerFired):
(MediaController::scriptExecutionContext):
(MediaController::hasAudio):
(MediaController::hasVideo):
(MediaController::hasClosedCaptions):
(MediaController::setClosedCaptionsVisible):
(MediaController::supportsScanning):
(MediaController::beginScrubbing):
(MediaController::endScrubbing):
(MediaController::canPlay):
(MediaController::isLiveStream):
(MediaController::hasSource):
(MediaController::returnToRealtime):
(MediaController::isBlocked):
(MediaController::hasEnded):

  • html/MediaController.h: Added.

(WebCore::MediaController::mediaGroup):
(WebCore::MediaController::paused):
(WebCore::MediaController::defaultPlaybackRate):
(WebCore::MediaController::playbackRate):
(WebCore::MediaController::volume):
(WebCore::MediaController::muted):
(WebCore::MediaController::readyState):
(WebCore::MediaController::playbackState):
(WebCore::MediaController::supportsFullscreen):
(WebCore::MediaController::isFullscreen):
(WebCore::MediaController::enterFullscreen):
(WebCore::MediaController::closedCaptionsVisible):
(WebCore::MediaController::refEventTarget):
(WebCore::MediaController::derefEventTarget):
(WebCore::MediaController::toMediaController):
(WebCore::MediaController::eventTargetData):
(WebCore::MediaController::ensureEventTargetData):

  • html/MediaController.idl: Added.

Add convenience functions to TimeRanges which can calculate intersections and
unions between TimeRanges objects.

  • html/TimeRanges.cpp:

(TimeRanges::copy):
(TimeRanges::invert):
(TimeRanges::intersectWith):
(TimeRanges::unionWith):

  • html/TimeRanges.h:

Add MediaControllerConstructor to the Window object.

  • page/DOMWindow.idl:

Add the two new attribute names, mediagroup and controller.

  • html/HTMLAttributeNames.in:

Add support for the new attributes, and add overridden behavior when a media element
has a current media controller:

  • html/HTMLMediaElement.cpp:

(WebCore::HTMLMediaElement::~HTMLMediaElement):
(WebCore::HTMLMediaElement::parseMappedAttribute):
(WebCore::HTMLMediaElement::prepareForLoad):
(WebCore::HTMLMediaElement::setReadyState):
(WebCore::HTMLMediaElement::setCurrentTime):
(WebCore::HTMLMediaElement::setPlaybackRate):
(WebCore::HTMLMediaElement::playInternal):
(WebCore::HTMLMediaElement::togglePlayState):
(WebCore::HTMLMediaElement::mediaPlayerTimeChanged):
(WebCore::HTMLMediaElement::seekable):
(WebCore::HTMLMediaElement::potentiallyPlaying):
(WebCore::HTMLMediaElement::endedPlayback):
(WebCore::HTMLMediaElement::updateVolume):
(WebCore::HTMLMediaElement::updatePlayState):
(WebCore::HTMLMediaElement::userCancelledLoad):
(WebCore::HTMLMediaElement::mediaGroup):
(WebCore::HTMLMediaElement::setMediaGroup):
(WebCore::HTMLMediaElement::controller):
(WebCore::HTMLMediaElement::setController):
(WebCore::HTMLMediaElement::updateMediaController):
(WebCore::HTMLMediaElement::isBlockedOnMediaController):

  • html/HTMLMediaElement.h:

(WebCore::HTMLMediaElement::hasSource):
(WebCore::HTMLMediaElement::isLiveStream):

  • html/HTMLMediaElement.idl:
  • bindings/js/JSHTMLMediaElementCustom.cpp: Added.

(WebCore::JSHTMLMediaElement::setMediaController):

Add convenience functions to store a mapping of media-elements-per-document to allow
a quick lookup of media elements with the same media group within a given document:

  • html/HTMLMediaElement.cpp:

(WebCore::documentToElementSetMap):
(WebCore::addElementToDocumentMap):
(WebCore::removeElementFromDocumentMap):

Add a function "seekable" which returns a TimeRanges containing the seekable time ranges
in a media element. By default this is a single range of [0, maxTimeSeekable].

  • platform/graphics/MediaPlayer.cpp:

(WebCore::MediaPlayer::seekable):

  • platform/graphics/MediaPlayer.h:
  • platform/graphics/MediaPlayerPrivate.h:

(WebCore::MediaPlayerPrivateInterface::seekable):

Support functions to cast between MediaController and EventTarget.

  • bindings/js/JSEventTarget.cpp:

(WebCore::toJS):

  • dom/EventTarget.cpp:

(WebCore::EventTarget::toMediaController):

  • dom/EventTarget.h:

Fixed an infinite-recursion bug due to a collision between WTF::currentTime and
ClockGeneric::currentTime:

  • platform/ClockGeneric.cpp:

(ClockGeneric::ClockGeneric):
(ClockGeneric::setCurrentTime):
(ClockGeneric::currentTime):
(ClockGeneric::setPlayRate):
(ClockGeneric::start):
(ClockGeneric::stop):
(ClockGeneric::now):

  • platform/ClockGeneric.h:

Boilerplate to support creating the derived sources for MediaController and adding new sources
to the project:

  • CMakeLists.txt:
  • DerivedSources.cpp:
  • DerivedSources.make:
  • GNUmakefile.list.am:
  • WebCore.gypi:
  • WebCore.xcodeproj/project.pbxproj:

LayoutTests:

  • media/media-controller-expected.txt: Added.
  • media/media-controller-playback-expected.txt: Added.
  • media/media-controller-playback.html: Added.
  • media/media-controller.html: Added.
  • platform/mac/fast/dom/Window/window-properties-expected.txt:
  • platform/mac/fast/js/global-constructors-expected.txt:
Location:
trunk
Files:
7 added
32 edited
3 copied

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r100158 r100159  
     12011-11-11  Jer Noble  <jer.noble@apple.com>
     2
     3        Implement MediaController.
     4        https://bugs.webkit.org/show_bug.cgi?id=71408
     5
     6        Reviewed by Eric Carlson.
     7
     8        * media/media-controller-expected.txt: Added.
     9        * media/media-controller-playback-expected.txt: Added.
     10        * media/media-controller-playback.html: Added.
     11        * media/media-controller.html: Added.
     12        * platform/mac/fast/dom/Window/window-properties-expected.txt:
     13        * platform/mac/fast/js/global-constructors-expected.txt:
     14
    1152011-11-14  Andrew Scherkus  <scherkus@chromium.org>
    216
  • trunk/LayoutTests/platform/mac/fast/dom/Window/window-properties-expected.txt

    r99859 r100159  
    12771277window.Math.sqrt [function]
    12781278window.Math.tan [function]
     1279window.MediaController [object MediaControllerConstructor]
     1280window.MediaController.prototype [object MediaControllerPrototype]
     1281window.MediaController.prototype.addEventListener [function]
     1282window.MediaController.prototype.dispatchEvent [function]
     1283window.MediaController.prototype.pause [function]
     1284window.MediaController.prototype.play [function]
     1285window.MediaController.prototype.removeEventListener [function]
    12791286window.MediaError [object MediaErrorConstructor]
    12801287window.MediaError.MEDIA_ERR_ABORTED [number]
  • trunk/LayoutTests/platform/mac/fast/js/global-constructors-expected.txt

    r97148 r100159  
    128128PASS ImageData.toString() is '[object ImageDataConstructor]'
    129129PASS KeyboardEvent.toString() is '[object KeyboardEventConstructor]'
     130PASS MediaController.toString() is '[object MediaControllerConstructor]'
    130131PASS MediaError.toString() is '[object MediaErrorConstructor]'
    131132PASS MediaList.toString() is '[object MediaListConstructor]'
  • trunk/Source/JavaScriptCore/ChangeLog

    r100152 r100159  
     12011-11-11  Jer Noble  <jer.noble@apple.com>
     2
     3        Implement MediaController.
     4        https://bugs.webkit.org/show_bug.cgi?id=71408
     5
     6        Reviewed by Eric Carlson.
     7
     8        Change the definition of WTF_USE_COREAUDIO to exclude Windows completely, as
     9        CoreAudioClock.h is not available there.
     10
     11        * wtf/Platform.h:
     12
    1132011-11-14  Patrick Gansterer  <paroga@webkit.org>
    214
  • trunk/Source/JavaScriptCore/wtf/Platform.h

    r100037 r100159  
    11281128#endif
    11291129
    1130 #if PLATFORM(MAC) || (PLATFORM(WIN) && !OS(WINCE) && !PLATFORM(WIN_CAIRO))
     1130#if PLATFORM(MAC)
    11311131#define WTF_USE_COREAUDIO 1
    11321132#endif
  • trunk/Source/WebCore/CMakeLists.txt

    r99984 r100159  
    277277    html/HTMLVideoElement.idl
    278278    html/ImageData.idl
     279    html/MediaController.idl
    279280    html/MediaError.idl
    280281    html/TextMetrics.idl
  • trunk/Source/WebCore/ChangeLog

    r100157 r100159  
     12011-11-08  Jer Noble  <jer.noble@apple.com>
     2
     3        Implement MediaController.
     4        https://bugs.webkit.org/show_bug.cgi?id=71408
     5
     6        Reviewed by Eric Carlson.
     7
     8        Tests: media/media-controller-playback.html
     9               media/media-controller.html
     10
     11        Adds support for the MediaController DOM object, and the mediagroup and mediacontroller
     12        HTMLMediaElement attributes.
     13
     14        MediaController is an DOM object which synchronizes playback of multiple HTMLMediaElements. It can
     15        either be created by a page script and assigned to a HTMLMediaElement using the controller property,
     16        or all HTMLMediaElements with identical mediagroup attributes will have a MediaController assigned
     17        automatically.
     18
     19        Add an abstract interface implemented by both MediaController and HTMLMediaElement.
     20        * html/MediaControllerInterface.h: Added.
     21        (WebCore::MediaControllerInterface::~MediaControllerInterface):
     22
     23        Add the MediaController object and IDL.
     24        * html/MediaController.cpp: Added.
     25        (mediaGroupToMediaControllerMap):
     26        (MediaController::mediaControllerForMediaGroup):
     27        (MediaController::create):
     28        (MediaController::MediaController):
     29        (MediaController::~MediaController):
     30        (MediaController::addMediaElement):
     31        (MediaController::removeMediaElement):
     32        (MediaController::containsMediaElement):
     33        (MediaController::buffered):
     34        (MediaController::seekable):
     35        (MediaController::played):
     36        (MediaController::duration):
     37        (MediaController::currentTime):
     38        (MediaController::setCurrentTime):
     39        (MediaController::play):
     40        (MediaController::pause):
     41        (MediaController::setDefaultPlaybackRate):
     42        (MediaController::setPlaybackRate):
     43        (MediaController::setVolume):
     44        (MediaController::setMuted):
     45        (MediaController::reportControllerState):
     46        (MediaController::updateReadyState):
     47        (MediaController::updatePlaybackState):
     48        (MediaController::updateMediaElements):
     49        (MediaController::scheduleEvent):
     50        (MediaController::asyncEventTimerFired):
     51        (MediaController::scriptExecutionContext):
     52        (MediaController::hasAudio):
     53        (MediaController::hasVideo):
     54        (MediaController::hasClosedCaptions):
     55        (MediaController::setClosedCaptionsVisible):
     56        (MediaController::supportsScanning):
     57        (MediaController::beginScrubbing):
     58        (MediaController::endScrubbing):
     59        (MediaController::canPlay):
     60        (MediaController::isLiveStream):
     61        (MediaController::hasSource):
     62        (MediaController::returnToRealtime):
     63        (MediaController::isBlocked):
     64        (MediaController::hasEnded):
     65        * html/MediaController.h: Added.
     66        (WebCore::MediaController::mediaGroup):
     67        (WebCore::MediaController::paused):
     68        (WebCore::MediaController::defaultPlaybackRate):
     69        (WebCore::MediaController::playbackRate):
     70        (WebCore::MediaController::volume):
     71        (WebCore::MediaController::muted):
     72        (WebCore::MediaController::readyState):
     73        (WebCore::MediaController::playbackState):
     74        (WebCore::MediaController::supportsFullscreen):
     75        (WebCore::MediaController::isFullscreen):
     76        (WebCore::MediaController::enterFullscreen):
     77        (WebCore::MediaController::closedCaptionsVisible):
     78        (WebCore::MediaController::refEventTarget):
     79        (WebCore::MediaController::derefEventTarget):
     80        (WebCore::MediaController::toMediaController):
     81        (WebCore::MediaController::eventTargetData):
     82        (WebCore::MediaController::ensureEventTargetData):
     83        * html/MediaController.idl: Added.
     84
     85        Add convenience functions to TimeRanges which can calculate intersections and
     86        unions between TimeRanges objects.
     87        * html/TimeRanges.cpp:
     88        (TimeRanges::copy):
     89        (TimeRanges::invert):
     90        (TimeRanges::intersectWith):
     91        (TimeRanges::unionWith):
     92        * html/TimeRanges.h:
     93
     94        Add MediaControllerConstructor to the Window object.
     95        * page/DOMWindow.idl:
     96
     97        Add the two new attribute names, mediagroup and controller.
     98        * html/HTMLAttributeNames.in:
     99
     100        Add support for the new attributes, and add overridden behavior when a media element
     101        has a current media controller:
     102        * html/HTMLMediaElement.cpp:
     103        (WebCore::HTMLMediaElement::~HTMLMediaElement):
     104        (WebCore::HTMLMediaElement::parseMappedAttribute):
     105        (WebCore::HTMLMediaElement::prepareForLoad):
     106        (WebCore::HTMLMediaElement::setReadyState):
     107        (WebCore::HTMLMediaElement::setCurrentTime):
     108        (WebCore::HTMLMediaElement::setPlaybackRate):
     109        (WebCore::HTMLMediaElement::playInternal):
     110        (WebCore::HTMLMediaElement::togglePlayState):
     111        (WebCore::HTMLMediaElement::mediaPlayerTimeChanged):
     112        (WebCore::HTMLMediaElement::seekable):
     113        (WebCore::HTMLMediaElement::potentiallyPlaying):
     114        (WebCore::HTMLMediaElement::endedPlayback):
     115        (WebCore::HTMLMediaElement::updateVolume):
     116        (WebCore::HTMLMediaElement::updatePlayState):
     117        (WebCore::HTMLMediaElement::userCancelledLoad):
     118        (WebCore::HTMLMediaElement::mediaGroup):
     119        (WebCore::HTMLMediaElement::setMediaGroup):
     120        (WebCore::HTMLMediaElement::controller):
     121        (WebCore::HTMLMediaElement::setController):
     122        (WebCore::HTMLMediaElement::updateMediaController):
     123        (WebCore::HTMLMediaElement::isBlockedOnMediaController):
     124        * html/HTMLMediaElement.h:
     125        (WebCore::HTMLMediaElement::hasSource):
     126        (WebCore::HTMLMediaElement::isLiveStream):
     127        * html/HTMLMediaElement.idl:
     128        * bindings/js/JSHTMLMediaElementCustom.cpp: Added.
     129        (WebCore::JSHTMLMediaElement::setMediaController):
     130
     131        Add convenience functions to store a mapping of media-elements-per-document to allow
     132        a quick lookup of media elements with the same media group within a given document:
     133        * html/HTMLMediaElement.cpp:
     134        (WebCore::documentToElementSetMap):
     135        (WebCore::addElementToDocumentMap):
     136        (WebCore::removeElementFromDocumentMap):
     137       
     138        Add a function "seekable" which returns a TimeRanges containing the seekable time ranges
     139        in a media element.  By default this is a single range of [0, maxTimeSeekable].
     140        * platform/graphics/MediaPlayer.cpp:
     141        (WebCore::MediaPlayer::seekable):
     142        * platform/graphics/MediaPlayer.h:
     143        * platform/graphics/MediaPlayerPrivate.h:
     144        (WebCore::MediaPlayerPrivateInterface::seekable):
     145
     146        Support functions to cast between MediaController and EventTarget.
     147        * bindings/js/JSEventTarget.cpp:
     148        (WebCore::toJS):
     149        * dom/EventTarget.cpp:
     150        (WebCore::EventTarget::toMediaController):
     151        * dom/EventTarget.h:
     152
     153        Fixed an infinite-recursion bug due to a collision between WTF::currentTime and
     154        ClockGeneric::currentTime:
     155        * platform/ClockGeneric.cpp:
     156        (ClockGeneric::ClockGeneric):
     157        (ClockGeneric::setCurrentTime):
     158        (ClockGeneric::currentTime):
     159        (ClockGeneric::setPlayRate):
     160        (ClockGeneric::start):
     161        (ClockGeneric::stop):
     162        (ClockGeneric::now):
     163        * platform/ClockGeneric.h:
     164
     165        Boilerplate to support creating the derived sources for MediaController and adding new sources
     166        to the project:
     167        * CMakeLists.txt:
     168        * DerivedSources.cpp:
     169        * DerivedSources.make:
     170        * GNUmakefile.list.am:
     171        * WebCore.gypi:
     172        * WebCore.xcodeproj/project.pbxproj:
     173
    11742011-11-14  Florin Malita  <fmalita@google.com>
    2175
  • trunk/Source/WebCore/DerivedSources.cpp

    r99984 r100159  
    229229#include "JSKeyboardEvent.cpp"
    230230#include "JSLocation.cpp"
     231#include "JSMediaController.cpp"
    231232#include "JSMediaError.cpp"
    232233#include "JSMediaList.cpp"
  • trunk/Source/WebCore/DerivedSources.make

    r99984 r100159  
    278278    Location \
    279279    LowPass2FilterNode \
     280    MediaController \
    280281    MediaElementAudioSourceNode \
    281282    MediaError \
  • trunk/Source/WebCore/DerivedSources.pri

    r99984 r100159  
    315315    html/HTMLVideoElement.idl \
    316316    html/ImageData.idl \
     317    html/MediaController.idl \
    317318    html/MediaError.idl \
    318319    html/TextMetrics.idl \
  • trunk/Source/WebCore/GNUmakefile.list.am

    r100115 r100159  
    360360        DerivedSources/WebCore/JSLocation.cpp \
    361361        DerivedSources/WebCore/JSLocation.h \
     362        DerivedSources/WebCore/JSMediaController.cpp \
     363        DerivedSources/WebCore/JSMediaController.h \
    362364        DerivedSources/WebCore/JSMediaError.cpp \
    363365        DerivedSources/WebCore/JSMediaError.h \
     
    792794        Source/WebCore/bindings/js/JSHTMLInputElementCustom.h \
    793795        Source/WebCore/bindings/js/JSHTMLLinkElementCustom.cpp \
     796        Source/WebCore/bindings/js/JSHTMLMediaElementCustom.cpp \
    794797        Source/WebCore/bindings/js/JSHTMLObjectElementCustom.cpp \
    795798        Source/WebCore/bindings/js/JSHTMLObjectElementCustom.h \
     
    18791882        Source/WebCore/html/LoadableTextTrack.cpp \
    18801883        Source/WebCore/html/LoadableTextTrack.h \
     1884        Source/WebCore/html/MediaController.cpp \
     1885        Source/WebCore/html/MediaController.h \
    18811886        Source/WebCore/html/MediaDocument.cpp \
    18821887        Source/WebCore/html/MediaDocument.h \
     
    24622467        Source/WebCore/platform/AsyncFileSystem.h \
    24632468        Source/WebCore/platform/AutodrainedPool.h \
     2469        Source/WebCore/platform/Clock.cpp \
     2470        Source/WebCore/platform/Clock.h \
     2471        Source/WebCore/platform/ClockGeneric.cpp \
     2472        Source/WebCore/platform/ClockGeneric.h \
    24642473        Source/WebCore/platform/ColorChooser.cpp \
    24652474        Source/WebCore/platform/ColorChooser.h \
  • trunk/Source/WebCore/Target.pri

    r100123 r100159  
    189189        bindings/v8/custom/V8HTMLInputElementCustom.cpp \
    190190        bindings/v8/custom/V8HTMLLinkElementCustom.cpp \
     191        bindings/v8/custom/V8HTMLMediaElementCustom.cpp \
    191192        bindings/v8/custom/V8HTMLOptionsCollectionCustom.cpp \
    192193        bindings/v8/custom/V8HTMLOutputElementCustom.cpp \
     
    299300        bindings/js/JSHTMLInputElementCustom.cpp \
    300301        bindings/js/JSHTMLLinkElementCustom.cpp \
     302        bindings/js/JSHTMLMediaElementCustom.cpp \
    301303        bindings/js/JSHTMLObjectElementCustom.cpp \
    302304        bindings/js/JSHTMLOptionsCollectionCustom.cpp \
     
    10151017    platform/text/LocalizedNumberNone.cpp \
    10161018    platform/text/QuotedPrintable.cpp \
     1019    platform/Clock.cpp \
     1020    platform/ClockGeneric.cpp \
    10171021    platform/ContentType.cpp \
    10181022    platform/CrossThreadCopier.cpp \
     
    10251029    platform/FileStream.cpp \
    10261030    platform/FileSystem.cpp \
    1027     platform/ClockGeneric.cpp \
    10281031    platform/GeolocationService.cpp \
    10291032    platform/image-decoders/qt/ImageFrameQt.cpp \
     
    18591862    html/LinkRelAttribute.h \
    18601863    html/LoadableTextTrack.h \
     1864    html/MediaController.h \
    18611865    html/MediaDocument.h \
    18621866    html/MicroDataItemValue.h \
     
    20472051    platform/Arena.h \
    20482052    platform/AsyncFileStream.h \
     2053    platform/Clock.h \
     2054    platform/ClockGeneric.h \
    20492055    platform/ContentType.h \
    20502056    platform/ContextMenu.h \
     
    20652071    platform/mock/SpeechInputClientMock.h \
    20662072    platform/mock/ScrollbarThemeMock.h \
    2067     platform/ClockGeneric.h \
    20682073    platform/graphics/BitmapImage.h \
    20692074    platform/graphics/Color.h \
     
    30893094        html/HTMLSourceElement.cpp \
    30903095        html/HTMLVideoElement.cpp \
     3096        html/MediaController.cpp \
    30913097        html/shadow/MediaControlElements.cpp \
    30923098        html/TimeRanges.cpp \
  • trunk/Source/WebCore/WebCore.gypi

    r100145 r100159  
    13321332            'html/HTMLVideoElement.idl',
    13331333            'html/ImageData.idl',
     1334            'html/MediaController.idl',
    13341335            'html/MediaError.idl',
    13351336            'html/TextMetrics.idl',
     
    18781879            'bindings/js/JSHTMLInputElementCustom.h',
    18791880            'bindings/js/JSHTMLLinkElementCustom.cpp',
     1881            'bindings/js/JSHTMLMediaElementCustom.cpp',
    18801882            'bindings/js/JSHTMLObjectElementCustom.cpp',
    18811883            'bindings/js/JSHTMLObjectElementCustom.h',
     
    22002202            'bindings/v8/custom/V8HTMLInputElementCustom.cpp',
    22012203            'bindings/v8/custom/V8HTMLLinkElementCustom.cpp',
     2204            'bindings/v8/custom/V8HTMLMediaElementCustom.cpp',
    22022205            'bindings/v8/custom/V8HTMLOptionsCollectionCustom.cpp',
    22032206            'bindings/v8/custom/V8HTMLOutputElementCustom.cpp',
     
    56075610            'html/LoadableTextTrack.cpp',
    56085611            'html/LoadableTextTrack.h',
     5612            'html/MediaController.cpp',
     5613            'html/MediaController.h',
    56095614            'html/MediaDocument.cpp',
    56105615            'html/MediaDocument.h',
  • trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj

    r100145 r100159  
    2626326263                        </File>
    2626426264                        <File
     26265                                RelativePath="..\platform\Clock.cpp"
     26266                                >
     26267                        </File>
     26268                        <File
     26269                                RelativePath="..\platform\Clock.h"
     26270                                >
     26271                        </File>
     26272                        <File
     26273                                RelativePath="..\platform\ClockGeneric.cpp"
     26274                                >
     26275                        </File>
     26276                        <File
     26277                                RelativePath="..\platform\ClockGeneric.h"
     26278                                >
     26279                        </File>
     26280                        <File
    2626526281                                RelativePath="..\platform\ContentType.cpp"
    2626626282                                >
     
    5771957735                        </File>
    5772057736                        <File
     57737                                RelativePath="..\html\MediaController.cpp"
     57738                                >
     57739                        </File>
     57740                        <File
     57741                                RelativePath="..\html\MediaController.h"
     57742                                >
     57743                        </File>
     57744                        <File
    5772157745                                RelativePath="..\html\MediaDocument.cpp"
    5772257746                                >
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r100035 r100159  
    57215721                CD0DBFEF1422768500280263 /* IRC_Composite_C_R0195_T345_P330.wav in Copy Audio Resources */ = {isa = PBXBuildFile; fileRef = CD0DBE0E1422759500280263 /* IRC_Composite_C_R0195_T345_P330.wav */; };
    57225722                CD0DBFF01422768500280263 /* IRC_Composite_C_R0195_T345_P345.wav in Copy Audio Resources */ = {isa = PBXBuildFile; fileRef = CD0DBE0F1422759500280263 /* IRC_Composite_C_R0195_T345_P345.wav */; };
     5723                CD27F6E51457685A0078207D /* JSMediaController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD27F6E2145767580078207D /* JSMediaController.cpp */; };
     5724                CD27F6E7145770D30078207D /* MediaController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD27F6E6145770D30078207D /* MediaController.cpp */; };
    57235725                CD82030A1395AB6A00F956C6 /* WebVideoFullscreenController.h in Headers */ = {isa = PBXBuildFile; fileRef = CD8203061395AB6A00F956C6 /* WebVideoFullscreenController.h */; settings = {ATTRIBUTES = (Private, ); }; };
    57245726                CD82030B1395AB6A00F956C6 /* WebVideoFullscreenController.mm in Sources */ = {isa = PBXBuildFile; fileRef = CD8203071395AB6A00F956C6 /* WebVideoFullscreenController.mm */; settings = {COMPILER_FLAGS = "-Wno-undef"; }; };
     
    57275729                CD8203101395ACE700F956C6 /* WebWindowAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = CD82030E1395ACE700F956C6 /* WebWindowAnimation.h */; };
    57285730                CD8203111395ACE700F956C6 /* WebWindowAnimation.mm in Sources */ = {isa = PBXBuildFile; fileRef = CD82030F1395ACE700F956C6 /* WebWindowAnimation.mm */; };
     5731                CDD525D7145B6DD0008D204D /* JSHTMLMediaElementCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDF65CCC145B6AFE00C4C7AA /* JSHTMLMediaElementCustom.cpp */; };
    57295732                CDEA763014608A53008B31F1 /* PlatformClockCA.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDEA762E146084DE008B31F1 /* PlatformClockCA.cpp */; };
    57305733                CDEA76341460B56F008B31F1 /* ClockGeneric.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDEA76321460AE29008B31F1 /* ClockGeneric.cpp */; };
     
    57325735                CDEA7C841276230400B846DD /* RenderFullScreen.h in Headers */ = {isa = PBXBuildFile; fileRef = CDEA7C821276230400B846DD /* RenderFullScreen.h */; };
    57335736                CDEA7C851276230400B846DD /* RenderFullScreen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDEA7C831276230400B846DD /* RenderFullScreen.cpp */; };
     5737                CDF65CC8145B1E7500C4C7AA /* MediaController.h in Headers */ = {isa = PBXBuildFile; fileRef = CD27F6E4145767870078207D /* MediaController.h */; settings = {ATTRIBUTES = (Private, ); }; };
     5738                CDF65CCA145B448800C4C7AA /* MediaControllerInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = CDF65CC9145B43A700C4C7AA /* MediaControllerInterface.h */; settings = {ATTRIBUTES = (Private, ); }; };
    57345739                CE02F0C411E83ADD00C6684A /* ScriptControllerBase.h in Headers */ = {isa = PBXBuildFile; fileRef = CE02F0C311E83ADD00C6684A /* ScriptControllerBase.h */; settings = {ATTRIBUTES = (Private, ); }; };
    57355740                CE057FA51220731100A476D5 /* DocumentMarkerController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CE057FA31220731100A476D5 /* DocumentMarkerController.cpp */; };
     
    1304113046                CD0DBE0E1422759500280263 /* IRC_Composite_C_R0195_T345_P330.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; name = IRC_Composite_C_R0195_T345_P330.wav; path = platform/audio/resources/IRC_Composite_C_R0195_T345_P330.wav; sourceTree = SOURCE_ROOT; };
    1304213047                CD0DBE0F1422759500280263 /* IRC_Composite_C_R0195_T345_P345.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; name = IRC_Composite_C_R0195_T345_P345.wav; path = platform/audio/resources/IRC_Composite_C_R0195_T345_P345.wav; sourceTree = SOURCE_ROOT; };
     13048                CD27F6E014575C1B0078207D /* MediaController.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = MediaController.idl; sourceTree = "<group>"; };
     13049                CD27F6E2145767580078207D /* JSMediaController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSMediaController.cpp; sourceTree = "<group>"; };
     13050                CD27F6E3145767580078207D /* JSMediaController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSMediaController.h; sourceTree = "<group>"; };
     13051                CD27F6E4145767870078207D /* MediaController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaController.h; sourceTree = "<group>"; };
     13052                CD27F6E6145770D30078207D /* MediaController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MediaController.cpp; sourceTree = "<group>"; };
    1304313053                CD4E0AFA11F7BC27009D3811 /* fullscreen.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; path = fullscreen.css; sourceTree = "<group>"; };
    1304413054                CD8203061395AB6A00F956C6 /* WebVideoFullscreenController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebVideoFullscreenController.h; sourceTree = "<group>"; };
     
    1304913059                CD82030F1395ACE700F956C6 /* WebWindowAnimation.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebWindowAnimation.mm; sourceTree = "<group>"; };
    1305013060                CDBD93BA1333BD4B002570E3 /* fullscreenQuickTime.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; path = fullscreenQuickTime.css; sourceTree = "<group>"; };
     13061                CDCE5CCF14633BC900D47CCA /* EventFactory.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = EventFactory.in; sourceTree = "<group>"; };
     13062                CDCE5CD014633BC900D47CCA /* EventTargetFactory.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = EventTargetFactory.in; sourceTree = "<group>"; };
    1305113063                CDEA762C14608224008B31F1 /* Clock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Clock.h; sourceTree = "<group>"; };
    1305213064                CDEA762E146084DE008B31F1 /* PlatformClockCA.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PlatformClockCA.cpp; sourceTree = "<group>"; };
     
    1305713069                CDEA7C821276230400B846DD /* RenderFullScreen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderFullScreen.h; sourceTree = "<group>"; };
    1305813070                CDEA7C831276230400B846DD /* RenderFullScreen.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderFullScreen.cpp; sourceTree = "<group>"; };
     13071                CDF65CC9145B43A700C4C7AA /* MediaControllerInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaControllerInterface.h; sourceTree = "<group>"; };
     13072                CDF65CCC145B6AFE00C4C7AA /* JSHTMLMediaElementCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSHTMLMediaElementCustom.cpp; sourceTree = "<group>"; };
    1305913073                CE02F0C311E83ADD00C6684A /* ScriptControllerBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptControllerBase.h; sourceTree = "<group>"; };
    1306013074                CE057FA31220731100A476D5 /* DocumentMarkerController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DocumentMarkerController.cpp; sourceTree = "<group>"; };
     
    1739917413                                F55B3DAB1251F12D003EF269 /* WeekInputType.cpp */,
    1740017414                                F55B3DAC1251F12D003EF269 /* WeekInputType.h */,
     17415                                CD27F6E014575C1B0078207D /* MediaController.idl */,
     17416                                CD27F6E4145767870078207D /* MediaController.h */,
     17417                                CD27F6E6145770D30078207D /* MediaController.cpp */,
     17418                                CDF65CC9145B43A700C4C7AA /* MediaControllerInterface.h */,
    1740117419                        );
    1740217420                        path = html;
     
    1763217650                        isa = PBXGroup;
    1763317651                        children = (
     17652                                CD27F6E2145767580078207D /* JSMediaController.cpp */,
     17653                                CD27F6E3145767580078207D /* JSMediaController.h */,
    1763417654                                49EECEF2105070C400099FAB /* JSArrayBuffer.cpp */,
    1763517655                                49EECEF3105070C400099FAB /* JSArrayBuffer.h */,
     
    1965819678                                E1AD14221295EA7F00ACA989 /* JSHTMLInputElementCustom.h */,
    1965919679                                E1AD139A1295D92600ACA989 /* JSHTMLLinkElementCustom.cpp */,
     19680                                CDF65CCC145B6AFE00C4C7AA /* JSHTMLMediaElementCustom.cpp */,
    1966019681                                BC305CA30C0781BB00CD20F0 /* JSHTMLObjectElementCustom.cpp */,
    1966119682                                E1AD14241295EA9500ACA989 /* JSHTMLObjectElementCustom.h */,
     
    2097520996                        isa = PBXGroup;
    2097620997                        children = (
     20998                                CDCE5CCF14633BC900D47CCA /* EventFactory.in */,
     20999                                CDCE5CD014633BC900D47CCA /* EventTargetFactory.in */,
    2097721000                                E1C4DE6D0EA75C650023CCD6 /* ActiveDOMObject.cpp */,
    2097821001                                E1C4DE680EA75C1E0023CCD6 /* ActiveDOMObject.h */,
     
    2467424697                                31313F661443B35F006E2A90 /* FilterEffectRenderer.h in Headers */,
    2467524698                                29CD61DE146D02890068E82A /* WebKitCSSShaderValue.h in Headers */,
     24699                                CDF65CC8145B1E7500C4C7AA /* MediaController.h in Headers */,
     24700                                CDF65CCA145B448800C4C7AA /* MediaControllerInterface.h in Headers */,
    2467624701                        );
    2467724702                        runOnlyForDeploymentPostprocessing = 0;
     
    2753227557                                CDEA763014608A53008B31F1 /* PlatformClockCA.cpp in Sources */,
    2753327558                                CDEA76341460B56F008B31F1 /* ClockGeneric.cpp in Sources */,
     27559                                CD27F6E51457685A0078207D /* JSMediaController.cpp in Sources */,
     27560                                CD27F6E7145770D30078207D /* MediaController.cpp in Sources */,
     27561                                CDD525D7145B6DD0008D204D /* JSHTMLMediaElementCustom.cpp in Sources */,
    2753427562                                CDEA76351460B71A008B31F1 /* Clock.cpp in Sources */,
    2753527563                                976F36EA14686225005E93B4 /* SecurityContext.cpp in Sources */,
  • trunk/Source/WebCore/bindings/generic/RuntimeEnabledFeatures.cpp

    r99500 r100159  
    114114}
    115115
     116bool RuntimeEnabledFeatures::mediaControllerEnabled()
     117{
     118    return MediaPlayer::isAvailable();
     119}
     120
    116121bool RuntimeEnabledFeatures::mediaErrorEnabled()
    117122{
  • trunk/Source/WebCore/bindings/generic/RuntimeEnabledFeatures.h

    r100091 r100159  
    9393    static bool htmlVideoElementEnabled();
    9494    static bool htmlSourceElementEnabled();
     95    static bool mediaControllerEnabled();
    9596    static bool mediaErrorEnabled();
    9697    static bool timeRangesEnabled();
  • trunk/Source/WebCore/bindings/js/JSBindingsAllInOne.cpp

    r99984 r100159  
    9393#include "JSHTMLInputElementCustom.cpp"
    9494#include "JSHTMLLinkElementCustom.cpp"
     95#include "JSHTMLMediaElementCustom.cpp"
    9596#include "JSHTMLObjectElementCustom.cpp"
    9697#include "JSHTMLOptionsCollectionCustom.cpp"
  • trunk/Source/WebCore/bindings/js/JSHTMLMediaElementCustom.cpp

    r100158 r100159  
    11/*
    2  * Copyright (C) 2011 Apple Inc.  All rights reserved.
     2 * Copyright (C) 2011 Apple Inc. All Rights Reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    1111 *    documentation and/or other materials provided with the distribution.
    1212 *
    13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
     13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
    1414 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    1515 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
     16 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
    1717 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
    1818 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     
    2424 */
    2525
    26 #ifndef ClockGeneric_h
    27 #define ClockGeneric_h
     26#include "config.h"
     27#if ENABLE(VIDEO)
    2828
    29 #include "Clock.h"
     29#include "JSHTMLMediaElement.h"
     30
     31#include "JSMediaController.h"
    3032
    3133namespace WebCore {
    3234
    33 class ClockGeneric : public Clock {
    34 public:
    35     ClockGeneric();
     35using namespace JSC;
    3636
    37 private:
    38     virtual void setCurrentTime(float);
    39     virtual float currentTime() const;
    40 
    41     virtual void setPlayRate(float);
    42     virtual float playRate() const { return m_rate; }
    43 
    44     virtual void start();
    45     virtual void stop();
    46     virtual bool isRunning() const { return m_running; }
    47 
    48     bool m_running;
    49     float m_rate;
    50     float m_offset;
    51     double m_startTime;
    52     mutable double m_lastTime;
    53 };
     37void JSHTMLMediaElement::setController(ExecState*, JSValue value)
     38{
     39    HTMLMediaElement* imp = static_cast<HTMLMediaElement*>(impl());
     40    // 4.8.10.11.2 Media controllers: controller attribute.
     41    // On setting, it must first remove the element's mediagroup attribute, if any,
     42    imp->setMediaGroup(String());
     43    // and then set the current media controller to the given value.
     44    imp->setController(toMediaController(value));
     45}
    5446
    5547}
    56 
    5748#endif
  • trunk/Source/WebCore/bindings/v8/custom/V8HTMLMediaElementCustom.cpp

    r100158 r100159  
    11/*
    2  * Copyright (C) 2011 Apple Inc.  All rights reserved.
     2 * Copyright (C) 2011 Apple Inc. All Rights Reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    1111 *    documentation and/or other materials provided with the distribution.
    1212 *
    13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
     13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
    1414 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    1515 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
     16 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
    1717 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
    1818 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     
    2424 */
    2525
    26 #ifndef ClockGeneric_h
    27 #define ClockGeneric_h
     26#include "config.h"
    2827
    29 #include "Clock.h"
     28#if ENABLE(VIDEO)
     29
     30#include "V8HTMLMediaElement.h"
     31
     32#include "V8MediaController.h"
     33#include "V8Proxy.h"
    3034
    3135namespace WebCore {
    3236
    33 class ClockGeneric : public Clock {
    34 public:
    35     ClockGeneric();
     37void V8HTMLMediaElement::controllerAccessorSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
     38{
     39    INC_STATS("DOM.HTMLMediaElement.mediaController._set");
     40    HTMLMediaElement* imp = V8HTMLMediaElement::toNative(info.Holder());
     41    MediaController* controller = 0;
     42    if (V8MediaController::HasInstance(value))
     43        controller = V8MediaController::toNative(value->ToObject());
     44   
     45    if (!controller) {
     46        throwError("Value is not of type MediaController");
     47        return;
     48    }
    3649
    37 private:
    38     virtual void setCurrentTime(float);
    39     virtual float currentTime() const;
    40 
    41     virtual void setPlayRate(float);
    42     virtual float playRate() const { return m_rate; }
    43 
    44     virtual void start();
    45     virtual void stop();
    46     virtual bool isRunning() const { return m_running; }
    47 
    48     bool m_running;
    49     float m_rate;
    50     float m_offset;
    51     double m_startTime;
    52     mutable double m_lastTime;
    53 };
     50    // 4.8.10.11.2 Media controllers: controller attribute.
     51    // On setting, it must first remove the element's mediagroup attribute, if any,
     52    imp->setMediaGroup(String());
     53    // and then set the current media controller to the given value.
     54    imp->setController(controller);
     55}
    5456
    5557}
    5658
    5759#endif
     60
  • trunk/Source/WebCore/dom/EventTarget.h

    r100064 r100159  
    5656    class JavaScriptAudioNode;
    5757    class LocalMediaStream;
     58    class MediaController;
    5859    class MediaStream;
    5960    class MessagePort;
  • trunk/Source/WebCore/dom/EventTargetFactory.in

    r100064 r100159  
    1414JavaScriptAudioNode conditional=WEB_AUDIO
    1515LocalMediaStream conditional=MEDIA_STREAM
     16MediaController conditional=VIDEO
    1617MediaStream conditional=MEDIA_STREAM
    1718MessagePort
  • trunk/Source/WebCore/html/HTMLAttributeNames.in

    r99821 r100159  
    149149mayscript
    150150media
     151mediagroup
    151152method
    152153min
  • trunk/Source/WebCore/html/HTMLMediaElement.cpp

    r100064 r100159  
    5353#include "HTMLVideoElement.h"
    5454#include "Logging.h"
     55#include "MediaController.h"
    5556#include "MediaControls.h"
    5657#include "MediaDocument.h"
     
    139140
    140141using namespace HTMLNames;
     142using namespace std;
     143
     144typedef HashMap<Document*, HashSet<HTMLMediaElement*> > DocumentElementSetMap;
     145static DocumentElementSetMap& documentToElementSetMap()
     146{
     147    DEFINE_STATIC_LOCAL(DocumentElementSetMap, map, ());
     148    return map;
     149}
     150
     151static void addElementToDocumentMap(HTMLMediaElement* element, Document* document)
     152{
     153    DocumentElementSetMap& map = documentToElementSetMap();
     154    HashSet<HTMLMediaElement*> set = map.take(document);
     155    set.add(element);
     156    map.add(document, set);
     157}
     158
     159static void removeElementFromDocumentMap(HTMLMediaElement* element, Document* document)
     160{
     161    DocumentElementSetMap& map = documentToElementSetMap();
     162    HashSet<HTMLMediaElement*> set = map.take(document);
     163    set.remove(element);
     164    if (!set.isEmpty())
     165        map.add(document, set);
     166}
    141167
    142168HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document* document)
     
    220246
    221247    setHasCustomWillOrDidRecalcStyle();
     248    addElementToDocumentMap(this, document);
    222249}
    223250
     
    239266    }
    240267#endif
     268
     269    if (m_mediaController)
     270        m_mediaController->removeMediaElement(this);
     271
     272    removeElementFromDocumentMap(this, document());
    241273}
    242274
     
    248280    document()->unregisterForDocumentActivationCallbacks(this);
    249281    document()->unregisterForMediaVolumeCallbacks(this);
     282    removeElementFromDocumentMap(this, document());
    250283    HTMLElement::willMoveToNewOwnerDocument();
    251284}
     
    259292    document()->registerForDocumentActivationCallbacks(this);
    260293    document()->registerForMediaVolumeCallbacks(this);
     294    addElementToDocumentMap(this, document());
    261295    HTMLElement::didMoveToNewOwnerDocument();
    262296}
     
    305339            m_player->setPreload(m_preload);
    306340
    307     } else if (attrName == onabortAttr)
     341    } else if (attrName == mediagroupAttr)
     342        setMediaGroup(attr->value());
     343    else if (attrName == onabortAttr)
    308344        setAttributeEventListener(eventNames().abortEvent, createAttributeEventListener(this, attr));
    309345    else if (attrName == onbeforeloadAttr)
     
    614650        invalidateCachedTime();
    615651        scheduleEvent(eventNames().emptiedEvent);
     652        updateMediaController();
    616653    }
    617654
     
    12491286
    12501287    updatePlayState();
     1288    updateMediaController();
    12511289}
    12521290
     
    15481586void HTMLMediaElement::setCurrentTime(float time, ExceptionCode& ec)
    15491587{
     1588    if (m_mediaController) {
     1589        ec = INVALID_STATE_ERR;
     1590        return;
     1591    }
    15501592    seek(time, ec);
    15511593}
     
    15991641{
    16001642    LOG(Media, "HTMLMediaElement::setPlaybackRate(%f)", rate);
    1601 
     1643   
    16021644    if (m_playbackRate != rate) {
    16031645        m_playbackRate = rate;
     
    16051647        scheduleEvent(eventNames().ratechangeEvent);
    16061648    }
    1607     if (m_player && potentiallyPlaying() && m_player->rate() != rate)
     1649
     1650    if (m_player && potentiallyPlaying() && m_player->rate() != rate && !m_mediaController)
    16081651        m_player->setRate(rate);
     1652}
     1653
     1654void HTMLMediaElement::updatePlaybackRate()
     1655{
     1656    float effectiveRate = m_mediaController ? m_mediaController->playbackRate() : m_playbackRate;
     1657    if (m_player && potentiallyPlaying() && m_player->rate() != effectiveRate && !m_mediaController)
     1658        m_player->setRate(effectiveRate);
    16091659}
    16101660
     
    17011751        seek(0, unused);
    17021752    }
    1703    
     1753
     1754    if (m_mediaController)
     1755        m_mediaController->bringElementUpToSpeed(this);
     1756
    17041757    if (m_paused) {
    17051758        m_paused = false;
     
    17151768
    17161769    updatePlayState();
     1770    updateMediaController();
    17171771}
    17181772
     
    19061960    // this method is only called from the built-in media controller
    19071961    if (canPlay()) {
    1908         setPlaybackRate(defaultPlaybackRate());
     1962        updatePlaybackRate();
    19091963        playInternal();
    19101964    } else
     
    23342388    float now = currentTime();
    23352389    float dur = duration();
    2336     if (!isnan(dur) && dur && now >= dur) {
    2337         if (loop()) {
     2390   
     2391    // When the current playback position reaches the end of the media resource when the direction of
     2392    // playback is forwards, then the user agent must follow these steps:
     2393    if (!isnan(dur) && dur && now >= dur && m_playbackRate > 0) {
     2394        // If the media element has a loop attribute specified and does not have a current media controller,
     2395        if (loop() && !m_mediaController) {
    23382396            ExceptionCode ignoredException;
    23392397            m_sentEndEvent = false;
    2340             seek(0, ignoredException);
     2398            //  then seek to the earliest possible position of the media resource and abort these steps.
     2399            seek(startTime(), ignoredException);
    23412400        } else {
    2342             if (!m_paused) {
     2401            // If the media element does not have a current media controller, and the media element
     2402            // has still ended playback, and the direction of playback is still forwards, and paused
     2403            // is false,
     2404            if (!m_mediaController && !m_paused) {
     2405                // changes paused to true and fires a simple event named pause at the media element.
    23432406                m_paused = true;
    23442407                scheduleEvent(eventNames().pauseEvent);
    23452408            }
     2409            // Queue a task to fire a simple event named ended at the media element.
    23462410            if (!m_sentEndEvent) {
    23472411                m_sentEndEvent = true;
    23482412                scheduleEvent(eventNames().endedEvent);
    23492413            }
     2414            // If the media element has a current media controller, then report the controller state
     2415            // for the media element's current media controller.
     2416            updateMediaController();
    23502417        }
    23512418    }
     
    25342601PassRefPtr<TimeRanges> HTMLMediaElement::seekable() const
    25352602{
    2536     // FIXME real ranges support
    2537     if (!maxTimeSeekable())
    2538         return TimeRanges::create();
    2539     return TimeRanges::create(minTimeSeekable(), maxTimeSeekable());
     2603    return m_player ? m_player->seekable() : TimeRanges::create();
    25402604}
    25412605
     
    25462610    // checks in couldPlayIfEnoughData().
    25472611    bool pausedToBuffer = m_readyStateMaximum >= HAVE_FUTURE_DATA && m_readyState < HAVE_FUTURE_DATA;
    2548     return (pausedToBuffer || m_readyState >= HAVE_FUTURE_DATA) && couldPlayIfEnoughData();
     2612    return (pausedToBuffer || m_readyState >= HAVE_FUTURE_DATA) && couldPlayIfEnoughData() && !isBlockedOnMediaController();
    25492613}
    25502614
     
    25682632
    25692633    // and the current playback position is the end of the media resource and the direction
    2570     // of playback is forwards and the media element does not have a loop attribute specified,
     2634    // of playback is forwards, Either the media element does not have a loop attribute specified,
     2635    // or the media element has a current media controller.
    25712636    float now = currentTime();
    25722637    if (m_playbackRate > 0)
    2573         return dur > 0 && now >= dur && !loop();
     2638        return dur > 0 && now >= dur && (!loop() || m_mediaController);
    25742639
    25752640    // or the current playback position is the earliest possible position and the direction
     
    26172682        Page* page = document()->page();
    26182683        float volumeMultiplier = page ? page->mediaVolume() : 1;
    2619    
    2620         m_player->setMuted(m_muted);
     2684        bool shouldMute = m_muted;
     2685
     2686        if (m_mediaController) {
     2687            volumeMultiplier *= m_mediaController->volume();
     2688            shouldMute = m_mediaController->muted();
     2689        }
     2690
     2691        m_player->setMuted(shouldMute);
    26212692        m_player->setVolume(m_volume * volumeMultiplier);
    26222693    }
     
    26852756            mediaControls()->playbackStopped();
    26862757    }
    2687    
     2758
     2759    updateMediaController();
     2760
    26882761    if (renderer())
    26892762        renderer()->updateFromElement();
    26902763}
    2691    
     2764
    26922765void HTMLMediaElement::setPausedInternal(bool b)
    26932766{
     
    27492822    // Reset m_readyState since m_player is gone.
    27502823    m_readyState = HAVE_NOTHING;
     2824    updateMediaController();
    27512825}
    27522826
     
    32413315#endif
    32423316
    3243 }
    3244 
    3245 #endif
     3317const String& HTMLMediaElement::mediaGroup() const
     3318{
     3319    return m_mediaGroup;
     3320}
     3321
     3322void HTMLMediaElement::setMediaGroup(const String& group)
     3323{
     3324    if (m_mediaGroup == group)
     3325        return;
     3326    m_mediaGroup = group;
     3327
     3328    // When a media element is created with a mediagroup attribute, and when a media element's mediagroup
     3329    // attribute is set, changed, or removed, the user agent must run the following steps:
     3330    // 1. Let m [this] be the media element in question.
     3331    // 2. Let m have no current media controller, if it currently has one.
     3332    setController(0);
     3333
     3334    // 3. If m's mediagroup attribute is being removed, then abort these steps.
     3335    if (group.isNull() || group.isEmpty())
     3336        return;
     3337
     3338    // 4. If there is another media element whose Document is the same as m's Document (even if one or both
     3339    // of these elements are not actually in the Document),
     3340    HashSet<HTMLMediaElement*> elements = documentToElementSetMap().get(document());
     3341    for (HashSet<HTMLMediaElement*>::iterator i = elements.begin(); i != elements.end(); ++i) {
     3342        if (*i == this)
     3343            continue;
     3344
     3345        // and which also has a mediagroup attribute, and whose mediagroup attribute has the same value as
     3346        // the new value of m's mediagroup attribute,       
     3347        if ((*i)->mediaGroup() == group) {
     3348            //  then let controller be that media element's current media controller.
     3349            setController((*i)->controller());
     3350            return;
     3351        }
     3352    }
     3353
     3354    // Otherwise, let controller be a newly created MediaController.
     3355    setController(MediaController::create(Node::scriptExecutionContext()));
     3356}
     3357
     3358MediaController* HTMLMediaElement::controller() const
     3359{
     3360    return m_mediaController.get();
     3361}
     3362
     3363void HTMLMediaElement::setController(PassRefPtr<MediaController> controller)
     3364{
     3365    if (m_mediaController)
     3366        m_mediaController->removeMediaElement(this);
     3367
     3368    m_mediaController = controller;
     3369
     3370    if (m_mediaController)
     3371        m_mediaController->addMediaElement(this);
     3372}
     3373
     3374void HTMLMediaElement::updateMediaController()
     3375{
     3376    if (m_mediaController)
     3377        m_mediaController->reportControllerState();
     3378}
     3379
     3380bool HTMLMediaElement::isBlocked() const
     3381{
     3382    // A media element is a blocked media element if its readyState attribute is in the
     3383    // HAVE_NOTHING state, the HAVE_METADATA state, or the HAVE_CURRENT_DATA state,
     3384    if (m_readyState <= HAVE_CURRENT_DATA)
     3385        return true;
     3386
     3387    // or if the element has paused for user interaction.
     3388    return pausedForUserInteraction();
     3389}
     3390
     3391bool HTMLMediaElement::isBlockedOnMediaController() const
     3392{
     3393    if (!m_mediaController)
     3394        return false;
     3395
     3396    // A media element is blocked on its media controller if the MediaController is a blocked
     3397    // media controller,
     3398    if (m_mediaController->isBlocked())
     3399        return true;
     3400
     3401    // or if its media controller position is either before the media resource's earliest possible
     3402    // position relative to the MediaController's timeline or after the end of the media resource
     3403    // relative to the MediaController's timeline.
     3404    float mediaControllerPosition = m_mediaController->currentTime();
     3405    if (mediaControllerPosition < startTime() || mediaControllerPosition > startTime() + duration())
     3406        return true;
     3407
     3408    return false;
     3409}
     3410
     3411}
     3412
     3413#endif
  • trunk/Source/WebCore/html/HTMLMediaElement.h

    r100064 r100159  
    3232#include "ActiveDOMObject.h"
    3333#include "MediaCanStartListener.h"
     34#include "MediaControllerInterface.h"
    3435#include "MediaPlayer.h"
    3536
     
    5354class HTMLSourceElement;
    5455class HTMLTrackElement;
     56class MediaController;
    5557class MediaControls;
    5658class MediaError;
     
    6769// no longer depends on typecasting a MediaPlayerClient to an HTMLMediaElement.
    6870
    69 class HTMLMediaElement : public HTMLElement, public MediaPlayerClient, private MediaCanStartListener, public ActiveDOMObject
     71class HTMLMediaElement : public HTMLElement, public MediaPlayerClient, private MediaCanStartListener, public ActiveDOMObject, public MediaControllerInterface
    7072#if ENABLE(VIDEO_TRACK)
    7173    , private TextTrackClient
     
    113115    enum NetworkState { NETWORK_EMPTY, NETWORK_IDLE, NETWORK_LOADING, NETWORK_NO_SOURCE };
    114116    NetworkState networkState() const;
    115    
     117
    116118    String preload() const;   
    117119    void setPreload(const String&);
     
    122124
    123125// ready state
    124     enum ReadyState { HAVE_NOTHING, HAVE_METADATA, HAVE_CURRENT_DATA, HAVE_FUTURE_DATA, HAVE_ENOUGH_DATA };
    125126    ReadyState readyState() const;
    126127    bool seeking() const;
     
    137138    float playbackRate() const;
    138139    void setPlaybackRate(float);
     140    void updatePlaybackRate();
    139141    bool webkitPreservesPitch() const;
    140142    void setWebkitPreservesPitch(bool);
     
    251253    enum InvalidURLAction { DoNothing, Complain };
    252254    bool isSafeToLoadURL(const KURL&, InvalidURLAction);
     255
     256    const String& mediaGroup() const;
     257    void setMediaGroup(const String&);
     258
     259    MediaController* controller() const;
     260    void setController(PassRefPtr<MediaController>);
    253261
    254262protected:
     
    405413    void setPausedInternal(bool);
    406414
     415    void setPlaybackRateInternal(float);
     416
    407417    virtual void mediaCanStart();
    408418
     
    422432    virtual void setItemValueText(const String&, ExceptionCode&);
    423433#endif
     434
     435    void updateMediaController();
     436    bool isBlocked() const;
     437    bool isBlockedOnMediaController() const;
     438    bool hasCurrentSrc() const { return !m_currentSrc.isEmpty(); }
     439    bool isLiveStream() const { return movieLoadType() == MediaPlayer::LiveStream; }
     440    bool isAutoplaying() const { return m_autoplaying; }
    424441
    425442    Timer<HTMLMediaElement> m_loadTimer;
     
    534551    Vector<CueIntervalTree::IntervalType> m_currentlyVisibleCues;
    535552#endif
     553
     554    String m_mediaGroup;
     555    friend class MediaController;
     556    RefPtr<MediaController> m_mediaController;
    536557};
    537558
  • trunk/Source/WebCore/html/HTMLMediaElement.idl

    r99984 r100159  
    116116    readonly attribute [EnabledAtRuntime=webkitVideoTrack] TextTrackList textTracks;
    117117#endif
     118
     119    attribute [Reflect, ConvertNullToNullString, ConvertNullStringToNull] DOMString mediaGroup;
     120    attribute [CustomSetter] MediaController controller;
    118121};
    119122}
  • trunk/Source/WebCore/html/MediaController.idl

    r100158 r100159  
    11/*
    2  * Copyright (C) 2011 Apple Inc.  All rights reserved.
     2 * Copyright (C) 2011 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 #include "config.h"
    27 #include "ClockGeneric.h"
     26module html {
     27    interface [
     28        Conditional=VIDEO,
     29        Constructor,
     30        CallWith=ScriptExecutionContext,
     31        GenerateToJS,
     32        EventTarget
     33    ] MediaController {
     34        readonly attribute TimeRanges buffered;
     35        readonly attribute TimeRanges seekable;
    2836
    29 #include "FloatConversion.h"
    30 #include <wtf/CurrentTime.h>
     37        readonly attribute double duration;
     38        attribute double currentTime
     39            setter raises (DOMException);
    3140
    32 using namespace WebCore;
     41        readonly attribute boolean paused;
     42        readonly attribute TimeRanges played;
     43        void play();
     44        void pause();
    3345
    34 ClockGeneric::ClockGeneric()
    35     : m_running(false)
    36     , m_rate(1)
    37     , m_offset(0)
    38 {
    39     m_startTime = m_lastTime = currentTime();
     46        attribute double defaultPlaybackRate;
     47        attribute double playbackRate;
     48
     49        attribute double volume
     50            setter raises (DOMException);
     51        attribute boolean muted;
     52
     53        // EventTarget interface
     54        void addEventListener(in DOMString type,
     55                              in EventListener listener,
     56                              in [Optional] boolean useCapture);
     57        void removeEventListener(in DOMString type,
     58                                 in EventListener listener,
     59                                 in [Optional] boolean useCapture);
     60        boolean dispatchEvent(in Event evt)
     61            raises(EventException);
     62    };
    4063}
    41 
    42 void ClockGeneric::setCurrentTime(float time)
    43 {
    44     m_startTime = m_lastTime = currentTime();
    45     m_offset = time;
    46 }
    47 
    48 float ClockGeneric::currentTime() const
    49 {
    50     if (m_running)
    51         m_lastTime = currentTime();
    52     float time = (narrowPrecisionToFloat(m_lastTime - m_startTime) * m_rate) + m_offset;
    53     return time;
    54 }
    55 
    56 void ClockGeneric::setPlayRate(float rate)
    57 {
    58     m_offset = currentTime();
    59     m_lastTime = m_startTime = currentTime();
    60     m_rate = rate;
    61 }
    62 
    63 void ClockGeneric::start()
    64 {
    65     if (m_running)
    66         return;
    67 
    68     m_lastTime = m_startTime = currentTime();
    69     m_running = true;
    70 }
    71 
    72 void ClockGeneric::stop()
    73 {
    74     if (!m_running)
    75         return;
    76 
    77     m_offset = currentTime();
    78     m_lastTime = m_startTime = currentTime();
    79     m_running = false;
    80 }
  • trunk/Source/WebCore/html/TimeRanges.cpp

    r99645 r100159  
    3232
    3333using namespace WebCore;
     34using namespace std;
    3435
    3536TimeRanges::TimeRanges(float start, float end)
     
    3839}
    3940
    40 PassRefPtr<TimeRanges> TimeRanges::copy()
     41PassRefPtr<TimeRanges> TimeRanges::copy() const
    4142{
    4243    RefPtr<TimeRanges> newSession = TimeRanges::create();
     
    4748   
    4849    return newSession.release();
     50}
     51
     52void TimeRanges::invert()
     53{
     54    RefPtr<TimeRanges> inverted = TimeRanges::create();
     55    float posInf = std::numeric_limits<float>::infinity();
     56    float negInf = -std::numeric_limits<float>::infinity();
     57
     58    if (!m_ranges.size())
     59        inverted->add(negInf, posInf);
     60    else {
     61        if (float start = m_ranges.first().m_start != negInf)
     62            inverted->add(negInf, start);
     63
     64        for (size_t index = 0; index + 1 < m_ranges.size(); ++index)
     65            inverted->add(m_ranges[index].m_end, m_ranges[index + 1].m_start);
     66
     67        if (float end = m_ranges.last().m_end != posInf)
     68            inverted->add(end, posInf);
     69    }
     70
     71    m_ranges.swap(inverted->m_ranges);
     72}
     73
     74void TimeRanges::intersectWith(const TimeRanges* other)
     75{
     76    ASSERT(other);
     77    RefPtr<TimeRanges> inverted = copy();
     78    RefPtr<TimeRanges> invertedOther = other->copy();
     79    inverted->unionWith(invertedOther.get());
     80    inverted->invert();
     81
     82    m_ranges.swap(inverted->m_ranges);
     83}
     84
     85void TimeRanges::unionWith(const TimeRanges* other)
     86{
     87    ASSERT(other);
     88    RefPtr<TimeRanges> unioned = copy();
     89    for (size_t index = 0; index < other->m_ranges.size(); ++index) {
     90        const Range& range = other->m_ranges[index];
     91        unioned->add(range.m_start, range.m_end);
     92    }
     93
     94    m_ranges.swap(unioned->m_ranges);
    4995}
    5096
  • trunk/Source/WebCore/html/TimeRanges.h

    r99645 r100159  
    4747    }
    4848
    49     PassRefPtr<TimeRanges> copy();
     49    PassRefPtr<TimeRanges> copy() const;
     50    void invert();
     51    void intersectWith(const TimeRanges*);
     52    void unionWith(const TimeRanges*);
    5053
    5154    unsigned length() const { return m_ranges.size(); }
  • trunk/Source/WebCore/page/DOMWindow.idl

    r99984 r100159  
    636636        attribute [Conditional=VIDEO, EnabledAtRuntime] TimeRangesConstructor TimeRanges;
    637637        attribute [Conditional=VIDEO, EnabledAtRuntime] HTMLSourceElementConstructor HTMLSourceElement;
     638        attribute [Conditional=VIDEO, EnabledAtRuntime] MediaControllerConstructor MediaController;
    638639
    639640#if defined(ENABLE_ANIMATION_API) && ENABLE_ANIMATION_API
  • trunk/Source/WebCore/platform/ClockGeneric.cpp

    r99530 r100159  
    3737    , m_offset(0)
    3838{
    39     m_startTime = m_lastTime = currentTime();
     39    m_startTime = m_lastTime = now();
    4040}
    4141
    4242void ClockGeneric::setCurrentTime(float time)
    4343{
    44     m_startTime = m_lastTime = currentTime();
     44    m_startTime = m_lastTime = now();
    4545    m_offset = time;
    4646}
     
    4949{
    5050    if (m_running)
    51         m_lastTime = currentTime();
     51        m_lastTime = now();
    5252    float time = (narrowPrecisionToFloat(m_lastTime - m_startTime) * m_rate) + m_offset;
    5353    return time;
     
    5656void ClockGeneric::setPlayRate(float rate)
    5757{
    58     m_offset = currentTime();
    59     m_lastTime = m_startTime = currentTime();
     58    m_offset = now();
     59    m_lastTime = m_startTime = now();
    6060    m_rate = rate;
    6161}
     
    6666        return;
    6767
    68     m_lastTime = m_startTime = currentTime();
     68    m_lastTime = m_startTime = now();
    6969    m_running = true;
    7070}
     
    7575        return;
    7676
    77     m_offset = currentTime();
    78     m_lastTime = m_startTime = currentTime();
     77    m_offset = now();
     78    m_lastTime = m_startTime = now();
    7979    m_running = false;
    8080}
     81
     82float ClockGeneric::now() const
     83{
     84    return WTF::currentTime();
     85}
     86
  • trunk/Source/WebCore/platform/ClockGeneric.h

    r99488 r100159  
    4646    virtual bool isRunning() const { return m_running; }
    4747
     48    float now() const;
     49
    4850    bool m_running;
    4951    float m_rate;
  • trunk/Source/WebCore/platform/graphics/MediaPlayer.cpp

    r97100 r100159  
    610610}
    611611
     612PassRefPtr<TimeRanges> MediaPlayer::seekable()
     613{
     614    return m_private->seekable();
     615}
     616
    612617float MediaPlayer::maxTimeSeekable()
    613618{
  • trunk/Source/WebCore/platform/graphics/MediaPlayer.h

    r97100 r100159  
    242242
    243243    PassRefPtr<TimeRanges> buffered();
     244    PassRefPtr<TimeRanges> seekable();
    244245    float maxTimeSeekable();
    245246
  • trunk/Source/WebCore/platform/graphics/MediaPlayerPrivate.h

    r97100 r100159  
    3030
    3131#include "MediaPlayer.h"
     32#include "TimeRanges.h"
    3233#include <wtf/Forward.h>
    3334
     
    9293    virtual MediaPlayer::ReadyState readyState() const = 0;
    9394
     95    virtual PassRefPtr<TimeRanges> seekable() const { return maxTimeSeekable() ? TimeRanges::create(0, maxTimeSeekable()) : TimeRanges::create(); }
    9496    virtual float maxTimeSeekable() const = 0;
    9597    virtual PassRefPtr<TimeRanges> buffered() const = 0;
Note: See TracChangeset for help on using the changeset viewer.