summaryrefslogtreecommitdiff
path: root/Source/WebCore/Modules/plugins/QuickTimePluginReplacement.js
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/Modules/plugins/QuickTimePluginReplacement.js')
-rw-r--r--Source/WebCore/Modules/plugins/QuickTimePluginReplacement.js350
1 files changed, 350 insertions, 0 deletions
diff --git a/Source/WebCore/Modules/plugins/QuickTimePluginReplacement.js b/Source/WebCore/Modules/plugins/QuickTimePluginReplacement.js
new file mode 100644
index 000000000..e59f835b0
--- /dev/null
+++ b/Source/WebCore/Modules/plugins/QuickTimePluginReplacement.js
@@ -0,0 +1,350 @@
+
+function createPluginReplacement(root, parent, host, attributeNames, attributeValues)
+{
+ return new Replacement(root, parent, host, attributeNames, attributeValues);
+};
+
+function Replacement(root, parent, host, attributeNames, attributeValues)
+{
+ this.root = root;
+ this.parent = parent;
+ this.host = host;
+ this.listeners = {};
+ this.scriptObject = {};
+
+ this.autoExitFullScreen = true;
+ this.postEvents = false;
+ this.height = 0;
+ this.width = 0;
+ this.src = "";
+ this.autohref = false;
+ this.href = "";
+ this.qtsrc = "";
+ this.baseUrl = "";
+ this.target = "";
+
+ this.createVideoElement(attributeNames, attributeValues);
+ this.createScriptInterface();
+};
+
+Replacement.prototype = {
+
+ HandledVideoEvents: {
+ loadstart: 'handleLoadStart',
+ error: 'handleError',
+ loadedmetadata: 'handleLoadedMetaData',
+ canplay: 'qt_canplay',
+ canplaythrough: 'qt_canplaythrough',
+ play: 'qt_play',
+ pause: 'qt_pause',
+ ended: 'handleEnded',
+ webkitfullscreenchange: 'handleFullscreenChange',
+ },
+
+ AttributeMap: {
+ autoexitfullscreen: 'autoExitFullScreen',
+ postdomevents: 'postEvents',
+ height: 'height',
+ width: 'width',
+ qtsrc: 'qtsrc',
+ src: 'src',
+ airplay: 'x-webkit-airplay=',
+ href: 'href',
+ target: 'target',
+ },
+
+ MethodMap: {
+ SetURL : 'setURL',
+ GetURL : 'url',
+ Play : 'play',
+ Stop : 'pause',
+ GetRate : 'rate',
+ SetRate : 'setRate',
+ IsFullScreen : 'isFullScreen',
+ ExitFullScreen : 'exitFullScreen',
+ GetPluginStatus : 'pluginStatus',
+ GetTime : 'currentTime',
+ SetTime : 'setCurrentTime',
+ SeekToDate : 'seekToDate',
+ GetDate : 'date',
+ GetDuration : 'duration',
+ GetTimeScale : 'timeScale',
+ GetMaxTimeLoaded : 'maxTimeLoaded',
+ GetMaxBytesLoaded : 'maxBytesLoaded',
+ GetMovieSize : 'movieSize',
+ GetTimedMetadataUpdates : 'timedMetadataUpdates',
+ GetAccessLog : 'accessLog',
+ GetErrorLog : 'errorLog',
+ },
+
+ TimeScale: 30000,
+
+ createVideoElement: function(attributeNames, attributeValues)
+ {
+ var video = this.video = document.createElement('video');
+
+ for (name in this.HandledVideoEvents)
+ video.addEventListener(name, this, false);
+
+ for (i = 0; i < attributeNames.length; i++) {
+ var property = this.AttributeMap[attributeNames[i]];
+ if (this[property] != undefined)
+ this[property] = attributeValues[i];
+ }
+
+ video.setAttribute('pseudo', '-webkit-plugin-replacement');
+ video.setAttribute('controls', 'controls');
+ this.setStatus('Waiting');
+
+ var src = this.resolveRelativeToUrl(this.src, "");
+ this.baseUrl = src;
+
+ // The 'qtsrc' attribute is used when a page author wanted to always use the QuickTime plug-in
+ // to load a media type even if another plug-in was registered for that type. It tells the
+ // plug-in to ignore the 'src' url, and to load the 'qtsrc' url instead.
+ if (this.qtsrc)
+ src = this.resolveRelativeToUrl(this.qtsrc, this.src);
+ if (this.href && this.target) {
+ src = this.resolveRelativeToUrl(this.href, this.src);
+ video.poster = this.src;
+ video.setAttribute('preload', 'none');
+ }
+
+ if (src.length) {
+ this.setStatus('Validating');
+ this.video.src = src;
+ }
+
+ this.root.appendChild(video);
+ },
+
+ resolveRelativeToUrl: function(url, baseUrl)
+ {
+ if (url.indexOf('://') != -1)
+ return url;
+ if (baseUrl.indexOf('://') == -1)
+ baseUrl = this.resolveRelativeToUrl(baseUrl, document.baseURI);
+
+ var base = document.createElement('base');
+ base.href = baseUrl;
+ document.head.appendChild(base);
+
+ var resolver = document.createElement('a');
+ resolver.href = url;
+ url = resolver.href;
+
+ document.head.removeChild(base);
+ base = null;
+
+ return url;
+ },
+
+ createScriptInterface: function()
+ {
+ for (name in this.MethodMap) {
+ var methodName = this.MethodMap[name];
+ this.scriptObject[name] = this[methodName].bind(this);
+ }
+ },
+
+ handleEvent: function(event)
+ {
+ if (event.target !== this.video)
+ return;
+
+ try {
+ var eventData = this.HandledVideoEvents[event.type];
+ if (!eventData)
+ return;
+
+ if (this[eventData] && typeof this[eventData] === "function")
+ this[eventData].call(this, event);
+ else
+ this.postEvent(eventData);
+ } catch(e) {
+ if (window.console)
+ console.error(e);
+ }
+ },
+
+ postEvent: function(eventName)
+ {
+ try {
+ if (this.postEvents)
+ this.host.postEvent(eventName);
+ } catch(e) { }
+ },
+
+ setStatus: function(status)
+ {
+ this.status = status;
+ },
+
+ handleLoadedMetaData: function(event)
+ {
+ this.setStatus('Playable');
+ this.postEvent('qt_validated');
+ this.postEvent('qt_loadedfirstframe');
+ this.postEvent('qt_loadedmetadata');
+ },
+
+ handleFullscreenChange: function(event)
+ {
+ this.postEvent(this.isFullScreen() ? 'qt_enterfullscreen' : 'qt_exitfullscreen');
+ },
+
+ handleError: function(event)
+ {
+ this.setStatus('Error');
+ this.postEvent('qt_error');
+ },
+
+ handleLoadStart:function(event)
+ {
+ if (this.video.poster)
+ this.setStatus('Waiting');
+ else
+ this.setStatus('Loading');
+ this.postEvent('qt_begin');
+ },
+
+ handleEnded: function(event)
+ {
+ this.postEvent('qt_ended');
+ if (this.isFullScreen() && this.autoExitFullScreen)
+ document.webkitExitFullscreen();
+ },
+
+ isFullScreen: function()
+ {
+ return document.webkitCurrentFullScreenElement === this.video;
+ },
+
+ setURL: function(url)
+ {
+ this.setStatus('Validating');
+ if (url.length)
+ url = this.resolveRelativeToUrl(url, this.baseUrl);
+ this.video.src = url;
+ },
+
+ url: function()
+ {
+ return this.video.currentSrc;
+ },
+
+ play: function()
+ {
+ this.video.play();
+ },
+
+ pause: function()
+ {
+ this.video.playbackRate = 0;
+ this.video.pause();
+ },
+
+ rate: function()
+ {
+ return this.video.paused ? 0 : 1;
+ },
+
+ setRate: function(rate)
+ {
+ if (rate)
+ this.video.play();
+ else
+ this.video.pause();
+ },
+
+ exitFullScreen: function()
+ {
+ document.webkitExitFullscreen();
+ },
+
+ pluginStatus: function()
+ {
+ return this.status;
+ },
+
+ currentTime: function()
+ {
+ return this.video.currentTime * this.TimeScale;
+ },
+
+ setCurrentTime: function(time)
+ {
+ this.video.currentTime = time / this.TimeScale;
+ },
+
+ seekToDate: function()
+ {
+ // FIXME: not implemented yet.
+ },
+
+ date: function()
+ {
+ return new Date();
+ },
+
+ duration: function()
+ {
+ return this.video.duration * this.TimeScale;
+ },
+
+ timeScale: function()
+ {
+ // Note: QuickTime movies and MPEG-4 files have a timescale, but it is not exposed by all media engines.
+ // 30000 works well with common frame rates, eg. 29.97 NTSC can be represented accurately as a time
+ // scale of 30000 and frame duration of 1001.
+ return 30000;
+ },
+
+ maxTimeLoaded: function()
+ {
+ return this.video.duration * this.TimeScale;
+ },
+
+ maxBytesLoaded: function()
+ {
+ var percentLoaded = this.video.buffered.end(0) / this.video.duration;
+ return percentLoaded * this.movieSize();
+ },
+
+ movieSize: function()
+ {
+ try {
+ return this.host.movieSize;
+ } catch(e) { }
+
+ return 0;
+ },
+
+ timedMetadataUpdates: function()
+ {
+ try {
+ return this.host.timedMetaData;
+ } catch(e) { }
+
+ return null;
+ },
+
+ accessLog: function()
+ {
+ try {
+ return this.host.accessLog;
+ } catch(e) { }
+
+ return null;
+ },
+
+ errorLog: function()
+ {
+ try {
+ return this.host.errorLog;
+ } catch(e) { }
+
+ return null;
+ },
+};
+