r83541 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r83540‎ | r83541 | r83542 >
Date:19:58, 8 March 2011
Author:dale
Status:deferred
Tags:
Comment:
* updated timed media handler to use mw.Uri
* import a few functions from uploadWizard utilities:: mw.isEmpty(), mw.isFull(), mw.isDefined(), mw.ucfirst()
* updated dependencies for embed player to include relevant uploadwizard ported modules.
* fixed some minor job queue issues with paging purges with updated encoded videos
* moved absoluteUrl into its own module / file
* moved client user agent helpers ( isAndroid() isIphone() into mediawiki.client ( could be merged or better use jquery.client ) )
* moved time utilities into mediawiki.UtilitiesTime.js
Modified paths:
  • /trunk/extensions/MwEmbedSupport/MwEmbedModules/MediaWikiSupport/resources/MediaWikiPlayerSupport.js (modified) (history)
  • /trunk/extensions/MwEmbedSupport/MwEmbedModules/MediaWikiSupport/resources/mw.Api.js (modified) (history)
  • /trunk/extensions/MwEmbedSupport/MwEmbedModules/MwEmbedSupport/MwEmbedSupport.php (modified) (history)
  • /trunk/extensions/MwEmbedSupport/MwEmbedModules/MwEmbedSupport/mediawiki (added) (history)
  • /trunk/extensions/MwEmbedSupport/MwEmbedModules/MwEmbedSupport/mediawiki.language.parser.js (deleted) (history)
  • /trunk/extensions/MwEmbedSupport/MwEmbedModules/MwEmbedSupport/mediawiki/mediawiki.Uri.js (added) (history)
  • /trunk/extensions/MwEmbedSupport/MwEmbedModules/MwEmbedSupport/mediawiki/mediawiki.UtilitiesTime.js (added) (history)
  • /trunk/extensions/MwEmbedSupport/MwEmbedModules/MwEmbedSupport/mediawiki/mediawiki.absoluteUrl.js (added) (history)
  • /trunk/extensions/MwEmbedSupport/MwEmbedModules/MwEmbedSupport/mediawiki/mediawiki.client.js (added) (history)
  • /trunk/extensions/MwEmbedSupport/MwEmbedModules/MwEmbedSupport/mediawiki/mediawiki.language.parser.js (added) (history)
  • /trunk/extensions/MwEmbedSupport/MwEmbedModules/MwEmbedSupport/mwEmbedSupport.js (modified) (history)
  • /trunk/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/EmbedPlayer.php (modified) (history)
  • /trunk/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/MediaElement.js (modified) (history)
  • /trunk/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/MediaSource.js (modified) (history)
  • /trunk/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/iframeApi/mw.IFramePlayerApiClient.js (modified) (history)
  • /trunk/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/iframeApi/mw.IFramePlayerApiServer.js (modified) (history)
  • /trunk/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayer.js (modified) (history)
  • /trunk/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerJava.js (modified) (history)
  • /trunk/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerKplayer.js (modified) (history)
  • /trunk/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/skins/mw.PlayerControlBuilder.js (modified) (history)
  • /trunk/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/tests/Player_Seek.html (modified) (history)
  • /trunk/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/tests/Player_ServerSeek.html (modified) (history)
  • /trunk/extensions/TimedMediaHandler/TimedMediaHandler.hooks.php (modified) (history)
  • /trunk/extensions/TimedMediaHandler/WebVideoTranscode/WebVideoTranscodeJob.php (modified) (history)

Diff [purge]

Index: trunk/extensions/TimedMediaHandler/WebVideoTranscode/WebVideoTranscodeJob.php
@@ -107,7 +107,7 @@
108108 array( 'LIMIT' => $limit + 1 )
109109 );
110110 foreach ( $res as $page ) {
111 - $title = Title::makeTitle( $element->page_namespace, $page->page_title );
 111+ $title = Title::makeTitle( $page->page_namespace, $page->page_title );
112112 $title->invalidateCache();
113113 }
114114 }
Index: trunk/extensions/TimedMediaHandler/TimedMediaHandler.hooks.php
@@ -29,9 +29,7 @@
3030 'webVideoTranscode' => 'WebVideoTranscodeJob'
3131 );
3232 // Transcode jobs must be explicitly requested from the job queue:
33 - $wgJobExplitRequestTypes+= array(
34 - 'webVideoTranscode'
35 - );
 33+ $wgJobExplitRequestTypes[] = 'webVideoTranscode';
3634
3735 $baseExtensionResource = array(
3836 'localBasePath' => dirname( __FILE__ ),
@@ -49,6 +47,7 @@
5048 'styles' => 'resources/embedPlayerIframe.css',
5149 )
5250 );
 51+
5352 // We should probably move this to a parser function but not working correctly in
5453 // dynamic contexts ( for example in special upload, when there is an "existing file" warning. )
5554 $wgHooks['BeforePageDisplay'][] = 'TimedMediaHandlerHooks::pageOutputHook';
@@ -56,10 +55,10 @@
5756
5857 // Exclude transcoded assets from normal thumbnail purging
5958 // ( a mantaince script could handle transcode asset purging)
60 - $wgExcludeFromThumbnailPurge += $wgTimedMediaHandlerFileExtensions;
 59+ $wgExcludeFromThumbnailPurge = array_merge( $wgExcludeFromThumbnailPurge, $wgTimedMediaHandlerFileExtensions );
6160 // Also add the .log file ( used in two pass encoding )
6261 // ( probably should move in-progress encodes out of web accessible directory )
63 - $wgExcludeFromThumbnailPurge+= array( 'log');
 62+ $wgExcludeFromThumbnailPurge[] = 'log';
