added some code to handle embedding in an iframe and mediafragment.
--- a/src/js/iframe_embed/embedder.js Tue Feb 14 17:13:44 2012 +0100
+++ b/src/js/iframe_embed/embedder.js Tue Feb 14 17:14:57 2012 +0100
@@ -3,3 +3,258 @@
to the iframe url in the page url.
*/
+IriSP = {};
+
+window.onhashchange = function() {
+ var url = window.location.href;
+ var frame = document.getElementById("metadataplayer_embed");
+
+ if ( url.split( "#" )[ 1 ] != null ) {
+ hashvalue = url.split("#")[1];
+ frame.contentWindow.postMessage({type: "hashchange", value: hashvalue}, "*");
+ }
+};
+
+
+IriSP.handleMessages = function(e) {
+ var history = window.history;
+
+ if ( !history.pushState ) {
+ return false;
+ }
+
+ if (e.data.type === "hashchange") {
+ console.log(e.data.value);
+ history.replaceState( {}, "", e.data.value);
+ }
+};
+
+// http://stackoverflow.com/questions/799981/document-ready-equivalent-without-jquery
+var ready = (function(){
+
+ var readyList,
+ DOMContentLoaded,
+ class2type = {};
+ class2type["[object Boolean]"] = "boolean";
+ class2type["[object Number]"] = "number";
+ class2type["[object String]"] = "string";
+ class2type["[object Function]"] = "function";
+ class2type["[object Array]"] = "array";
+ class2type["[object Date]"] = "date";
+ class2type["[object RegExp]"] = "regexp";
+ class2type["[object Object]"] = "object";
+
+ var ReadyObj = {
+ // Is the DOM ready to be used? Set to true once it occurs.
+ isReady: false,
+ // A counter to track how many items to wait for before
+ // the ready event fires. See #6781
+ readyWait: 1,
+ // Hold (or release) the ready event
+ holdReady: function( hold ) {
+ if ( hold ) {
+ ReadyObj.readyWait++;
+ } else {
+ ReadyObj.ready( true );
+ }
+ },
+ // Handle when the DOM is ready
+ ready: function( wait ) {
+ // Either a released hold or an DOMready/load event and not yet ready
+ if ( (wait === true && !--ReadyObj.readyWait) || (wait !== true && !ReadyObj.isReady) ) {
+ // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
+ if ( !document.body ) {
+ return setTimeout( ReadyObj.ready, 1 );
+ }
+
+ // Remember that the DOM is ready
+ ReadyObj.isReady = true;
+ // If a normal DOM Ready event fired, decrement, and wait if need be
+ if ( wait !== true && --ReadyObj.readyWait > 0 ) {
+ return;
+ }
+ // If there are functions bound, to execute
+ readyList.resolveWith( document, [ ReadyObj ] );
+
+ // Trigger any bound ready events
+ //if ( ReadyObj.fn.trigger ) {
+ // ReadyObj( document ).trigger( "ready" ).unbind( "ready" );
+ //}
+ }
+ },
+ bindReady: function() {
+ if ( readyList ) {
+ return;
+ }
+ readyList = ReadyObj._Deferred();
+
+ // Catch cases where $(document).ready() is called after the
+ // browser event has already occurred.
+ if ( document.readyState === "complete" ) {
+ // Handle it asynchronously to allow scripts the opportunity to delay ready
+ return setTimeout( ReadyObj.ready, 1 );
+ }
+
+ // Mozilla, Opera and webkit nightlies currently support this event
+ if ( document.addEventListener ) {
+ // Use the handy event callback
+ document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
+ // A fallback to window.onload, that will always work
+ window.addEventListener( "load", ReadyObj.ready, false );
+
+ // If IE event model is used
+ } else if ( document.attachEvent ) {
+ // ensure firing before onload,
+ // maybe late but safe also for iframes
+ document.attachEvent( "onreadystatechange", DOMContentLoaded );
+
+ // A fallback to window.onload, that will always work
+ window.attachEvent( "onload", ReadyObj.ready );
+
+ // If IE and not a frame
+ // continually check to see if the document is ready
+ var toplevel = false;
+
+ try {
+ toplevel = window.frameElement == null;
+ } catch(e) {}
+
+ if ( document.documentElement.doScroll && toplevel ) {
+ doScrollCheck();
+ }
+ }
+ },
+ _Deferred: function() {
+ var // callbacks list
+ callbacks = [],
+ // stored [ context , args ]
+ fired,
+ // to avoid firing when already doing so
+ firing,
+ // flag to know if the deferred has been cancelled
+ cancelled,
+ // the deferred itself
+ deferred = {
+
+ // done( f1, f2, ...)
+ done: function() {
+ if ( !cancelled ) {
+ var args = arguments,
+ i,
+ length,
+ elem,
+ type,
+ _fired;
+ if ( fired ) {
+ _fired = fired;
+ fired = 0;
+ }
+ for ( i = 0, length = args.length; i < length; i++ ) {
+ elem = args[ i ];
+ type = ReadyObj.type( elem );
+ if ( type === "array" ) {
+ deferred.done.apply( deferred, elem );
+ } else if ( type === "function" ) {
+ callbacks.push( elem );
+ }
+ }
+ if ( _fired ) {
+ deferred.resolveWith( _fired[ 0 ], _fired[ 1 ] );
+ }
+ }
+ return this;
+ },
+
+ // resolve with given context and args
+ resolveWith: function( context, args ) {
+ if ( !cancelled && !fired && !firing ) {
+ // make sure args are available (#8421)
+ args = args || [];
+ firing = 1;
+ try {
+ while( callbacks[ 0 ] ) {
+ callbacks.shift().apply( context, args );//shifts a callback, and applies it to document
+ }
+ }
+ finally {
+ fired = [ context, args ];
+ firing = 0;
+ }
+ }
+ return this;
+ },
+
+ // resolve with this as context and given arguments
+ resolve: function() {
+ deferred.resolveWith( this, arguments );
+ return this;
+ },
+
+ // Has this deferred been resolved?
+ isResolved: function() {
+ return !!( firing || fired );
+ },
+
+ // Cancel
+ cancel: function() {
+ cancelled = 1;
+ callbacks = [];
+ return this;
+ }
+ };
+
+ return deferred;
+ },
+ type: function( obj ) {
+ return obj == null ?
+ String( obj ) :
+ class2type[ Object.prototype.toString.call(obj) ] || "object";
+ }
+ }
+ // The DOM ready check for Internet Explorer
+ function doScrollCheck() {
+ if ( ReadyObj.isReady ) {
+ return;
+ }
+
+ try {
+ // If IE is used, use the trick by Diego Perini
+ // http://javascript.nwbox.com/IEContentLoaded/
+ document.documentElement.doScroll("left");
+ } catch(e) {
+ setTimeout( doScrollCheck, 1 );
+ return;
+ }
+
+ // and execute any waiting functions
+ ReadyObj.ready();
+ }
+ // Cleanup functions for the document ready method
+ if ( document.addEventListener ) {
+ DOMContentLoaded = function() {
+ document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
+ ReadyObj.ready();
+ };
+
+ } else if ( document.attachEvent ) {
+ DOMContentLoaded = function() {
+ // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
+ if ( document.readyState === "complete" ) {
+ document.detachEvent( "onreadystatechange", DOMContentLoaded );
+ ReadyObj.ready();
+ }
+ };
+ }
+ function ready( fn ) {
+ // Attach the listeners
+ ReadyObj.bindReady();
+
+ var type = ReadyObj.type( fn );
+
+ // Add the callback
+ readyList.done( fn );//readyList is result of _Deferred()
+ }
+ return ready;
+})();
+
+ready(function() { window.addEventListener('message', IriSP.handleMessages, false); });
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/js/modules/embed.js Tue Feb 14 17:14:57 2012 +0100
@@ -0,0 +1,21 @@
+/* embed module - listens and relay hash changes to a parent window. */
+
+IriSP.EmbedModule = function(Popcorn, config, Serializer) {
+ IriSP.Module.call(this, Popcorn, config, Serializer);
+
+ window.addEventListener('message', IriSP.wrap(this, this.handleMessages), false);
+ this._Popcorn.listen("IriSP.Mediafragment.hashchange", IriSP.wrap(this, this.relayChanges));
+};
+
+IriSP.EmbedModule.prototype = new IriSP.Module();
+
+IriSP.EmbedModule.prototype.handleMessages = function(e) {
+ if (e.data.type === "hashchange") {
+ window.location.hash = e.data.value;
+ }
+};
+
+IriSP.EmbedModule.prototype.relayChanges = function(newHash) {
+ window.parent.postMessage({type: "hashchange", value: newHash}, "*");
+ return;
+};
\ No newline at end of file
--- a/src/js/modules/mediafragment.js Tue Feb 14 17:13:44 2012 +0100
+++ b/src/js/modules/mediafragment.js Tue Feb 14 17:14:57 2012 +0100
@@ -40,7 +40,7 @@
this._serializer.sync(IriSP.wrap(this, function() {
this.lookupAnnotation.call(this, annotationId);
}));
- }
+ }
}
};
@@ -62,6 +62,9 @@
} else {
var ntime = time.toFixed(2);
}
+
+ // used to relay the new hash to the embedder
+ this._Popcorn.trigger("IriSP.Mediafragment.hashchange", "#t=" + ntime);
splitArr = window.location.href.split( "#" )
history.replaceState( {}, "", splitArr[0] + "#t=" + ntime );
@@ -76,10 +79,15 @@
if ( !history.pushState ) {
return false;
}
+
+
+ // used to relay the new hash to the embedder
+ this._Popcorn.trigger("IriSP.Mediafragment.hashchange", "#id=" + annotationId);
splitArr = window.location.href.split( "#" )
history.replaceState( {}, "", splitArr[0] + "#id=" + annotationId);
-
+
+
// reset the mutex afterwards to prevent the module from reacting to his own changes.
window.setTimeout(function() { _this.mutex = false }, 50);
};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/integration/polemic-iframe.htm Tue Feb 14 17:14:57 2012 +0100
@@ -0,0 +1,18 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html dir="ltr" xml:lang="fr" xmlns="http://www.w3.org/1999/xhtml" lang="fr">
+
+<head>
+<title>Test d'intégration iframe</title>
+</head>
+
+<body>
+
+ <div style="width:650px;font-family: 'Trebuchet MS', 'Helvetica', 'Arial', 'Verdana', 'sans-serif';">
+ <h1>MetaDataPlayer </h1>
+ Test d'intégration avec une iframe.
+ </div>
+
+
+ <script type="text/javascript" src="../../src/js/iframe_embed/embedder.js" type="text/javascript"></script>
+ <iframe id="metadataplayer_embed" src="./polemic.htm" width="640" height="480"></iframe>
+ </html>