r68592 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r68591‎ | r68592 | r68593 >
Date:23:43, 25 June 2010
Author:dale
Status:deferred
Tags:
Comment:
* basic video insert for smil player
Modified paths:
  • /branches/MwEmbedStandAlone/modules/AddMedia/tests/Firefogg_GUI.html (modified) (history)
  • /branches/MwEmbedStandAlone/modules/SmilPlayer/mw.Smil.js (modified) (history)
  • /branches/MwEmbedStandAlone/modules/SmilPlayer/mw.SmilAnimate.js (modified) (history)
  • /branches/MwEmbedStandAlone/modules/SmilPlayer/mw.SmilBody.js (modified) (history)
  • /branches/MwEmbedStandAlone/modules/SmilPlayer/mw.SmilBuffer.js (modified) (history)
  • /branches/MwEmbedStandAlone/modules/SmilPlayer/mw.SmilLayout.js (modified) (history)

Diff [purge]

Index: branches/MwEmbedStandAlone/modules/SmilPlayer/mw.SmilBody.js
@@ -11,11 +11,18 @@
1212 // Used to store elements for getElementsForTime method
1313 elementsInRange: [],
1414
 15+ // Used to store elements out of range for getElementsForTime method
 16+ elementsOutOfRange: [],
 17+
1518 // Index of auto assigned ids
1619 idIndex : 0,
1720
 21+ // Cache of ids of previous list of active elements
 22+ // This lets us cache a valid element list for a given amount of time
 23+ cacheElementList: {},
 24+
