Index: trunk/extensions/TimedMediaHandler/WebVideoTranscode/WebVideoTranscodeJob.php |
— | — | @@ -107,7 +107,7 @@ |
108 | 108 | array( 'LIMIT' => $limit + 1 ) |
109 | 109 | ); |
110 | 110 | foreach ( $res as $page ) { |
111 | | - $title = Title::makeTitle( $element->page_namespace, $page->page_title ); |
| 111 | + $title = Title::makeTitle( $page->page_namespace, $page->page_title ); |
112 | 112 | $title->invalidateCache(); |
113 | 113 | } |
114 | 114 | } |
Index: trunk/extensions/TimedMediaHandler/TimedMediaHandler.hooks.php |
— | — | @@ -29,9 +29,7 @@ |
30 | 30 | 'webVideoTranscode' => 'WebVideoTranscodeJob' |
31 | 31 | ); |
32 | 32 | // Transcode jobs must be explicitly requested from the job queue: |
33 | | - $wgJobExplitRequestTypes+= array( |
34 | | - 'webVideoTranscode' |
35 | | - ); |
| 33 | + $wgJobExplitRequestTypes[] = 'webVideoTranscode'; |
36 | 34 | |
37 | 35 | $baseExtensionResource = array( |
38 | 36 | 'localBasePath' => dirname( __FILE__ ), |
— | — | @@ -49,6 +47,7 @@ |
50 | 48 | 'styles' => 'resources/embedPlayerIframe.css', |
51 | 49 | ) |
52 | 50 | ); |
| 51 | + |
53 | 52 | // We should probably move this to a parser function but not working correctly in |
54 | 53 | // dynamic contexts ( for example in special upload, when there is an "existing file" warning. ) |
55 | 54 | $wgHooks['BeforePageDisplay'][] = 'TimedMediaHandlerHooks::pageOutputHook'; |
— | — | @@ -56,10 +55,10 @@ |
57 | 56 | |
58 | 57 | // Exclude transcoded assets from normal thumbnail purging |
59 | 58 | // ( a mantaince script could handle transcode asset purging) |
60 | | - $wgExcludeFromThumbnailPurge += $wgTimedMediaHandlerFileExtensions; |
| 59 | + $wgExcludeFromThumbnailPurge = array_merge( $wgExcludeFromThumbnailPurge, $wgTimedMediaHandlerFileExtensions ); |
61 | 60 | // Also add the .log file ( used in two pass encoding ) |
62 | 61 | // ( probably should move in-progress encodes out of web accessible directory ) |
63 | | - $wgExcludeFromThumbnailPurge+= array( 'log'); |
| 62 | + $wgExcludeFromThumbnailPurge[] = 'log'; |
64 | 63 | |
65 | 64 | // Api hooks for derivatives and query video derivatives |
66 | 65 | $wgAPIPropModules += array( |
Index: trunk/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/EmbedPlayer.php |
— | — | @@ -22,6 +22,9 @@ |
23 | 23 | 'dependencies' => array( |
24 | 24 | // mwEmbed support module |
25 | 25 | 'mwEmbedSupport', |
| 26 | + 'mediawiki.client', |
| 27 | + 'mediawiki.UtilitiesTime', |
| 28 | + 'mediawiki.Uri', |
26 | 29 | |
27 | 30 | // Sub classes: |
28 | 31 | 'MediaElement', |
— | — | @@ -30,6 +33,7 @@ |
31 | 34 | 'mw.EmbedTypes', |
32 | 35 | |
33 | 36 | // jQuery dependencies: |
| 37 | + 'jquery.client', |
34 | 38 | 'jquery.hoverIntent', |
35 | 39 | 'jquery.cookie', |
36 | 40 | 'jquery.ui.mouse', |
Index: trunk/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/tests/Player_Seek.html |
— | — | @@ -14,8 +14,8 @@ |
15 | 15 | <script type="text/javascript"> |
16 | 16 | mw.ready( function(){ |
17 | 17 | // 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 ){ |
20 | 20 | // run the start offset: |
21 | 21 | var startTime = urlParts.anchor.split('=')[1]; |
22 | 22 | |
Index: trunk/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/tests/Player_ServerSeek.html |
— | — | @@ -13,8 +13,8 @@ |
14 | 14 | <script type="text/javascript"> |
15 | 15 | mw.ready( function(){ |
16 | 16 | // 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 ){ |
19 | 19 | // run the start offset: |
20 | 20 | var startTime = urlParts.anchor.split('=')[1]; |
21 | 21 | |
Index: trunk/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/MediaElement.js |
— | — | @@ -379,15 +379,13 @@ |
380 | 380 | /** |
381 | 381 | * Get playable sources |
382 | 382 | * |
383 | | - * @returns {Array} of playable sources |
| 383 | + * @returns {Array} of playable media sources |
384 | 384 | */ |
385 | 385 | getPlayableSources: function() { |
386 | 386 | var playableSources = []; |
387 | 387 | for ( var i = 0; i < this.sources.length; i++ ) { |
388 | 388 | if ( this.isPlayableType( this.sources[i].mimeType ) ) { |
389 | 389 | playableSources.push( this.sources[i] ); |
390 | | - } else { |
391 | | - mw.log( "type " + this.sources[i].mimeType + ' is not playable' ); |
392 | 390 | } |
393 | 391 | }; |
394 | 392 | return playableSources; |
Index: trunk/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayer.js |
— | — | @@ -1160,7 +1160,7 @@ |
1161 | 1161 | |
1162 | 1162 | // Update Thumbnail for the "player" |
1163 | 1163 | this.updatePosterHTML(); |
1164 | | - |
| 1164 | + |
1165 | 1165 | // Add controls if enabled: |
1166 | 1166 | if ( this.controls ) { |
1167 | 1167 | this.controlBuilder.addControls(); |
Index: trunk/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/skins/mw.PlayerControlBuilder.js |
— | — | @@ -717,7 +717,7 @@ |
718 | 718 | |
719 | 719 | mw.log('trigger::addControlBindingsEvent'); |
720 | 720 | $( embedPlayer ).trigger( 'addControlBindingsEvent'); |
721 | | - |
| 721 | + |
722 | 722 | // TODO should break out all control components into their own class and have them work with bindings |
723 | 723 | $( embedPlayer ).bind('SourceChange', function(){ |
724 | 724 | if( _this.supportedComponets['sourceSwitch'] ){ |
— | — | @@ -1526,7 +1526,7 @@ |
1527 | 1527 | */ |
1528 | 1528 | showDownloadWithSources : function( $target ) { |
1529 | 1529 | var _this = this; |
1530 | | - mw.log( 'showDownloadWithSources::' + $target.length ); |
| 1530 | + mw.log( 'PlayerControlBuilder::showDownloadWithSources::' + $target.length ); |
1531 | 1531 | var embedPlayer = this.embedPlayer; |
1532 | 1532 | // Empty the target: |
1533 | 1533 | $target.empty(); |
— | — | @@ -1535,7 +1535,7 @@ |
1536 | 1536 | var $textList = $( '<ul />' ); |
1537 | 1537 | $j.each( embedPlayer.mediaElement.getSources(), function( index, source ) { |
1538 | 1538 | if( source.getSrc() ) { |
1539 | | - mw.log("showDownloadWithSources:: Add src: " + source.getTitle() ); |
| 1539 | + mw.log("PlayerControlBuilder::showDownloadWithSources:: Add src: " + source.getTitle() ); |
1540 | 1540 | var $dl_line = $( '<li />').append( |
1541 | 1541 | $('<a />') |
1542 | 1542 | .attr( 'href', source.getSrc() ) |
— | — | @@ -1556,6 +1556,7 @@ |
1557 | 1557 | |
1558 | 1558 | } |
1559 | 1559 | } ); |
| 1560 | + |
1560 | 1561 | if( $mediaList.find('li').length != 0 ) { |
1561 | 1562 | $target.append( |
1562 | 1563 | $('<h2 />') |
Index: trunk/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerJava.js |
— | — | @@ -106,8 +106,8 @@ |
107 | 107 | || |
108 | 108 | mw.getConfig( 'relativeCortadoAppletPath' ) === false ) |
109 | 109 | ){ |
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 ]; |
112 | 112 | } else { |
113 | 113 | appletLoc = 'http://theora.org/cortado.jar'; |
114 | 114 | } |
Index: trunk/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/MediaSource.js |
— | — | @@ -78,8 +78,8 @@ |
79 | 79 | // Set default URLTimeEncoding if we have a time url: |
80 | 80 | // not ideal way to discover if content is on an oggz_chop server. |
81 | 81 | // 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' ) { |
84 | 84 | this.URLTimeEncoding = true; |
85 | 85 | } |
86 | 86 | |
— | — | @@ -263,11 +263,13 @@ |
264 | 264 | break; |
265 | 265 | } |
266 | 266 | |
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){} |
272 | 274 | |
273 | 275 | // Return the mime type string if not known type. |
274 | 276 | return this.mimeType; |
— | — | @@ -282,9 +284,9 @@ |
283 | 285 | getURLDuration : function() { |
284 | 286 | // check if we have a URLTimeEncoding: |
285 | 287 | 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( '/' ); |
289 | 291 | this.start_npt = times[0]; |
290 | 292 | this.end_npt = times[1]; |
291 | 293 | this.startOffset = mw.npt2seconds( this.start_npt ); |
— | — | @@ -313,9 +315,14 @@ |
314 | 316 | // we can issue a HEAD request and read the mime type of the media... |
315 | 317 | // ( this will detect media mime type independently of the url name ) |
316 | 318 | // 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 | + |
318 | 326 | // Get the extension from the url or from the relative name: |
319 | | - var ext = ( urlParts.file )? /[^.]+$/.exec( urlParts.file ) : /[^.]+$/.exec( uri ); |
320 | 327 | switch( ext.toString().toLowerCase() ) { |
321 | 328 | case 'smil': |
322 | 329 | case 'sml': |
Index: trunk/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/iframeApi/mw.IFramePlayerApiClient.js |
— | — | @@ -25,8 +25,8 @@ |
26 | 26 | this.iframe = iframe; |
27 | 27 | this.playerProxy = playerProxy; |
28 | 28 | // 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(); |
31 | 31 | |
32 | 32 | this.addPlayerSendApi(); |
33 | 33 | this.addPlayerReciveApi(); |
Index: trunk/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/iframeApi/mw.IFramePlayerApiServer.js |
— | — | @@ -202,7 +202,7 @@ |
203 | 203 | } |
204 | 204 | // @@FIXME we should also check protocol to avoid |
205 | 205 | // http vs https |
206 | | - var originDomain = mw.parseUri( origin ).host; |
| 206 | + var originDomain = new mw.Uri( origin ).host; |
207 | 207 | |
208 | 208 | // Check the domains: |
209 | 209 | for ( var i =0; i < domainWhiteList.length; i++ ) { |
Index: trunk/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerKplayer.js |
— | — | @@ -40,7 +40,7 @@ |
41 | 41 | flashvars.entryId = mw.absoluteUrl(_this.getSrc()); |
42 | 42 | |
43 | 43 | // 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' ) { |
45 | 45 | playerPath = mw.getRelativeMwEmbedPath() + 'modules/EmbedPlayer/binPlayers/kaltura-player'; |
46 | 46 | flashvars.entryId = _this.getSrc(); |
47 | 47 | } |
Index: trunk/extensions/MwEmbedSupport/MwEmbedModules/MediaWikiSupport/resources/mw.Api.js |
— | — | @@ -241,7 +241,7 @@ |
242 | 242 | * false if the domain is |
243 | 243 | */ |
244 | 244 | 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 |
246 | 246 | || url.indexOf( '://' ) == -1 ) |
247 | 247 | { |
248 | 248 | return true; |
Index: trunk/extensions/MwEmbedSupport/MwEmbedModules/MediaWikiSupport/resources/MediaWikiPlayerSupport.js |
— | — | @@ -18,7 +18,7 @@ |
19 | 19 | }); |
20 | 20 | |
21 | 21 | /** |
22 | | - * Master function to add mediaWiki support to embedPlayer |
| 22 | + * Closure function wraps mediaWiki embedPlayer bindings |
23 | 23 | */ |
24 | 24 | mw.addMediaWikiPlayerSupport = function( embedPlayer ){ |
25 | 25 | |
— | — | @@ -108,13 +108,13 @@ |
109 | 109 | * |
110 | 110 | * TODO parse the resource page template |
111 | 111 | * |
112 | | - * @parm {String} wikiText Resource wiki text page contents |
| 112 | + * @parm {String} resourceHTML Resource wiki text page contents |
113 | 113 | */ |
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, ' '); |
117 | 117 | |
118 | | - var imgWidth = ( embedPlayer.controlBuilder.getOverlayWidth() < 250 )? 45 : 90; |
| 118 | + var imgWidth = ( embedPlayer.controlBuilder.getOverlayWidth() < 250 )? 45 : 120; |
119 | 119 | |
120 | 120 | return $( '<div/>' ).addClass( 'creditline' ) |
121 | 121 | .append( |
— | — | @@ -160,26 +160,22 @@ |
161 | 161 | var apiUrl = mw.getApiProviderURL( apiProvider ); |
162 | 162 | var fileTitle = 'File:' + unescape( apiTitleKey).replace(/File:|Image:/, ''); |
163 | 163 | |
164 | | - // Get the image info |
| 164 | + // Get the image page ( cache for 1 hour ) |
165 | 165 | var request = { |
166 | | - 'prop' : 'imageinfo', |
167 | | - 'titles' : fileTitle, |
168 | | - 'iiprop' : 'url' |
| 166 | + 'action': 'parse', |
| 167 | + 'page': fileTitle, |
| 168 | + 'smaxage' : 3600, |
| 169 | + 'maxage' : 3600 |
169 | 170 | }; |
170 | 171 | var articleUrl = ''; |
171 | 172 | 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) |
184 | 180 | } |
185 | 181 | // failed |
186 | 182 | 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 @@ |
30 | 30 | ), |
31 | 31 | 'messageFile' => 'MwEmbedSupport.i18n.php', |
32 | 32 | ), |
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' ), |
34 | 38 | 'jquery.menu' => array( |
35 | 39 | 'scripts' => 'jquery.menu/jquery.menu.js', |
36 | 40 | '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 |
1 | 98 | + 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 |
1 | 120 | + 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 |
1 | 243 | + text/plain |
Added: svn:eol-style |
2 | 244 | + 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 |
1 | 252 | + 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 |
1 | 49 | + text/plain |
Index: trunk/extensions/MwEmbedSupport/MwEmbedModules/MwEmbedSupport/mwEmbedSupport.js |
— | — | @@ -57,22 +57,20 @@ |
58 | 58 | mw.ready = function( callback ) { |
59 | 59 | if( mw.interfacesReadyFlag === false ) { |
60 | 60 | // Add the callbcak to the onLoad function stack |
61 | | - $j( mw ).bind( 'InterfacesReady', callback ); |
| 61 | + $( mw ).bind( 'InterfacesReady', callback ); |
62 | 62 | } else { |
63 | 63 | // If mwReadyFlag is already "true" issue the callback directly: |
64 | 64 | callback(); |
65 | 65 | } |
66 | 66 | }; |
| 67 | + // Once interfaces are ready update the mwReadyFlag |
| 68 | + $( mw ).bind('InterfacesReady', function(){ mw.interfacesReadyFlag = true } ); |
67 | 69 | |
68 | | - |
69 | | - // Once interfaces are ready update the mwReadyFlag |
70 | | - $j( mw ).bind('InterfacesReady', function(){ mw.interfacesReadyFlag = true } ); |
71 | | - |
72 | 70 | // 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(){ |
75 | 73 | // All interfaces have been setup trigger InterfacesReady event |
76 | | - $j( mw ).trigger( 'InterfacesReady' ); |
| 74 | + $( mw ).trigger( 'InterfacesReady' ); |
77 | 75 | }); |
78 | 76 | }); |
79 | 77 | |
— | — | @@ -103,7 +101,10 @@ |
104 | 102 | * legacy support to get the mwEmbed resource path: |
105 | 103 | */ |
106 | 104 | 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; |
108 | 109 | }; |
109 | 110 | |
110 | 111 | /** |
— | — | @@ -135,9 +136,64 @@ |
136 | 137 | }; |
137 | 138 | |
138 | 139 | /** |
| 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 | + /** |
139 | 196 | * 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. |
142 | 198 | * |
143 | 199 | * TODO Replace with new Neil's new parser functions |
144 | 200 | */ |
— | — | @@ -233,71 +289,9 @@ |
234 | 290 | |
235 | 291 | /** |
236 | 292 | * Utility Functions |
237 | | - * |
238 | | - * TOOD some of these utility functions are used in the upload Wizard, break them out into |
239 | | - * associated files. |
240 | 293 | */ |
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; |
249 | 294 | |
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 | | - |
260 | 295 | /** |
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 | | - /** |
302 | 296 | * A version comparison utility function Handles version of types |
303 | 297 | * {Major}.{MinorN}.{Patch} |
304 | 298 | * |
— | — | @@ -326,117 +320,8 @@ |
327 | 321 | return true; |
328 | 322 | }; |
329 | 323 | |
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 | | - }; |
349 | 324 | |
350 | 325 | /** |
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 | | - /** |
441 | 326 | * addLoaderDialog small helper for displaying a loading dialog |
442 | 327 | * |
443 | 328 | * @param {String} |
— | — | @@ -446,7 +331,7 @@ |
447 | 332 | $dialog = mw.addDialog( { |
448 | 333 | 'title' : dialogHtml, |
449 | 334 | 'content' : dialogHtml + '<br>' + |
450 | | - $j('<div />') |
| 335 | + $('<div />') |
451 | 336 | .loadingSpinner() |
452 | 337 | .html() |
453 | 338 | }); |
— | — | @@ -467,7 +352,7 @@ |
468 | 353 | */ |
469 | 354 | mw.addDialog = function ( options ) { |
470 | 355 | // Remove any other dialog |
471 | | - $j( '#mweDialog' ).remove(); |
| 356 | + $( '#mweDialog' ).remove(); |
472 | 357 | |
473 | 358 | if( !options){ |
474 | 359 | options = {}; |
— | — | @@ -487,8 +372,8 @@ |
488 | 373 | } |
489 | 374 | |
490 | 375 | // Append the dialog div on top: |
491 | | - $j( 'body' ).append( |
492 | | - $j('<div />') |
| 376 | + $( 'body' ).append( |
| 377 | + $('<div />') |
493 | 378 | .attr( { |
494 | 379 | 'id' : "mweDialog", |
495 | 380 | 'title' : options.title |
— | — | @@ -513,7 +398,7 @@ |
514 | 399 | var buttonMsg = options.buttons; |
515 | 400 | buttons = { }; |
516 | 401 | options.buttons[ buttonMsg ] = function() { |
517 | | - $j( this ).dialog( 'close' ); |
| 402 | + $( this ).dialog( 'close' ); |
518 | 403 | }; |
519 | 404 | } |
520 | 405 | |
— | — | @@ -524,126 +409,17 @@ |
525 | 410 | ], |
526 | 411 | uiRequest |
527 | 412 | ], function() { |
528 | | - $j( '#mweDialog' ).dialog( options ); |
| 413 | + $( '#mweDialog' ).dialog( options ); |
529 | 414 | } ); |
530 | | - return $j( '#mweDialog' ); |
| 415 | + return $( '#mweDialog' ); |
531 | 416 | }; |
532 | 417 | |
533 | 418 | /** |
534 | 419 | * Close the loader dialog created with addLoaderDialog |
535 | 420 | */ |
536 | 421 | mw.closeLoaderDialog = function() { |
537 | | - $j( '#mweDialog' ).dialog( 'destroy' ).remove(); |
| 422 | + $( '#mweDialog' ).dialog( 'destroy' ).remove(); |
538 | 423 | }; |
539 | 424 | |
540 | | - mw.isMobileDevice = function(){ |
541 | | - return ( mw.isIphone() || mw.isIpod() || mw.isIpad() || mw.isAndroid2() ) |
542 | | - }, |
543 | 425 | |
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 | | - |
650 | 426 | } )( mediaWiki, jQuery ); |
\ No newline at end of file |