6463
6564 // Api hooks for derivatives and query video derivatives
6665 $wgAPIPropModules += array(
Index: trunk/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/EmbedPlayer.php
@@ -22,6 +22,9 @@
2323 'dependencies' => array(
2424 // mwEmbed support module
2525 'mwEmbedSupport',
 26+ 'mediawiki.client',
 27+ 'mediawiki.UtilitiesTime',
 28+ 'mediawiki.Uri',
2629
2730 // Sub classes:
2831 'MediaElement',
@@ -30,6 +33,7 @@
3134 'mw.EmbedTypes',
3235
3336 // jQuery dependencies:
 37+ 'jquery.client',
3438 'jquery.hoverIntent',
3539 'jquery.cookie',
3640 'jquery.ui.mouse',
Index: trunk/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/tests/Player_Seek.html
@@ -14,8 +14,8 @@
1515 <script type="text/javascript">
1616 mw.ready( function(){
1717 // check for hash:
18 - var urlParts = mw.parseUri( document.URL);
19 - if( urlParts.anchor ){
 18+ var urlParts = new mw.Uri( document.URL);
 19+ if( urlParts.fragment ){
2020 // run the start offset:
2121 var startTime = urlParts.anchor.split('=')[1];
2222
Index: trunk/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/tests/Player_ServerSeek.html
@@ -13,8 +13,8 @@
1414 <script type="text/javascript">
1515 mw.ready( function(){
1616 // check for hash:
17 - var urlParts = mw.parseUri( document.URL);
18 - if( urlParts.anchor ){
 17+ var urlParts = new mw.Uri( document.URL );
 18+ if( urlParts.fragment ){
1919 // run the start offset:
2020 var startTime = urlParts.anchor.split('=')[1];
2121
Index: trunk/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/MediaElement.js
@@ -379,15 +379,13 @@
380380 /**
381381 * Get playable sources
382382 *
383 - * @returns {Array} of playable sources
 383+ * @returns {Array} of playable media sources
384384 */
385385 getPlayableSources: function() {
386386 var playableSources = [];
387387 for ( var i = 0; i < this.sources.length; i++ ) {
388388 if ( this.isPlayableType( this.sources[i].mimeType ) ) {
389389 playableSources.push( this.sources[i] );
390 - } else {
391 - mw.log( "type " + this.sources[i].mimeType + ' is not playable' );
392390 }
393391 };
394392 return playableSources;
Index: trunk/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayer.js
@@ -1160,7 +1160,7 @@
11611161
11621162 // Update Thumbnail for the "player"
11631163 this.updatePosterHTML();
1164 -
 1164+
11651165 // Add controls if enabled:
11661166 if ( this.controls ) {
11671167 this.controlBuilder.addControls();
Index: trunk/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/skins/mw.PlayerControlBuilder.js
@@ -717,7 +717,7 @@
718718
719719 mw.log('trigger::addControlBindingsEvent');
720720 $( embedPlayer ).trigger( 'addControlBindingsEvent');
721 -
 721+
722722 // TODO should break out all control components into their own class and have them work with bindings
723723 $( embedPlayer ).bind('SourceChange', function(){
724724 if( _this.supportedComponets['sourceSwitch'] ){
@@ -1526,7 +1526,7 @@
15271527 */
15281528 showDownloadWithSources : function( $target ) {
15291529 var _this = this;
1530 - mw.log( 'showDownloadWithSources::' + $target.length );
 1530+ mw.log( 'PlayerControlBuilder::showDownloadWithSources::' + $target.length );
15311531 var embedPlayer = this.embedPlayer;
15321532 // Empty the target:
15331533 $target.empty();
@@ -1535,7 +1535,7 @@
15361536 var $textList = $( '<ul />' );
15371537 $j.each( embedPlayer.mediaElement.getSources(), function( index, source ) {
15381538 if( source.getSrc() ) {
1539 - mw.log("showDownloadWithSources:: Add src: " + source.getTitle() );
 1539+ mw.log("PlayerControlBuilder::showDownloadWithSources:: Add src: " + source.getTitle() );
15401540 var $dl_line = $( '<li />').append(
15411541 $('<a />')
15421542 .attr( 'href', source.getSrc() )
@@ -1556,6 +1556,7 @@
15571557
15581558 }
15591559 } );
 1560+
15601561 if( $mediaList.find('li').length != 0 ) {
15611562 $target.append(
15621563 $('<h2 />')
Index: trunk/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerJava.js
@@ -106,8 +106,8 @@
107107 ||
108108 mw.getConfig( 'relativeCortadoAppletPath' ) === false )
109109 ){
110 - if ( window.cortadoDomainLocations[ mw.parseUri( mediaSrc ).host ] ) {
111 - appletLoc = window.cortadoDomainLocations[ mw.parseUri( mediaSrc ).host ];
 110+ if ( window.cortadoDomainLocations[ new mw.Uri( mediaSrc ).host ] ) {
 111+ appletLoc = window.cortadoDomainLocations[ new mw.Uri( mediaSrc ).host ];
112112 } else {
113113 appletLoc = 'http://theora.org/cortado.jar';
114114 }
Index: trunk/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/MediaSource.js
@@ -78,8 +78,8 @@
7979 // Set default URLTimeEncoding if we have a time url:
8080 // not ideal way to discover if content is on an oggz_chop server.
8181 // should check some other way.
82 - var pUrl = mw.parseUri ( this.src );
83 - if ( typeof pUrl[ 'queryKey' ][ 't' ] != 'undefined' ) {
 82+ var pUrl = new mw.Uri ( this.src );
 83+ if ( typeof pUrl.query[ 't' ] != 'undefined' ) {
8484 this.URLTimeEncoding = true;
8585 }
8686
@@ -263,11 +263,13 @@
264264 break;
265265 }
266266
267 - // Return tilte based on file name:
268 - var urlParts = mw.parseUri( this.getSrc() );
269 - if( urlParts.file ){
270 - return urlParts.file;
271 - }
 267+ // Return title based on file name:
 268+ try{
 269+ var fileName = new mw.Uri( this.getSrc() ).path.split('/').pop();
 270+ if( fileName ){
 271+ return fileName;
 272+ }
 273+ } catch(e){}
272274
273275 // Return the mime type string if not known type.
274276 return this.mimeType;
@@ -282,9 +284,9 @@
283285 getURLDuration : function() {
284286 // check if we have a URLTimeEncoding:
285287 if ( this.URLTimeEncoding ) {
286 - var annoURL = mw.parseUri( this.src );
287 - if ( annoURL.queryKey.t ) {
288 - var times = annoURL.queryKey.t.split( '/' );
 288+ var annoURL = new mw.Uri( this.src );
 289+ if ( annoURL.query.t ) {
 290+ var times = annoURL.query.t.split( '/' );
289291 this.start_npt = times[0];
290292 this.end_npt = times[1];
291293 this.startOffset = mw.npt2seconds( this.start_npt );
@@ -313,9 +315,14 @@
314316 // we can issue a HEAD request and read the mime type of the media...
315317 // ( this will detect media mime type independently of the url name )
316318 // http://www.jibbering.com/2002/4/httprequest.html
317 - var urlParts = mw.parseUri( uri );
 319+ var ext ='';
 320+ try{
 321+ ext = /[^.]+$/.exec( new mw.Uri( uri ).path );
 322+ } catch ( e){
 323+ ext = /[^.]+$/.exec( uri );
 324+ };
 325+
318326 // Get the extension from the url or from the relative name:
319 - var ext = ( urlParts.file )? /[^.]+$/.exec( urlParts.file ) : /[^.]+$/.exec( uri );
320327 switch( ext.toString().toLowerCase() ) {
321328 case 'smil':
322329 case 'sml':
Index: trunk/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/iframeApi/mw.IFramePlayerApiClient.js
@@ -25,8 +25,8 @@
2626 this.iframe = iframe;
2727 this.playerProxy = playerProxy;
2828 // Set the iframe server
29 - var srcParts = mw.parseUri( mw.absoluteUrl( $(this.iframe).attr('src') ) );
30 - this.iframeServer = srcParts.protocol + '://' + srcParts.authority;
 29+ var srcParts = new mw.Uri( mw.absoluteUrl( $(this.iframe).attr('src') ) );
 30+ this.iframeServer = srcParts.protocol + '://' + srcParts.getAuthority();
3131
3232 this.addPlayerSendApi();
3333 this.addPlayerReciveApi();
Index: trunk/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/iframeApi/mw.IFramePlayerApiServer.js
@@ -202,7 +202,7 @@
203203 }
204204 // @@FIXME we should also check protocol to avoid
205205 // http vs https
206 - var originDomain = mw.parseUri( origin ).host;
 206+ var originDomain = new mw.Uri( origin ).host;
207207
208208 // Check the domains:
209209 for ( var i =0; i < domainWhiteList.length; i++ ) {
Index: trunk/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerKplayer.js
@@ -40,7 +40,7 @@
4141 flashvars.entryId = mw.absoluteUrl(_this.getSrc());
4242
4343 // Use a relative url if the protocal is file://
44 - if (mw.parseUri(document.URL).protocol == 'file') {
 44+ if ( new mw.Uri( document.URL ).protocol == 'file' ) {
4545 playerPath = mw.getRelativeMwEmbedPath() + 'modules/EmbedPlayer/binPlayers/kaltura-player';
4646 flashvars.entryId = _this.getSrc();
4747 }
Index: trunk/extensions/MwEmbedSupport/MwEmbedModules/MediaWikiSupport/resources/mw.Api.js
@@ -241,7 +241,7 @@
242242 * false if the domain is
243243 */
244244 mw.isLocalDomain = function( url ) {
245 - if( mw.parseUri( document.URL ).host == mw.parseUri( url ).host
 245+ if( new mw.Uri( document.URL ).host == new mw.Uri( url ).host
246246 || url.indexOf( '://' ) == -1 )
247247 {
248248 return true;
Index: trunk/extensions/MwEmbedSupport/MwEmbedModules/MediaWikiSupport/resources/MediaWikiPlayerSupport.js
@@ -18,7 +18,7 @@
1919 });
2020
2121 /**
22 - * Master function to add mediaWiki support to embedPlayer
 22+ * Closure function wraps mediaWiki embedPlayer bindings
2323 */
2424 mw.addMediaWikiPlayerSupport = function( embedPlayer ){
2525
@@ -108,13 +108,13 @@
109109 *
110110 * TODO parse the resource page template
111111 *
112 - * @parm {String} wikiText Resource wiki text page contents
 112+ * @parm {String} resourceHTML Resource wiki text page contents
113113 */
114 - function doCreditLine( articleUrl ){
115 - // Get the title str
116 - var titleStr = apiTitleKey.replace(/_/g, ' ');
 114+ function doCreditLine( resourceHTML, articleUrl ){
 115+ // Get the title string ( again a "Title" like js object could help out here. )
 116+ var titleStr = embedPlayer.apiTitleKey.replace(/_/g, ' ');
117117
118 - var imgWidth = ( embedPlayer.controlBuilder.getOverlayWidth() < 250 )? 45 : 90;
 118+ var imgWidth = ( embedPlayer.controlBuilder.getOverlayWidth() < 250 )? 45 : 120;
119119
120120 return $( '<div/>' ).addClass( 'creditline' )
121121 .append(
@@ -160,26 +160,22 @@
161161 var apiUrl = mw.getApiProviderURL( apiProvider );
162162 var fileTitle = 'File:' + unescape( apiTitleKey).replace(/File:|Image:/, '');
163163
164 - // Get the image info
 164+ // Get the image page ( cache for 1 hour )
165165 var request = {
166 - 'prop' : 'imageinfo',
167 - 'titles' : fileTitle,
168 - 'iiprop' : 'url'
 166+ 'action': 'parse',
 167+ 'page': fileTitle,
 168+ 'smaxage' : 3600,
 169+ 'maxage' : 3600
169170 };
170171 var articleUrl = '';
171172 mw.getJSON( apiUrl, request, function( data ){
172 - if ( data.query.pages ) {
173 - for ( var i in data.query.pages ) {
174 - var imageProps = data.query.pages[i];
175 - // Check properties for "missing"
176 - if( imageProps.imageinfo && imageProps.imageinfo[0] && imageProps.imageinfo[0].descriptionurl ){
177 - $creditsCache = doCreditLine( imageProps.imageinfo[0].descriptionurl );
178 - // Found page
179 - $target.html( $creditsCache );
180 - callback( true );
181 - return ;
182 - }
183 - }
 173+ descUrl = apiUrl.replace( 'api.php', 'index.php');
 174+ descUrl+= '?title=' + fileTitle;
 175+ if ( data && data.parse && data.parse.text && data.parse.text['*'] ) {
 176+ // TODO improve provider 'concept' to support page title link genneration
 177+ $creditsCache = doCreditLine( data.parse.text['*'], descUrl );
 178+ } else {
 179+ $creditsCache = doCreditLine( false, descUrl)
184180 }
185181 // failed
186182 callback( false );
Index: trunk/extensions/MwEmbedSupport/MwEmbedModules/MwEmbedSupport/mediawiki.language.parser.js
@@ -1,241 +0,0 @@
2 -/**
3 -* Mediawiki language text parser for handling mediawiki style {{PLURAL}} i81n template substitution
4 -* and basic [$1 link text] substitution.
5 -*
6 -* XXXXXXXXXXXXXXXX
7 -* XXX This should be replaced by the "peg based parser Neil is working on"
8 -* XXXXXXXXXXXXXXX
9 -*/
10 -
11 -/**
12 -* MediaWiki wikitext "Parser" constructor
13 -*
14 -* @param {String} wikiText the wikitext to be parsed
15 -* @return {Object} parserObj returns a parser object that has methods:
16 -* getHtml() which returns the html representation of the text
17 -*/
18 -mediaWiki.language.parser = function( wikiText, options) {
19 - // return the parserObj
20 - this.init( wikiText, options );
21 -};
22 -
23 -mediaWiki.language.parser.prototype = {
24 - // The parser output string ( lazy init )
25 - '_htmlOutput': false,
26 -
27 - // The wiki text to be parsed ( required parameter of the constructor )
28 - '_wikiText' : '',
29 -
30 - // The default parser options
31 - '_defaultParserOptions' : {
32 - /**
33 - * Name template processors ( like PLURAL, GENDER )
34 - *
35 - * Magic named templates are passed off to their associated function
36 - *
37 - * Dependent functions should be defined BEFORE the parser is included, or
38 - * passed into the parser as part of the runtime options
39 - */
40 - 'templateProcessors' : {
41 - 'PLURAL' : mw.language.pluralProcessor
42 - }
43 - },
44 -
45 - // Internal parser options ( set via parserOptions argument and default parser options )
46 - '_options' : {},
47 -
48 - /**
49 - * constructor
50 - */
51 - 'init' : function( wikiText, parserOptions ) {
52 - this._wikiText = wikiText;
53 - this.options = $.extend( this._defaultParserOptions, parserOptions);
54 - },
55 -
56 - /**
57 - * Update the wiki text value and invalidate the cache
58 - *
59 - * @param {string} wikiText
60 - * The wiki text string the parser works on.
61 - */
62 - 'updateText' : function( wikiText ) {
63 - this._wikiText = wikiText;
64 -
65 - // Invalidate the output ( will force a re-parse )
66 - this._htmlOutput = false;
67 - },
68 -
69 - /**
70 - * Recursively parse out template:
71 - *
72 - * contains a few local scope helper functions:
73 - */
74 - 'parse': function() {
75 - var _this = this;
76 -
77 - // Setup local swap string constants
78 - var JQUERY_SWAP_STRING = 'ZjQuerySwapZ';
79 - var LINK_SWAP_STRING = 'ZreplaceZ';
80 -
81 - // Local scope functions for parser:
82 -
83 - /**
84 - * Recurse through text and tokenize the open and close templates into "node" objects
85 - */
86 - function recurseTokenizeNodes ( text ) {
87 - var node = { };
88 - //mw.log( 'recurseTokenizeNodes:' + text );
89 - // Inspect each char
90 - for ( var a = 0; a < text.length; a++ ) {
91 - if ( text.charAt(a) == '{' && text.charAt(a + 1) == '{' ) {
92 - a = a + 2;
93 - node['parent'] = node;
94 - if ( !node['child'] ) {
95 - node['child'] = new Array();
96 - }
97 -
98 - node['child'].push( recurseTokenizeNodes( text.substr( a ) ) );
99 - } else if ( text.charAt(a) == '}' && text.charAt(a + 1) == '}' ) {
100 - a++;
101 - if ( !node['parent'] ) {
102 - return node;
103 - }
104 - node = node['parent'];
105 - }
106 - if ( !node['text'] ) {
107 - node['text'] = '';
108 - }
109 - // Don't put }} closures into output:
110 - if ( text.charAt(a) && text.charAt(a) != '}' ) {
111 - node['text'] += text.charAt(a);
112 - }
113 - }
114 - return node;
115 - }
116 -
117 - /**
118 - * Parse template text as template name and named params
119 - * @param {String} templateString Template String to be parsed
120 - */
121 - function parseTemplateText( templateString ) {
122 - var templateObject = { };
123 -
124 - //mw.log( 'parseTemplateText:' + templateString );
125 -
126 - // Get template name:
127 - templateName = templateString.split( '\|' ).shift() ;
128 - templateName = templateName.split( '\{' ).shift() ;
129 - templateName = templateName.replace( /^\s+|\s+$/g, "" ); //trim
130 -
131 - // Check for arguments:
132 - if ( templateName.split( ':' ).length == 1 ) {
133 - templateObject["name"] = templateName;
134 - } else {
135 - templateObject["name"] = templateName.split( ':' ).shift();
136 - templateObject["arg"] = templateName.split( ':' ).pop();
137 - }
138 -
139 - var paramSet = templateString.split( '\|' );
140 - paramSet.splice( 0, 1 );
141 - if ( paramSet.length ) {
142 - templateObject.parameters = new Array();
143 - for ( var pInx in paramSet ) {
144 - var paramString = paramSet[ pInx ];
145 - // check for empty param
146 - if ( paramString == '' ) {
147 - templateObject.parameters[ pInx ] = '';
148 - continue;
149 - }
150 - for ( var b = 0 ; b < paramString.length ; b++ ) {
151 - if ( paramString[b] == '=' && b > 0 && b < paramString.length && paramString[b - 1] != '\\' ) {
152 - // named param
153 - templateObject.parameters[ paramString.split( '=' ).shift() ] = paramString.split( '=' ).pop();
154 - } else {
155 - // indexed param
156 - templateObject.parameters[ pInx ] = paramString;
157 - }
158 - }
159 - }
160 - }
161 - return templateObject;
162 - }
163 -
164 - /**
165 - * Get template text using the templateProcesors
166 - */
167 - function getTextFromTemplateNode( node ) {
168 - node.templateObject = parseTemplateText ( node.text );
169 - // Do magic swap if template key found in this.options.templateProcessors
170 - if ( node.templateObject.name in _this.options.templateProcessors ) {
171 - var nodeText = _this.options.templateProcessors[ node.templateObject.name ]( node.templateObject );
172 - return nodeText;
173 - } else {
174 - // don't swap just return text
175 - return node.text;
176 - }
177 - };
178 -
179 - /**
180 - * recurse_magic_swap
181 - *
182 - * Go the inner most child first then swap upward:
183 - */
184 - var parentNode = null;
185 - function recurse_magic_swap( node ) {
186 - if ( !parentNode )
187 - parentNode = node;
188 -
189 - if ( node['child'] ) {
190 - // swap all the children:
191 - for ( var i in node['child'] ) {
192 - var nodeText = recurse_magic_swap( node['child'][i] );
193 - // swap it into current
194 - if ( node.text ) {
195 - node.text = node.text.replace( node['child'][i].text, nodeText );
196 - }
197 - // swap into parent
198 - parentNode.text = parentNode.text.replace( node['child'][i].text, nodeText );
199 - }
200 - // Get the updated node text
201 - var nodeText = getTextFromTemplateNode( node );
202 - parentNode.text = parentNode.text.replace( node.text , nodeText );
203 -
204 - // Return the node text
205 - return node.text;
206 - } else {
207 - return getTextFromTemplateNode( node );
208 - }
209 - }
210 -
211 - // Parse out the template node structure:
212 - this.parentNode = recurseTokenizeNodes ( this._wikiText );
213 -
214 - // Strip out the parent from the root
215 - this.parentNode['parent'] = null;
216 -
217 - // Do the recursive magic swap on the node structure
218 - this._htmlOutput = recurse_magic_swap( this.parentNode );
219 - },
220 -
221 - /**
222 - * Returns the transformed wikitext
223 - *
224 - * Build output from swappable index
225 - * (all transforms must be expanded in parse stage and linearly rebuilt)
226 - *
227 - * @@NOTE
228 - * Alternatively we could build output using a place-holder & replace system
229 - * (this lets us be slightly more sloppy with ordering and indexes, but probably slower)
230 - *
231 - * Ideal: we build a 'wiki DOM'
232 - * When editing you update the data structure directly
233 - * Then in output time you just go DOM->html-ish output without re-parsing the whole thing
234 - */
235 - 'getHTML': function() {
236 - // wikiText updates should invalidate _htmlOutput
237 - if ( ! this._htmlOutput ) {
238 - this.parse();
239 - }
240 - return this._htmlOutput;
241 - }
242 -};
\ No newline at end of file
Index: trunk/extensions/MwEmbedSupport/MwEmbedModules/MwEmbedSupport/MwEmbedSupport.php
@@ -29,7 +29,11 @@
3030 ),
3131 'messageFile' => 'MwEmbedSupport.i18n.php',
3232 ),
33 - 'mediawiki.language.parser' => array( 'scripts'=> 'mediawiki.language.parser.js' ),
 33+ 'mediawiki.UtilitiesTime' => array( 'scripts' => 'mediawiki/mediawiki.UtilitiesTime.js' ),
 34+ 'mediawiki.client' => array( 'scripts' => 'mediawiki/mediawiki.client.js' ),
 35+ 'mediawiki.Uri' => array( 'scripts' => 'mediawiki/mediawiki.Uri.js' ),
 36+
 37+ 'mediawiki.language.parser' => array( 'scripts'=> 'mediawiki/mediawiki.language.parser.js' ),
3438 'jquery.menu' => array(
3539 'scripts' => 'jquery.menu/jquery.menu.js',
3640 'styles' => 'jquery.menu/jquery.menu.css'
Index: trunk/extensions/MwEmbedSupport/MwEmbedModules/MwEmbedSupport/mediawiki/mediawiki.UtilitiesTime.js
@@ -0,0 +1,96 @@
 2+/**
 3+ * dependencies: [ mw ]
 4+ */
 5+( function( mw ) {
 6+
 7+ /**
 8+ * Given a float number of seconds, returns npt format response. ( ignore
 9+ * days for now )
 10+ *
 11+ * @param {Float}
 12+ * sec Seconds
 13+ * @param {Boolean}
 14+ * show_ms If milliseconds should be displayed.
 15+ * @return {Float} String npt format
 16+ */
 17+ mw.seconds2npt = function( sec, show_ms ) {
 18+ if ( isNaN( sec ) ) {
 19+ mw.log("Warning: trying to get npt time on NaN:" + sec);
 20+ return '0:00:00';
 21+ }
 22+
 23+ var tm = mw.seconds2Measurements( sec );
 24+
 25+ // Round the number of seconds to the required number of significant
 26+ // digits
 27+ if ( show_ms ) {
 28+ tm.seconds = Math.round( tm.seconds * 1000 ) / 1000;
 29+ } else {
 30+ tm.seconds = Math.round( tm.seconds );
 31+ }
 32+ if ( tm.seconds < 10 ){
 33+ tm.seconds = '0' + tm.seconds;
 34+ }
 35+ if( tm.hours == 0 ){
 36+ hoursStr = '';
 37+ } else {
 38+ if ( tm.minutes < 10 )
 39+ tm.minutes = '0' + tm.minutes;
 40+
 41+ hoursStr = tm.hours + ":";
 42+ }
 43+ return hoursStr + tm.minutes + ":" + tm.seconds;
 44+ };
 45+
 46+ /**
 47+ * Given seconds return array with 'days', 'hours', 'min', 'seconds'
 48+ *
 49+ * @param {float}
 50+ * sec Seconds to be converted into time measurements
 51+ */
 52+ mw.seconds2Measurements = function ( sec ){
 53+ var tm = {};
 54+ tm.days = Math.floor( sec / ( 3600 * 24 ) );
 55+ tm.hours = Math.floor( sec / 3600 );
 56+ tm.minutes = Math.floor( ( sec / 60 ) % 60 );
 57+ tm.seconds = sec % 60;
 58+ return tm;
 59+ };
 60+
 61+ /**
 62+ * Take hh:mm:ss,ms or hh:mm:ss.ms input, return the number of seconds
 63+ *
 64+ * @param {String}
 65+ * npt_str NPT time string
 66+ * @return {Float} Number of seconds
 67+ */
 68+ mw.npt2seconds = function ( npt_str ) {
 69+ if ( !npt_str ) {
 70+ // mw.log('npt2seconds:not valid ntp:'+ntp);
 71+ return 0;
 72+ }
 73+ // Strip {npt:}01:02:20 or 32{s} from time if present
 74+ npt_str = npt_str.replace( /npt:|s/g, '' );
 75+
 76+ var hour = 0;
 77+ var min = 0;
 78+ var sec = 0;
 79+
 80+ times = npt_str.split( ':' );
 81+ if ( times.length == 3 ) {
 82+ sec = times[2];
 83+ min = times[1];
 84+ hour = times[0];
 85+ } else if ( times.length == 2 ) {
 86+ sec = times[1];
 87+ min = times[0];
 88+ } else {
 89+ sec = times[0];
 90+ }
 91+ // Sometimes a comma is used instead of period for ms
 92+ sec = sec.replace( /,\s?/, '.' );
 93+ // Return seconds float
 94+ return parseInt( hour * 3600 ) + parseInt( min * 60 ) + parseFloat( sec );
 95+ };
 96+
 97+} )( window.mediaWiki );
\ No newline at end of file
Property changes on: trunk/extensions/MwEmbedSupport/MwEmbedModules/MwEmbedSupport/mediawiki/mediawiki.UtilitiesTime.js
___________________________________________________________________
Added: svn:mime-type
198 + text/plain
Index: trunk/extensions/MwEmbedSupport/MwEmbedModules/MwEmbedSupport/mediawiki/mediawiki.client.js
@@ -0,0 +1,118 @@
 2+/**
 3+ * mediawiki.client has some convenience functions for user agent checks
 4+ *
 5+ * TODO this should be combined with or bootstrap jquery.client.js
 6+ */
 7+( function( mw ) {
 8+
 9+ mw.isMobileDevice = function(){
 10+ return ( mw.isIphone() || mw.isIpod() || mw.isIpad() || mw.isAndroid2() )
 11+ },
 12+
 13+ mw.isIphone = function(){
 14+ return ( navigator.userAgent.indexOf('iPhone') != -1 && ! mw.isIpad() );
 15+ };
 16+
 17+ // Uses hack described at:
 18+ // http://www.bdoran.co.uk/2010/07/19/detecting-the-iphone4-and-resolution-with-javascript-or-php/
 19+ mw.isIphone4 = function(){
 20+ return ( mw.isIphone() && ( window.devicePixelRatio && window.devicePixelRatio >= 2 ) );
 21+ };
 22+ mw.isIpod = function(){
 23+ return ( navigator.userAgent.indexOf('iPod') != -1 );
 24+ };
 25+ mw.isIpad = function(){
 26+ return ( navigator.userAgent.indexOf('iPad') != -1 );
 27+ };
 28+
 29+ // Android 2 has some restrictions vs other mobile platforms
 30+ mw.isAndroid2 = function(){
 31+ return ( navigator.userAgent.indexOf( 'Android 2.') != -1 );
 32+ };
 33+
 34+ /**
 35+ * Fallforward system by default prefers flash.
 36+ *
 37+ * This is separate from the EmbedPlayer library detection to provide
 38+ * package loading control NOTE: should be phased out in favor of browser
 39+ * feature detection where possible
 40+ *
 41+ */
 42+ mw.isHTML5FallForwardNative = function(){
 43+ if( mw.isMobileHTML5() ){
 44+ return true;
 45+ }
 46+ // Check for url flag to force html5:
 47+ if( document.URL.indexOf('forceMobileHTML5') != -1 ){
 48+ return true;
 49+ }
 50+ // Fall forward native:
 51+ // if the browser supports flash ( don't use html5 )
 52+ if( mw.supportsFlash() ){
 53+ return false;
 54+ }
 55+ // No flash return true if the browser supports html5 video tag with
 56+ // basic support for canPlayType:
 57+ if( mw.supportsHTML5() ){
 58+ return true;
 59+ }
 60+
 61+ return false;
 62+ };
 63+
 64+ mw.isMobileHTML5 = function(){
 65+ // Check for a mobile html5 user agent:
 66+ if ( mw.isIphone() ||
 67+ mw.isIpod() ||
 68+ mw.isIpad() ||
 69+ mw.isAndroid2()
 70+ ){
 71+ return true;
 72+ }
 73+ return false;
 74+ };
 75+
 76+ mw.supportsHTML5 = function(){
 77+ // Blackberry is evil in its response to canPlayType calls.
 78+ if( navigator.userAgent.indexOf('BlackBerry') != -1 ){
 79+ return false ;
 80+ }
 81+ var dummyvid = document.createElement( "video" );
 82+ if( dummyvid.canPlayType ) {
 83+ return true;
 84+ }
 85+ return false;
 86+ };
 87+
 88+ mw.supportsFlash = function(){
 89+ // Check if the client does not have flash and has the video tag
 90+ if ( navigator.mimeTypes && navigator.mimeTypes.length > 0 ) {
 91+ for ( var i = 0; i < navigator.mimeTypes.length; i++ ) {
 92+ var type = navigator.mimeTypes[i].type;
 93+ var semicolonPos = type.indexOf( ';' );
 94+ if ( semicolonPos > -1 ) {
 95+ type = type.substr( 0, semicolonPos );
 96+ }
 97+ if (type == 'application/x-shockwave-flash' ) {
 98+ // flash is installed
 99+ return true;
 100+ }
 101+ }
 102+ }
 103+
 104+ // for IE:
 105+ var hasObj = true;
 106+ if( typeof ActiveXObject != 'undefined' ){
 107+ try {
 108+ var obj = new ActiveXObject( 'ShockwaveFlash.ShockwaveFlash' );
 109+ } catch ( e ) {
 110+ hasObj = false;
 111+ }
 112+ if( hasObj ){
 113+ return true;
 114+ }
 115+ }
 116+ return false;
 117+ };
 118+
 119+} )( window.mediaWiki );
\ No newline at end of file
Property changes on: trunk/extensions/MwEmbedSupport/MwEmbedModules/MwEmbedSupport/mediawiki/mediawiki.client.js
___________________________________________________________________
Added: svn:mime-type
1120 + text/plain
Index: trunk/extensions/MwEmbedSupport/MwEmbedModules/MwEmbedSupport/mediawiki/mediawiki.language.parser.js
@@ -0,0 +1,241 @@
 2+/**
 3+* Mediawiki language text parser for handling mediawiki style {{PLURAL}} i81n template substitution
 4+* and basic [$1 link text] substitution.
 5+*
 6+* XXXXXXXXXXXXXXXX
 7+* XXX This should be replaced by the "peg based parser Neil is working on"
 8+* XXXXXXXXXXXXXXX
 9+*/
 10+
 11+/**
 12+* MediaWiki wikitext "Parser" constructor
 13+*
 14+* @param {String} wikiText the wikitext to be parsed
 15+* @return {Object} parserObj returns a parser object that has methods:
 16+* getHtml() which returns the html representation of the text
 17+*/
 18+mediaWiki.language.parser = function( wikiText, options) {
 19+ // return the parserObj
 20+ this.init( wikiText, options );
 21+};
 22+
 23+mediaWiki.language.parser.prototype = {
 24+ // The parser output string ( lazy init )
 25+ '_htmlOutput': false,
 26+
 27+ // The wiki text to be parsed ( required parameter of the constructor )
 28+ '_wikiText' : '',
 29+
 30+ // The default parser options
 31+ '_defaultParserOptions' : {
 32+ /**
 33+ * Name template processors ( like PLURAL, GENDER )
 34+ *
 35+ * Magic named templates are passed off to their associated function
 36+ *
 37+ * Dependent functions should be defined BEFORE the parser is included, or
 38+ * passed into the parser as part of the runtime options
 39+ */
 40+ 'templateProcessors' : {
 41+ 'PLURAL' : mw.language.pluralProcessor
 42+ }
 43+ },
 44+
 45+ // Internal parser options ( set via parserOptions argument and default parser options )
 46+ '_options' : {},
 47+
 48+ /**
 49+ * constructor
 50+ */
 51+ 'init' : function( wikiText, parserOptions ) {
 52+ this._wikiText = wikiText;
 53+ this.options = $.extend( this._defaultParserOptions, parserOptions);
 54+ },
 55+
 56+ /**
 57+ * Update the wiki text value and invalidate the cache
 58+ *
 59+ * @param {string} wikiText
 60+ * The wiki text string the parser works on.
 61+ */
 62+ 'updateText' : function( wikiText ) {
 63+ this._wikiText = wikiText;
 64+
 65+ // Invalidate the output ( will force a re-parse )
 66+ this._htmlOutput = false;
 67+ },
 68+
 69+ /**
 70+ * Recursively parse out template:
 71+ *
 72+ * contains a few local scope helper functions:
 73+ */
 74+ 'parse': function() {
 75+ var _this = this;
 76+
 77+ // Setup local swap string constants
 78+ var JQUERY_SWAP_STRING = 'ZjQuerySwapZ';
 79+ var LINK_SWAP_STRING = 'ZreplaceZ';
 80+
 81+ // Local scope functions for parser:
 82+
 83+ /**
 84+ * Recurse through text and tokenize the open and close templates into "node" objects
 85+ */
 86+ function recurseTokenizeNodes ( text ) {
 87+ var node = { };
 88+ //mw.log( 'recurseTokenizeNodes:' + text );
 89+ // Inspect each char
 90+ for ( var a = 0; a < text.length; a++ ) {
 91+ if ( text.charAt(a) == '{' && text.charAt(a + 1) == '{' ) {
 92+ a = a + 2;
 93+ node['parent'] = node;
 94+ if ( !node['child'] ) {
 95+ node['child'] = new Array();
 96+ }
 97+
 98+ node['child'].push( recurseTokenizeNodes( text.substr( a ) ) );
 99+ } else if ( text.charAt(a) == '}' && text.charAt(a + 1) == '}' ) {
 100+ a++;
 101+ if ( !node['parent'] ) {
 102+ return node;
 103+ }
 104+ node = node['parent'];
 105+ }
 106+ if ( !node['text'] ) {
 107+ node['text'] = '';
 108+ }
 109+ // Don't put }} closures into output:
 110+ if ( text.charAt(a) && text.charAt(a) != '}' ) {
 111+ node['text'] += text.charAt(a);
 112+ }
 113+ }
 114+ return node;
 115+ }
 116+
 117+ /**
 118+ * Parse template text as template name and named params
 119+ * @param {String} templateString Template String to be parsed
 120+ */
 121+ function parseTemplateText( templateString ) {
 122+ var templateObject = { };
 123+
 124+ //mw.log( 'parseTemplateText:' + templateString );
 125+
 126+ // Get template name:
 127+ templateName = templateString.split( '\|' ).shift() ;
 128+ templateName = templateName.split( '\{' ).shift() ;
 129+ templateName = templateName.replace( /^\s+|\s+$/g, "" ); //trim
 130+
 131+ // Check for arguments:
 132+ if ( templateName.split( ':' ).length == 1 ) {
 133+ templateObject["name"] = templateName;
 134+ } else {
 135+ templateObject["name"] = templateName.split( ':' ).shift();
 136+ templateObject["arg"] = templateName.split( ':' ).pop();
 137+ }
 138+
 139+ var paramSet = templateString.split( '\|' );
 140+ paramSet.splice( 0, 1 );
 141+ if ( paramSet.length ) {
 142+ templateObject.parameters = new Array();
 143+ for ( var pInx in paramSet ) {
 144+ var paramString = paramSet[ pInx ];
 145+ // check for empty param
 146+ if ( paramString == '' ) {
 147+ templateObject.parameters[ pInx ] = '';
 148+ continue;
 149+ }
 150+ for ( var b = 0 ; b < paramString.length ; b++ ) {
 151+ if ( paramString[b] == '=' && b > 0 && b < paramString.length && paramString[b - 1] != '\\' ) {
 152+ // named param
 153+ templateObject.parameters[ paramString.split( '=' ).shift() ] = paramString.split( '=' ).pop();
 154+ } else {
 155+ // indexed param
 156+ templateObject.parameters[ pInx ] = paramString;
 157+ }
 158+ }
 159+ }
 160+ }
 161+ return templateObject;
 162+ }
 163+
 164+ /**
 165+ * Get template text using the templateProcesors
 166+ */
 167+ function getTextFromTemplateNode( node ) {
 168+ node.templateObject = parseTemplateText ( node.text );
 169+ // Do magic swap if template key found in this.options.templateProcessors
 170+ if ( node.templateObject.name in _this.options.templateProcessors ) {
 171+ var nodeText = _this.options.templateProcessors[ node.templateObject.name ]( node.templateObject );
 172+ return nodeText;
 173+ } else {
 174+ // don't swap just return text
 175+ return node.text;
 176+ }
 177+ };
 178+
 179+ /**
 180+ * recurse_magic_swap
 181+ *
 182+ * Go the inner most child first then swap upward:
 183+ */
 184+ var parentNode = null;
 185+ function recurse_magic_swap( node ) {
 186+ if ( !parentNode )
 187+ parentNode = node;
 188+
 189+ if ( node['child'] ) {
 190+ // swap all the children:
 191+ for ( var i in node['child'] ) {
 192+ var nodeText = recurse_magic_swap( node['child'][i] );
 193+ // swap it into current
 194+ if ( node.text ) {
 195+ node.text = node.text.replace( node['child'][i].text, nodeText );
 196+ }
 197+ // swap into parent
 198+ parentNode.text = parentNode.text.replace( node['child'][i].text, nodeText );
 199+ }
 200+ // Get the updated node text
 201+ var nodeText = getTextFromTemplateNode( node );
 202+ parentNode.text = parentNode.text.replace( node.text , nodeText );
 203+
 204+ // Return the node text
 205+ return node.text;
 206+ } else {
 207+ return getTextFromTemplateNode( node );
 208+ }
 209+ }
 210+
 211+ // Parse out the template node structure:
 212+ this.parentNode = recurseTokenizeNodes ( this._wikiText );
 213+
 214+ // Strip out the parent from the root
 215+ this.parentNode['parent'] = null;
 216+
 217+ // Do the recursive magic swap on the node structure
 218+ this._htmlOutput = recurse_magic_swap( this.parentNode );
 219+ },
 220+
 221+ /**
 222+ * Returns the transformed wikitext
 223+ *
 224+ * Build output from swappable index
 225+ * (all transforms must be expanded in parse stage and linearly rebuilt)
 226+ *
 227+ * @@NOTE
 228+ * Alternatively we could build output using a place-holder & replace system
 229+ * (this lets us be slightly more sloppy with ordering and indexes, but probably slower)
 230+ *
 231+ * Ideal: we build a 'wiki DOM'
 232+ * When editing you update the data structure directly
 233+ * Then in output time you just go DOM->html-ish output without re-parsing the whole thing
 234+ */
 235+ 'getHTML': function() {
 236+ // wikiText updates should invalidate _htmlOutput
 237+ if ( ! this._htmlOutput ) {
 238+ this.parse();
 239+ }
 240+ return this._htmlOutput;
 241+ }
 242+};
\ No newline at end of file
Property changes on: trunk/extensions/MwEmbedSupport/MwEmbedModules/MwEmbedSupport/mediawiki/mediawiki.language.parser.js
___________________________________________________________________
Added: svn:mime-type
1243 + text/plain
Added: svn:eol-style
2244 + native
Index: trunk/extensions/MwEmbedSupport/MwEmbedModules/MwEmbedSupport/mediawiki/mediawiki.Uri.js
@@ -0,0 +1,250 @@
 2+/**
 3+ * Library for simple URI parsing and manipulation. Requires jQuery.
 4+ *
 5+ * Do not expect full RFC 3986 compliance. Intended to be minimal, but featureful.
 6+ * The use cases we have in mind are constructing 'next page' or 'previous page' URLs,
 7+ * detecting whether we need to use cross-domain proxies for an API, constructing simple
 8+ * URL-based API calls, etc.
 9+ *
 10+ * Intended to compress very well if you use a JS-parsing minifier.
 11+ *
 12+ * Dependencies: mw, mw.Utilities, jQuery
 13+ *
 14+ * Example:
 15+ *
 16+ * var uri = new mw.Uri( 'http://foo.com/mysite/mypage.php?quux=2' );
 17+ *
 18+ * if ( uri.host == 'foo.com' ) {
 19+ * uri.host = 'www.foo.com';
 20+ * uri.extend( { bar: 1 } );
 21+ *
 22+ * $( 'a#id1' ).setAttr( 'href', uri );
 23+ * // anchor with id 'id1' now links to http://www.foo.com/mysite/mypage.php?bar=1&quux=2
 24+ *
 25+ * $( 'a#id2' ).setAttr( 'href', uri.clone().extend( { bar: 3, pif: 'paf' } ) );
 26+ * // anchor with id 'id2' now links to http://www.foo.com/mysite/mypage.php?bar=3&quux=2&pif=paf
 27+ * }
 28+ *
 29+ * Parsing here is regex based, so may not work on all URIs, but is good enough for most.
 30+ *
 31+ * Given a URI like
 32+ * 'http://usr:pwd@www.test.com:81/dir/dir.2/index.htm?q1=0&&test1&test2=value+%28escaped%29#top':
 33+ * The returned object will have the following properties:
 34+ *
 35+ * protocol 'http'
 36+ * user 'usr'
 37+ * password 'pwd'
 38+ * host 'www.test.com'
 39+ * port '81'
 40+ * path '/dir/dir.2/index.htm'
 41+ * query { q1: 0, test1: '', test2: 'value (escaped)' }
 42+ * fragment 'top'
 43+ *
 44+ * n.b. 'password' is not technically allowed for HTTP URIs, but it is possible with other sorts of URIs.
 45+ *
 46+ * You can modify the properties directly. Then use the toString() method to extract the full URI string again.
 47+ *
 48+ * parsing based on parseUri 1.2.2 (c) Steven Levithan <stevenlevithan.com> MIT License
 49+ * http://stevenlevithan.com/demo/parseuri/js/
 50+ *
 51+ */
 52+
 53+( function( mw, $ ) {
 54+ /**
 55+ * Constructs URI object. Throws error if arguments are illegal/impossible, or otherwise don't parse.
 56+ * @constructor
 57+ * @param {!Object|String} URI string, or an Object with appropriate properties (especially another URI object to clone). Object must have non-blank 'protocol', 'host', and 'path' properties.
 58+ * @param {Boolean} strict mode (when parsing a string)
 59+ */
 60+ mw.Uri = function( uri, strictMode ) {
 61+ strictMode = !!strictMode;
 62+ if ( mw.isFull( uri ) ) {
 63+ if ( typeof uri === 'string' ) {
 64+ this._parse( uri, strictMode );
 65+ } else if ( typeof uri === 'object' ) {
 66+ var _this = this;
 67+ $.each( this._properties, function( i, property ) {
 68+ _this[property] = uri[property];
 69+ } );
 70+ if ( ! mw.isDefined( this.query ) ) {
 71+ this.query = {};
 72+ }
 73+ }
 74+ }
 75+ //if ( !( this.protocol && this.host && this.path ) ) {
 76+ // throw new Error( "bad constructor arguments for " + uri);
 77+ //}
 78+ };
 79+
 80+ mw.Uri.prototype = {
 81+
 82+ /**
 83+ * Standard encodeURIComponent, with extra stuff to make all browsers work similarly and more compliant with RFC 3986
 84+ * @param {String} string
 85+ * @return {String} encoded for URI
 86+ */
 87+ encode: function( component ) {
 88+ return encodeURIComponent( component )
 89+ .replace( /!/g, '%21')
 90+ .replace( /'/g, '%27')
 91+ .replace( /\(/g, '%28')
 92+ .replace( /\)/g, '%29')
 93+ .replace( /\*/g, '%2A')
 94+ .replace( /%20/g, '+' );
 95+ },
 96+
 97+ /**
 98+ * Standard decodeURIComponent, with '+' to space
 99+ * @param {String} string encoded for URI
 100+ * @return {String} decoded string
 101+ */
 102+ decode: function( component ) {
 103+ return decodeURIComponent( component ).replace( /\+/g, ' ' );
 104+ },
 105+
 106+ // regular expressions to parse many common URIs.
 107+ // @private
 108+ _parser: {
 109+ strict: /^(?:([^:\/?#]+):)?(?:\/\/(?:(?:([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)?((?:[^?#\/]*\/)*[^?#]*)(?:\?([^#]*))?(?:#(.*))?/,
 110+ loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?(?:(?:([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?((?:\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?[^?#\/]*)(?:\?([^#]*))?(?:#(.*))?/
 111+ },
 112+
 113+ /* the order here matches the order of captured matches in the above parser regexes */
 114+ // @private
 115+ _properties: [
 116+ "protocol", // http
 117+ "user", // usr
 118+ "password", // pwd
 119+ "host", // www.test.com
 120+ "port", // 81
 121+ "path", // /dir/dir.2/index.htm
 122+ "query", // q1=0&&test1&test2=value (will become { q1: 0, test1: '', test2: 'value' } )
 123+ "fragment" // top
 124+ ],
 125+
 126+ /**
 127+ * Parse a string and set our properties accordingly.
 128+ * @param {String} URI
 129+ * @param {Boolean} strictness
 130+ * @return {Boolean} success
 131+ */
 132+ _parse: function( str, strictMode ) {
 133+ var matches = this._parser[ strictMode ? "strict" : "loose" ].exec( str );
 134+ var uri = this;
 135+ $.each( uri._properties, function( i, property ) {
 136+ uri[ property ] = matches[ i+1 ];
 137+ } );
 138+
 139+ // uri.query starts out as the query string; we will parse it into key-val pairs then make
 140+ // that object the "query" property.
 141+ // we overwrite query in uri way to make cloning easier, it can use the same list of properties.
 142+ var query = {};
 143+ // using replace to iterate over a string
 144+ // JS 1.3 - function as parameter to replace
 145+ // Note: uri does not work with repeated parameter names (e.g. foo=1&foo=2 )
 146+ if ( uri.query ) {
 147+ uri.query.replace( /(?:^|&)([^&=]*)=?([^&]*)/g, function ($0, $1, $2) {
 148+ if ( $1 ) {
 149+ query[ uri.decode( $1 ) ] = uri.decode( $2 );
 150+ }
 151+ } );
 152+ }
 153+ this.query = query;
 154+ },
 155+
 156+ /**
 157+ * Returns user and password portion of a URI.
 158+ * @return {String}
 159+ */
 160+ getUserInfo: function() {
 161+ var userInfo = '';
 162+ if ( mw.isFull( this.user ) ) {
 163+ userInfo += this.encode( this.user );
 164+ if ( mw.isFull( this.password ) ) {
 165+ userInfo += ':' + this.encode( this.password );
 166+ }
 167+ }
 168+ return userInfo;
 169+ },
 170+
 171+ /**
 172+ * Gets host and port portion of a URI.
 173+ * @return {String}
 174+ */
 175+ getHostPort: function() {
 176+ return this.host
 177+ + ( mw.isFull( this.port ) ? ':' + this.port
 178+ : ''
 179+ );
 180+ },
 181+
 182+ /**
 183+ * Returns the userInfo and host and port portion of the URI.
 184+ * In most real-world URLs, this is simply the hostname, but it is more general.
 185+ * @return {String}
 186+ */
 187+ getAuthority: function() {
 188+ var userInfo = this.getUserInfo();
 189+ return ( mw.isFull( userInfo ) ? userInfo + '@'
 190+ : ''
 191+ )
 192+ + this.getHostPort();
 193+ },
 194+
 195+ /**
 196+ * Returns the query arguments of the URL, encoded into a string
 197+ * Does not preserve the order of arguments passed into the URI. Does handle escaping.
 198+ * @return {String}
 199+ */
 200+ getQueryString: function() {
 201+ var pairs = [];
 202+ var _this = this;
 203+ $.each( this.query, function( key, value ) {
 204+ pairs.push( _this.encode( key ) + '=' + _this.encode( value ) );
 205+ } );
 206+ return pairs.join( '&' );
 207+ },
 208+
 209+ /**
 210+ * Returns everything after the authority section of the URI
 211+ * @return {String}
 212+ */
 213+ getRelativePath: function() {
 214+ var queryString = this.getQueryString();
 215+ return this.path
 216+ + ( mw.isFull( queryString ) ? '?' + queryString
 217+ : ''
 218+ )
 219+ + ( mw.isFull( this.fragment ) ? '#' + this.encode( this.fragment )
 220+ : ''
 221+ );
 222+ },
 223+
 224+ /**
 225+ * Gets the entire URI string. May not be precisely the same as input due to order of query arguments.
 226+ * @return {String} the URI string
 227+ */
 228+ toString: function() {
 229+ return this.protocol + '://' + this.getAuthority() + this.getRelativePath();
 230+ },
 231+
 232+ /**
 233+ * Clone this URI
 234+ * @return {Object} new URI object with same properties
 235+ */
 236+ clone: function() {
 237+ return new mw.Uri( this );
 238+ },
 239+
 240+ /**
 241+ * Extend the query -- supply query parameters to override or add to ours
 242+ * @param {Object} query parameters in key-val form to override or add
 243+ * @return {Object} this URI object
 244+ */
 245+ extend: function( parameters ) {
 246+ $.extend( this.query, parameters );
 247+ return this;
 248+ }
 249+ };
 250+
 251+} )( window.mediaWiki, jQuery );
Property changes on: trunk/extensions/MwEmbedSupport/MwEmbedModules/MwEmbedSupport/mediawiki/mediawiki.Uri.js
___________________________________________________________________
Added: svn:mime-type
1252 + text/plain
Index: trunk/extensions/MwEmbedSupport/MwEmbedModules/MwEmbedSupport/mediawiki/mediawiki.absoluteUrl.js
@@ -0,0 +1,47 @@
 2+
 3+( function( mw ) {
 4+ /**
 5+ * makeAbsolute takes makes the given
 6+ * document.URL or a contextUrl param
 7+ *
 8+ * @param {String}
 9+ * source path or url
 10+ * @param {String}
 11+ * contextUrl The domain / context for creating an absolute url
 12+ * from a relative path
 13+ * @return {=String} absolute url
 14+ */
 15+ mw.absoluteUrl = function( source, contextUrl ) {
 16+ var isAlreadyAbsolute = true;
 17+ try{
 18+ var parsedSrc = new mw.Uri( source );
 19+ } catch(e){
 20+ isAlreadyAbsolute = false;
 21+ };
 22+ // If source was parsed successfully return ( already absolute )
 23+ if( isAlreadyAbsolute ){
 24+ return source;
 25+ }
 26+
 27+ // Get parent Url location the context URL
 28+ if( !contextUrl ) {
 29+ contextUrl = document.URL;
 30+ }
 31+ var parsedUrl = new mw.Uri( contextUrl );
 32+
 33+ // Check for local windows file that does not flip the slashes:
 34+ if( parsedUrl.directory == '' && parsedUrl.protocol == 'file' ){
 35+ // pop off the file
 36+ var fileUrl = contextUrl.split( '\\');
 37+ fileUrl.pop();
 38+ return fileUrl.join('\\') + '\\' + src;
 39+ }
 40+ // Check for leading slash:
 41+ if( src.indexOf( '/' ) === 0 ) {
 42+ return parsedUrl.protocol + '://' + parsedUrl.authority + src;
 43+ }else{
 44+ return parsedUrl.protocol + '://' + parsedUrl.authority + parsedUrl.directory + src;
 45+ }
 46+ };
 47+
 48+} )( window.mediaWiki );
\ No newline at end of file
Property changes on: trunk/extensions/MwEmbedSupport/MwEmbedModules/MwEmbedSupport/mediawiki/mediawiki.absoluteUrl.js
___________________________________________________________________
Added: svn:mime-type
149 + text/plain
Index: trunk/extensions/MwEmbedSupport/MwEmbedModules/MwEmbedSupport/mwEmbedSupport.js
@@ -57,22 +57,20 @@
5858 mw.ready = function( callback ) {
5959 if( mw.interfacesReadyFlag === false ) {
6060 // Add the callbcak to the onLoad function stack
61 - $j( mw ).bind( 'InterfacesReady', callback );
 61+ $( mw ).bind( 'InterfacesReady', callback );
6262 } else {
6363 // If mwReadyFlag is already "true" issue the callback directly:
6464 callback();
6565 }
6666 };
 67+ // Once interfaces are ready update the mwReadyFlag
 68+ $( mw ).bind('InterfacesReady', function(){ mw.interfacesReadyFlag = true } );
6769
68 -
69 - // Once interfaces are ready update the mwReadyFlag
70 - $j( mw ).bind('InterfacesReady', function(){ mw.interfacesReadyFlag = true } );
71 -
7270 // Once the DOM is ready start setting up interfaces
73 - $j( document ).ready(function(){
74 - $j( mw ).triggerQueueCallback('SetupInterface', function(){
 71+ $( document ).ready(function(){
 72+ $( mw ).triggerQueueCallback('SetupInterface', function(){
7573 // All interfaces have been setup trigger InterfacesReady event
76 - $j( mw ).trigger( 'InterfacesReady' );
 74+ $( mw ).trigger( 'InterfacesReady' );
7775 });
7876 });
7977
@@ -103,7 +101,10 @@
104102 * legacy support to get the mwEmbed resource path:
105103 */
106104 mw.getMwEmbedPath = function(){
107 - return mediaWiki.config.get( 'wgLoadScript' ).replace('load.php', '');
 105+ if ( mediaWiki.config.get( 'wgLoadScript' ) ){
 106+ return mediaWiki.config.get( 'wgLoadScript' ).replace('load.php', '');
 107+ }
 108+ return false;
108109 };
109110
110111 /**
@@ -135,9 +136,64 @@
136137 };
137138
138139 /**
 140+ * Check if an object is empty or if its an empty string.
 141+ *
 142+ * @param {Object} object Object to be checked
 143+ * @return {Boolean}
 144+ */
 145+ mw.isEmpty = function( obj ) {
 146+ if( typeof obj === 'string' ) {
 147+ if( obj === '' ) return true;
 148+ // Non empty string:
 149+ return false;
 150+ }
 151+
 152+ // If an array check length:
 153+ if( Object.prototype.toString.call( obj ) === "[object Array]"
 154+ && obj.length === 0 ) {
 155+ return true;
 156+ }
 157+
 158+ // Else check as an obj:
 159+ for( var i in obj ) { return false; }
 160+
 161+ // Else obj is empty:
 162+ return true;
 163+ };
 164+
 165+ /**
 166+ * Opposite of mw.isEmpty
 167+ *
 168+ * @param {Object} object Object to be checked
 169+ * @return {Boolean}
 170+ */
 171+ mw.isFull = function( obj ) {
 172+ return ! mw.isEmpty( obj );
 173+ };
 174+
 175+ /**
 176+ * Check if something is defined
 177+ * (inlineable?)
 178+ * @param {Object}
 179+ * @return boolean
 180+ */
 181+ mw.isDefined = function( obj ) {
 182+ return typeof obj !== 'undefined';
 183+ };
 184+
 185+
 186+ /**
 187+ * Upper-case the first letter of a string.
 188+ * @param string
 189+ * @return string with first letter uppercased.
 190+ */
 191+ mw.ucfirst = function( s ) {
 192+ return s.substring(0,1).toUpperCase() + s.substr(1);
 193+ };
 194+
 195+ /**
139196 * gM ( get Message ) in js2 conflated jQuery return type with string return type
140 - * Do a legacy check for input paramaters this should be in favor
141 - * of calling the correct function.
 197+ * Do a legacy check for input paramaters and call the correct function.
142198 *
143199 * TODO Replace with new Neil's new parser functions
144200 */
@@ -233,71 +289,9 @@
234290
235291 /**
236292 * Utility Functions
237 - *
238 - * TOOD some of these utility functions are used in the upload Wizard, break them out into
239 - * associated files.
240293 */
241 - /**
242 - * parseUri 1.2.2 (c) Steven Levithan <stevenlevithan.com> MIT License
243 - */
244 - mw.parseUri = function (str) {
245 - var o = mw.parseUri.options,
246 - m = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
247 - uri = {},
248 - i = 14;
249294
250 - while (i--) uri[o.key[i]] = m[i] || "";
251 -
252 - uri[o.q.name] = {};
253 - uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
254 - if ($1) uri[o.q.name][$1] = $2;
255 - });
256 -
257 - return uri;
258 - };
259 -
260295 /**
261 - * getAbsoluteUrl takes a src and returns the absolute location given the
262 - * document.URL or a contextUrl param
263 - *
264 - * @param {String}
265 - * src path or url
266 - * @param {String}
267 - * contextUrl The domain / context for creating an absolute url
268 - * from a relative path
269 - * @return {String} absolute url
270 - */
271 - mw.absoluteUrl = function( src, contextUrl ) {
272 -
273 - var parsedSrc = mw.parseUri( src );
274 -
275 - // Source is already absolute return:
276 - if( parsedSrc.protocol != '') {
277 - return src;
278 - }
279 -
280 - // Get parent Url location the context URL
281 - if( !contextUrl ) {
282 - contextUrl = document.URL;
283 - }
284 - var parsedUrl = mw.parseUri( contextUrl );
285 -
286 - // Check for IE local file that does not flip the slashes
287 - if( parsedUrl.directory == '' && parsedUrl.protocol == 'file' ){
288 - // pop off the file
289 - var fileUrl = contextUrl.split( '\\');
290 - fileUrl.pop();
291 - return fileUrl.join('\\') + '\\' + src;
292 - }
293 -
294 - // Check for leading slash:
295 - if( src.indexOf( '/' ) === 0 ) {
296 - return parsedUrl.protocol + '://' + parsedUrl.authority + src;
297 - }else{
298 - return parsedUrl.protocol + '://' + parsedUrl.authority + parsedUrl.directory + src;
299 - }
300 - };
301 - /**
302296 * A version comparison utility function Handles version of types
303297 * {Major}.{MinorN}.{Patch}
304298 *
@@ -326,117 +320,8 @@
327321 return true;
328322 };
329323
330 - /**
331 - * Parse URI function
332 - *
333 - * For documentation on its usage see:
334 - * http://stevenlevithan.com/demo/parseuri/js/
335 - */
336 - mw.parseUri.options = {
337 - strictMode: false,
338 - key: ["source", "protocol", "authority", "userInfo", "user", "password", "host",
339 - "port", "relative", "path", "directory", "file", "query", "anchor"],
340 - q: {
341 - name: "queryKey",
342 - parser: /(?:^|&)([^&=]*)=?([^&]*)/g
343 - },
344 - parser: {
345 - strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
346 - loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
347 - }
348 - };
349324
350325 /**
351 - * Given a float number of seconds, returns npt format response. ( ignore
352 - * days for now )
353 - *
354 - * @param {Float}
355 - * sec Seconds
356 - * @param {Boolean}
357 - * show_ms If milliseconds should be displayed.
358 - * @return {Float} String npt format
359 - */
360 - mw.seconds2npt = function( sec, show_ms ) {
361 - if ( isNaN( sec ) ) {
362 - mw.log("Warning: trying to get npt time on NaN:" + sec);
363 - return '0:00:00';
364 - }
365 -
366 - var tm = mw.seconds2Measurements( sec );
367 -
368 - // Round the number of seconds to the required number of significant
369 - // digits
370 - if ( show_ms ) {
371 - tm.seconds = Math.round( tm.seconds * 1000 ) / 1000;
372 - } else {
373 - tm.seconds = Math.round( tm.seconds );
374 - }
375 - if ( tm.seconds < 10 ){
376 - tm.seconds = '0' + tm.seconds;
377 - }
378 - if( tm.hours == 0 ){
379 - hoursStr = '';
380 - } else {
381 - if ( tm.minutes < 10 )
382 - tm.minutes = '0' + tm.minutes;
383 -
384 - hoursStr = tm.hours + ":";
385 - }
386 - return hoursStr + tm.minutes + ":" + tm.seconds;
387 - };
388 -
389 - /**
390 - * Given seconds return array with 'days', 'hours', 'min', 'seconds'
391 - *
392 - * @param {float}
393 - * sec Seconds to be converted into time measurements
394 - */
395 - mw.seconds2Measurements = function ( sec ){
396 - var tm = {};
397 - tm.days = Math.floor( sec / ( 3600 * 24 ) );
398 - tm.hours = Math.floor( sec / 3600 );
399 - tm.minutes = Math.floor( ( sec / 60 ) % 60 );
400 - tm.seconds = sec % 60;
401 - return tm;
402 - };
403 -
404 - /**
405 - * Take hh:mm:ss,ms or hh:mm:ss.ms input, return the number of seconds
406 - *
407 - * @param {String}
408 - * npt_str NPT time string
409 - * @return {Float} Number of seconds
410 - */
411 - mw.npt2seconds = function ( npt_str ) {
412 - if ( !npt_str ) {
413 - // mw.log('npt2seconds:not valid ntp:'+ntp);
414 - return 0;
415 - }
416 - // Strip {npt:}01:02:20 or 32{s} from time if present
417 - npt_str = npt_str.replace( /npt:|s/g, '' );
418 -
419 - var hour = 0;
420 - var min = 0;
421 - var sec = 0;
422 -
423 - times = npt_str.split( ':' );
424 - if ( times.length == 3 ) {
425 - sec = times[2];
426 - min = times[1];
427 - hour = times[0];
428 - } else if ( times.length == 2 ) {
429 - sec = times[1];
430 - min = times[0];
431 - } else {
432 - sec = times[0];
433 - }
434 - // Sometimes a comma is used instead of period for ms
435 - sec = sec.replace( /,\s?/, '.' );
436 - // Return seconds float
437 - return parseInt( hour * 3600 ) + parseInt( min * 60 ) + parseFloat( sec );
438 - };
439 -
440 - /**
441326 * addLoaderDialog small helper for displaying a loading dialog
442327 *
443328 * @param {String}
@@ -446,7 +331,7 @@
447332 $dialog = mw.addDialog( {
448333 'title' : dialogHtml,
449334 'content' : dialogHtml + '<br>' +
450 - $j('<div />')
 335+ $('<div />')
451336 .loadingSpinner()
452337 .html()
453338 });
@@ -467,7 +352,7 @@
468353 */
469354 mw.addDialog = function ( options ) {
470355 // Remove any other dialog
471 - $j( '#mweDialog' ).remove();
 356+ $( '#mweDialog' ).remove();
472357
473358 if( !options){
474359 options = {};
@@ -487,8 +372,8 @@
488373 }
489374
490375 // Append the dialog div on top:
491 - $j( 'body' ).append(
492 - $j('<div />')
 376+ $( 'body' ).append(
 377+ $('<div />')
493378 .attr( {
494379 'id' : "mweDialog",
495380 'title' : options.title
@@ -513,7 +398,7 @@
514399 var buttonMsg = options.buttons;
515400 buttons = { };
516401 options.buttons[ buttonMsg ] = function() {
517 - $j( this ).dialog( 'close' );
 402+ $( this ).dialog( 'close' );
518403 };
519404 }
520405
@@ -524,126 +409,17 @@
525410 ],
526411 uiRequest
527412 ], function() {
528 - $j( '#mweDialog' ).dialog( options );
 413+ $( '#mweDialog' ).dialog( options );
529414 } );
530 - return $j( '#mweDialog' );
 415+ return $( '#mweDialog' );
531416 };
532417
533418 /**
534419 * Close the loader dialog created with addLoaderDialog
535420 */
536421 mw.closeLoaderDialog = function() {
537 - $j( '#mweDialog' ).dialog( 'destroy' ).remove();
 422+ $( '#mweDialog' ).dialog( 'destroy' ).remove();
538423 };
539424
540 - mw.isMobileDevice = function(){
541 - return ( mw.isIphone() || mw.isIpod() || mw.isIpad() || mw.isAndroid2() )
542 - },
543425
544 - // MOVE TO jquery.client
545 - // move to jquery.client
546 - mw.isIphone = function(){
547 - return ( navigator.userAgent.indexOf('iPhone') != -1 && ! mw.isIpad() );
548 - };
549 - // Uses hack described at:
550 - // http://www.bdoran.co.uk/2010/07/19/detecting-the-iphone4-and-resolution-with-javascript-or-php/
551 - mw.isIphone4 = function(){
552 - return ( mw.isIphone() && ( window.devicePixelRatio && window.devicePixelRatio >= 2 ) );
553 - };
554 - mw.isIpod = function(){
555 - return ( navigator.userAgent.indexOf('iPod') != -1 );
556 - };
557 - mw.isIpad = function(){
558 - return ( navigator.userAgent.indexOf('iPad') != -1 );
559 - };
560 - // Android 2 has some restrictions vs other mobile platforms
561 - mw.isAndroid2 = function(){
562 - return ( navigator.userAgent.indexOf( 'Android 2.') != -1 );
563 - };
564 -
565 - /**
566 - * Fallforward system by default prefers flash.
567 - *
568 - * This is separate from the EmbedPlayer library detection to provide
569 - * package loading control NOTE: should be phased out in favor of browser
570 - * feature detection where possible
571 - *
572 - */
573 - mw.isHTML5FallForwardNative = function(){
574 - if( mw.isMobileHTML5() ){
575 - return true;
576 - }
577 - // Check for url flag to force html5:
578 - if( document.URL.indexOf('forceMobileHTML5') != -1 ){
579 - return true;
580 - }
581 - // Fall forward native:
582 - // if the browser supports flash ( don't use html5 )
583 - if( mw.supportsFlash() ){
584 - return false;
585 - }
586 - // No flash return true if the browser supports html5 video tag with
587 - // basic support for canPlayType:
588 - if( mw.supportsHTML5() ){
589 - return true;
590 - }
591 -
592 - return false;
593 - };
594 -
595 - mw.isMobileHTML5 = function(){
596 - // Check for a mobile html5 user agent:
597 - if ( mw.isIphone() ||
598 - mw.isIpod() ||
599 - mw.isIpad() ||
600 - mw.isAndroid2()
601 - ){
602 - return true;
603 - }
604 - return false;
605 - };
606 - mw.supportsHTML5 = function(){
607 - // Blackberry is evil in its response to canPlayType calls.
608 - if( navigator.userAgent.indexOf('BlackBerry') != -1 ){
609 - return false ;
610 - }
611 - var dummyvid = document.createElement( "video" );
612 - if( dummyvid.canPlayType ) {
613 - return true;
614 - }
615 - return false;
616 - };
617 -
618 - mw.supportsFlash = function(){
619 - // Check if the client does not have flash and has the video tag
620 - if ( navigator.mimeTypes && navigator.mimeTypes.length > 0 ) {
621 - for ( var i = 0; i < navigator.mimeTypes.length; i++ ) {
622 - var type = navigator.mimeTypes[i].type;
623 - var semicolonPos = type.indexOf( ';' );
624 - if ( semicolonPos > -1 ) {
625 - type = type.substr( 0, semicolonPos );
626 - }
627 - if (type == 'application/x-shockwave-flash' ) {
628 - // flash is installed
629 - return true;
630 - }
631 - }
632 - }
633 -
634 - // for IE:
635 - var hasObj = true;
636 - if( typeof ActiveXObject != 'undefined' ){
637 - try {
638 - var obj = new ActiveXObject( 'ShockwaveFlash.ShockwaveFlash' );
639 - } catch ( e ) {
640 - hasObj = false;
641 - }
642 - if( hasObj ){
643 - return true;
644 - }
645 - }
646 - return false;
647 - };
648 -
649 -
650426 } )( mediaWiki, jQuery );
\ No newline at end of file

Status & tagging log