1825 // Constructor:
19 - init: function( smilObject ){
 26+ init: function( smilObject ){
2027 this.smil = smilObject;
2128 this.$dom = this.smil.getDom().find( 'body' );
2229
@@ -54,42 +61,55 @@
5562 */
5663 renderTime: function( time, deltaTime ){
5764 var _this = this;
 65+
5866 // Get all the draw elements from the body this time:
59 - var elementList = this.getElementsForTime( time );
60 - //mw.log("SmilBody::renderTime: draw " + elementList.length + " elementList" );
61 -
62 - $j.each( elementList , function( inx, smilElement ) {
63 - // xxx need to
64 - // var relativeTime = time - smilElement.parentTimeOffset;
65 - var relativeTime = time - $j( smilElement ).data ( 'parentStartOffset' );
66 -
67 - // Render the active elements using the layout engine
68 - _this.smil.getLayout().drawElement( smilElement, relativeTime );
69 -
70 - // Transform the elements per animate engine
71 - _this.smil.getAnimate().animateTransform( smilElement, relativeTime, deltaTime );
72 - } );
 67+ var elementList = this.getElementsForTime( time ,
 68+ /* SMIL Element in Range */
 69+ function( smilElement) {
 70+ // var relativeTime = time - smilElement.parentTimeOffset;
 71+ var relativeTime = time - $j( smilElement ).data ( 'parentStartOffset' );
 72+
 73+ // Render the active elements using the layout engine
 74+ _this.smil.getLayout().drawElement( smilElement );
 75+
 76+ // Transform the elements per animate engine
 77+ _this.smil.getAnimate().animateTransform( smilElement, relativeTime, deltaTime );
 78+ },
 79+ /* SMIL Element out of range */
 80+ function( smilElement ){
 81+ // Hide the element in the layout
 82+ _this.smil.getLayout().hideElement( smilElement );
 83+ }
 84+ );
7385 },
7486
7587 /**
 88+ * Check if we have a valid element cache:
 89+ * XXX not yet working.
 90+ */
 91+ isValidElementCache: function( time ){
 92+ if( time > this.cacheElementList.validStart && time > this.cacheElementList.validEnd ) {
 93+ return this.cacheElementList.elements;
 94+ }
 95+ },
 96+
 97+ /**
7698 * Gets all the elements for a given time.
7799 */
78 - getElementsForTime: function ( time ) {
 100+ getElementsForTime: function ( time , inRangeCallback, outOfRangeCallback ) {
79101 var startOffset = 0;
80102 if( !time ) {
81103 time =0;
82 - }
83 - // Empty out the requested element set:
84 - this.elementsInRange = [];
85 - this.getElementsForTimeRecurse( this.$dom, time, startOffset);
86 - return this.elementsInRange;
 104+ }
 105+ // Empty out the requested element set:
 106+ this.getElementsForTimeRecurse( this.$dom, time, startOffset, inRangeCallback, outOfRangeCallback);
87107 },
88108
89109 /**
90110 * getElementsForTimeRecurse
91111 * @param {Object} $node Node to recursively search for elements in the given time range
92112 */
93 - getElementsForTimeRecurse: function( $node, time, startOffset){
 113+ getElementsForTimeRecurse: function( $node, time, startOffset, inRangeCallback, outOfRangeCallback){
94114 // Setup local pointers:
95115 var nodeDuration = this.getNodeDuration( $node );
96116 var nodeType = this.getNodeSmilType( $node );
@@ -100,51 +120,45 @@
101121 if( !startOffset ) {
102122 startOffset = 0;
103123 }
104 -
105 - /*mw.log( "getElementsForTimeRecurse::" +
106 - ' time: ' + time +
107 - ' nodeName: ' + $j( $node ).get(0).nodeName +
108 - ' nodeType: ' + nodeType +
109 - ' nodeDur: ' + nodeDuration +
110 - ' offset: ' + startOffset
111 - );*/
112 -
113 - // If startOffset is > time skip node and all its children
114 - if( startOffset > time ){
115 - mw.log(" Reached end, startOffset is:" + startOffset + ' > ' + time );
116 - return ;
117 - }
118 -
119 - // Means we need to seek ahead
120 - /*if( startOffset < time ){
121 - mw.log( "Seek ahead: startOffset is: " + startOffset + ' < ' + time );
122 - return ;
123 - }*/
124 -
 124+
 125+
125126 // If 'par' or 'seq' recurse to get elements for layout
126 - if( nodeType == 'par'|| nodeType == 'seq' ) {
 127+ if( nodeType == 'par' || nodeType == 'seq' ) {
127128 if( $node.children().length ) {
128129 $node.children().each( function( inx, childNode ){
129 - //mw.log(" recurse:: startOffset:" + nodeType + ' start offset:' + startOffset );
130 - var childDur = _this.getElementsForTimeRecurse( $j( childNode ), time, startOffset);
131 - // If element parent is a 'seq' increment startOffset:
 130+ // mw.log(" recurse:: startOffset:" + nodeType + ' start offset:' + startOffset );
 131+ var childDur = _this.getElementsForTimeRecurse(
 132+ $j( childNode ),
 133+ time,
 134+ startOffset,
 135+ inRangeCallback,
 136+ outOfRangeCallback
 137+ );
 138+ // If element parent is a 'seq' increment startOffset as we recurse for each child
132139 if( nodeType == 'seq' ) {
133140 //mw.log(" Parent Seq:: add child dur: " + childDur );
134141 startOffset += childDur;
135 - }
 142+ }
136143 });
137144 }
138 - }
 145+ }
139146
140 - // If the nodeType is "ref" add to this.elementsInRange array
 147+ // If the nodeType is "ref" or smilText run the callback
141148 if( nodeType == 'ref' || nodeType == 'smilText' ) {
142149 // Add the parent startOffset
143 - $node.data( 'parentStartOffset', startOffset );
144 - // Ref type get the
145 - this.elementsInRange.push( $node );
146 - //mw.log("Add ref to elementsInRange:: " + nodeType + " length:" + this.elementsInRange.length);
147 - }
148 -
 150+ $node.data( 'parentStartOffset', startOffset );
 151+
 152+ // Check if element is in range:
 153+ if( time >= startOffset && time <= ( startOffset + nodeDuration) ){
 154+ if( inRangeCallback ){
 155+ inRangeCallback( $node );
 156+ }
 157+ } else {
 158+ if( outOfRangeCallback ){
 159+ outOfRangeCallback( $node );
 160+ }
 161+ }
 162+ }
149163 // Return the node Duration for tracking startOffset
150164 return this.getNodeDuration( $node );
151165 },
@@ -170,6 +184,7 @@
171185 ) {
172186 return $node.data('computedDuration');
173187 }
 188+
