Index: branches/MwEmbedStandAlone/mwEmbedFrame.php |
— | — | @@ -27,10 +27,11 @@ |
28 | 28 | 'apiProvider', |
29 | 29 | 'durationHint', |
30 | 30 | 'poster', |
31 | | - 'kEntryId', |
32 | | - 'kWidgetId' , |
33 | | - 'skin' |
| 31 | + 'kentryid', |
| 32 | + 'kwidgetid' , |
| 33 | + 'skin' |
34 | 34 | ); |
| 35 | + var $playerIframeId = 'iframeVid'; |
35 | 36 | |
36 | 37 | // When used in direct source mode the source asset. |
37 | 38 | // NOTE: can be an array of sources in cases of "many" sources set |
— | — | @@ -53,7 +54,12 @@ |
54 | 55 | $this->$attributeKey = htmlspecialchars( $_GET[$attributeKey] ); |
55 | 56 | } |
56 | 57 | } |
57 | | - |
| 58 | + |
| 59 | + // Check for debug flag |
| 60 | + if( isset( $_GET['debug'] ) ){ |
| 61 | + $this->debug = true; |
| 62 | + } |
| 63 | + |
58 | 64 | // Process the special "src" attribute |
59 | 65 | if( isset( $_GET['src'] ) ){ |
60 | 66 | if( is_array( $_GET['src'] ) ){ |
— | — | @@ -66,12 +72,14 @@ |
67 | 73 | } |
68 | 74 | |
69 | 75 | } |
70 | | - private function getVideoTag(){ |
| 76 | + private function getVideoTag( ){ |
71 | 77 | // Add default video tag with 100% width / height |
72 | 78 | // ( parent embed is responsible for setting the iframe size ) |
73 | | - $o = '<video style="width:100%;height:100%"'; |
| 79 | + $o = '<video id="' . htmlspecialchars( $this->playerIframeId ) . '" style="width:100%;height:100%"'; |
74 | 80 | foreach( $this->playerAttributes as $attributeKey){ |
75 | | - $o.= ' ' . $attributeKey . '="' . htmlspecialchars( $this->$attributeKey ) . '"'; |
| 81 | + if( isset( $this->$attributeKey ) ){ |
| 82 | + $o.= ' ' . $attributeKey . '="' . htmlspecialchars( $this->$attributeKey ) . '"'; |
| 83 | + } |
76 | 84 | } |
77 | 85 | //Close the video attributes |
78 | 86 | $o.='>'; |
— | — | @@ -81,14 +89,14 @@ |
82 | 90 | $o.= '<source src="' . htmlspecialchars( $src ) . '"></source>'; |
83 | 91 | } |
84 | 92 | } |
85 | | - $o.= '</video>'; |
| 93 | + $o.= '</video>'; |
86 | 94 | return $o; |
87 | 95 | } |
88 | 96 | private function outputEmbedFrame( ){ |
89 | 97 | // Setup the embed string based on attribute set: |
90 | 98 | $embedResourceList = 'window.jQuery,mwEmbed,mw.style.mwCommon,$j.fn.menu,mw.style.jquerymenu,mw.EmbedPlayer,mw.EmbedPlayerNative,mw.EmbedPlayerJava,mw.PlayerControlBuilder,$j.fn.hoverIntent,mw.style.EmbedPlayer,$j.cookie,$j.ui,mw.style.ui_redmond,$j.widget,$j.ui.mouse,mw.PlayerSkinKskin,mw.style.PlayerSkinKskin,mw.TimedText,mw.style.TimedText,$j.ui.slider'; |
91 | 99 | |
92 | | - if( $this->kEntryId ){ |
| 100 | + if( $this->kentryid ){ |
93 | 101 | $embedResourceList.= ',' . implode(',', array( |
94 | 102 | 'KalturaClientBase', |
95 | 103 | 'KalturaClient', |
— | — | @@ -99,7 +107,7 @@ |
100 | 108 | 'mw.KWidgetSupport', |
101 | 109 | 'mw.KAnalytics', |
102 | 110 | 'mw.KDPMapping', |
103 | | - 'mw.MobilePlayerTimeline', |
| 111 | + 'mw.MobileAdTimeline', |
104 | 112 | 'mw.KAds' |
105 | 113 | ) ); |
106 | 114 | } |
— | — | @@ -110,32 +118,45 @@ |
111 | 119 | <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> |
112 | 120 | <title>mwEmbed iframe</title> |
113 | 121 | <style type="text/css"> |
114 | | - body { |
115 | | - margin-left: 0px; |
116 | | - margin-top: 0px; |
117 | | - margin-right: 0px; |
118 | | - margin-bottom: 0px; |
| 122 | + body { |
| 123 | + margin:0; |
| 124 | + position:fixed; |
| 125 | + top:0px; |
| 126 | + left:0px; |
| 127 | + bottom:0px; |
| 128 | + right:0px; |
| 129 | + |
119 | 130 | } |
120 | | - </style> |
121 | | - <script type="text/javascript" src="ResourceLoader.php?class=<?php echo $embedResourceList?>"></script> |
| 131 | + </style> |
| 132 | + <script type="text/javascript" src="ResourceLoader.php?class=<?php |
| 133 | + echo $embedResourceList; |
| 134 | + if( $this->debug ){ |
| 135 | + echo '&debug=true'; |
| 136 | + } |
| 137 | + ?>"></script> |
| 138 | + |
122 | 139 | <script type="text/javascript"> |
123 | 140 | //Set some iframe embed config: |
124 | | - |
125 | | - // Do not overlay controls since we cant dynamically resize the embed window. |
126 | | - mw.setConfig( 'EmbedPlayer.OverlayControls', false ); |
127 | | - |
128 | 141 | // We can't support full screen in object context since it requires outter page DOM control |
129 | 142 | mw.setConfig( 'EmbedPlayer.EnableFullscreen', false ); |
| 143 | + |
| 144 | + // Enable the iframe player server: |
| 145 | + mw.setConfig( 'EmbedPlayer.EnalbeIFramePlayerServer', true ); |
130 | 146 | |
| 147 | + mw.ready(function(){ |
| 148 | + // Trigger fullscreen so that iframe resize keeps player size |
| 149 | + $j( '#<?php echo htmlspecialchars( $this->playerIframeId )?>' ) |
| 150 | + .get(0).fullscreen(); |
| 151 | + }); |
131 | 152 | </script> |
132 | 153 | </head> |
133 | 154 | <body> |
134 | 155 | <? |
135 | | - // Check if we have code to output player embed |
136 | | - if( $this->apiTitleKey || count( $this->sources ) != 0 ) { |
| 156 | + // Check if we have a way to get sources: |
| 157 | + if( $this->apiTitleKey || $this->kentryid || count( $this->sources ) != 0 ) { |
137 | 158 | echo $this->getVideoTag(); |
138 | 159 | } else { |
139 | | - echo "Error: mwEmbedFrame missing required parameter ( src or apiTitleKey )"; |
| 160 | + echo "Error: mwEmbedFrame missing required parameter for video sources"; |
140 | 161 | } |
141 | 162 | ?> |
142 | 163 | </body> |
Index: branches/MwEmbedStandAlone/mwEmbed.js |
— | — | @@ -398,17 +398,17 @@ |
399 | 399 | |
400 | 400 | // xxx should use refactor "ready" stuff into a "domReady" class |
401 | 401 | // So we would not have local scope globals like this: |
402 | | - if ( mwReadyFlag ) { |
| 402 | + //if ( mwReadyFlag ) { |
403 | 403 | // Load the module directly if load request is after |
404 | 404 | // mw.ready has run |
405 | | - this.load( resourceSet, callback ); |
406 | | - } else { |
407 | | - this.addToModuleLoaderQueue( |
408 | | - loadRequest, |
409 | | - resourceSet, |
410 | | - callback |
411 | | - ); |
412 | | - } |
| 405 | + this.load( resourceSet, callback ); |
| 406 | + //} else { |
| 407 | + // this.addToModuleLoaderQueue( |
| 408 | + // loadRequest, |
| 409 | + // resourceSet, |
| 410 | + // callback |
| 411 | + // ); |
| 412 | + //} |
413 | 413 | return ; |
414 | 414 | } |
415 | 415 | |
— | — | @@ -1419,12 +1419,12 @@ |
1420 | 1420 | |
1421 | 1421 | // If jQuery is available and debug is off load the script via jQuery |
1422 | 1422 | // ( will use XHR if on same domain ) |
1423 | | - if( mw.isset( 'window.jQuery' ) |
1424 | | - && mw.getConfig( 'debug' ) === false |
| 1423 | + if( mw.isset( 'window.jQuery' ) |
| 1424 | + && mw.getConfig( 'debug' ) === false |
1425 | 1425 | && typeof $j != 'undefined' |
1426 | 1426 | && mw.parseUri( url ).protocal != 'file' |
1427 | 1427 | && !isCssFile ) |
1428 | | - { |
| 1428 | + { |
1429 | 1429 | $j.getScript( url, myCallback); |
1430 | 1430 | return ; |
1431 | 1431 | } |
Index: branches/MwEmbedStandAlone/modules/EmbedPlayer/loader.js |
— | — | @@ -61,20 +61,25 @@ |
62 | 62 | |
63 | 63 | // The default share embed mode ( can be "object" or "videojs" ) |
64 | 64 | // |
65 | | - // "object" will provide a <object tag pointing to mwEmbedFrame.php |
| 65 | + // "iframe" will provide a <iframe tag pointing to mwEmbedFrame.php |
66 | 66 | // Object embedding should be much more compatible with sites that |
67 | 67 | // let users embed flash applets |
68 | 68 | // "videojs" will include the source javascript and video tag to |
69 | 69 | // rewrite the player on the remote page DOM |
70 | 70 | // Video tag embedding is much more mash-up friendly but exposes |
71 | 71 | // the remote site to the mwEmbed javascript and can be a xss issue. |
72 | | - "EmbedPlayer.ShareEmbedMode" : 'object', |
| 72 | + "EmbedPlayer.ShareEmbedMode" : 'iframe', |
73 | 73 | |
74 | 74 | // Default player skin name |
75 | 75 | "EmbedPlayer.SkinName" : "mvpcf", |
76 | 76 | |
77 | 77 | // Number of milliseconds between interface updates |
78 | | - 'EmbedPlayer.MonitorRate' : 250 |
| 78 | + 'EmbedPlayer.MonitorRate' : 250, |
| 79 | + |
| 80 | + // If the embedPlayer should accept arguments from |
| 81 | + 'EmbedPlayer.EnalbeIFramePlayerServer' : false, |
| 82 | + |
| 83 | + 'EmbedPLayer.IFramePlayer.DomainWhiteList' : '*' |
79 | 84 | } ); |
80 | 85 | |
81 | 86 | // Add class file paths |
— | — | @@ -98,7 +103,10 @@ |
99 | 104 | "mw.PlayerSkinKskin" : "skins/kskin/mw.PlayerSkinKskin.js", |
100 | 105 | |
101 | 106 | "mw.PlayerSkinMvpcf" : "skins/mvpcf/mw.PlayerSkinMvpcf.js", |
102 | | - "mw.style.PlayerSkinMvpcf" : "skins/mvpcf/mw.style.PlayerSkinMvpcf.css" |
| 107 | + "mw.style.PlayerSkinMvpcf" : "skins/mvpcf/mw.style.PlayerSkinMvpcf.css", |
| 108 | + |
| 109 | + "mw.IFramePlayerApiServer" : "mw.IFramePlayerApiServer.js", |
| 110 | + "mw.IFramePlayerApiClient" : "mw.IFramePlayerApiClient.js" |
103 | 111 | } ); |
104 | 112 | |
105 | 113 | /** |
— | — | @@ -124,12 +132,10 @@ |
125 | 133 | * mwEmbed player is setup before any other mw.ready calls |
126 | 134 | */ |
127 | 135 | mw.addSetupHook( function( callback ) { |
128 | | - mw.rewritePagePlayerTags(); |
129 | | - // Run the setupFlag to continue setup |
130 | | - callback(); |
| 136 | + mw.rewritePagePlayerTags( callback ); |
131 | 137 | }); |
132 | 138 | |
133 | | - mw.rewritePagePlayerTags = function() { |
| 139 | + mw.rewritePagePlayerTags = function( callback ) { |
134 | 140 | mw.log( 'EmbedPlayer:: Document::' + mw.documentHasPlayerTags() ); |
135 | 141 | if( mw.documentHasPlayerTags() ) { |
136 | 142 | var rewriteElementCount = 0; |
— | — | @@ -147,13 +153,15 @@ |
148 | 154 | .attr('id', 'loadingSpinner_' + $j( element ).attr('id') ) |
149 | 155 | .addClass( 'playerLoadingSpinner' ); |
150 | 156 | |
151 | | - }); |
| 157 | + }); |
152 | 158 | // Load the embedPlayer module ( then run queued hooks ) |
153 | | - mw.load( 'EmbedPlayer', function ( ) { |
| 159 | + mw.load( 'EmbedPlayer', function ( ) { |
154 | 160 | mw.log("EmbedPlayer:: do rewrite players:" + $j( mw.getConfig( 'EmbedPlayer.RewriteTags' ) ).length ); |
155 | 161 | // Rewrite the EmbedPlayer.RewriteTags with the |
156 | | - $j( mw.getConfig( 'EmbedPlayer.RewriteTags' ) ).embedPlayer(); |
| 162 | + $j( mw.getConfig( 'EmbedPlayer.RewriteTags' ) ).embedPlayer( callback ); |
157 | 163 | }) |
| 164 | + } else { |
| 165 | + callback(); |
158 | 166 | } |
159 | 167 | } |
160 | 168 | |
— | — | @@ -185,8 +193,7 @@ |
186 | 194 | '$j.fn.menu', |
187 | 195 | 'mw.style.jquerymenu', |
188 | 196 | '$j.ui.slider' |
189 | | - ] |
190 | | - |
| 197 | + ] |
191 | 198 | ]; |
192 | 199 | |
193 | 200 | // Pass every tag being rewritten through the update request function |
— | — | @@ -242,7 +249,13 @@ |
243 | 250 | if( $j.inArray( 'mw.style.PlayerSkin' + skinCaseName, dependencyRequest ) == -1 ){ |
244 | 251 | dependencyRequest.push( 'mw.style.PlayerSkin' + skinCaseName ); |
245 | 252 | } |
246 | | - |
| 253 | + |
| 254 | + // Check if the iFrame player server is enabled: |
| 255 | + if( mw.getConfig('EmbedPlayer.EnalbeIFramePlayerServer') ){ |
| 256 | + dependencyRequest.push( 'mw.IFramePlayerApiServer' ); |
| 257 | + } |
| 258 | + |
| 259 | + |
247 | 260 | // Allow extension to extend the request. |
248 | 261 | $j( mw ).trigger( 'LoaderEmbedPlayerUpdateRequest', |
249 | 262 | [ playerElement, dependencyRequest ] ); |
Index: branches/MwEmbedStandAlone/modules/EmbedPlayer/mw.EmbedPlayer.js |
— | — | @@ -440,7 +440,7 @@ |
441 | 441 | $j( '#' + playerInterface.id ).data( i, $j( playerElement ).data( i ) ); |
442 | 442 | } |
443 | 443 | } |
444 | | - } |
| 444 | + } |
445 | 445 | |
446 | 446 | // Pass the id to any hook that needs to interface prior to checkPlayerSources |
447 | 447 | mw.log("EmbedPlayer::addElement :trigger " + playerInterface.id ); |
— | — | @@ -580,8 +580,8 @@ |
581 | 581 | |
582 | 582 | // Set swapPlayerElement has height / width set and set to loading: |
583 | 583 | $j( swapPlayerElement ).css( { |
584 | | - 'width' : playerInterface.width + 'px', |
585 | | - 'height' : playerInterface.height + 'px' |
| 584 | + 'width' : playerInterface.width, |
| 585 | + 'height' : playerInterface.height |
586 | 586 | } ); |
587 | 587 | |
588 | 588 | // If we don't already have a loadSpiner add one: |
— | — | @@ -1385,10 +1385,12 @@ |
1386 | 1386 | // string -> boolean |
1387 | 1387 | if( this[ attr ] == "false" ) this[attr] = false; |
1388 | 1388 | if( this[ attr ] == "true" ) this[attr] = true; |
1389 | | - } |
| 1389 | + } |
| 1390 | + // |
1390 | 1391 | |
| 1392 | + |
1391 | 1393 | if( this.apiTitleKey ){ |
1392 | | - this.apiTitleKey = unescape( this.apiTitleKey ); |
| 1394 | + this.apiTitleKey = decodeURI( this.apiTitleKey ); |
1393 | 1395 | } |
1394 | 1396 | |
1395 | 1397 | // Hide "controls" if using native player controls: |
— | — | @@ -1499,15 +1501,32 @@ |
1500 | 1502 | * @param {Element} element Source element to grab size from |
1501 | 1503 | */ |
1502 | 1504 | setPlayerSize: function( element ) { |
| 1505 | + |
| 1506 | + this.height = $j(element).css( 'height' ); |
| 1507 | + this.width = $j(element).css( 'width' ); |
1503 | 1508 | |
1504 | | - this.height = parseInt( $j(element).css( 'height' ) ); |
1505 | | - this.width = parseInt( $j(element).css( 'width' ) ); |
1506 | | - |
1507 | | - if( !this.height && !this.width ) { |
1508 | | - this.height = parseInt( $j(element).attr( 'height' ) ); |
1509 | | - this.width = parseInt( $j(element).attr( 'width' ) ); |
1510 | | - } |
| 1509 | + // Set to parent size ( resize events will cause player size updates) |
| 1510 | + if( this.height.indexOf('100%') != -1 || this.width.indexOf('100%') != -1 ){ |
| 1511 | + $relativeParent = $j(element).parents().filter(function() { |
| 1512 | + // reduce to only relative position or "body" elements |
| 1513 | + return $j(this).is('body') || $j(this).css('position') == 'relative'; |
| 1514 | + }).slice(0,1); // grab only the "first" |
| 1515 | + this.width = $relativeParent.width(); |
| 1516 | + this.height = $relativeParent.height(); |
| 1517 | + } |
| 1518 | + // make sure height and width are a number |
| 1519 | + this.height = parseInt( this.height ); |
| 1520 | + this.width = parseInt( this.width ); |
| 1521 | + |
| 1522 | + // Set via attribute if CSS is zero or NaN and we have an attribute value: |
| 1523 | + this.height = ( this.height==0 || isNaN( this.height ) |
| 1524 | + && $j(element).attr( 'height' ) ) ? |
| 1525 | + parseInt( $j(element).attr( 'height' ) ): this.height; |
| 1526 | + this.width = ( this.width == 0 || isNaN( this.width ) |
| 1527 | + && $j(element).attr( 'width' ) )? |
| 1528 | + parseInt( $j(element).attr( 'width' ) ): this.width; |
1511 | 1529 | |
| 1530 | + |
1512 | 1531 | // Special case for audio |
1513 | 1532 | // Firefox sets audio height to "0px" while webkit uses 32px .. force zero: |
1514 | 1533 | if( element.tagName.toLowerCase() == 'audio' && this.height == '32' ) { |
— | — | @@ -1556,7 +1575,7 @@ |
1557 | 1576 | this.width = size.width; |
1558 | 1577 | this.height = size.height; |
1559 | 1578 | var playerSize = {'width' : this.width, 'height' : this.height }; |
1560 | | - // check if height needs to include interface contorls |
| 1579 | + // check if height needs to include interface controls |
1561 | 1580 | if( ! this.controlBuilder.checkOverlayControls() ){ |
1562 | 1581 | size.height = size.height + this.controlBuilder.height; |
1563 | 1582 | } |
— | — | @@ -1576,7 +1595,7 @@ |
1577 | 1596 | * @return {Number} pixel height of the video |
1578 | 1597 | */ |
1579 | 1598 | getPlayerWidth: function() { |
1580 | | - return parseInt( this.width ); |
| 1599 | + return $j( this ).width(); |
1581 | 1600 | }, |
1582 | 1601 | |
1583 | 1602 | /** |
— | — | @@ -1585,7 +1604,7 @@ |
1586 | 1605 | * @return {Number} pixel height of the video |
1587 | 1606 | */ |
1588 | 1607 | getPlayerHeight: function() { |
1589 | | - return parseInt( this.height ); |
| 1608 | + return $j( this ).height(); |
1590 | 1609 | }, |
1591 | 1610 | |
1592 | 1611 | /** |
— | — | @@ -1726,7 +1745,7 @@ |
1727 | 1746 | */ |
1728 | 1747 | checkForTimedText: function( ) { |
1729 | 1748 | var _this = this; |
1730 | | - mw.log( 'EmbedPlayer::checkForTimedText: ' + _this.id + " height: " + this.height ); |
| 1749 | + mw.log( 'EmbedPlayer::checkForTimedText: ' + _this.id ); |
1731 | 1750 | // Check for timedText support |
1732 | 1751 | if( this.isTimedTextSupported() ) { |
1733 | 1752 | mw.load( 'TimedText', function() { |
— | — | @@ -2052,7 +2071,7 @@ |
2053 | 2072 | * Show the player |
2054 | 2073 | */ |
2055 | 2074 | showPlayer : function () { |
2056 | | - mw.log( 'EmbedPlayer:: Show player: ' + this.id ); |
| 2075 | + mw.log( 'EmbedPlayer:: Show player: ' + this.id + ' interace: w:' + this.width + ' h:' + this.height); |
2057 | 2076 | var _this = this; |
2058 | 2077 | // Set-up the local controlBuilder instance: |
2059 | 2078 | this.controlBuilder = new mw.PlayerControlBuilder( this ); |
— | — | @@ -2065,8 +2084,8 @@ |
2066 | 2085 | $j('<div>') |
2067 | 2086 | .addClass( 'mwplayer_interface ' + this.controlBuilder.playerClass ) |
2068 | 2087 | .css({ |
2069 | | - 'width' : parseInt( this.width ) + 'px', |
2070 | | - 'height' : parseInt( this.height ) + 'px', |
| 2088 | + 'width' : this.width, |
| 2089 | + 'height' : this.height, |
2071 | 2090 | 'position' : 'relative' |
2072 | 2091 | }) |
2073 | 2092 | ) |
— | — | @@ -2177,34 +2196,9 @@ |
2178 | 2197 | this.serverSeekTime = mw.npt2seconds( start_npt ); |
2179 | 2198 | } |
2180 | 2199 | }, |
| 2200 | + |
2181 | 2201 | |
2182 | 2202 | /** |
2183 | | - * Render a thumbnail at a given time |
2184 | | - * NOTE: Should overwrite by embed library if we can render frames natively |
2185 | | - * |
2186 | | - * @param {Object} options Options for rendered timeline thumb |
2187 | | - */ |
2188 | | - renderTimelineThumbnail: function( options ) { |
2189 | | - var my_thumb_src = this.mediaElement.getPosterSrc(); |
2190 | | - // check if our thumbnail has a time attribute: |
2191 | | - if ( my_thumb_src.indexOf( 't=' ) !== -1 ) { |
2192 | | - var time_ntp = mw.seconds2npt ( options.time + parseInt( this.startOffset ) ); |
2193 | | - my_thumb_src = mw.replaceUrlParams( my_thumb_src, { |
2194 | | - 't' : time_ntp, |
2195 | | - 'size' : options.size |
2196 | | - }); |
2197 | | - } |
2198 | | - var thumb_class = ( typeof options['thumb_class'] != 'undefined' ) ? options['thumb_class'] : ''; |
2199 | | - return '<div class="ui-corner-all ' + thumb_class + '" src="' + my_thumb_src + '" ' + |
2200 | | - 'style="height:' + options.height + 'px;' + |
2201 | | - 'width:' + options.width + 'px" >' + |
2202 | | - '<img src="' + my_thumb_src + '" ' + |
2203 | | - 'style="height:' + options.height + 'px;' + |
2204 | | - 'width:' + options.width + 'px">' + |
2205 | | - '</div>'; |
2206 | | - }, |
2207 | | - |
2208 | | - /** |
2209 | 2203 | * Update Thumb time with npt formated time |
2210 | 2204 | * @param {String} time NPT formated time to update thumbnail |
2211 | 2205 | */ |
— | — | @@ -2482,8 +2476,8 @@ |
2483 | 2477 | */ |
2484 | 2478 | getEmbeddingHTML: function() { |
2485 | 2479 | switch( mw.getConfig( 'EmbedPlayer.ShareEmbedMode' ) ){ |
2486 | | - case 'object': |
2487 | | - return this.getShareEmbedObject() |
| 2480 | + case 'iframe': |
| 2481 | + return this.getShareIframeObject(); |
2488 | 2482 | break; |
2489 | 2483 | case 'videojs': |
2490 | 2484 | return this.getShareEmbedVideoJs(); |
— | — | @@ -2532,31 +2526,18 @@ |
2533 | 2527 | |
2534 | 2528 | if( this.duration ) { |
2535 | 2529 | params.durationHint = parseFloat( this.duration ); |
2536 | | - } |
2537 | | - // Set width / height of iframe embed ( child iframe / object can't read parent frame size ) |
2538 | | - if( this.width ){ |
2539 | | - params.width = parseInt( this.width ); |
2540 | | - } |
2541 | | - if( this.height ){ |
2542 | | - params.height = parseInt( this.height ); |
2543 | | - } |
| 2530 | + } |
2544 | 2531 | iframeUrl += $j.param( params ); |
2545 | 2532 | |
2546 | 2533 | // Set up embedFrame src path |
2547 | | - var embedCode = '<object data="' + mw.escapeQuotesHTML( iframeUrl ) + '" '; |
| 2534 | + var embedCode = '<iframe src="' + mw.escapeQuotesHTML( iframeUrl ) + '" '; |
2548 | 2535 | |
2549 | | - // Set width / height of embed object ( give extra space for controls ) |
2550 | | - if( this.width || this.height ){ |
2551 | | - embedCode += ( this.width )? 'width="' + this.width +'" ': ''; |
2552 | | - embedCode += ( this.height )? 'height="' + |
2553 | | - parseInt( this.height + this.controlBuilder.getHeight() + 2 ) + |
2554 | | - '" ': ''; |
2555 | | - } |
2556 | | - //Make sure overflow is hidden: |
2557 | | - embedCode += 'style="overflow:hidden" '; |
2558 | | - |
| 2536 | + // Set width / height of embed object |
| 2537 | + embedCode += 'width="' + this.getPlayerWidth() +'" '; |
| 2538 | + embedCode += 'height="' + this.getPlayerHeight() + '" '; |
| 2539 | + |
2559 | 2540 | // Close up the embedCode tag: |
2560 | | - embedCode+='></object>'; |
| 2541 | + embedCode+='></iframe>'; |
2561 | 2542 | |
2562 | 2543 | // Return the embed code |
2563 | 2544 | return embedCode; |
— | — | @@ -2671,7 +2652,15 @@ |
2672 | 2653 | * Starts the "monitor" |
2673 | 2654 | */ |
2674 | 2655 | play: function() { |
2675 | | - var _this = this; |
| 2656 | + var _this = this; |
| 2657 | + // Run play hook (if we we did not bind the native player ) |
| 2658 | + if( this.paused && this.useNativePlayerControls() ){ |
| 2659 | + this.paused = false; |
| 2660 | + mw.log("trigger play event::" + !this.paused); |
| 2661 | + $j( this ).trigger( 'play' ); |
| 2662 | + } |
| 2663 | + this.paused = false; |
| 2664 | + |
2676 | 2665 | mw.log( "EmbedPlayer:: play" ); |
2677 | 2666 | // Hide any overlay: |
2678 | 2667 | this.controlBuilder.closeMenuOverlay(); |
— | — | @@ -2689,16 +2678,9 @@ |
2690 | 2679 | } else { |
2691 | 2680 | // the plugin is already being displayed |
2692 | 2681 | this.seeking = false; |
2693 | | - } |
| 2682 | + } |
2694 | 2683 | |
2695 | | - // Run play hook (if we were previously in paused state ) |
2696 | | - if( this.paused ){ |
2697 | | - this.paused = false; |
2698 | | - mw.log("trigger play event::"); |
2699 | | - //$j( this ).trigger( 'play' ); |
2700 | | - } |
2701 | 2684 | |
2702 | | - |
2703 | 2685 | this.$interface.find('.play-btn span') |
2704 | 2686 | .removeClass( 'ui-icon-play' ) |
2705 | 2687 | .addClass( 'ui-icon-pause' ); |
— | — | @@ -2740,13 +2722,13 @@ |
2741 | 2723 | */ |
2742 | 2724 | pause: function( event ) { |
2743 | 2725 | var _this = this; |
2744 | | - |
2745 | | - // only trigger the pause event if not already in paused state: |
2746 | | - if( this.paused === false ){ |
| 2726 | + // Trigger the pause event if not already paused and using native controls: |
| 2727 | + if( this.paused === false && this.useNativePlayerControls() ){ |
2747 | 2728 | this.paused = true; |
2748 | | - mw.log('EmbedPlayer:trigger pause'); |
2749 | | - //$j( this ).trigger('pause' ); |
2750 | | - } |
| 2729 | + mw.log('EmbedPlayer:trigger pause:' + this.paused); |
| 2730 | + $j( this ).trigger('pause' ); |
| 2731 | + } |
| 2732 | + this.paused = true; |
2751 | 2733 | |
2752 | 2734 | // update the ctrl "paused state" |
2753 | 2735 | this.$interface.find('.play-btn span' ) |
Index: branches/MwEmbedStandAlone/modules/EmbedPlayer/skins/kskin/mw.style.PlayerSkinKskin.css |
— | — | @@ -187,7 +187,6 @@ |
188 | 188 | border: medium none; |
189 | 189 | display: none; |
190 | 190 | left: 0; |
191 | | - opacity: 0.9; |
192 | 191 | position: absolute; |
193 | 192 | top: 0; |
194 | 193 | z-index: 2; |
Index: branches/MwEmbedStandAlone/modules/EmbedPlayer/skins/kskin/mw.PlayerSkinKskin.js |
— | — | @@ -36,7 +36,7 @@ |
37 | 37 | .append( |
38 | 38 | $j( '<span />' ) |
39 | 39 | .text( gM( 'mwe-embedplayer-menu_btn' ) ) |
40 | | - ) |
| 40 | + ); |
41 | 41 | } |
42 | 42 | }, |
43 | 43 | 'volumeControl': { |
— | — | @@ -63,7 +63,14 @@ |
64 | 64 | 'top' : '0px', |
65 | 65 | 'bottom' : ( ctrlObj.getHeight() + 2 ) + 'px' |
66 | 66 | } ); |
67 | | - |
| 67 | + |
| 68 | + // Note safari can't display video overlays with text: |
| 69 | + // see bug https://bugs.webkit.org/show_bug.cgi?id=48379 |
| 70 | + |
| 71 | + var userAgent = navigator.userAgent.toLowerCase(); |
| 72 | + if( userAgent.indexOf('safari') != -1 ){ |
| 73 | + $menuOverlay.css('opacity', '0.9'); |
| 74 | + } |
68 | 75 | // Setup menu offset ( if player height < getOverlayHeight ) |
69 | 76 | // This displays the menu outside of the player on small embeds |
70 | 77 | if ( embedPlayer.getPlayerHeight() < ctrlObj.getOverlayHeight() ) { |
— | — | @@ -116,7 +123,7 @@ |
117 | 124 | 'bottom' : '0px', |
118 | 125 | 'right' : '45px', |
119 | 126 | 'overflow' : 'hidden' |
120 | | - } ) |
| 127 | + } ); |
121 | 128 | for ( var menuItem in ctrlObj.supportedMenuItems ) { |
122 | 129 | $menuScreens.append( |
123 | 130 | $j( '<div />' ) |
Index: branches/MwEmbedStandAlone/modules/EmbedPlayer/skins/mw.PlayerControlBuilder.js |
— | — | @@ -117,13 +117,7 @@ |
118 | 118 | 'right' : '0px' |
119 | 119 | } ); |
120 | 120 | // Check for overlay controls: |
121 | | - if( _this.checkOverlayControls() ) { |
122 | | - $controlBar.hide(); |
123 | | - // Make sure the interface is correct height: |
124 | | - embedPlayer.$interface.css( { |
125 | | - 'height' : parseInt( embedPlayer.height ) |
126 | | - } ); |
127 | | - } else { |
| 121 | + if( ! _this.checkOverlayControls() ) { |
128 | 122 | // Add some space to interface for the control bar ( if not overlaying controls ) |
129 | 123 | embedPlayer.$interface.css( { |
130 | 124 | 'height' : parseInt( embedPlayer.height ) + parseInt( this.height ) +2 |
— | — | @@ -495,10 +489,11 @@ |
496 | 490 | 'width' : embedPlayer.getWidth(), |
497 | 491 | 'height' : embedPlayer.getHeight() |
498 | 492 | }); |
| 493 | + |
499 | 494 | // Restore the play button |
500 | 495 | $interface.find('.play-btn-large').animate( { |
501 | | - 'left' : ( ( embedPlayer.getPlayerWidth() - this.getComponentWidth( 'playButtonLarge' ) ) / 2 ), |
502 | | - 'top' : ( ( embedPlayer.getPlayerHeight() -this.getComponentHeight( 'playButtonLarge' ) ) / 2 ) |
| 496 | + 'left' : ( ( embedPlayer.getWidth() - this.getComponentWidth( 'playButtonLarge' ) ) / 2 ), |
| 497 | + 'top' : ( ( embedPlayer.getHeight() -this.getComponentHeight( 'playButtonLarge' ) ) / 2 ) |
503 | 498 | } ); |
504 | 499 | |
505 | 500 | }, |
— | — | @@ -638,6 +633,7 @@ |
639 | 634 | * set to true for the player or via config |
640 | 635 | */ |
641 | 636 | checkOverlayControls: function(){ |
| 637 | + |
642 | 638 | //if the player "supports" overlays: |
643 | 639 | if( ! this.embedPlayer.supports['overlays'] ){ |
644 | 640 | return false; |
— | — | @@ -653,8 +649,9 @@ |
654 | 650 | return false; |
655 | 651 | } |
656 | 652 | |
657 | | - // don't hide controls when content "height" is 0 ( audio tags ) |
658 | | - if( this.embedPlayer.getPlayerHeight() == 0 ){ |
| 653 | + // Don't hide controls when content "height" is 0px ( audio tags ) |
| 654 | + if( this.embedPlayer.getPlayerHeight() === 0 && |
| 655 | + $j(this.embedPlayer).css('height').indexOf('%') == -1 ){ |
659 | 656 | return false; |
660 | 657 | } |
661 | 658 | if( this.embedPlayer.controls === false ){ |
— | — | @@ -718,8 +715,10 @@ |
719 | 716 | mw.log( 'controlBuilder: doWarningBindinng: ' + preferenceId + ' wm: ' + warningMsg); |
720 | 717 | // Set up local pointer to the embedPlayer |
721 | 718 | var embedPlayer = this.embedPlayer; |
722 | | - var _this = this; |
| 719 | + var _this = this; |
723 | 720 | |
| 721 | + // make sure the |
| 722 | + |
724 | 723 | $j( embedPlayer ).hoverIntent({ |
725 | 724 | 'timeout': 2000, |
726 | 725 | 'over': function() { |
— | — | @@ -761,30 +760,28 @@ |
762 | 761 | 'type' : "checkbox", |
763 | 762 | 'name' : 'ffwarn_' + embedPlayer.id |
764 | 763 | }) |
765 | | - .click( function() { |
766 | | - if ( $j( this ).is( ':checked' ) ) { |
767 | | - // Set up a cookie for 7 days: |
768 | | - $j.cookie( preferenceId, false, { expires: 7 } ); |
769 | | - // Set the current instance |
770 | | - mw.setConfig( preferenceId, false ); |
771 | | - $j( '#warningOverlay_' + embedPlayer.id ).fadeOut( 'slow' ); |
772 | | - // set the local prefrence to false |
773 | | - _this.addWarningFlag = false; |
774 | | - } else { |
775 | | - mw.setConfig( preferenceId, true ); |
776 | | - $j.cookie( preferenceId, true ); |
777 | | - } |
| 764 | + .click( function() { |
| 765 | + mw.log("WarningBindinng:: set " + preferenceId + ' to hidewarning ' ); |
| 766 | + // Set up a cookie for 30 days: |
| 767 | + $j.cookie( preferenceId, 'hidewarning', { expires: 30 } ); |
| 768 | + // Set the current instance |
| 769 | + mw.setConfig( preferenceId, false ); |
| 770 | + $j( '#warningOverlay_' + embedPlayer.id ).fadeOut( 'slow' ); |
| 771 | + // set the local prefrence to false |
| 772 | + _this.addWarningFlag = false; |
778 | 773 | } ) |
779 | 774 | ); |
780 | 775 | $targetWarning.append( |
781 | | - $j('<span />') |
| 776 | + $j('<label />') |
782 | 777 | .text( gM( 'mwe-embedplayer-do_not_warn_again' ) ) |
| 778 | + .attr( 'for', 'ffwarn_' + embedPlayer.id ) |
783 | 779 | ); |
784 | 780 | } |
785 | 781 | // Check the global config before showing the warning |
786 | | - if ( mw.getConfig( preferenceId ) === true ){ |
| 782 | + if ( mw.getConfig( preferenceId ) === true && $j.cookie( preferenceId ) != 'hidewarning' ){ |
| 783 | + mw.log("WarningBindinng:: show warning " + mw.getConfig( preferenceId ) + ' cookie: '+ $j.cookie( preferenceId ) + 'typeof:' + typeof $j.cookie( preferenceId )); |
787 | 784 | $j( '#warningOverlay_' + embedPlayer.id ).fadeIn( 'slow' ); |
788 | | - } |
| 785 | + }; |
789 | 786 | }, |
790 | 787 | 'out': function() { |
791 | 788 | $j( '#warningOverlay_' + embedPlayer.id ).fadeOut( 'slow' ); |
Index: branches/MwEmbedStandAlone/modules/EmbedPlayer/mw.EmbedPlayerNative.js |
— | — | @@ -25,12 +25,39 @@ |
26 | 26 | // NOTE the bug where onSeeked does not seem fire consistently may no longer be applicable |
27 | 27 | prevCurrentTime: -1, |
28 | 28 | |
29 | | - // Store the progress event ( updated durring monitor ) |
| 29 | + // Store the progress event ( updated during monitor ) |
30 | 30 | progressEventData: null, |
31 | 31 | |
32 | 32 | // If the media loaded event has been fired |
33 | 33 | mediaLoadedFlag: null, |
34 | 34 | |
| 35 | + // All the native events per: |
| 36 | + // http://www.w3.org/TR/html5/video.html#mediaevents |
| 37 | + nativeEvents : [ |
| 38 | + 'loadstart', |
| 39 | + 'progress', |
| 40 | + 'suspend', |
| 41 | + 'abort', |
| 42 | + 'error', |
| 43 | + 'emptied', |
| 44 | + 'stalled', |
| 45 | + 'play', |
| 46 | + 'pause', |
| 47 | + 'loadedmetadata', |
| 48 | + 'loadeddata', |
| 49 | + 'waiting', |
| 50 | + 'playing', |
| 51 | + 'canplay', |
| 52 | + 'canplaythough', |
| 53 | + 'seeking', |
| 54 | + 'seeked', |
| 55 | + 'timeupdate', |
| 56 | + 'ended', |
| 57 | + 'ratechange', |
| 58 | + 'durationchange', |
| 59 | + 'volumechange' |
| 60 | + ], |
| 61 | + |
35 | 62 | // Native player supported feature set |
36 | 63 | supports: { |
37 | 64 | 'playHead' : true, |
— | — | @@ -39,10 +66,8 @@ |
40 | 67 | 'timeDisplay' : true, |
41 | 68 | 'volumeControl' : true, |
42 | 69 | 'overlays' : true |
43 | | - }, |
| 70 | + }, |
44 | 71 | |
45 | | - insertAndPlayingConfig : false, |
46 | | - |
47 | 72 | /** |
48 | 73 | * updates the supported features given the "type of player" |
49 | 74 | */ |
— | — | @@ -130,37 +155,22 @@ |
131 | 156 | mw.log( "f:native:postEmbedJS:" ); |
132 | 157 | |
133 | 158 | // Setup local pointer: |
134 | | - var vid = this.getPlayerElement(); |
135 | | - if ( typeof this.playerElement != 'undefined' ) { |
136 | | - // Apply media element bindings: |
137 | | - this.applyMediaElementBindings(); |
138 | | - |
139 | | - // Check for load flag |
140 | | - if ( this.onlyLoadFlag ) { |
141 | | - vid.pause(); |
142 | | - vid.load(); |
143 | | - } else { |
144 | | - // Issue play request |
145 | | - vid.play(); |
146 | | - } |
147 | | - |
148 | | - setTimeout( function() { |
149 | | - _this.monitor(); |
150 | | - }, 100 ); |
151 | | - |
152 | | - } else { |
153 | | - // False inserts don't seem to be as much of a problem as before: |
154 | | - mw.log( 'Could not grab vid obj trying again:' + typeof this.playerElement ); |
155 | | - this.grab_try_count++; |
156 | | - if ( this.grab_count == 20 ) { |
157 | | - mw.log( 'Could not get vid object after 20 tries re-run: getEmbedObj() ?' ) ; |
158 | | - } else { |
159 | | - setTimeout( function() { |
160 | | - _this.postEmbedJS(); |
161 | | - }, 150 ); |
162 | | - } |
163 | | - |
164 | | - } |
| 159 | + var vid = this.getPlayerElement(); |
| 160 | + // Apply media element bindings: |
| 161 | + this.applyMediaElementBindings(); |
| 162 | + |
| 163 | + // Check for load flag |
| 164 | + if ( this.onlyLoadFlag ) { |
| 165 | + vid.pause(); |
| 166 | + vid.load(); |
| 167 | + } else { |
| 168 | + // Issue play request |
| 169 | + vid.play(); |
| 170 | + } |
| 171 | + |
| 172 | + setTimeout( function() { |
| 173 | + _this.monitor(); |
| 174 | + }, 100 ); |
165 | 175 | }, |
166 | 176 | |
167 | 177 | /** |
— | — | @@ -173,6 +183,7 @@ |
174 | 184 | mw.log( " Error: applyMediaElementBindings without player elemnet"); |
175 | 185 | return ; |
176 | 186 | } |
| 187 | + |
177 | 188 | // Bind events to local js methods: |
178 | 189 | vid.addEventListener( 'canplaythrough', function() { $j( _this ).trigger('canplaythrough'); }, true); |
179 | 190 | vid.addEventListener( 'loadedmetadata', function() { _this.onloadedmetadata() }, true); |
— | — | @@ -321,7 +332,7 @@ |
322 | 333 | this.getPlayerElement(); |
323 | 334 | |
324 | 335 | if ( !this.playerElement ) { |
325 | | - mw.log( 'Error: mwEmbedPlayer::getPlayerElementTime: missing ' + this.id + ' stop monitor' ); |
| 336 | + mw.log( 'mwEmbedPlayer::getPlayerElementTime: ' + this.id + ' not in dom ( stop monitor)' ); |
326 | 337 | return false; |
327 | 338 | } |
328 | 339 | // Return the playerElement currentTime |
— | — | @@ -432,6 +443,7 @@ |
433 | 444 | onVolumeChange: function(){ |
434 | 445 | //mw.log( "native::volumechange::trigger" ); |
435 | 446 | //this.volume = this.playerElement.volume; |
| 447 | + $j( this ).trigger( 'volumechange' ); |
436 | 448 | }, |
437 | 449 | |
438 | 450 | /** |
— | — | @@ -504,10 +516,14 @@ |
505 | 517 | */ |
506 | 518 | onSeeked: function() { |
507 | 519 | mw.log("native:onSeeked"); |
508 | | - this.seeking = false; |
| 520 | + |
509 | 521 | mw.log("native:onSeeked:trigger"); |
510 | 522 | // Trigger the html5 action on the parent |
511 | | - $j( this ).trigger( 'seeked' ); |
| 523 | + if( this.seeking && this.useNativePlayerControls() ){ |
| 524 | + this.seeking = false; |
| 525 | + $j( this ).trigger( 'seeked' ); |
| 526 | + } |
| 527 | + this.seeking = false; |
512 | 528 | }, |
513 | 529 | |
514 | 530 | /** |
— | — | @@ -522,8 +538,8 @@ |
523 | 539 | * Handle the native play event |
524 | 540 | */ |
525 | 541 | onPlay: function(){ |
526 | | - mw.log("EmbedPlayer:native:: OnPlay"); |
527 | | - // Update the interface |
| 542 | + mw.log("EmbedPlayer:native:: OnPlay"); |
| 543 | + // Update the interface ( if paused ) |
528 | 544 | this.parent_play(); |
529 | 545 | }, |
530 | 546 | |
— | — | @@ -574,8 +590,7 @@ |
575 | 591 | */ |
576 | 592 | onended: function() { |
577 | 593 | var _this = this; |
578 | | - mw.log( 'EmbedPlayer:native: onended:' + this.playerElement.currentTime + ' real dur:' + this.getDuration() + |
579 | | - ' insertAndPlayingConfig: ' + this.insertAndPlayingConfig); |
| 594 | + mw.log( 'EmbedPlayer:native: onended:' + this.playerElement.currentTime + ' real dur:' + this.getDuration() ); |
580 | 595 | |
581 | 596 | this.onClipDone(); |
582 | 597 | } |