added some code to handle embedding in an iframe and mediafragment. popcorn-port
authorhamidouk
Tue, 14 Feb 2012 17:14:57 +0100
branchpopcorn-port
changeset 809 1997dae651c6
parent 808 f7de8a24fc74
child 810 85a278e12495
added some code to handle embedding in an iframe and mediafragment.
src/js/iframe_embed/embedder.js
src/js/modules/embed.js
src/js/modules/mediafragment.js
test/integration/polemic-iframe.htm
--- 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>