174189 var _this = this;
175190 var duration = 0;
176191
Index: branches/MwEmbedStandAlone/modules/SmilPlayer/mw.SmilLayout.js
@@ -64,21 +64,27 @@
6565 },
6666
6767 /**
68 - * RenderElement smilElement at a given time.
69 - * If the element does not exist in the html dom add it.
70 - * Updates a given element for the requested time
 68+ * Draw a smilElement to the layout.
 69+ *
 70+ * If the element does not exist in the html dom add it.
7171 */
72 - drawElement: function( smilElement, time ) {
 72+ drawElement: function( smilElement ) {
7373 var _this = this;
74 - var nodeName = $j( smilElement ).get(0).nodeName ;
75 -
 74+ // Check for quick "show" path:
 75+ var $targetElement = this.$rootLayout.find( '#' + this.smil.getAssetId( smilElement ) )
 76+ if( $targetElement.length ){
 77+ $targetElement.show();
 78+ }
 79+
 80+ // Else draw the node into the regionTarget
 81+
7682 //mw.log( "SmilLayout::drawElement: " + nodeName + '.' + $j( smilElement ).attr('id' ) + ' into ' + regionId );
7783 var regionId = $j( smilElement ).attr( 'region');
7884 if( regionId ){
7985 var $regionTarget = this.$rootLayout.find( '#' + regionId );
8086 // Check for region target in $rootLayout
8187 if( $regionTarget.length == 0 ) {
82 - mw.log( "Error in SmilLayout::renderElement, Could not find region:" + regionId + " for " + nodeName);
 88+ mw.log( "Error in SmilLayout::renderElement, Could not find region:" + regionId );
8389 return ;
8490 }
8591 } else {
@@ -87,53 +93,90 @@
8894 }
8995
9096 // Check that the element is already in the dom
91 - if( $regionTarget.find( '#' + this.smil.getAssetId( smilElement ) ).length == 0 ){
 97+ var $targetElement = $regionTarget.find( '#' + this.smil.getAssetId( smilElement ) );
 98+ if( $targetElement.length == 0 ){
 99+ mw.log(" drawElement:: " + this.smil.getAssetId( smilElement ) );
92100 // Append the Smil to the target region
93 - $regionTarget.append( this.getSmilElementHtml( smilElement ) )
 101+ $regionTarget.append(
 102+ _this.getSmilElementHtml( smilElement )
 103+ )
 104+ } else {
 105+ // Make sure the element is visable ( may be faster to just call show directly)
 106+ if( $targetElement.is(':hidden') ) {
 107+ $targetElement.show();
 108+ }
94109 }
95110 },
96111
97112 /**
 113+ * Hide a smilElement in the layout
 114+ */
 115+ hideElement: function( smilElement ){
 116+ // Check that the element is already in the dom
 117+ var $targetElement = this.$rootLayout.find( '#' + this.smil.getAssetId( smilElement ) );
 118+ if( $targetElement.length ){
 119+ // Issue a quick hide request
 120+ $targetElement.hide();
 121+ }
 122+ },
 123+
 124+ /**
98125 * Get the transformed smil element in html format
99126 * @param
100127 */
101 - getSmilElementHtml: function ( smilElement, time ) {
102 - var nodeName = $j( smilElement ).get(0).nodeName ;
103 - mw.log("Get Smil Element Html: " + nodeName );
104 -
105 - var smilType = this.smil.getRefType( smilElement )
106 -
 128+ getSmilElementHtml: function ( smilElement ) {
 129+ var smilType = this.smil.getRefType( smilElement )
107130 switch( smilType ){
108131 // Not part of strict smil, but saves time being able have an "html" display mode
109132 case 'cdata_html':
110 - return this.getSmilCDATAHtml( smilElement, time );
 133+ return this.getSmilCDATAHtml( smilElement );
111134 break;
 135+ case 'video':
 136+ return this.getSmilVideoHtml( smilElement );
 137+ break;
112138 // Smil Text: http://www.w3.org/TR/SMIL/smil-text.html (obviously we support a subset )
113139 case 'smiltext':
114 - return this.getSmilTextHtml( smilElement, time);
 140+ return this.getSmilTextHtml( smilElement );
115141 break;
116142 case 'img':
117 - return this.getSmilImgHtml( smilElement, time);
 143+ return this.getSmilImgHtml( smilElement );
118144 break;
119145 }
120146 mw.log( "Error: Could not find smil layout transform for element type: " +
121 - nodeName + ' of type ' + $j( smilElement ).attr( 'type' ) );
 147+ smilType + ' of type ' + $j( smilElement ).attr( 'type' ) );
 148+
122149 return $j('<span />')
 150+ .attr( 'id' , this.smil.getAssetId( smilElement ) )
123151 .css( {
124152 'position' : 'absolute',
125153 'zindex' : 9999 // xxx need to clean up z-index system
126154 })
127 - .text( 'Error: unknown type:' + nodeName );
 155+ .text( 'Error: unknown type:' + smilType );
128156 },
129157
130158 /**
 159+ * Return the video
 160+ */
 161+ getSmilVideoHtml: function( videoElement ){
 162+ return $j('<video />')
 163+ .attr( {
 164+ 'id' : this.smil.getAssetId( videoElement ),
 165+ 'src' : this.smil.getAssetUrl( $j( videoElement ).attr( 'src' ) )
 166+ } )
 167+ .css( {
 168+ 'width': '100%',
 169+ 'height' : '100%'
 170+ })
 171+ },
 172+
 173+ /**
131174 * Get Smil CDATA ( passed through jQuery .clean as part of fragment creation )
132 - * XXX Sequrity XXX
 175+ * XXX Security XXX
133176 * Here we are parsing in SMIL -> HTML should be careful about XSS or script elevation
134177 *
135178 * @@TODO check if this is "local" only smil and enforce domain on all asset sources
136179 */
137 - getSmilCDATAHtml: function( smilElement, time ){
 180+ getSmilCDATAHtml: function( smilElement ){
138181 // Get "clean" smil data
139182 var el = $j( smilElement ).get(0);
140183 var xmlCdata = '';
@@ -144,24 +187,27 @@
145188 xmlCdata += node.nodeValue;
146189 }
147190 }
 191+
 192+ var textCss = this.transformSmilCss( smilElement );
 193+
148194 // Return the cdata
149195 return $j('<div />')
150 - .attr( 'id' , this.smil.getAssetId( textElement ) )
 196+ .attr( 'id' , this.smil.getAssetId( smilElement ) )
151197 // Wrap in font-size percentage relative to virtual size
152198 .css( 'font-size', ( ( this.targetWidth / this.virtualWidth )*100 ) + '%' )
153199 .append(
154 - // We pass the xmlCdata via jQuery fragment creation to
155 - // filter the result of "non-clean" html.
156 - $j( xmlCdata )
 200+ // We pass the xmlCdata via jQuery fragment creation, this runs jquery.clean()
 201+ // and filters the result html.
 202+ $j( xmlCdata )
 203+ .css( textCss )
157204 );
158205
159206 },
160207
161208 /**
162 - * Get a text element per given time
163 - * xxx we need to use "relativeTime"
 209+ * Get a text element html
164210 */
165 - getSmilTextHtml: function( textElement, relativeTime ) {
 211+ getSmilTextHtml: function( textElement ) {
166212 var _this = this;
167213
168214 // Empty initial text value
@@ -174,29 +220,7 @@
175221 textValue = $j( textElement ).text();
176222 }
177223
178 - var textCss = _this.transformSmilCss( textElement );
179 -
180 - // Make the font size fixed so it can be scaled
181 - // based on: http://style.cleverchimp.com/font_size_intervals/altintervals.html
182 - var sizeMap = {
183 - 'xx-small' : '.57em',
184 - 'x-small' : '.69em',
185 - 'small' : '.83em',
186 - 'medium' : '1em',
187 - 'large' : '1.2em',
188 - 'x-large' : '1.43em',
189 - 'xx-large' : '1.72em'
190 - }
191 - if( sizeMap[ textCss['font-size'] ] ){
192 - textCss['font-size'] = sizeMap[ textCss['font-size'] ];
193 - }
194 -
195 - // If the font size is pixel based parent span will have no effect,
196 - // directly resize the pixels
197 - if( textCss['font-size'] && textCss['font-size'].indexOf('px') != -1 ){
198 - textCss['font-size'] = ( parseFloat( textCss['font-size'] )
199 - * ( this.targetWidth / this.virtualWidth ) ) + 'px';
200 - }
 224+ var textCss = _this.transformSmilCss( textElement );
201225
202226 // Return the htmlElement
203227 return $j('<span />')
@@ -216,24 +240,9 @@
217241 * Get Image html per given smil element and requested time
218242 * @param {element} imgElement The image tag element to be updated
219243 */
220 - getSmilImgHtml: function( imgElement, relativeTime ) {
 244+ getSmilImgHtml: function( imgElement ) {
221245 // Check if we have child transforms and select the transform that is in range
222 - var panZoom = null;
223 - if( $j( imgElement ).children().length ){
224 - $j( imgElement ).children().each(function(inx, childNode ){
225 - if( childNode.nodeName == 'animate' ){
226 - // add begin / duration to animation bucket ( computed value )
227 -
228 - // get panZoom value
229 - }
230 - })
231 - // calculate animation position
232 - } else {
233 - // Set pan zoom from imgElement ( if set )
234 - if( $j( imgElement ).attr('panZoom') ){
235 - panZoom = this.parsePanZoom( $j( imgElement ).attr('panZoom') );
236 - }
237 - }
 246+ var panZoom = null;
238247 mw.log( "Add image:" + this.smil.getAssetUrl( $j( imgElement ).attr( 'src' ) ) );
239248 // XXX get context of smil document for relative or absolute paths:
240249 return $j('<img />')
@@ -430,6 +439,30 @@
431440 cssAttributes[ smilAttributeToCss[ attr.nodeName ]] = attr.nodeValue;
432441 }
433442 }
 443+
 444+ // Make the font size fixed so it can be scaled
 445+ // based on: http://style.cleverchimp.com/font_size_intervals/altintervals.html
 446+ var sizeMap = {
 447+ 'xx-small' : '.57em',
 448+ 'x-small' : '.69em',
 449+ 'small' : '.83em',
 450+ 'medium' : '1em',
 451+ 'large' : '1.2em',
 452+ 'x-large' : '1.43em',
 453+ 'xx-large' : '1.72em'
 454+ }
 455+ if( sizeMap[ cssAttributes['font-size'] ] ){
 456+ cssAttributes['font-size'] = cssAttributes[ textCss['font-size'] ];
 457+ }
 458+
 459+ // If the font size is pixel based parent span will have no effect,
 460+ // directly resize the pixels
 461+ if( cssAttributes['font-size'] && cssAttributes['font-size'].indexOf('px') != -1 ){
 462+ cssAttributes['font-size'] = ( parseFloat( cssAttributes['font-size'] )
 463+ * ( this.targetWidth / this.virtualWidth ) ) + 'px';
 464+ }
 465+
 466+
434467 // Translate rootLayout properties into div
435468 return cssAttributes;
436469 }
Index: branches/MwEmbedStandAlone/modules/SmilPlayer/mw.SmilAnimate.js
@@ -46,28 +46,28 @@
4747 var animateTimeDelta = 0;
4848
4949 this.animateInterval[ this.smil.getAssetId( smilElement ) ] =
50 - setInterval(
51 - function(){
52 - var timeElapsed = new Date().getTime() - animationStartTime;
53 - // Set the animate Time delta
54 - animateTimeDelta += _this.callbackRate;
55 -
56 - if( animateTimeDelta > deltaTime || timeElapsed > deltaTime ){
57 - // Stop animating:
58 - clearInterval( _this.animateInterval[ _this.smil.getAssetId( smilElement ) ] );
59 - return ;
60 - }
61 -
62 - if( Math.abs( timeElapsed - animateTimeDelta ) > 100 ){
63 - mw.log( "Error more than 100ms lag within animateTransform loop: te:" + timeElapsed +
64 - ' td:' + animateTimeDelta + ' diff: ' + Math.abs( timeElapsed - animateTimeDelta ) );
65 - }
66 -
67 - // Do the transform request:
68 - _this.transformElement( smilElement, animateTime + ( animateTimeDelta/1000 ) );
69 - },
70 - this.callbackRate
71 - );
 50+ setInterval(
 51+ function(){
 52+ var timeElapsed = new Date().getTime() - animationStartTime;
 53+ // Set the animate Time delta
 54+ animateTimeDelta += _this.callbackRate;
 55+
 56+ if( animateTimeDelta > deltaTime || timeElapsed > deltaTime ){
 57+ // Stop animating:
 58+ clearInterval( _this.animateInterval[ _this.smil.getAssetId( smilElement ) ] );
 59+ return ;
 60+ }
 61+
 62+ if( Math.abs( timeElapsed - animateTimeDelta ) > 100 ){
 63+ mw.log( "Error more than 100ms lag within animateTransform loop: te:" + timeElapsed +
 64+ ' td:' + animateTimeDelta + ' diff: ' + Math.abs( timeElapsed - animateTimeDelta ) );
 65+ }
 66+
 67+ // Do the transform request:
 68+ _this.transformElement( smilElement, animateTime + ( animateTimeDelta/1000 ) );
 69+ },
 70+ this.callbackRate
 71+ );
7272 },
7373
7474 /**
Index: branches/MwEmbedStandAlone/modules/SmilPlayer/mw.Smil.js
@@ -222,12 +222,13 @@
223223 var contextUrl = mw.absoluteUrl( this.smilUrl );
224224 return mw.absoluteUrl( assetPath, contextUrl );
225225 },
 226+
226227 /**
227228 * Get the smil resource type based on nodeName and type attribute
228229 */
229 - getRefType: function(
 230+ getRefType: function( smilElement ) {
230231 // Get the smil type
231 - var smilType = nodeName.toLowerCase();
 232+ var smilType = $j( smilElement ).get(0).nodeName.toLowerCase();
232233 if( smilType == 'ref' ){
233234 // If the smilType is ref, check for a content type
234235 switch( $j( smilElement ).attr( 'type' ) ) {
@@ -241,6 +242,7 @@
242243 break;
243244 }
244245 }
 246+ return smilType;
245247 },
246248
247249 /**
Index: branches/MwEmbedStandAlone/modules/SmilPlayer/mw.SmilBuffer.js
@@ -20,7 +20,7 @@
2121 timeIsBuffered: function( time, callback ) {
2222
2323 // Get active body elements
24 - var activeElements = this.smil.getBody().getElementsForTime( time );
 24+ //this.smil.getBody().getElementsForTime( time );
2525 // Check load status per temporal offset
2626
2727 // setTimeout to call self until buffer is ready
Index: branches/MwEmbedStandAlone/modules/AddMedia/tests/Firefogg_GUI.html
@@ -103,7 +103,7 @@
104104 $j( '#fogg-status' ).append(
105105 gM('fogg-wont-upload-to-server' ),
106106 $j('<br />' ), $j('<br />' )
107 - );
 107+ );
108108
109109 for( var i = 0; i < langSupported.length; i++ ){
110110 var urlParts = mw.parseUri( document.URL );

Status & tagging log