From b265151b57bb6d0d31a8be6ace52ee979954a893 Mon Sep 17 00:00:00 2001 From: Michael Dale Date: Mon, 15 Nov 2010 14:42:02 +0000 Subject: [PATCH] sync with mwEmbed ( mostly whitespace updates ) git-svn-id: http://www.kaltura.org/kalorg/html5video/trunk/mwEmbed@1179 b58a29cf-3064-46da-94c6-1c29cc75c8e5 --- ResourceLoader.php | 60 +- includes/NamedResourceLoader.php | 14 +- includes/noMediaWikiConfig.php | 8 +- loader.js | 121 +- modules/AddMedia/css/mw.style.AddMedia.css | 12 +- modules/AddMedia/jquery.dragDropFile.js | 20 +- modules/AddMedia/loader.js | 73 +- modules/AddMedia/mw.Firefogg.js | 418 +-- modules/AddMedia/mw.FirefoggGUI.js | 178 +- modules/AddMedia/mw.RemoteSearchDriver.js | 1409 ++++----- modules/AddMedia/mw.UploadForm.js | 432 +-- modules/AddMedia/mw.UploadHandler.js | 456 +-- modules/AddMedia/mw.UploadInterface.js | 196 +- .../AddMedia/searchLibs/archiveOrgSearch.js | 82 +- .../AddMedia/searchLibs/baseRemoteSearch.js | 262 +- modules/AddMedia/searchLibs/flickrSearch.js | 56 +- modules/AddMedia/searchLibs/kalturaSearch.js | 188 +- .../AddMedia/searchLibs/mediaWikiSearch.js | 198 +- modules/AddMedia/searchLibs/metavidSearch.js | 126 +- modules/AddMedia/tests/Add_Media_Wizard.html | 40 +- modules/AddMedia/tests/Firefogg_GUI.html | 88 +- modules/ApiProxy/ApiProxyPage.js | 10 +- modules/ApiProxy/NestedCallbackIframe.html | 2 +- modules/ApiProxy/loader.js | 16 +- modules/ApiProxy/mw.ApiProxy.js | 720 ++--- modules/ApiProxy/tests/testApiProxy.html | 84 +- modules/ClipEdit/ClipEdit.i18n.php | 180 +- modules/ClipEdit/loader.js | 6 +- modules/ClipEdit/mw.ClipEdit.js | 324 +-- modules/EmbedPlayer/EmbedPlayer.i18n.php | 185 +- modules/EmbedPlayer/loader.js | 347 +-- modules/EmbedPlayer/mw.EmbedPlayer.js | 2518 +++++++++-------- modules/EmbedPlayer/mw.EmbedPlayerGeneric.js | 16 +- modules/EmbedPlayer/mw.EmbedPlayerHtml.js | 124 +- modules/EmbedPlayer/mw.EmbedPlayerJava.js | 142 +- modules/EmbedPlayer/mw.EmbedPlayerKplayer.js | 83 +- modules/EmbedPlayer/mw.EmbedPlayerNative.js | 413 +-- modules/EmbedPlayer/mw.EmbedPlayerVlc.js | 154 +- .../EmbedPlayer/mw.IFramePlayerApiClient.js | 170 +- .../EmbedPlayer/mw.IFramePlayerApiServer.js | 178 +- .../skins/kskin/mw.PlayerSkinKskin.js | 320 ++- .../skins/kskin/mw.style.PlayerSkinKskin.css | 39 +- .../skins/mvpcf/mw.style.PlayerSkinMvpcf.css | 26 +- .../skins/mw.PlayerControlBuilder.js | 1091 ++++--- .../skins/mw.style.EmbedPlayer.css | 2 +- .../tests/Player_HTML5_Bindings.html | 48 - .../tests/Player_IncludeJQuery.html | 6 +- modules/EmbedPlayer/tests/Player_Sources.html | 17 +- .../EmbedPlayer/tests/Player_Themable.html | 44 +- modules/MiroSubs/MiroSubs.i18n.php | 4 +- modules/MiroSubs/README | 13 + .../css/universal-subs-icon-small.png | Bin 0 -> 701 bytes modules/MiroSubs/loader.js | 46 +- modules/MiroSubs/mw.MiroSubsConfig.js | 147 +- modules/PlayerThemer/loader.js | 21 +- modules/PlayerThemer/mw.PlayerThemer.js | 168 +- modules/Playlist/loader.js | 42 +- modules/Playlist/mw.Playlist.js | 471 ++- .../Playlist/mw.PlaylistHandlerMediaRss.js | 61 +- modules/Playlist/tests/Player_MediaRss.html | 26 +- .../actions/mw.SequencerActionsEdit.js | 84 +- .../actions/mw.SequencerActionsSequence.js | 266 +- .../actions/mw.SequencerActionsView.js | 93 +- modules/Sequencer/css/mw.style.Sequencer.css | 33 +- modules/Sequencer/loader.js | 99 +- modules/Sequencer/mw.FirefoggRender.js | 152 +- modules/Sequencer/mw.Sequencer.js | 170 +- modules/Sequencer/mw.SequencerAddByUri.js | 94 +- modules/Sequencer/mw.SequencerAddMedia.js | 166 +- modules/Sequencer/mw.SequencerConfig.js | 47 +- modules/Sequencer/mw.SequencerKeyBindings.js | 20 +- modules/Sequencer/mw.SequencerMenu.js | 138 +- modules/Sequencer/mw.SequencerPlayer.js | 73 +- modules/Sequencer/mw.SequencerRender.js | 65 - modules/Sequencer/mw.SequencerServer.js | 246 +- modules/Sequencer/mw.SequencerTimeline.js | 550 ++-- .../remotes/mw.MediaWikiRemoteSequencer.js | 300 +- .../remotes/mw.style.SequencerRemote.css | 6 +- modules/Sequencer/tools/mw.SequencerTools.js | 789 +++--- modules/SmilPlayer/loader.js | 38 +- modules/SmilPlayer/mw.EmbedPlayerSmil.js | 260 +- modules/SmilPlayer/mw.Smil.js | 152 +- modules/SmilPlayer/mw.SmilAnimate.js | 404 +-- modules/SmilPlayer/mw.SmilBody.js | 290 +- modules/SmilPlayer/mw.SmilBuffer.js | 306 +- modules/SmilPlayer/mw.SmilHooks.js | 36 +- modules/SmilPlayer/mw.SmilLayout.js | 582 ++-- modules/SmilPlayer/mw.SmilTransitions.js | 136 +- modules/SmilPlayer/mw.style.SmilLayout.css | 3 +- modules/SwarmTransport/loader.js | 30 +- .../SwarmTransport/mw.EmbedPlayerSwarmVlc.js | 16 +- modules/SwarmTransport/mw.SwarmTransport.js | 108 +- .../tests/SwarmTransport_CommonsApi.html | 44 +- .../tests/SwarmTransprot_Url.html | 44 +- modules/TimedText/TimedText.i18n.php | 2 +- modules/TimedText/css/mw.style.TimedText.css | 10 +- .../TimedText/css/mw.style.TimedTextEdit.css | 168 +- modules/TimedText/loader.js | 70 +- modules/TimedText/mw.TimedText.js | 748 ++--- modules/TimedText/mw.TimedTextEdit.js | 208 +- .../TimedText/remotes/RemoteMwTimedText.js | 104 +- .../TimedText/tests/Player_Timed_Text.html | 244 +- mwEmbed.i18n.php | 2 +- mwEmbed.js | 1437 +++++----- mwEmbedFrame.php | 136 +- remotes/AddMediaWizardEditPage.js | 74 +- remotes/mediaWiki.js | 430 ++- remotes/uploadPage.js | 42 +- skins/common/mw.style.mwCommon.css | 48 +- 109 files changed, 11139 insertions(+), 11125 deletions(-) delete mode 100644 modules/EmbedPlayer/tests/Player_HTML5_Bindings.html create mode 100644 modules/MiroSubs/README create mode 100644 modules/MiroSubs/css/universal-subs-icon-small.png delete mode 100644 modules/Sequencer/mw.SequencerRender.js diff --git a/ResourceLoader.php b/ResourceLoader.php index e6ab5926fd..52e5d9115c 100644 --- a/ResourceLoader.php +++ b/ResourceLoader.php @@ -16,9 +16,9 @@ // Check if we are an entry point or being used as part of MEDIAWIKI: if ( !defined( 'MEDIAWIKI' ) && !defined( 'SCRIPTLOADER_MEDIAWIKI') ) { - // Allow an installation an optional PHP customization/overrides file + // Allow an installation an optional PHP customization/overrides file if ( is_file ( dirname( __FILE__ ) .'/../localSettings.php' ) ) { - require_once dirname( __FILE__ ) .'/../localSettings.php'; + require_once dirname( __FILE__ ) .'/../localSettings.php'; } // Load stand alone Resource Loader config @@ -122,9 +122,9 @@ function doResourceLoader() { // Setup script loader header ( to easy identify file data ) if( $this->outputFormat == 'js' ) { $this->output .= 'var mwResourceLoaderDate = "' . - xml::escapeJsString( date( 'c' ) ) . '";' . "\n"; + xml::escapeJsString( date( 'c' ) ) . '";' . "\n"; $this->output .= 'var mwResourceLoaderRequestKey = "' . - xml::escapeJsString( $this->requestKey ) . '";' . "\n"; + xml::escapeJsString( $this->requestKey ) . '";' . "\n"; } // Build the output @@ -142,7 +142,7 @@ function doResourceLoader() { // MwEmbed is a core component so it includes loaders and other styles if( $resourceName == 'mwEmbed' && $this->outputFormat != 'messages' ){ // Output core components ( parts of core mwEmbed that are in different files ) - $coreComponentsList = NamedResourceLoader::getComponentsList(); + $coreComponentsList = NamedResourceLoader::getComponentsList(); foreach( $coreComponentsList as $componentClassName ) { // Output the core component via the script loader: $this->output .= $this->getLocalizedScriptText( $componentClassName ); @@ -156,24 +156,24 @@ function doResourceLoader() { // Output the current language resource js $this->output .= NamedResourceLoader::getLanguageJs( $this->langCode ); - + // Output the localSettings.js $localSettingsJsPath = realpath( dirname( __FILE__ ) ) . '/localSettings.js'; if( is_file( $localSettingsJsPath ) ){ wfSuppressWarnings(); $this->output .= file_get_contents( $localSettingsJsPath ); wfRestoreWarnings(); - } - - // Add the required core mwEmbed style sheets + } + + // Add the required core mwEmbed style sheets // removed for now because when creating stand alone packages js package with css // the paths get messed up. /*if( !isset( $this->namedFileList[ 'mw.style.mwCommon' ] ) ) { $this->output .= $this->getResourceText( 'mw.style.mwCommon' ); }*/ - // Output "special" IE comment tag to support video tags mwEmbed tags. - $this->notMinifiedTopOutput .= '/*@cc_on@if(@_jscript_version<9){\'video audio source track\'.replace(/\w+/g,function(n){document.createElement(n)})}@end@*/'."\n"; + // Output "special" IE comment tag to support "special" mwEmbed tags. + $this->notMinifiedTopOutput .='/*@cc_on@if(@_jscript_version<9){\'video audio source itext playlist\'.replace(/\w+/g,function(n){document.createElement(n)})}@end@*/'."\n"; } } @@ -232,7 +232,7 @@ static private function getOnDoneCallback( ){ * * @param {String} $js_string Javascript string to be minified * @param {String} $requestKey Unique key for minification - * @return minified javascript value + * @return minified javascript value */ static function getMinifiedJs( & $js_string, $requestKey='' ){ global $wgJavaPath, $wgClosureCompilerPath, $wgClosureCompilerLevel; @@ -274,14 +274,14 @@ static function getClosureMinifiedJs( & $js_string, $requestKey=''){ // Write the grouped javascript to a temporary file: // ( closure compiler does not support reading from standard in pipe ) $td = wfTempDir(); - $jsFileName = $td . '/' . md5( $requestKey ) . '.tmp.js'; - file_put_contents( $jsFileName, $js_string ); + $jsFileName = $td . '/' . md5( $requestKey ) . '.tmp.js'; + file_put_contents( $jsFileName, $js_string ); $retval = ''; $cmd = $wgJavaPath . ' -jar ' . $wgClosureCompilerPath; $cmd.= ' --js ' . $jsFileName; if( $wgClosureCompilerLevel ) - $cmd.= ' --compilation_level ' . wfEscapeShellArg( $wgClosureCompilerLevel ); + $cmd.= ' --compilation_level ' . wfEscapeShellArg( $wgClosureCompilerLevel ); // only output js ( no warnings ) $cmd.= ' --warning_level QUIET'; @@ -344,7 +344,7 @@ function getResourceText( $resourceName ){ } return $sk->generateUserJs( $titleParams[ 'useskin' ] ) . "\n"; } - } else if( isset( $titleParams['gen' ] ) && $titleParams['gen' ] == 'css' ) { + } else if( isset( $titleParams['gen' ] ) && $titleParams['gen' ] == 'css' ) { return $sk->generateUserStylesheet(); } } else { @@ -377,7 +377,7 @@ function getResourceText( $resourceName ){ $filePath = self::getPathFromClass( $resourceName ); if( ! $filePath ) { - $this->errorMsg .= "\nError could not get file path: ". xml::escapeJsString( $resourceName ) ."\n"; + $this->errorMsg .= "\nError could not get file path: ". xml::escapeJsString( $resourceName ) ."\n"; return false; } @@ -399,7 +399,7 @@ function getResourceText( $resourceName ){ return $output; }else{ - $this->errorMsg .= "\nError could not read file: ". xml::escapeJsString( $filePath ) ."\n"; + $this->errorMsg .= "\nError could not read file: ". xml::escapeJsString( $filePath ) ."\n"; return false; } } @@ -424,7 +424,7 @@ private function transformCssOutput( $resourceName, $cssString , $path ='') { // Using the local mediaWiki entry point we should have our $wgScriptPath global global $wgScriptPath; $prePendPath = ( $wgScriptPath == '' ) ? '' : $wgScriptPath . '/'; - $cssOptions[ 'prependRelativePath' ] = $prePendPath . dirname( $path ) . '/'; + $cssOptions[ 'prependRelativePath' ] = $prePendPath . dirname( $path ) . '/'; } else { // Get the server URL $serverUri = $this->getResourceLoaderUri(); @@ -630,7 +630,7 @@ function preProcRequestVars() { // Update the outupt format is "css", "messages" or "js" if( isset( $_GET['format'] ) && - ( $_GET['format'] == 'css' || $_GET['format'] == 'messages') + ( $_GET['format'] == 'css' || $_GET['format'] == 'messages') ){ $this->outputFormat = $_GET['format']; } else { @@ -670,10 +670,10 @@ function preProcRequestVars() { // Check for the requested classes if ( $reqClassList && count( $reqClassList ) > 0 ) { // Clean the resource list and populate namedFileList - foreach ( $reqClassList as $reqClass ) { + foreach ( $reqClassList as $reqClass ) { //do some simple checks: if ( trim( $reqClass ) != '' ){ - if( substr( $reqClass, 0, 3 ) == 'WT:' && strtolower( substr( $reqClass, -3) ) == '.js' ){ + if( substr( $reqClass, 0, 3 ) == 'WT:' && strtolower( substr( $reqClass, -3) ) == '.js' ){ // Wiki page requests (must end with .js): $requestKey .= $reqClass; }else if( substr( $reqClass, 0, 3 ) != 'WT:' ){ @@ -719,7 +719,7 @@ public static function checkForCommonsLanguageFormHack( $langKey){ $langKey = str_replace($formName, '', $langKey); //English wikipedia puts "-" after language keys remove that: if( $langKey[ strlen( $langKey ) - 1 ] == '-'){ - $langKey = substr( $langKey, 0, strlen( $langKey ) - 1 ); + $langKey = substr( $langKey, 0, strlen( $langKey ) - 1 ); } return $langKey; } @@ -765,7 +765,7 @@ function getFileContents( $filePath ) { global $IP; $ext = substr($filePath, strrpos($filePath, '.') + 1); - if ( self::validFileExtension( $ext) ) { + if ( self::validFileExtension( $ext) ) { $this->errorMsg .= "\nError file name must end with .js or .css " . htmlspecialchars( $filePath ) . " \n "; return false; } @@ -832,7 +832,7 @@ function transformScriptText( $scriptText , $moduleName){ // try each of these search patterns in the same order as before. // Get the mw.addMessage javascript - self::$addMessageJs = $this->getAddMessagesFromScriptText( $scriptText , $moduleName); + self::$addMessageJs = $this->getAddMessagesFromScriptText( $scriptText , $moduleName); // Check for mw.includeAllModuleMsgs() call to be replaced with all the msgs // Use preg_replace_callback to avoid back-refrence substitution @@ -881,7 +881,7 @@ static function removeLogStatements( $jsString ){ break; } if( count( $matches ) > 0 ){ - $startOfLogIndex = strlen( $matches[1][0] ) + $matches[1][1]; + $startOfLogIndex = strlen( $matches[1][0] ) + $matches[1][1]; // append everything up to this point: $outputJs .= substr( $jsString, $i, ( $startOfLogIndex - strlen( $matches[1][0] ) )-$i ); @@ -913,7 +913,7 @@ static function removeLogStatements( $jsString ){ } break; case ')': - if( ! $inquote && !$inSingleQuote ){ + if( ! $inquote && !$inSingleQuote ){ $parenthesesDepth--; } break; @@ -984,7 +984,7 @@ static public function getAddMessagesIndex( $str ){ } } // Check for ); at the end - preg_match( '/\s*\)\s*\;?/', $str, $matches, PREG_OFFSET_CAPTURE, $returnIndex['e'] ); + preg_match( '/\s*\)\s*\;?/', $str, $matches, PREG_OFFSET_CAPTURE, $returnIndex['e'] ); if( $matches[0][1] ){ $returnIndex[ 'efull' ] = $matches[0][1] + strlen( $matches[0][0] ); } @@ -1111,7 +1111,7 @@ function getMsgKeysFromScriptText( & $scriptString , $moduleName){ $inx = self::getAddMessageKeyIndex( $scriptString ); if( $inx ) { // get the javascript array string: - $javaScriptArrayString = substr($scriptString, $inx['s'], ($inx['e']-$inx['s'])) ; + $javaScriptArrayString = substr($scriptString, $inx['s'], ($inx['e']-$inx['s'])) ; // Match all the quoted msg keys preg_match_all( "/\"([^\"]*)\"/", $javaScriptArrayString, $matches); $messageSet = array(); @@ -1240,7 +1240,7 @@ public function isFileCached() { * Loads and outputs the file from the file cache */ public function outputFile() { - if ( ResourceLoader::clientAcceptsGzip() && substr( $this->filename, -3 ) == '.gz' ) { + if ( ResourceLoader::clientAcceptsGzip() && substr( $this->filename, -3 ) == '.gz' ) { header( 'Content-Encoding: gzip' ); readfile( $this->filename ); return true; diff --git a/includes/NamedResourceLoader.php b/includes/NamedResourceLoader.php index 7d865166b3..b677ec3a8f 100755 --- a/includes/NamedResourceLoader.php +++ b/includes/NamedResourceLoader.php @@ -49,7 +49,7 @@ public static function loadResourcePaths(){ wfProfileIn( $fname ); - $mwEmbedAbsolutePath = ( $wgMwEmbedDirectory == '' ) ? $IP : $IP .'/' .$wgMwEmbedDirectory; + $mwEmbedAbsolutePath = ( $wgMwEmbedDirectory == '' ) ? $IP : $IP .'/' .$wgMwEmbedDirectory; // Add the mwEmbed localizations $wgExtensionMessagesFiles[ 'mwEmbed' ] = $mwEmbedAbsolutePath . '/mwEmbed.i18n.php'; @@ -90,7 +90,7 @@ public static function loadResourcePaths(){ } // Get all the classes from the enabled mwEmbed modules folder - foreach( self::$moduleList as $na => $moduleName ) { + foreach( self::$moduleList as $na => $moduleName ) { $relativeSlash = ( $wgMwEmbedDirectory == '' )? '' : '/'; $modulePath = $wgMwEmbedDirectory . $relativeSlash . 'modules/' . $moduleName; self::proccessModulePath( $moduleName, $modulePath ); @@ -124,7 +124,7 @@ private static function proccessModulePath( $moduleName, $modulePath ){ self::$directoryContext = $modulePath; // Check for the loader.js - if( !is_file( $modulePath . '/loader.js' ) ){ + if( !is_file( $modulePath . '/loader.js' ) ){ throw new MWException( "Javascript Module $moduleName missing loader.js file\n" ); return false; } @@ -151,7 +151,7 @@ private static function proccessModulePath( $moduleName, $modulePath ){ */ private static function proccessLoaderContent( & $fileContent , $moduleName){ // Add the mwEmbed loader js to its global collector: - self::$combinedLoadersJs .= $fileContent; + self::$combinedLoadersJs .= $fileContent; // Is there a way to pass arguments in preg_replace_callback ? self::$currentModuleName = $moduleName; @@ -169,7 +169,7 @@ private static function proccessLoaderContent( & $fileContent , $moduleName){ */ public static function getLanguageJs( $langKey = 'en' ){ global $wgMwEmbedDirectory; - $path = $wgMwEmbedDirectory . '/languages/classes/Language' . ucfirst( $langKey ) . '.js'; + $path = $wgMwEmbedDirectory . '/languages/classes/Language' . ucfirst( $langKey ) . '.js'; if( is_file( $path ) ){ $languageJs = file_get_contents( $path ); return $languageJs; @@ -231,7 +231,7 @@ private static function preg_buildModuleList( $jsvar ){ } $moduleSet = explode(',', $jsvar[1] ); - $mwEmbedAbsolutePath = ( $wgMwEmbedDirectory == '' )? $IP: $IP .'/' .$wgMwEmbedDirectory; + $mwEmbedAbsolutePath = ( $wgMwEmbedDirectory == '' )? $IP: $IP .'/' .$wgMwEmbedDirectory; foreach( $moduleSet as $na => $moduleName ) { // Skip empty module names @@ -272,7 +272,7 @@ private static function preg_classPathLoader( $jsvar ) { foreach ( $jClassSet as $resourceName => $classPath ) { // Strip $ from resource (as they are stripped on URL request parameter input) $resourceName = str_replace( '$', '', $resourceName ); - $classPath = ( self::$directoryContext == '' )? $classPath : self::$directoryContext . '/' . $classPath; + $classPath = ( self::$directoryContext == '' )? $classPath : self::$directoryContext . '/' . $classPath; // Throw an error if we already have defined this class: // This prevents a module from registering a shared class diff --git a/includes/noMediaWikiConfig.php b/includes/noMediaWikiConfig.php index b515358ec2..ebe1caa561 100644 --- a/includes/noMediaWikiConfig.php +++ b/includes/noMediaWikiConfig.php @@ -161,9 +161,9 @@ function wfLoadMsgKeys( $langKey ){ throw new MWException( "Missing msgFile: " . htmlspecialchars( $msgFile ) . "\n" ); } require( $msgFile ); - // First include the English fallback, + // First include the English fallback, $wgMessageCache = array_merge( $wgMessageCache, $messages[ 'en' ] ); - // Then override with the current language: + // Then override with the current language: if( isset( $messages[ $langKey ] ) ) { $wgMessageCache = array_merge( $wgMessageCache, $messages[ $langKey ] ); } @@ -198,8 +198,8 @@ function wfProfileOut( $name ){ } function microtime_float() { - list($usec, $sec) = explode(" ", microtime()); - return ((float)$usec + (float)$sec); + list($usec, $sec) = explode(" ", microtime()); + return ((float)$usec + (float)$sec); } /** diff --git a/loader.js b/loader.js index dac331aae9..72d41a4bd3 100644 --- a/loader.js +++ b/loader.js @@ -3,18 +3,18 @@ * Core "loader.js" for mwEmbed * * This loader along with all the enabled module loaders is combined with mwEmbed.js -* via the script-loader. +* via the script-loader. * */ /** -* Core js components -* +* Core js components +* * These components are pieces of the core mwEmbed lib -* They are in separate files to keep the code easier to maintain. +* They are in separate files to keep the code easier to maintain. * * All mwEmbed core classes are loaded on every mwEmbed request -* +* * NOTE: All user / application module code should go into /modules * and enabled in mwEnabledModuleList below. */ @@ -27,23 +27,23 @@ var mwCoreComponentList = [ /** * The default set of enabled modules -* ( Modules can also be enabled via mediaWiki extensions ) -* +* ( Modules can also be enabled via mediaWiki extensions ) +* * Each enabledModules array value should be a name -* of a folder in mwEmbed/modules +* of a folder in mwEmbed/modules * * Modules must define a loader.js file in the root -* of the module folder. -* +* of the module folder. +* * A loader file should only include: * * Class paths of the module classes * * Style sheets of the module * * Loader function(s) that load module classes -* * Any code you want run on all pages like checking the DOM -* for a tag that invokes your loader. +* * Any code you want run on all pages like checking the DOM +* for a tag that invokes your loader. * * When using the scriptLoader the enabledModules loader code -* is transcluded into base mwEmbed class include. +* is transcluded into base mwEmbed class include. */ var mwEnabledModuleList = [ 'AddMedia', @@ -53,7 +53,7 @@ var mwEnabledModuleList = [ 'Sequencer', 'TimedText', 'SmilPlayer', - 'Playlist', + 'Playlist', 'SwarmTransport', 'SyntaxHighlighter', 'MiroSubs', @@ -62,59 +62,59 @@ var mwEnabledModuleList = [ ]; /** -* mwEmbed default config values. -*/ +* mwEmbed default config values. +*/ mw.setDefaultConfig ( { - // Default coreComponents: + // Default coreComponents: 'coreComponents' : mwCoreComponentList, - // Default enabled modules: - 'enabledModules' : mwEnabledModuleList, - + // Default enabled modules: + 'enabledModules' : mwEnabledModuleList, + // Default jquery ui skin name - 'jQueryUISkin' : 'redmond', + 'jQueryUISkin' : 'redmond', - // The mediaWiki path of mwEmbed + // The mediaWiki path of mwEmbed 'mediaWikiEmbedPath' : 'js/mwEmbed/', - + // Api actions that must be submitted in a POST, and need an api proxy for cross domain calls 'apiPostActions': [ 'login', 'purge', 'rollback', 'delete', 'undelete', 'protect', 'block', 'unblock', 'move', 'edit', 'upload', 'emailuser', 'import', 'userrights' ], - + //If we are in debug mode ( results in fresh debug javascript includes ) 'debug' : false, - + // Default request timeout ( for cases where we include js and normal browser timeout can't be used ) // stored in seconds 'defaultRequestTimeout' : 30, - - // Default user language is "en" Can be overwritten by: - // "uselang" url param - // wgUserLang global + + // Default user language is "en" Can be overwritten by: + // "uselang" url param + // wgUserLang global 'userLanguage' : 'en', - - // Set the default providers ( you can add more provider via {provider_id}_apiurl = apiUrl + + // Set the default providers ( you can add more provider via {provider_id}_apiurl = apiUrl 'commons_apiurl' : 'http://commons.wikimedia.org/w/api.php', - + // Set the default loader group strategy 'loader.groupStrategy' : 'module', - - // Default appendJS string ( not used outside of wikimedia gadget system ) + + // Default appendJS string ( not used outside of wikimedia gadget system ) 'Mw.AppendWithJS' : false - + } ); /** * -- Load Class Paths -- -* -* PHP AutoLoader reads this loader.js file along with -* all the "loader.js" files to determine script-loader +* +* PHP AutoLoader reads this loader.js file along with +* all the "loader.js" files to determine script-loader * class paths -* +* */ -// Set the loaderContext for the classFiles paths call: +// Set the loaderContext for the classFiles paths call: mw.setConfig( 'loaderContext', '' ); /** @@ -122,8 +122,8 @@ mw.setConfig( 'loaderContext', '' ); */ mw.addResourcePaths( { "mwEmbed" : "mwEmbed.js", - "window.jQuery" : "libraries/jquery/jquery-1.4.2.js", - + "window.jQuery" : "libraries/jquery/jquery-1.4.2.js", + "mw.Language" : "components/mw.Language.js", "mw.Parser" : "components/mw.Parser.js", "mw.Api" : "components/mw.Api.js", @@ -131,38 +131,39 @@ mw.addResourcePaths( { "JSON" : "libraries/json/json2.js", "$j.replaceText.js" : "libraries/jquery/plugins/jquery.replaceText.js", - + "$j.fn.menu" : "libraries/jquery/plugins/jquery.menu/jquery.menu.js", "mw.style.jquerymenu" : "libraries/jquery/plugins/jquery.menu/jquery.menu.css", - + "$j.fn.pngFix" : "libraries/jquery/plugins/jquery.pngFix.js", "$j.fn.autocomplete" : "libraries/jquery/plugins/jquery.autocomplete.js", "mw.style.autocomplete" : "libraries/jquery/plugins/jquery.autocomplete.css", - + "$j.fn.hoverIntent" : "libraries/jquery/plugins/jquery.hoverIntent.js", "$j.fn.datePicker" : "libraries/jquery/plugins/jquery.datePicker.js", - + "mw.style.ui_redmond" : "skins/jquery.ui.themes/redmond/jquery-ui-1.7.2.css", "mw.style.ui_darkness" : "skins/jquery.ui.themes/darkness/jquery-ui-1.7.2.css", "mw.style.ui_le-frog" : "skins/jquery.ui.themes/le-frog/jquery-ui-1.7.2.css", "mw.style.ui_start" : "skins/jquery.ui.themes/start/jquery-ui-1.7.2.css", "mw.style.ui_sunny" : "skins/jquery.ui.themes/sunny/jquery-ui-1.7.2.css", - - "mw.style.mwCommon" : "skins/common/mw.style.mwCommon.css", + + "mw.style.mwCommon" : "skins/common/mw.style.mwCommon.css", "$j.cookie" : "libraries/jquery/plugins/jquery.cookie.js", + "$j.postMessage" : "libraries/jquery/plugins/jquery.postmessage.js", - + "$j.contextMenu" : "libraries/jquery/plugins/jquery.contextMenu.js", "$j.fn.suggestions" : "libraries/jquery/plugins/jquery.suggestions.js", "$j.fn.textSelection" : "libraries/jquery/plugins/jquery.textSelection.js", "$j.browserTest" : "libraries/jquery/plugins/jquery.browserTest.js", "$j.fn.jWizard" : "libraries/jquery/plugins/jquery.jWizard.js", - "$j.ui" : "libraries/jquery/jquery.ui/ui/jquery.ui.core.js", + "$j.ui" : "libraries/jquery/jquery.ui/ui/jquery.ui.core.js", "$j.widget" : "libraries/jquery/jquery.ui/ui/jquery.ui.widget.js", - + "$j.effects.blind" : "libraries/jquery/jquery.ui/ui/jquery.effects.blind.js", "$j.effects.bounce" : "libraries/jquery/jquery.ui/ui/jquery.effects.bounce.js", "$j.effects.clip" : "libraries/jquery/jquery.ui/ui/jquery.effects.clip.js", @@ -174,30 +175,30 @@ mw.addResourcePaths( { "$j.effects.pulsate" : "libraries/jquery/jquery.ui/ui/jquery.effects.pulsate.js", "$j.effects.scale" : "libraries/jquery/jquery.ui/ui/jquery.effects.scale.js", "$j.effects.shake" : "libraries/jquery/jquery.ui/ui/jquery.effects.shake.js", - "$j.effects.slide" : "libraries/jquery/jquery.ui/ui/jquery.effects.slide.js", + "$j.effects.slide" : "libraries/jquery/jquery.ui/ui/jquery.effects.slide.js", "$j.effects.transfer" : "libraries/jquery/jquery.ui/ui/jquery.effects.transfer.js", - + "$j.ui.accordion" : "libraries/jquery/jquery.ui/ui/jquery.ui.accordion.js", "$j.ui.autocomplete" : "libraries/jquery/jquery.ui/ui/jquery.ui.autocomplete.js", "$j.ui.button" : "libraries/jquery/jquery.ui/ui/jquery.ui.button.js", - "$j.ui.datepicker" : "libraries/jquery/jquery.ui/ui/jquery.ui.datepicker.js", + "$j.ui.datepicker" : "libraries/jquery/jquery.ui/ui/jquery.ui.datepicker.js", "$j.ui.dialog" : "libraries/jquery/jquery.ui/ui/jquery.ui.dialog.js", "$j.ui.droppable" : "libraries/jquery/jquery.ui/ui/jquery.ui.droppable.js", "$j.ui.draggable" : "libraries/jquery/jquery.ui/ui/jquery.ui.draggable.js", - "$j.ui.mouse" : "libraries/jquery/jquery.ui/ui/jquery.ui.mouse.js", - "$j.ui.position" : "libraries/jquery/jquery.ui/ui/jquery.ui.position.js", + "$j.ui.mouse" : "libraries/jquery/jquery.ui/ui/jquery.ui.mouse.js", + "$j.ui.position" : "libraries/jquery/jquery.ui/ui/jquery.ui.position.js", "$j.ui.progressbar" : "libraries/jquery/jquery.ui/ui/jquery.ui.progressbar.js", "$j.ui.resizable" : "libraries/jquery/jquery.ui/ui/jquery.ui.resizable.js", - "$j.ui.selectable" : "libraries/jquery/jquery.ui/ui/jquery.ui.selectable.js", + "$j.ui.selectable" : "libraries/jquery/jquery.ui/ui/jquery.ui.selectable.js", "$j.ui.slider" : "libraries/jquery/jquery.ui/ui/jquery.ui.slider.js", "$j.ui.sortable" : "libraries/jquery/jquery.ui/ui/jquery.ui.sortable.js", "$j.ui.tabs" : "libraries/jquery/jquery.ui/ui/jquery.ui.tabs.js" - - + + } ); // Add a special css dependency for $j.ui mw.addStyleResourceDependency( { - '$j.ui' : ( 'mw.style.ui_' + mw.getConfig( 'jQueryUISkin' ) ) + '$j.ui' : ( 'mw.style.ui_' + mw.getConfig( 'jQueryUISkin' ) ) } ); diff --git a/modules/AddMedia/css/mw.style.AddMedia.css b/modules/AddMedia/css/mw.style.AddMedia.css index 2160731332..c6962ab051 100644 --- a/modules/AddMedia/css/mw.style.AddMedia.css +++ b/modules/AddMedia/css/mw.style.AddMedia.css @@ -27,13 +27,13 @@ display:block; } -.rsd_control_container{ +.rsd_control_container{ margin: 10px 0; width: 100%; } .rsd_cp_tab img{ - border:0px; + border:0px; } .rsd_cp_tab a{ height:16px; @@ -50,7 +50,7 @@ position: absolute; bottom: 0px; left: 3px; - font-size: x-small; + font-size: x-small; } .rsd_import_button { mergin-left: 5px; @@ -66,7 +66,7 @@ position: absolute; top: 0px; right: 0px; - font-size: x-small; + font-size: x-small; } .rsd_license { position: absolute; @@ -113,7 +113,7 @@ .rsd_result_enumeration { margin: 0 1em; } -.rsd_results_body { +.rsd_results_body { width: 100%; } #rsd_results_header { @@ -141,7 +141,7 @@ margin: 5px; } .mv_clip_box_result_over{ - border: thin solid #F99; + border: thin solid #F99; } .mv_clip_list_result{ padding:10px; diff --git a/modules/AddMedia/jquery.dragDropFile.js b/modules/AddMedia/jquery.dragDropFile.js index 3e6596af24..eadf28062b 100644 --- a/modules/AddMedia/jquery.dragDropFile.js +++ b/modules/AddMedia/jquery.dragDropFile.js @@ -45,7 +45,7 @@ mw.addMessages( { $j( '#multiple_file_input' ).remove(); - $j( 'body' ).append( + $j( 'body' ).append( $j('
') .attr( { 'title' : gM( 'mwe-upload-multi', fileCount ), @@ -82,19 +82,19 @@ mw.addMessages( { $j( '#multiple_file_input' ).dialogFitWindow(); } ); // add the inital table / title: - $j( '#multiple_file_input' ).empty().html( + $j( '#multiple_file_input' ).empty().html( $j('

') .text( gM( 'mwe-review-upload' ) ), - + $j( '' ) - .attr({ + .attr({ 'width' : "100%", 'border' : "1", 'border' : 'none' }) .addClass( 'table_list' ) ); - + $j.each( files, function( i, file ) { if ( file.fileSize < 64048576 ) { $j( '#multiple_file_input .table_list' ).append( @@ -102,19 +102,19 @@ mw.addMessages( { $j('
').css({ 'width': '300px', 'padding' : '5px' - }).append( + }).append( $j('').attr( { 'width' : '250', - 'src' : file.getAsDataURL() + 'src' : file.getAsDataURL() } ) ), - + $j('') .attr('valign', 'top') .append( 'File Name:
' + - 'File Desc:
' - ) + 'File Desc:
' + ) ) ) // do the add-media-wizard with the upload tab diff --git a/modules/AddMedia/loader.js b/modules/AddMedia/loader.js index a9c914d7bd..ec32388261 100644 --- a/modules/AddMedia/loader.js +++ b/modules/AddMedia/loader.js @@ -8,22 +8,22 @@ mw.addMessages( { "mwe-loading-add-media-wiz" : "Loading add media wizard" }); - + // Add class file paths ( From ROOT ) mw.addResourcePaths( { "$j.fn.dragDropFile" : "jquery.dragDropFile.js", - + "mw.UploadForm" : "mw.UploadForm.js", - + "mw.UploadHandler" : "mw.UploadHandler.js", "mw.UploadInterface" : "mw.UploadInterface.js", "mw.Firefogg" : "mw.Firefogg.js", "mw.FirefoggGUI" : "mw.FirefoggGUI.js", - - "mw.RemoteSearchDriver" : "mw.RemoteSearchDriver.js", + + "mw.RemoteSearchDriver" : "mw.RemoteSearchDriver.js", "mw.style.AddMedia" : "css/mw.style.AddMedia.css", - + "baseRemoteSearch" : "searchLibs/baseRemoteSearch.js", "mediaWikiSearch" : "searchLibs/mediaWikiSearch.js", "metavidSearch" : "searchLibs/metavidSearch.js", @@ -31,37 +31,37 @@ "flickrSearch" : "searchLibs/flickrSearch.js", "baseRemoteSearch" : "searchLibs/baseRemoteSearch.js", "kalturaSearch" : "searchLibs/kalturaSearch.js" - - } ); - - // Upload form includes "datapicker" + + } ); + + // Upload form includes "datapicker" mw.addModuleLoader( 'AddMedia.UploadForm', [ [ 'mw.UploadForm', - '$j.ui', - '$j.widget', - '$j.ui.mouse' + '$j.ui' ], [ + '$j.widget', + '$j.ui.mouse', '$j.ui.datepicker' ] - ] - ); - + ] + ); + //Setup the addMediaWizard module - mw.addModuleLoader( 'AddMedia.addMediaWizard', - // Define loader set: + mw.addModuleLoader( 'AddMedia.addMediaWizard', + // Define loader set: [ [ 'mw.RemoteSearchDriver', 'mw.style.AddMedia', '$j.cookie', '$j.fn.textSelection', - '$j.browserTest', // ( textSelection uses browserTest ) + '$j.browserTest', // ( textSelection uses browserTest ) '$j.ui' ], [ '$j.widget', '$j.ui.mouse', - '$j.ui.resizable', + '$j.ui.resizable', '$j.ui.position', '$j.ui.draggable', '$j.ui.dialog', @@ -69,7 +69,7 @@ '$j.ui.sortable' ] ] ); - + //Set a variable for the base upload interface for easy inclusion var baseUploadlibs = [ [ @@ -81,35 +81,35 @@ '$j.widget', '$j.ui.mouse', '$j.ui.progressbar', - '$j.ui.position', + '$j.ui.position', '$j.ui.dialog', '$j.ui.draggable' ] ]; - + /* - * Upload interface loader: + * Upload interface loader: */ - + mw.addModuleLoader( 'AddMedia.UploadHandler', baseUploadlibs ); - + /** * The Firefogg loaders * - * Includes both firefogg & firefogg "GUI" which share some loading logic: - */ - - // Clone the baseUploadlibs array and add the firefogg lib: + * Includes both firefogg & firefogg "GUI" which share some loading logic: + */ + + // Clone the baseUploadlibs array and add the firefogg lib: var mwBaseFirefoggReq = baseUploadlibs.slice( 0 ) mwBaseFirefoggReq[ 0 ].push( 'mw.Firefogg' ); - + mw.addModuleLoader( 'AddMedia.firefogg', mwBaseFirefoggReq ); - - mw.addModuleLoader( 'AddMedia.FirefoggGUI', function() { - // Clone the array: + + mw.addModuleLoader( 'AddMedia.FirefoggGUI', function() { + // Clone the array: var request = mwBaseFirefoggReq.slice( 0 ) ; - - // Add firefogg gui classes to a new "request" var: + + // Add firefogg gui classes to a new "request" var: request.push( [ 'mw.FirefoggGUI', '$j.cookie', @@ -117,6 +117,7 @@ '$j.ui.slider', '$j.ui.datepicker' ] ); + return request; } ); diff --git a/modules/AddMedia/mw.Firefogg.js b/modules/AddMedia/mw.Firefogg.js index a8e6813b73..a24647e548 100644 --- a/modules/AddMedia/mw.Firefogg.js +++ b/modules/AddMedia/mw.Firefogg.js @@ -5,9 +5,9 @@ mw.addMessages({ "mwe-upload-transcoded-status" : "Transcoded", - "mwe-upload-transcode-in-progress" : "Transcode and upload in progress (do not close this window)", - "fogg-transcoding" : "Encoding video", - "fogg-select_file" : "Select file", + "mwe-upload-transcode-in-progress" : "Transcode and upload in progress (do not close this window)", + "fogg-transcoding" : "Encoding video", + "fogg-select_file" : "Select file", "fogg-select_new_file" : "Select new file", "fogg-select_url" : "Select URL", "fogg-check_for_firefogg" : "Checking for Firefogg...", @@ -19,13 +19,13 @@ mw.addMessages({ "fogg-please-install-about-linktext" : "about Firefogg", "fogg-use_latest_firefox" : "Please first install $1. Then revisit this page to install the Firefogg<\/b> extension.<\/i>", "fogg-latest-firefox" : "latest Firefox", - "fogg-passthrough_mode" : "Your selected file is already ogg or not a video file", + "fogg-passthrough_mode" : "Your selected file is already ogg or not a video file", "fogg-encoding-done" : "Encoding complete", "fogg-badtoken" : "Token is not valid", "fogg-preview" : "Preview video", "fogg-hidepreview" : "Hide preview", "fogg-warning-firebug" : "Firebug can cause conflicts with Firefogg. Please disable Firebug for this page.", - "fogg-missing-webm-support" : "Please use a [$1 webm compatible] browsers to preview results of webm videos" + "fogg-missing-webm-support" : "Please use a [$1 webm compatible] browsers to preview results of webm videos" }); var firefogg_install_links = { @@ -36,7 +36,7 @@ var firefogg_install_links = { var default_firefogg_options = { // Callback for upload completion - 'doneUploadCb': false, + 'doneUploadCb': false, // The API URL to upload to 'apiUrl': null, @@ -46,16 +46,16 @@ var default_firefogg_options = { // True if we will be showing the encoder interface 'encoder_interface': false, - - // If the install firefogg should be shown or not. + + // If the install firefogg should be shown or not. 'showFoggWarningFlag' : true, // jQuery selector identifying the target control container or form (can't be left null) 'selector': '', - // May be "upload" to if we are rewriting an upload form, or "local" if we are encoding a local file + // May be "upload" to if we are rewriting an upload form, or "local" if we are encoding a local file 'form_type': 'local', - + // Special Mode that just checks for firefogg install and puts a notice after the target 'installCheckMode': false, @@ -91,34 +91,34 @@ var default_firefogg_options = { // True if we should show a preview of the encoding progress 'show_preview': true, - - //If we should enable chunk uploads ( mediaWiki api supports chunk uploads) + + //If we should enable chunk uploads ( mediaWiki api supports chunk uploads) 'enableChunks' : false }; /** * Setup firefogg jquery binding -* NOTE: we should have the firefogg binding work the same way as -* the upload form binding. +* NOTE: we should have the firefogg binding work the same way as +* the upload form binding. */ ( function( $ ) { $.fn.firefogg = function( options ) { if ( !options ){ options = { }; } - + // Add the selector options[ 'selector' ] = this.selector; - - // Setup the Firefogg: + + // Setup the Firefogg: var myFogg = new mw.Firefogg( options ); - - // Kind of silly installCheckMode check - // need to refactor as described in init :: installCheckMode + + // Kind of silly installCheckMode check + // need to refactor as described in init :: installCheckMode if ( myFogg && ! myFogg.installCheckMode ) { myFogg.doRewrite( ); var selectorElement = $j( this.selector ).get( 0 ); - selectorElement[ 'uploadHandler' ] = myFogg; + selectorElement[ 'uploadHandler' ] = myFogg; } } } )( jQuery ); @@ -130,28 +130,28 @@ mw.Firefogg = function( options ) { mw.Firefogg.prototype = { // extends mw.BaseUploadHandler // Minimum version of firefogg allowed min_firefogg_version: '1.2.06', - - // The default encoder settings - // NOTE: should be mw.getConfig based - default_encoder_settings: { + + // The default encoder settings + // NOTE: should be mw.getConfig based + default_encoder_settings: { 'maxSize' : '400', - 'videoBitrate' : '544', - 'audioBitrate' : '96', - 'noUpscaling' : true + 'videoBitrate' : '544', + 'audioBitrate' : '96', + 'noUpscaling' : true }, - + // Lazy initialized, use getFirefogg() - have_firefogg: null, - + have_firefogg: null, + // Lazy initialized, use getEncoderSettings() - current_encoder_settings: null, - + current_encoder_settings: null, + // Lazy initialized, use getSourceFileInfo() - sourceFileInfo: null, - + sourceFileInfo: null, + // Valid ogg extensions ogg_extensions: [ 'ogg', 'ogv', 'oga' ], - + passthrough: false, sourceMode: 'file', @@ -167,7 +167,7 @@ mw.Firefogg.prototype = { // extends mw.BaseUploadHandler if ( !options.apiUrl ){ options.upload_mode = 'post'; } - + // Set options for ( var i in default_firefogg_options ) { if ( typeof options[ i ] != 'undefined' ) { @@ -175,24 +175,24 @@ mw.Firefogg.prototype = { // extends mw.BaseUploadHandler } else { this[ i ] = default_firefogg_options[i]; } - } + } // Check for special installCheckMode - + // NOTE we should refactor install checks into static functions / entry points - // so that they can be called without initializing the firefogg object with a special flag. - if( this.installCheckMode ){ - if ( ! this.getFirefogg() ) { - this.form_type = 'upload'; + // so that they can be called without initializing the firefogg object with a special flag. + if( this.installCheckMode ){ + if ( ! this.getFirefogg() ) { + this.form_type = 'upload'; // Show install firefogg msg this.showInstallFirefog(); return ; } - if( typeof console != 'undefined' && console.firebug ) { + if( typeof console != 'undefined' && console.firebug ) { this.appendFirebugWarning(); } mw.log( "installCheckMode no firefogg init"); return ; - } + } // Inherit from mw.BaseUploadHandler var myBUI = new mw.UploadHandler( options ); @@ -202,13 +202,13 @@ mw.Firefogg.prototype = { // extends mw.BaseUploadHandler if ( this[ i ] ) { this[ 'parent_'+ i ] = myBUI[i]; } else { - this[ i ] = myBUI[i]; + this[ i ] = myBUI[i]; } - } - + } + // Setup ui uploadHandler pointer this.ui.uploadHandler = this; - + if ( !this.selector ) { mw.log('firefogg: missing selector '); } @@ -220,7 +220,7 @@ mw.Firefogg.prototype = { // extends mw.BaseUploadHandler */ doRewrite: function( callback ) { var _this = this; - mw.log( 'sel len: ' + this.selector + '::' + $j( this.selector ).length + + mw.log( 'sel len: ' + this.selector + '::' + $j( this.selector ).length + ' tag:' + $j( this.selector ).get( 0 ).tagName ); if ( $j( this.selector ).length >= 0 ) { if ( $j( this.selector ).get( 0 ).tagName.toLowerCase() == 'input' ) { @@ -266,20 +266,20 @@ mw.Firefogg.prototype = { // extends mw.BaseUploadHandler if ( /^target_btn_/.test( target ) ) { // Button var msg = gM( target.replace( /^target_btn_/, 'fogg-' ) ); - return ' '; } else if ( /^target_input_/.test( target ) ) { // Text input var msg = gM( target.replace( /^target_input_/, 'fogg-' ) ); - return ' '; } else if ( /^target_/.test( target ) ) { - // Message - var msg = gM( target.replace( /^target_/, 'fogg-' ) ); + // Message + var msg = gM( target.replace( /^target_/, 'fogg-' ) ); return '
' + msg + '
'; } else { mw.log( 'Invalid target: ' + target ); @@ -328,8 +328,8 @@ mw.Firefogg.prototype = { // extends mw.BaseUploadHandler .click( function() { _this.selectSourceFile(); }); - } - + } + // Set up the click handler for the "save local file" button if( _this.target_btn_save_local_file ) { @@ -340,32 +340,32 @@ mw.Firefogg.prototype = { // extends mw.BaseUploadHandler } ); } }, - + /** * Show the install firefogg msg */ showInstallFirefog: function( target ) { var _this = this; - + if( target ){ this.target_use_latest_firefox = target; this.target_please_install = target; } - + var upMsg = ( _this.form_type == 'upload' ) ? gM( 'fogg-for_improved_uploads' ) + ' ' : gM( 'fogg-not-installed') + ' '; - + // Show the "use latest Firefox" message if necessary mw.log( 'mw.Firefogg:: browser: ' + mw.versionIsAtLeast( '1.9.1', $j.browser.version ) ); if ( !( $j.browser.mozilla && mw.versionIsAtLeast( '1.9.1', $j.browser.version ) ) ) { mw.log( 'mw.Firefogg::show use latest::' + _this.target_use_latest_firefox ); - - // Add the use_latest if not present: + + // Add the use_latest if not present: if ( !this.target_use_latest_firefox ) { $j( this.selector ).after( $j( '
' ) .addClass( 'target_use_latest_firefox' ) - .html( + .html( gM('fogg-use_latest_firefox', $j('') .attr({ @@ -376,55 +376,55 @@ mw.Firefogg.prototype = { // extends mw.BaseUploadHandler gM( 'fogg-latest-firefox' ) ) ) - ) + ) ); this.target_use_latest_firefox = this.selector + ' ~ .target_use_latest_firefox'; } - - // Add the upload msg if we are "uploading" + + // Add the upload msg if we are "uploading" if ( _this.form_type == 'upload' ) { $j( _this.target_use_latest_firefox ) .prepend( upMsg ); } - + $j( _this.target_use_latest_firefox ).show(); return ; } mw.log( 'mw.Firefogg::should show install link'); - + // Otherwise show the "install Firefogg" message var firefoggUrl = _this.getFirefoggInstallUrl(); - if( firefoggUrl ) { - // Add the target please install in not present: + if( firefoggUrl ) { + // Add the target please install in not present: if ( !this.target_please_install ) { - $j( this.selector ).after( + $j( this.selector ).after( $j('
') .addClass( 'ui-corner-all target_please_install' ) .css({ 'border' : 'thin solid black', 'margin' : '4px' - }) + }) ); this.target_please_install = this.selector + ' ~ .target_please_install'; - } - // Add the install msg - $j( _this.target_please_install ) - .append( + } + // Add the install msg + $j( _this.target_please_install ) + .append( upMsg, gM( 'fogg-please-install', // Install link $j('') .text( gM( "fogg-please-install-install-linktext" ) ) .attr('href', firefoggUrl ), - + // About link $j('') .text( gM( "fogg-please-install-about-linktext" ) ) .attr({ 'href' : 'http://commons.wikimedia.org/wiki/Commons:Firefogg', - 'target' : '_new' + 'target' : '_new' } ) - ) + ) ) .css( 'padding', '10px' ) .show(); @@ -452,8 +452,8 @@ mw.Firefogg.prototype = { // extends mw.BaseUploadHandler */ getFirefogg: function() { if ( this.have_firefogg == null ) { - if ( typeof( Firefogg ) != 'undefined' - && mw.versionIsAtLeast(this.min_firefogg_version, Firefogg().version ) ) + if ( typeof( Firefogg ) != 'undefined' + && mw.versionIsAtLeast(this.min_firefogg_version, Firefogg().version ) ) { this.have_firefogg = true; this.fogg = new Firefogg(); @@ -469,13 +469,13 @@ mw.Firefogg.prototype = { // extends mw.BaseUploadHandler * Set up the upload form */ setupForm: function() { - mw.log( 'firefogg::setupForm::' ); - var _this = this; + mw.log( 'firefogg::setupForm::' ); + var _this = this; // Set up the parent if we are in upload mode if ( this.form_type == 'upload' ) { this.parent_setupForm(); } - + // If Firefogg is not available, just show a "please install" message if ( ! _this.getFirefogg() ) { // Show install firefogg msg @@ -484,15 +484,15 @@ mw.Firefogg.prototype = { // extends mw.BaseUploadHandler } return ; } - + // If uploading and firefogg is on show warning - if ( this.form_type == 'upload' - && typeof console != 'undefined' + if ( this.form_type == 'upload' + && typeof console != 'undefined' && console.firebug && _this.showFoggWarningFlag ) { this.appendFirebugWarning(); } - // Change the file browser to type text. We can't simply change the attribute so + // Change the file browser to type text. We can't simply change the attribute so // we have to delete and recreate. var inputTag = ''; mw.log( 'set input: ' + inputTag ); - + $j( this.selector ).replaceWith( inputTag ); this.target_input_file_name = 'input[name=' + $j( this.selector ).attr( 'name' ) + ']'; @@ -525,28 +525,28 @@ mw.Firefogg.prototype = { // extends mw.BaseUploadHandler $j( '
' ) .addClass( 'ui-state-error ui-corner-all' ) .html( gM( 'fogg-warning-firebug' ) ) - .css({ + .css({ 'width' : 'auto', 'margin' : '5px', 'padding' : '5px' }) - ); + ); }, - + /** * Create controls for showing a transcode preview */ createPreviewControls: function() { var _this = this; - - // Set the initial button html: + + // Set the initial button html: var buttonHtml = ''; if( _this.show_preview == true ) { buttonHtml = $j.btnHtml( gM( 'fogg-hidepreview' ), 'fogg_preview', 'triangle-1-s' ); } else { buttonHtml = $j.btnHtml( gM( 'fogg-preview' ), 'fogg_preview', 'triangle-1-e' ); } - + // Add the preview button and canvas $j( '#upProgressDialog' ).append( $j('
') @@ -611,7 +611,7 @@ mw.Firefogg.prototype = { // extends mw.BaseUploadHandler var _this = this; // Set up the hidden video to pull frames from if( $j( '#fogg_preview_vid' ).length == 0 ) - $j( 'body' ).append( + $j( 'body' ).append( $j('') .attr({ 'href' : 'http://www.webmproject.org/users/', @@ -844,13 +844,13 @@ mw.Firefogg.prototype = { // extends mw.BaseUploadHandler }) ) } - } + } _this.ui.setPrompt( gM( 'fogg-encoding-done' ), - $j( '
' ).append( + $j( '
' ).append( gM( 'fogg-encoding-done' ), $j('
' ), videoEmbedCode - ) + ) ); //Load the video and set a callback: var v = $j( '#fogg_final_vid' ).get( 0 ); @@ -874,7 +874,7 @@ mw.Firefogg.prototype = { // extends mw.BaseUploadHandler //also resize the dialog box $j( '#upProgressDialog' ).dialog( 'option', 'width', vW + 20 ); $j( '#upProgressDialog' ).dialog( 'option', 'height', vH + 120 ); - + //also position the dialog container $j( '#upProgressDialog') .dialog( 'option', 'position', 'center' ); } @@ -886,16 +886,16 @@ mw.Firefogg.prototype = { // extends mw.BaseUploadHandler }, /** - * Get the appropriate encoder settings for the current Firefogg object, + * Get the appropriate encoder settings for the current Firefogg object, * into which a video has already been selected. */ getEncoderSettings: function() { - // set the current_encoder_settings form the default_encoder_settings if not yet set + // set the current_encoder_settings form the default_encoder_settings if not yet set if ( this.current_encoder_settings == null ) { - - // Clone the default settings + + // Clone the default settings var settings = $j.extend( { }, this.default_encoder_settings) ; - + // Grab the extension var sf = this.fogg.sourceFilename; if ( !sf ) { @@ -918,15 +918,15 @@ mw.Firefogg.prototype = { // extends mw.BaseUploadHandler settings['passthrough'] = true; } - mw.log( 'base setupAutoEncoder::' + this.getSourceFileInfo().contentType + + mw.log( 'base setupAutoEncoder::' + this.getSourceFileInfo().contentType + ' passthrough:' + settings['passthrough'] ); - + this.current_encoder_settings = settings; - } - + } + // Remove maxSize if width or height is set: - if( ( this.current_encoder_settings['width'] || this.current_encoder_settings['height'] ) - && this.current_encoder_settings['maxSize'] ){ + if( ( this.current_encoder_settings['width'] || this.current_encoder_settings['height'] ) + && this.current_encoder_settings['maxSize'] ){ delete this.current_encoder_settings['maxSize']; } @@ -936,7 +936,7 @@ mw.Firefogg.prototype = { // extends mw.BaseUploadHandler } else { this.fogg.setFormat('ogg'); } - + return this.current_encoder_settings; }, @@ -954,7 +954,7 @@ mw.Firefogg.prototype = { // extends mw.BaseUploadHandler isOggFormat: function() { var contentType = this.getSourceFileInfo().contentType; - return ( contentType.indexOf("video/ogg") != -1 + return ( contentType.indexOf("video/ogg") != -1 || contentType.indexOf("application/ogg") != -1 ); }, @@ -962,7 +962,7 @@ mw.Firefogg.prototype = { // extends mw.BaseUploadHandler * Get the default title of the progress window */ getProgressTitle: function() { - mw.log( "fogg:getProgressTitle f:" + ( this.getFirefogg() ? 'on' : 'off' ) + + mw.log( "fogg:getProgressTitle f:" + ( this.getFirefogg() ? 'on' : 'off' ) + ' mode:' + this.form_type ); // Return the parent's title if we don't have Firefogg turned on if ( !this.getFirefogg() || !this.firefogg_form_action ) { @@ -981,48 +981,48 @@ mw.Firefogg.prototype = { // extends mw.BaseUploadHandler * NOTE: should probably be dispatched from BaseUploadHandler doUpload instead */ doUpload: function() { - var _this = this; - + var _this = this; + _this.uploadBeginTime = (new Date()).getTime(); // If Firefogg is disabled or doing an copyByUrl upload, just invoke the parent method if( !this.getFirefogg() || this.isCopyUpload() ) { _this.parent_doUpload(); return ; } - // We are doing a firefogg upload: + // We are doing a firefogg upload: mw.log( "firefogg: doUpload:: " ); - - // Add the preview controls if transcoding: - if ( !_this.getEncoderSettings()['passthrough'] ) { + + // Add the preview controls if transcoding: + if ( !_this.getEncoderSettings()['passthrough'] ) { // Setup the firefogg transcode dialog (if not passthrough ) - _this.ui.setup( { - 'title' : gM( 'mwe-upload-transcode-in-progress' ), - 'statusType' : 'transcode' + _this.ui.setup( { + 'title' : gM( 'mwe-upload-transcode-in-progress' ), + 'statusType' : 'transcode' } ); - - // setup preview controls: + + // setup preview controls: _this.createPreviewControls(); } - // Update the formData 'comment' per the upload description + // Update the formData 'comment' per the upload description $j(this.form).find("[name='comment']").val( _this.getUploadDescription() ); - + // Get the input form data into an array mw.log( 'get this.formData ::' ); var data = $j( this.form ).serializeArray(); this.formData = {}; for ( var i = 0; i < data.length; i++ ) { if ( data[i]['name'] ) { - // Special case of upload.js commons hack: + // Special case of upload.js commons hack: if( data[i]['name'] == 'wpUploadDescription' ) { - this.formData[ 'comment' ] = data[i]['value']; + this.formData[ 'comment' ] = data[i]['value']; }else{ this.formData[ data[i]['name'] ] = data[i]['value']; } } } - - - + + + // Get the edit token from formData if it's not set already if ( !_this.editToken && _this.formData['token'] ) { _this.editToken = _this.formData['token']; @@ -1043,16 +1043,16 @@ mw.Firefogg.prototype = { // extends mw.BaseUploadHandler _this.editToken = editToken; _this.doUploadWithFormData(); } ); - + }, - - /** + + /** * Internal function called once the token and form data is avaliable */ doUploadWithFormData: function() { var _this = this; // We can do a chunk upload - if( _this.upload_mode == 'post' && _this.enableChunks ) { + if( _this.upload_mode == 'post' && _this.enableChunks ) { _this.doChunkUpload(); } else if ( _this.upload_mode == 'post' ) { // Encode and then do a post upload @@ -1060,19 +1060,19 @@ mw.Firefogg.prototype = { // extends mw.BaseUploadHandler function /* onProgress */ ( progress ) { _this.ui.updateProgress( progress ); }, - function /* onDone */ () { + function /* onDone */ () { var uploadRequest = _this.getUploadApiRequest(); - + // Update the UI for uploading - _this.ui.setup( { + _this.ui.setup( { 'title' : gM( 'mwe-upload-in-progress' ), - 'statusType' : 'upload' + 'statusType' : 'upload' } ); - + mw.log( 'Do POST upload to:' +_this.apiUrl + ' with data:\n' + JSON.stringify( uploadRequest ) ); - + _this.fogg.post( _this.apiUrl, 'file', JSON.stringify( uploadRequest ) ); - + _this.doUploadStatus(); } ); @@ -1082,7 +1082,7 @@ mw.Firefogg.prototype = { // extends mw.BaseUploadHandler }, /** - * Do both uploading and encoding at the same time. Uploads 1MB chunks as + * Do both uploading and encoding at the same time. Uploads 1MB chunks as * they become ready. */ doChunkUpload : function() { @@ -1091,7 +1091,7 @@ mw.Firefogg.prototype = { // extends mw.BaseUploadHandler _this.action_done = false; if ( !_this.getEncoderSettings()['passthrough'] ) { - // We are transcoding to Ogg. Fix the destination extension, it + // We are transcoding to Ogg. Fix the destination extension, it // must be ogg/ogv/oga. var fileName = _this.formData['filename']; var ext = ''; @@ -1099,18 +1099,18 @@ mw.Firefogg.prototype = { // extends mw.BaseUploadHandler if ( dotPos != -1 ) { ext = fileName.substring( dotPos ).toLowerCase(); } - if ( $j.inArray( ext.substr( 1 ), _this.ogg_extensions ) == -1 ) { + if ( $j.inArray( ext.substr( 1 ), _this.ogg_extensions ) == -1 ) { var extreg = new RegExp( ext + '$', 'i' ); _this.formData['filename'] = fileName.replace( extreg, '.ogg' ); } } _this.doChunkUploadWithFormData(); }, - + /** * Get the uplaod api request object from _this.formData - * - * @param {Object} options Options + * + * @param {Object} options Options */ getUploadApiRequest: function( options ) { var _this = this; @@ -1135,23 +1135,23 @@ mw.Firefogg.prototype = { // extends mw.BaseUploadHandler if ( _this.formData['ignorewarnings'] ) { request['ignorewarnings'] = _this.formData['ignorewarnings']; } - + return request; }, - + /** * Internal function called from doChunkUpload() when form data is available */ doChunkUploadWithFormData: function() { var _this = this; - mw.log( "firefogg::doChunkUploadWithFormData: " + _this.editToken ); - // get the upload api request; + mw.log( "firefogg::doChunkUploadWithFormData: " + _this.editToken ); + // get the upload api request; var uploadRequest = this.getUploadApiRequest( { 'enableChunks' : true } ); var encoderSettings = this.getEncoderSettings(); mw.log( 'do fogg upload/encode call: ' + _this.apiUrl + ' :: ' + JSON.stringify( uploadRequest ) ); mw.log( 'foggEncode: ' + JSON.stringify( encoderSettings ) ); - _this.fogg.upload( JSON.stringify( encoderSettings ), _this.apiUrl, + _this.fogg.upload( JSON.stringify( encoderSettings ), _this.apiUrl, JSON.stringify( uploadRequest ) ); // Start polling the upload status @@ -1168,30 +1168,30 @@ mw.Firefogg.prototype = { // extends mw.BaseUploadHandler */ doEncode: function( progressCallback, doneCallback ) { var _this = this; - _this.action_done = false; - + _this.action_done = false; + var encoderSettings = this.getEncoderSettings(); - - // Check for special encode settings that remap things. - - // Check if encoderSettings passthrough is on ( then skip the encode ) - if( encoderSettings['passthrough'] == true) { + + // Check for special encode settings that remap things. + + // Check if encoderSettings passthrough is on ( then skip the encode ) + if( encoderSettings['passthrough'] == true) { // Firefogg requires an encode request to setup a the file to be uploaded. _this.fogg.encode( JSON.stringify( { 'passthrough' : true } ) ); doneCallback(); - return ; - } - - mw.log( 'doEncode: with: ' + JSON.stringify( encoderSettings ) ); - _this.fogg.encode( JSON.stringify( encoderSettings ) ); - + return ; + } + + mw.log( 'doEncode: with: ' + JSON.stringify( encoderSettings ) ); + _this.fogg.encode( JSON.stringify( encoderSettings ) ); + // Setup a local function for timed callback: var encodingStatus = function() { var status = _this.fogg.status(); - if ( _this.show_preview == true - && _this.fogg.state == 'encoding' + if ( _this.show_preview == true + && _this.fogg.state == 'encoding' // No way to seek in VP8 atm && _this.current_encoder_settings['videoCodec'] != 'vp8') { _this.renderPreview(); @@ -1216,7 +1216,7 @@ mw.Firefogg.prototype = { // extends mw.BaseUploadHandler }, /** - * Poll the upload progress and update the UI regularly until the upload is complete. + * Poll the upload progress and update the UI regularly until the upload is complete. * * Asynchronous, returns immediately. */ @@ -1237,8 +1237,8 @@ mw.Firefogg.prototype = { // extends mw.BaseUploadHandler mw.log( "could not parse uploadstatus / could not get responseText: " + e ); } } - - // Check response is not null and old response does not match current + + // Check response is not null and old response does not match current if ( typeof response_text != 'undefined' && _this.oldResponseText != response_text ) { mw.log( 'Fogg: new result text:' + response_text + ' state:' + _this.fogg.state ); _this.oldResponseText = response_text; @@ -1246,7 +1246,7 @@ mw.Firefogg.prototype = { // extends mw.BaseUploadHandler try { var apiResult = JSON.parse( response_text ); } catch( e ) { - mw.log( "could not parse response_text::" + response_text + + mw.log( "could not parse response_text::" + response_text + ' ...for now try with eval...' ); try { var apiResult = eval( response_text ); @@ -1254,7 +1254,7 @@ mw.Firefogg.prototype = { // extends mw.BaseUploadHandler var apiResult = null; } } - + // Process the api result ( if not a chunk ) if( ! apiResult.resultUrl ){ _this.processApiResult ( apiResult ); @@ -1262,12 +1262,12 @@ mw.Firefogg.prototype = { // extends mw.BaseUploadHandler } } - // Show the video preview if encoding and show_preview is enabled. + // Show the video preview if encoding and show_preview is enabled. if ( _this.show_preview == true && _this.fogg.state == 'encoding') { _this.renderPreview(); } - - //mw.log( 'Update fogg progress: ' + _this.fogg.progress() ); + + //mw.log( 'Update fogg progress: ' + _this.fogg.progress() ); // If not an error, Update the progress bar _this.ui.updateProgress( _this.fogg.progress() ); @@ -1291,23 +1291,23 @@ mw.Firefogg.prototype = { // extends mw.BaseUploadHandler // Close the ui _this.ui.close(); return true; - } + } // Else pass off the api Success to interface: - _this.ui.showApiSuccess( apiResult ); - return true; + _this.ui.showApiSuccess( apiResult ); + return true; } else { - // Done state with error? + // Done state with error? // Should not be possible because firefogg would not be "done" without resultURL mw.log( " Upload done in chunks mode, but no resultUrl!" ); } - + } uploadStatus(); }, /** * This is the cancel button handler, referenced by getCancelButton() in the parent. - * @param {Element} dialogElement Dialog element that was "canceled" + * @param {Element} dialogElement Dialog element that was "canceled" */ onCancel: function( dialogElement ) { if ( !this.getFirefogg() ) { @@ -1316,7 +1316,7 @@ mw.Firefogg.prototype = { // extends mw.BaseUploadHandler mw.log( 'firefogg:cancel' ) if ( confirm( gM( 'mwe-cancel-confim' ) ) ) { this.action_done = true; - this.fogg.cancel(); + this.fogg.cancel(); $j( dialogElement ).empty().dialog( 'close' ); } // Don't follow the # link: diff --git a/modules/AddMedia/mw.FirefoggGUI.js b/modules/AddMedia/mw.FirefoggGUI.js index dc3a234920..ad731608a9 100644 --- a/modules/AddMedia/mw.FirefoggGUI.js +++ b/modules/AddMedia/mw.FirefoggGUI.js @@ -4,7 +4,7 @@ mw.addMessages({ "fogg-wont-upload-to-server" : "Note: Your video file will be locally encoded and not upload to any server", - "fogg-save_local_file" : "Encode to File", + "fogg-save_local_file" : "Encode to File", "fogg-help-sticky" : "Help (click to stick)", "fogg-cg-preset" : "Preset: $1<\/strong>", "fogg-cg-quality" : "Basic quality and resolution control", @@ -13,7 +13,7 @@ mw.addMessages({ "fogg-cg-advVideo" : "Advanced video encoding controls", "fogg-cg-advAudio" : "Advanced audio encoding controls", "fogg-preset-custom" : "Custom settings", - "fogg-webvideo-desc" : "Ogg Web video Theora, Vorbis 600 kbit\/s and 400px maximum width", + "fogg-webvideo-desc" : "Ogg Web video Theora, Vorbis 600 kbit\/s and 400px maximum width", "fogg-savebandwidth-desc" : "Ogg Low bandwidth Theora, Vorbis 164 kbit\/s and 200px maximum width", "fogg-highquality-desc" : "Ogg High quality Theora, Vorbis 1080px maximum width", "fogg-webvideo-webm-desc" : "Webm Web video VP8 600 kbit\/s and 480px maximum width", @@ -75,21 +75,21 @@ mw.addMessages({ /** * Setup firefoggGUI jquery binding */ -( function( $ ) { +( function( $ ) { $.fn.firefoggGUI = function( options ) { if ( !options ) - options = { }; - + options = { }; + // Add the selector options['selector'] = this.selector; - - // Setup the firefogg interface: + + // Setup the firefogg interface: var myFogg = new mw.FirefoggGUI( options ); - + if ( myFogg ) { myFogg.setupForm( ); var selectorElement = $j( options.selector ).get( 0 ); - selectorElement['firefogg'] = myFogg; + selectorElement['firefogg'] = myFogg; } } } )( jQuery ); @@ -125,10 +125,11 @@ mw.FirefoggGUI.prototype = { 'custom': { 'descKey': 'fogg-preset-custom', 'conf': {} - }, + }, 'webvideo': { 'desc': gM( 'fogg-webvideo-desc' ), 'conf': { + 'videoCodec' : 'theora', 'maxSize' : 400, 'videoBitrate' : 544, 'audioBitrate' : 96, @@ -138,6 +139,7 @@ mw.FirefoggGUI.prototype = { 'savebandwidth': { 'desc': gM( 'fogg-savebandwidth-desc' ), 'conf': { + 'videoCodec' : 'theora', 'maxSize' : 200, 'videoBitrate' : 164, 'audioBitrate' : 32, @@ -150,6 +152,7 @@ mw.FirefoggGUI.prototype = { 'hqstream': { 'desc': gM( 'fogg-highquality-desc' ), 'conf': { + 'videoCodec' : 'theora', 'maxSize' : 1080, 'videoQuality' : 6, 'audioQuality' : 3, @@ -243,7 +246,7 @@ mw.FirefoggGUI.prototype = { }, 'framerate': { 'default' : '24', - 'selectVal' : [ '12', '16', { '24000:1001' : '23.97' }, '24', '25', + 'selectVal' : [ '12', '16', { '24000:1001' : '23.97' }, '24', '25', { '30000:1001' : '29.97' }, '30' ], 'type' : "select", 'group' : "advVideo" @@ -325,18 +328,18 @@ mw.FirefoggGUI.prototype = { /** * Initialize this object */ - init: function( options ) { - + init: function( options ) { + // Set up a supported object: for ( var key in options ) { if ( typeof default_mvAdvFirefogg_config[key] != 'undefined' ) { this[key] = options[key]; } - } - + } + // Inherit the base mvFirefogg class: var baseFirefogg = new mw.Firefogg( options ); - for ( var key in baseFirefogg ) { + for ( var key in baseFirefogg ) { if ( typeof this[key] != 'undefined' ) { this[ 'basefogg_' + key ] = baseFirefogg[ key ]; } else { @@ -345,15 +348,15 @@ mw.FirefoggGUI.prototype = { } return this; }, - + /** - * Setup the form + * Setup the form */ - setupForm: function() { - //empty out the selector: + setupForm: function() { + //empty out the selector: $j( this.selector ).empty(); - // Check for firefogg: - if ( ! this.getFirefogg() ) { + // Check for firefogg: + if ( ! this.getFirefogg() ) { // Show install firefogg msg this.showInstallFirefog(); $j('.target_please_install').css( { 'width': 400, 'margin':'auto' } ); @@ -376,11 +379,11 @@ mw.FirefoggGUI.prototype = { var gdout = ''; $j.each( this.config_groups, function( inx, group_key ) { gdout += '
' + - '

' + + '

' + gM( 'fogg-cg-' + group_key ) + '

' + '
'; // Output this group's control options: - gdout += '' + + gdout += '
' + ''; // If this is the preset group, output the preset control if ( group_key == 'preset' ) { @@ -401,7 +404,7 @@ mw.FirefoggGUI.prototype = { $j( this.selector ).append( '

' ); } // Hide the container and add the output - $j( this.target_control_container ).hide(); + $j( this.target_control_container ).hide(); $j( this.target_control_container ).html( gdout ); }, @@ -422,25 +425,25 @@ mw.FirefoggGUI.prototype = { target + '" href="#">' + linkText + ''; - case 'target_btn_select_url': - return $j.btnHtml( gM( 'fogg-select_url' ), target, 'link' ); + case 'target_btn_select_url': + return $j.btnHtml( gM( 'fogg-select_url' ), target, 'link' ); case 'target_use_latest_firefox': case 'target_please_install': - case 'target_passthrough_mode': - var text = gM( target.replace( /^target_/, 'fogg-' ) ); - return '
' + - '

' + - '' + + '' + - text + + text + '

' + '
'; case 'target_input_file_name': var text = gM( 'fogg-input_file_name' ); - return '


'; default: @@ -471,8 +474,8 @@ mw.FirefoggGUI.prototype = { out += '
').append( $j('
' + ''; // Get the default value (or an empty string if there is no default) @@ -489,27 +492,27 @@ mw.FirefoggGUI.prototype = { case 'int': case 'float': var size = ( type == 'string' || type == 'date' ) ? '14' : '4'; - out += ''; break; case 'boolean': var checked_attr = ( defaultValue === true ) ? ' checked="true"' : ''; - out += ''; break; case 'slider': var strMax = this.default_encoder_config[ configKey ].range.max + ''; maxDigits = strMax.length + 1; - out += '' + '
'; @@ -571,13 +574,13 @@ mw.FirefoggGUI.prototype = { $j( this.target_input_file_name ).width( 250 ); // Special preset action - $j( this.selector + ' ._preset_select' ).change( function() { + $j( this.selector + ' ._preset_select' ).change( function() { _this.updatePresetSelection( $j( this ).val() ); }); // Bind control actions for ( var configKey in this.default_encoder_config ) { - var confEntry = this.default_encoder_config[configKey]; + var confEntry = this.default_encoder_config[configKey]; // Initial state is hidden $j( this.selector + ' .helpRow_' + configKey ).hide(); @@ -630,7 +633,7 @@ mw.FirefoggGUI.prototype = { case 'boolean': $j( this.selector + ' ._' + configKey) .click( function() { - _this.updateLocalValue( _this.getClassId( this ), + _this.updateLocalValue( _this.getClassId( this ), $j( this ).is( ":checked" ) ); _this.updatePresetSelection( 'custom' ); }); @@ -640,10 +643,10 @@ mw.FirefoggGUI.prototype = { case 'int': case 'float': // Check if we have a validate function on the string - $j( this.selector + ' ._' + configKey ).change( function() { + $j( this.selector + ' ._' + configKey ).change( function() { $j( this ).val( _this.updateLocalValue( _this.getClassId( this ), - $j( this ).val() ) + $j( this ).val() ) ); _this.updatePresetSelection( 'custom' ); }); @@ -658,11 +661,11 @@ mw.FirefoggGUI.prototype = { } }); break; - case 'slider': - /** + case 'slider': + /** * Return true or false of out of range and update the related value - */ - var keepAspectRatio = function( sliderId, value ){ + */ + var keepAspectRatio = function( sliderId, value ){ // Maintain source video aspect ratio if ( sliderId == 'width' ) { var sourceHeight = _this.sourceFileInfo.video[0]['height']; @@ -681,7 +684,7 @@ mw.FirefoggGUI.prototype = { return false; } }; - + $j( this.selector + ' .slider_' + configKey ).slider({ range: "min", animate: true, @@ -693,7 +696,7 @@ mw.FirefoggGUI.prototype = { var sliderId = _this.getClassId( this, 'slider_' ); $j( _this.selector + ' ._' + sliderId ).val( ui.value ); - keepAspectRatio( sliderId, ui.value ); + keepAspectRatio( sliderId, ui.value ); }, change: function( event, ui ) { var sliderId = _this.getClassId( this, 'slider_' ); @@ -704,8 +707,8 @@ mw.FirefoggGUI.prototype = { $j( this.selector + ' ._' + configKey ).change( function() { var classId = _this.getClassId( this ); - var validValue = _this.updateLocalValue( classId, - $j( this ).val() + var validValue = _this.updateLocalValue( classId, + $j( this ).val() ); _this.updatePresetSelection( 'custom' ); // Change it to the validated value @@ -714,7 +717,7 @@ mw.FirefoggGUI.prototype = { //mw.log( "update: " + _this.selector + ' .slider' + classId ); $j( _this.selector + ' .slider_' + classId ) .slider('value', validValue ); - // Keep aspect ratio: + // Keep aspect ratio: keepAspectRatio( classId, validValue ); }); break; @@ -735,9 +738,10 @@ mw.FirefoggGUI.prototype = { /** * Update the UI due to a change in preset */ - updatePresetSelection: function( presetKey ) { + updatePresetSelection: function( presetKey ) { + var _this = this; // Update the local configuration - this.local_settings['default'] = presetKey; + this.local_settings['default'] = presetKey; mw.log( 'update preset desc: ' + presetKey ); var presetDesc = ''; if ( this.local_settings.presets[presetKey].desc ) { @@ -747,7 +751,15 @@ mw.FirefoggGUI.prototype = { } if( presetKey != 'custom' ){ // Copy the preset into custom settings - this.local_settings.presets['custom']['conf'] = $j.extend( {}, this.local_settings.presets[presetKey]['conf'] ); + this.local_settings.presets['custom']['conf'] = $j.extend( {}, this.local_settings.presets[presetKey]['conf'] ); + + // Set the actual HTML & widgets based on any local settings values: + $j.each( _this.local_settings.presets['custom']['conf'], function( inx, val ) { + if ( $j( _this.selector + ' ._' + inx ).length != 0 ) { + $j( _this.selector + ' ._' + inx ).val( val ); + } + } ); + } // Update the preset title $j( this.selector + ' .gd_preset' ) @@ -787,12 +799,12 @@ mw.FirefoggGUI.prototype = { }, /** - * Validate the new config setting, fixing its type and bounding it within a - * range if required. Update the configuration with the validated value and + * Validate the new config setting, fixing its type and bounding it within a + * range if required. Update the configuration with the validated value and * return it. */ - updateLocalValue: function( confKey, value ) { - if ( typeof this.default_encoder_config[ confKey ] == 'undefined' ) { + updateLocalValue: function( confKey, value ) { + if ( typeof this.default_encoder_config[ confKey ] == 'undefined' ) { mw.log( "Error: could not update conf key: " + confKey ) return value; } @@ -831,37 +843,37 @@ mw.FirefoggGUI.prototype = { }, /** - * Given an element or selector, get its primary class, and strip a given + * Given an element or selector, get its primary class, and strip a given * prefix from it. * * If no prefix is given, "_" is assumed. */ getClassId: function( element, prefix ) { - - var eltClass = $j( element ).attr( "class" ).split( ' ' ).slice( 0, 1 ).toString(); + + var eltClass = $j( element ).attr( "class" ).split( ' ' ).slice( 0, 1 ).toString(); if ( !prefix ) { prefix = '_'; } if ( eltClass.substr( 0, prefix.length ) == prefix ) { eltClass = eltClass.substr( prefix.length ); - } + } return eltClass; }, /** - * Get the appropriate encoder settings for the current Firefogg object, + * Get the appropriate encoder settings for the current Firefogg object, * into which a video has already been selected. Overrides the base method. */ getEncoderSettings: function() { // update the encoder settings (from local settings) var pKey = this.local_settings['default']; - // Update the current encoder settings: + // Update the current encoder settings: this.current_encoder_settings = this.local_settings.presets[ pKey ].conf; // Call the base function // Note that settings will be a reference and can be modified this.basefogg_getEncoderSettings(); - + // Allow re-encoding of files that are already ogg (unlike in the base class) if ( this.isOggFormat() ) { @@ -928,7 +940,7 @@ mw.FirefoggGUI.prototype = { setValues( k, val, maxVal ); } if( fileInfo.code && fileInfo.code == 'badfile') { - // Can't read file info ( but maybe can still encode it?) + // Can't read file info ( but maybe can still encode it?) this.updateValuesInHtml(); return ; } @@ -946,7 +958,7 @@ mw.FirefoggGUI.prototype = { } setValues( k, val, maxVal ); } - + // Audio stream settings, assumes for now there is only one stream for ( var i in fileInfo.audio[0] ) { var val = fileInfo.audio[0][i]; @@ -974,7 +986,7 @@ mw.FirefoggGUI.prototype = { $j( _this.selector + ' .slider_' + inx ).slider( 'option', 'max', new_max ); // update slider/input value: - _this.updateInterfaceValue( inx, + _this.updateInterfaceValue( inx, _this.local_settings.presets['custom']['conf'][inx] ); } } @@ -983,7 +995,7 @@ mw.FirefoggGUI.prototype = { this.updateValuesInHtml(); }, - doEncode: function( progressCallback, doneCallback ) { + doEncode: function( progressCallback, doneCallback ) { this.basefogg_doEncode( progressCallback, doneCallback ); }, @@ -1013,8 +1025,8 @@ mw.FirefoggGUI.prototype = { this.local_settings = JSON.parse( $j.cookie( 'fogg_settings' ) ); } // set to default if not loaded yet: - if ( this.local_settings && this.local_settings.presets - && this.local_settings.presets['custom']['conf'] ) + if ( this.local_settings && this.local_settings.presets + && this.local_settings.presets['custom']['conf'] ) { mw.log( 'local settings already populated' ); } else { @@ -1027,7 +1039,7 @@ mw.FirefoggGUI.prototype = { * FIXME: not called, does nothing */ clearSettings: function( force ) { - + }, /** diff --git a/modules/AddMedia/mw.RemoteSearchDriver.js b/modules/AddMedia/mw.RemoteSearchDriver.js index 1a608f0ac9..9ae6197fb7 100644 --- a/modules/AddMedia/mw.RemoteSearchDriver.js +++ b/modules/AddMedia/mw.RemoteSearchDriver.js @@ -34,20 +34,20 @@ mw.addMessages( { "mwe-no-import-by-url-linktext" : "$wgAllowCopyUploads", "mwe-results_from" : "Results from $1", "mwe-missing_desc_see_source" : "This asset is missing a description. Please check the [$1 source] and help describe it.", - + "rsd_config_error" : "Add media wizard configuration error: $1", "mwe-your-recent-uploads" : "Your recent uploads to $1", "mwe-no_recent_uploads" : "No recent uploads", - + "mwe-not-logged-in-uploads" : "You may not be logged in so no recent uploads can be displayed. $1 login and $2", "mwe-ie-eye-permision" : "If using Internet Explorer and logged in, you may need to adjust your privacy settings", - - "mwe-loggin-link" : "Please login", + + "mwe-loggin-link" : "Please login", "mwe-try-again-link" : "try again", - + "mwe-upload-a-file" : "Upload a new file", "mwe-upload-a-file-to" : "Upload a new file to $1", - + "mwe-resource_page_desc" : "Resource page description:", "mwe-edit_resource_desc" : "Edit wiki text resource description:", "mwe-local_resource_title" : "Local resource title:", @@ -60,17 +60,17 @@ mw.addMessages( { "mwe-do-more-modification" : "Do more modification", "mwe-checking-resource" : "Checking for resource", "mwe-resource-needs-import" : "Resource $1 needs to be imported to $2", - + "mwe-warning-upload-to-commons" : "$1 recommends you upload to Wikimedia Commons, only upload locally after you have read $2", "mwe-local-upload-policy-link" : "local upload policy" , - + "mwe-ftype-svg" : "SVG vector file", "mwe-ftype-jpg" : "JPEG image file", "mwe-ftype-png" : "PNG image file", "mwe-ftype-oga" : "Ogg audio file", "mwe-ftype-ogg" : "Ogg video file", "mwe-ftype-unk" : "Unknown file format", - + "rsd-wiki_commons-title": "Wikimedia Commons", "rsd-wiki_commons": "Wikimedia Commons, an archive of freely-licensed educational media content (images, sound and video clips)", @@ -87,94 +87,94 @@ mw.addMessages( { "rsd-flickr-desc" : "Flickr.com, an online photo sharing site", "rsd-metavid-title" : "Metavid.org", "rsd-metavid-desc" : "Metavid.org, a community archive of US House and Senate floor proceedings", - + "rsd-search-timeout" : "The search request did not complete. The server may be down experiencing heavy load. You can try again later" } ); /** * default_remote_search_options -* +* * Options for initializing the remote search driver */ var default_remote_search_options = { // The div that will hold the search interface - 'target_container': null, + 'target_container': null, // The target button or link that will invoke the search interface - 'target_invoke_button': null, + 'target_invoke_button': null, // Default id for search target input 'target_search_input' : '#rsd_q', - + /** - * Callback functions: + * Callback functions: */ 'resourceSelectionCallback' : null, - + 'displaySearchResultsCallback' : null, - + /** * import_url_mode * Can be 'api', 'autodetect', 'remote_link' * api: uses the mediawiki api to insert the media asset * autodetect: checks for api support before using the api to insert the media asset * remote_link: hot-links the media directly into the page as html - */ - 'import_url_mode': 'api', - + */ + 'import_url_mode': 'api', + // The api target can be "local" or the url or remote api entry point - 'upload_api_target': 'local', - + 'upload_api_target': 'local', + // Name of the upload target - 'upload_api_name': null, - + 'upload_api_name': null, + // Target title used for previews of wiki page usually: wgPageName 'target_title': null, // Edit tools (can be an array of tools or keyword 'all') 'enabled_tools': 'all', - // Target text box + // Target text box 'target_textbox': null, - + // Where output render should go: 'target_render_area': null, - + // Default search query - 'default_query': null, + 'default_query': null, // Canonical namespace prefix for images/ files - 'canonicalFileNS': 'File', + 'canonicalFileNS': 'File', // Enabled providers can be keyword 'all' or an array of enabled content provider keys - 'enabled_providers': 'all', - - // Enabled license types can any set of + 'enabled_providers': 'all', + + // Enabled license types can any set of // 'pd' (public domain), 'by' ( attribution ) , 'sa' (share alike ), - // 'nd' ( no derivatives ) - // 'nc' ( non-commercial ), 'all' ( all found licenses are "ok") - 'enabled_licenses' : ['pd', 'by', 'sa' ], - - // If the input text should be displayed + // 'nd' ( no derivatives ) + // 'nc' ( non-commercial ), 'all' ( all found licenses are "ok") + 'enabled_licenses' : ['pd', 'by', 'sa' ], + + // If the input text should be displayed 'displaySearchInput' : true, - + // If we should display resource icons - 'displayResourceInfoIcons' : true, - + 'displayResourceInfoIcons' : true, + // If we should display the result format button. 'displayResultFormatButton': true, - - // Set a default provider + + // Set a default provider 'default_provider': null, - + // The timeout for search providers ( in seconds ) - 'search_provider_timeout': 10 + 'search_provider_timeout': 10 }; /** -* Set the jQuery bindings: -*/ +* Set the jQuery bindings: +*/ ( function( $ ) { $.fn.addMediaWizard = function( options, callback ) { @@ -184,14 +184,14 @@ var default_remote_search_options = { callback( window['rsdMVRS'] ); } } - + $.addMediaWizard = function( options ) { - $.fn.addMediaWizard ( options, function( amwObj ) { + $.fn.addMediaWizard ( options, function( amwObj ) { // Do the add-media-wizard display amwObj.createUI(); } ); } - + } )( jQuery ); /** @@ -215,19 +215,19 @@ mw.RemoteSearchDriver.prototype = { // Result cleared flag 'results_cleared': false, - - // Current provider stores the current provider + + // Current provider stores the current provider 'current_provider': null, - + // Previous provider stores the previous provider for provider switching when calling search - // NOTE: can be removed once we clean up "upload" tab abstraction + // NOTE: can be removed once we clean up "upload" tab abstraction 'previus_provider': null, - + // Caret position of target text area ( lazy initialized ) - 'caretPos': null, - + 'caretPos': null, + // Text area value ( lazy initialized ) - 'textboxValue': null, + 'textboxValue': null, /** the default content providers list. * @@ -237,10 +237,10 @@ mw.RemoteSearchDriver.prototype = { * @@todo we will want to load more per user-preference and per category lookup */ content_providers: { - /** + /** * Content_providers documentation * - * @enabled: whether the search provider can be selected + * @enabled: whether the search provider can be selected * * @default: default: if the current provider should be displayed (only one should be the default) * @@ -251,7 +251,7 @@ mw.RemoteSearchDriver.prototype = { * @homepage: the homepage url for the search provider * * @apiUrl: the url to query against given the library type: - * + * * @lib: the search library to use corresponding to the * search object ie: 'mediaWiki' = new mediaWikiSearch() * @@ -271,39 +271,39 @@ mw.RemoteSearchDriver.prototype = { * @check_shared : if we should check for shared repository asset * */ - + /* * Local wiki search */ 'this_wiki': { 'enabled': 1, - 'apiUrl': ( wgServer && wgScriptPath ) ? - wgServer + wgScriptPath + '/api.php' : null, - - 'detailsUrl' : ( wgServer && wgArticlePath )? wgServer + wgArticlePath : null, - + 'apiUrl': ( wgServer && wgScriptPath ) ? + wgServer + wgScriptPath + '/api.php' : null, + + 'detailsUrl' : ( wgServer && wgArticlePath )? wgServer + wgArticlePath : null, + 'lib': 'mediaWiki', - 'homepage' : ( wgServer && wgScript ) ? + 'homepage' : ( wgServer && wgScript ) ? wgServer + wgScript : null, 'local': true, 'tab_img': false }, - + /** * Kaltura aggregated search - */ + */ 'kaltura': { 'enabled': 1, 'homepage': 'http://kaltura.com', 'apiUrl': 'http://kaldev.kaltura.com/michael/aggregator.php', - + 'detailsUrl' : 'http://videos.kaltura.com/$1', - + 'lib': 'kaltura', 'resource_prefix' : '', 'tab_image':false }, - + /** * Wikipedia Commons search provider configuration */ @@ -312,24 +312,24 @@ mw.RemoteSearchDriver.prototype = { 'homepage': 'http://commons.wikimedia.org/wiki/Main_Page', 'apiUrl': 'http://commons.wikimedia.org/w/api.php', 'detailsUrl' : 'http://commons.wikimedia.org/wiki/$1', - + 'lib': 'mediaWiki', 'tab_img': true, - + // Prefix on imported resources (not applicable if the repository is local or shared) - 'resource_prefix': 'WC_', + 'resource_prefix': 'WC_', - // Commons can be enabled as a remote repo do check shared + // Commons can be enabled as a remote repo do check shared 'check_shared': true, - // List all the domains where commons is local ( lets you avoid an api check for "shared" repo ) - 'local_domains': [ 'wikimedia', 'wikipedia', 'wikibooks' ], - + // List all the domains where commons is local ( lets you avoid an api check for "shared" repo ) + 'local_domains': [ 'wikimedia', 'wikipedia', 'wikibooks' ], + // Specific to wiki commons config: // If we should search the title - 'search_title': false + 'search_title': false }, - + /** * Internet archive search provider configuration */ @@ -339,29 +339,29 @@ mw.RemoteSearchDriver.prototype = { 'apiUrl': 'http://www.archive.org/advancedsearch.php', 'detailsUrl' : 'http://www.archive.org/details/$1', - + 'lib': 'archiveOrg', 'local': false, 'resource_prefix': 'AO_', 'tab_img': true }, - + /** * Flickr search provider configuration */ 'flickr': { 'enabled': 1, - 'homepage': 'http://www.flickr.com/about/', + 'homepage': 'http://www.flickr.com/about/', 'apiUrl': 'http://www.flickr.com/services/rest/', 'detailsUrl' : 'http://www.flickr.com/photos/', - + 'lib': 'flickr', 'local': false, // Just prefix with Flickr_ for now. 'resource_prefix': 'Flickr_', 'tab_img': true }, - + /** * Metavid search provider configuration */ @@ -370,31 +370,31 @@ mw.RemoteSearchDriver.prototype = { 'homepage': 'http://metavid.org/wiki/Metavid_Overview', 'apiUrl': 'http://metavid.org/w/index.php?title=Special:MvExportSearch', 'detailsUrl' : 'http://metavid.org/wiki/Stream:$1', - - 'lib': 'metavid', - 'local': false, - + + 'lib': 'metavid', + 'local': false, + // MV prefix for metavid imported resources - 'resource_prefix': 'MV_', - + 'resource_prefix': 'MV_', + // if the domain name contains metavid // no need to import metavid content to metavid sites - 'local_domains': [ 'metavid' ], - + 'local_domains': [ 'metavid' ], + // which stream to import, could be mv_ogg_high_quality // or flash stream, see ROE xml for keys - 'stream_import_key': 'mv_ogg_low_quality', - + 'stream_import_key': 'mv_ogg_low_quality', + // if running the remoteEmbed extension no need to copy local // syntax will be [remoteEmbed:roe_url link title] - 'remote_embed_ext': false, - + 'remote_embed_ext': false, + 'tab_img': true }, - + /** - * Special Upload tab provider - */ + * Special Upload tab provider + */ 'upload': { 'enabled': 1, 'title': 'Upload' @@ -402,8 +402,8 @@ mw.RemoteSearchDriver.prototype = { }, /** - * License define: - * + * License define: + * * NOTE: we only support creative commons type licenses * * Based on listing: http://creativecommons.org/licenses/ @@ -442,24 +442,24 @@ mw.RemoteSearchDriver.prototype = { } }, - // Width of image resources + // Width of image resources thumb_width: 80, - - // The width of an image when editing + + // The width of an image when editing defaultImageEditWidth: 400, - - // The width of the video embed while editing the resource + + // The width of the video embed while editing the resource defaultVideoEditWidth: 400, - - // The insert position of the asset (overwritten by cursor position) - insert_text_pos: 0, - + + // The insert position of the asset (overwritten by cursor position) + insert_text_pos: 0, + // Default display mode of search results displayMode : 'box', // box or list // The ClipEdit Object - clipEdit: null, - + clipEdit: null, + /** * The initialisation function * @@ -468,7 +468,7 @@ mw.RemoteSearchDriver.prototype = { init: function( options ) { var _this = this; mw.log( 'RemoteSearchDriver:init' ); - + // Add in a local "id" reference to each provider for ( var provider_id in this.content_providers ) { this.content_providers[ provider_id ].id = provider_id; @@ -490,7 +490,7 @@ mw.RemoteSearchDriver.prototype = { var provider = this.content_providers[ provider_id ]; // Set the provider id provider[ 'id' ] = provider_id - + if ( _this.enabled_providers == 'all' && !this.current_provider && provider.apiUrl ) { this.current_provider = provider_id; break; @@ -512,13 +512,13 @@ mw.RemoteSearchDriver.prototype = { } // Set the upload target name if unset - if ( _this.upload_api_target == 'local' - && ! _this.upload_api_name + if ( _this.upload_api_target == 'local' + && ! _this.upload_api_name && typeof wgServer != 'undefined' ) { - _this.upload_api_name = mw.parseUri( wgServer ).host; + _this.upload_api_name = mw.parseUri( wgServer ).host; } else { - // Disable upload tab if no target is avaliable + // Disable upload tab if no target is avaliable this.content_providers[ 'upload' ].enabled = false; } @@ -532,7 +532,7 @@ mw.RemoteSearchDriver.prototype = { _this.upload_api_target = mw.getLocalApiUrl(); } } - + // Set up the "add media wizard" button, which invokes this object if ( !this.target_invoke_button || $j( this.target_invoke_button ).length == 0 ) { mw.log( "RemoteSearchDriver:: no target invocation provided " ); @@ -549,17 +549,17 @@ mw.RemoteSearchDriver.prototype = { } return this; }, - - + + /** * Get license icon html * @param license_key the license key (ie "by-sa" or "by-nc-sa" etc) - * + * * @return {jQuery element} A div containing the license icons. */ getLicenseIconHtml: function( licenseObj ) { - + var $licenseLink = $j( '' ) .attr( { 'target' : '_new', @@ -567,7 +567,7 @@ mw.RemoteSearchDriver.prototype = { 'title' : licenseObj.title } ) .append( licenseObj.img_html ); - + $licenseBox = $j( '
' ) .addClass( 'rsd_license' ) .attr( { @@ -613,10 +613,10 @@ mw.RemoteSearchDriver.prototype = { * @param license_url the url of the license */ getLicenseFromUrl: function( license_url ) { - // Get the license key: + // Get the license key: var licenseKey = this.getLicenseKeyFromUrl( license_url ); if( licenseKey ) { - // Return the license object: + // Return the license object: return this.getLicenseFromKey( licenseKey , license_url ); } // Could not find it return mwe-unknown_license @@ -626,7 +626,7 @@ mw.RemoteSearchDriver.prototype = { 'lurl': license_url }; }, - + /** * Get a license key from a url string * @parma {String} license_url License url to get key from @@ -637,7 +637,7 @@ mw.RemoteSearchDriver.prototype = { if ( license_url == 'http://www.usa.gov/copyright.shtml' || license_url == 'http://creativecommons.org/licenses/publicdomain' ) { return 'pd'; - } + } // First do a direct lookup check: for ( var j = 0; j < this.licenses.cc.licenses.length; j++ ) { var jLicense = this.licenses.cc.licenses[ j ]; @@ -654,25 +654,25 @@ mw.RemoteSearchDriver.prototype = { } return false; }, - + /** * Check if the license is compatible with this.enabled_licenses * @ - * @retrun true if license is compatible and false if not + * @retrun true if license is compatible and false if not */ checkCompatibleLicense: function( license_url ) { - var licenseKey = this.getLicenseKeyFromUrl( license_url ); + var licenseKey = this.getLicenseKeyFromUrl( license_url ); if( ! licenseKey ) - return false; + return false; var licenseSet = licenseKey.split( '-' ); - for ( var i = 0; i < licenseSet.length; i++ ) { + for ( var i = 0; i < licenseSet.length; i++ ) { if( $j.inArray( licenseSet[i], this.enabled_licenses ) == -1) { return false; } } return true; }, - + /** * Get mime type icon from a provided mime type * @param str mime type of the requested file @@ -704,20 +704,20 @@ mw.RemoteSearchDriver.prototype = { return $j( '
' ) .addClass( 'rsd_file_type ui-corner-all ui-state-default ui-widget-content' ) - .attr( 'title', gM( 'mwe-ftype-' + type ) ) + .attr( 'title', gM( 'mwe-ftype-' + type ) ) .text( type ); }, - + /** * createUI * - * Creates the remote search driver User Interface + * Creates the remote search driver User Interface */ createUI: function() { - var _this = this; + var _this = this; this.clearTextboxCache(); - // Setup the parent container (if not already created) + // Setup the parent container (if not already created) mw.log(" looking for: " + _this.target_container); if( !_this.target_container || $j( _this.target_container ).length == 0 ) { this.createDialogContainer(); @@ -725,8 +725,8 @@ mw.RemoteSearchDriver.prototype = { // Empty out the target $j( _this.target_container ).empty(); } - - // Setup remote search dialog & bindings + + // Setup remote search dialog & bindings this.initDialog(); // Update the target binding to just un-hide the dialog: @@ -740,41 +740,41 @@ mw.RemoteSearchDriver.prototype = { } ); } }, - + /** * showDialog - * Displays a dialog + * Displays a dialog */ showDialog: function() { var _this = this; mw.log( "showDialog::" ); - + // Create the UI this.createUI(); - - + + _this.clearTextboxCache(); var query = _this.getDefaultQuery(); - - // Refresh the container if "upload" or "changed query" - if ( query != $j( this.target_search_input ).val() - || - this.current_provider == 'upload' ) + + // Refresh the container if "upload" or "changed query" + if ( query != $j( this.target_search_input ).val() + || + this.current_provider == 'upload' ) { $j( this.target_search_input ).val( query ); _this.updateResults(); } // $j(_this.target_container).dialog("open"); $j( _this.target_container ).parents( '.ui-dialog' ).fadeIn( 'slow' ); - - - + + + // re-center the dialog: $j( _this.target_container ).dialog( 'option', 'position', 'center' ); }, - + /** - * Clears the textbox cache. + * Clears the textbox cache. */ clearTextboxCache: function() { this.caretPos = null; @@ -794,9 +794,9 @@ mw.RemoteSearchDriver.prototype = { } return this.caretPos; }, - + /** - * Get the value of the target textbox. + * Get the value of the target textbox. */ getTextboxValue: function() { if ( this.textboxValue == null ) { @@ -808,7 +808,7 @@ mw.RemoteSearchDriver.prototype = { } return this.textboxValue; }, - + /** * Get the default query from the text selection */ @@ -826,42 +826,42 @@ mw.RemoteSearchDriver.prototype = { // If the query is still empty try the page title: if( this.default_query != '' && typeof wgTitle != 'undefined' ) this.default_query = wgTitle; - + return this.default_query; }, - + /** * Creates the dialog container */ createDialogContainer: function() { mw.log( "createDialogContainer" ); var _this = this; - + _this.target_container = '#rsd_modal_target'; - + // add the parent target_container if not provided or missing if ( _this.target_container && $j( _this.target_container ).length != 0 ) { //remove old dialog $j( _this.target_container ).remove(); } - + $j( 'body' ).append( $j('
') .attr({ 'id' : 'rsd_modal_target', - 'title' : gM( 'mwe-add_media_wizard' ) - }) + 'title' : gM( 'mwe-add_media_wizard' ) + }) .css("position", 'relative') ); // Get layout - mw.log( 'width: ' + $j( window ).width() + ' height: ' + $j( window ).height() ); - - // Build cancel button + mw.log( 'width: ' + $j( window ).width() + ' height: ' + $j( window ).height() ); + + // Build cancel button var cancelButton = {}; cancelButton[ gM( 'mwe-cancel' ) ] = function() { _this.onCancelResourceEdit(); } - + $j( _this.target_container ).dialog( { bgiframe: true, autoOpen: true, @@ -878,9 +878,9 @@ mw.RemoteSearchDriver.prototype = { _this.onCancelResourceEdit(); $j( this ).parents( '.ui-dialog' ).fadeOut( 'slow' ); } - } ); + } ); //$j( _this.target_container ).dialogFitWindow(); - + // Add the window resize hook to keep dialog layout $j( window ).resize( function() { $j( _this.target_container ).dialogFitWindow(); @@ -889,28 +889,28 @@ mw.RemoteSearchDriver.prototype = { /** * Sets up the initial html interface - */ + */ initDialog: function() { mw.log( 'f::initDialog' ); - var _this = this; - + var _this = this; + var $mainContainer = $j( this.target_container ); // Add the provider seleciton $mainContainer.append( this.createProviderSelection() ); - - // Add the searchInput control if it should be displayed: + + // Add the searchInput control if it should be displayed: if( this.displaySearchInput ){ $mainContainer.append( this.createSearchInput() ); }; - + this.$resultsContainer = $j('
').attr({ id : "rsd_results_container" }); - + $mainContainer.append( this.$filtersContainer ); $mainContainer.append( this.$resultsContainer ); - + // Run the default search: if ( this.getDefaultQuery() ){ _this.updateResults(); @@ -935,7 +935,7 @@ mw.RemoteSearchDriver.prototype = { } return false; } ); - + // Set form bindings $j( '#rsd_form' ) .unbind() @@ -944,7 +944,7 @@ mw.RemoteSearchDriver.prototype = { // Don't submit the form return false; } ); - + // Setup base cancel button binding this.onCancelResourceEdit(); }, @@ -962,13 +962,13 @@ mw.RemoteSearchDriver.prototype = { } return enabledProviders; }, - + createProviderSelection: function(){ var _this = this; var $providerSelection = $j( '
    ' ) .addClass( "ui-provider-selection" ); // Add enabled search providers. - $j.each( _this.getEnabledProviders(), function(providerName, provider){ + $j.each( _this.getEnabledProviders(), function(providerName, provider){ var $anchor = $j( '
    ' ) .text( gM( 'rsd-' + providerName + '-title' ) ) .attr({ @@ -977,7 +977,7 @@ mw.RemoteSearchDriver.prototype = { if ( _this.current_provider == providerName) { $anchor.addClass( 'ui-selected' ); } - + $anchor.click( function() { $j( this ).parent().parent().find( '.ui-selected' ) .removeClass( 'ui-selected' ); @@ -987,7 +987,7 @@ mw.RemoteSearchDriver.prototype = { _this.updateResults( _this.current_provider, true ); return false; }); - + var $listItem = $j( '
  • ' ); $listItem.append( $anchor ); $providerSelection.append( $listItem ); @@ -1004,24 +1004,24 @@ mw.RemoteSearchDriver.prototype = { .addClass( "rsd_control_container" ); var $searchForm = $j( '
    ' ).attr({ - id : "rsd_form", + id : "rsd_form", action : "javascript:return false" }); - - var $searchButton = $j.button({ - icon: 'search', - text: gM( 'mwe-media_search' ) + + var $searchButton = $j.button({ + icon: 'search', + text: gM( 'mwe-media_search' ) }) .addClass( 'rsd_search_button' ) - .click(function () { + .click(function () { if( _this.current_provider == 'upload' ){ - _this.current_provider = _this.previus_provider; + _this.current_provider = _this.previus_provider; } _this.updateResults( _this.current_provider, true ); return false; }); - + var $searchBox = $j( '' ) .addClass( 'ui-corner-all' ) .attr({ @@ -1046,7 +1046,7 @@ mw.RemoteSearchDriver.prototype = { $searchForm.append( $searchBox ); $searchForm.append( $searchButton ); - + // Add optional upload buttons. if ( this.content_providers['upload'].enabled) { $uploadButton = $j.button( { icon: 'disk', text: gM( 'mwe-upload_tab' ) }) @@ -1061,33 +1061,33 @@ mw.RemoteSearchDriver.prototype = { return false; }); $searchForm.append( $uploadButton ); - /* + /* // Import functionality not yet supported $importButton = $j.button({icon: 'import', text: 'import'}) .addClass("rsd_import_button"); .append( $importButton ); */ } - + $controlContainer.append( $searchForm ); - + return $controlContainer; }, - + /** * Shows the upload tab loader and issues a call to showUploadForm */ showUploadTab: function() { mw.log( "showUploadTab::" ); var _this = this; - + // Set the tab container to loading: this.$resultsContainer.loadingSpinner(); - + // Show the upload form (use the standard module AddMedia.firefogg // This way we get a high cache hit rate by using a general module - // and not grouping mw.UploadForm into the upload code set - mw.load( [ 'AddMedia.firefogg', 'AddMedia.UploadForm' ], function() { + // and not grouping mw.UploadForm into the upload code set + mw.load( [ 'AddMedia.firefogg', 'AddMedia.UploadForm' ], function() { var provider = _this.content_providers[ 'this_wiki' ]; // Load this_wiki search system to grab the resource _this.loadSearchLib( provider, function() { @@ -1095,15 +1095,15 @@ mw.RemoteSearchDriver.prototype = { } ); } ); }, - + /** * Once the uploadForm is ready display it for the upload provider - * + * * @param {Object} provider Provider object for Upload From */ showUploadForm: function( provider ) { var _this = this; - + // Do basic layout form on left upload "bin" on right $uploadTableRow = $j('
').attr( { @@ -1116,117 +1116,117 @@ mw.RemoteSearchDriver.prototype = { .append( $j('

') .addClass( 'upload-a-file-msg' ) - .text( gM( 'mwe-upload-a-file' ) ), - + .text( gM( 'mwe-upload-a-file' ) ), + $j('
').attr({ 'id': 'rsd_upload_form' }) .loadingSpinner() ), - + $j('

').attr( { 'valign' : 'top', 'id':'upload_bin' } ) .loadingSpinner() ) - this.$resultsContainer.html( + this.$resultsContainer.html( $j('').append( $uploadTableRow - ) + ) ); - - this.showRecentUserUploads( '#upload_bin' ); - + + this.showRecentUserUploads( '#upload_bin' ); + // Send the upload target menu from UploadForm class mw.UploadForm.getUploadMenu( { 'target': '#rsd_upload_form', - 'uploadTargets' : _this.getUploadTargets(), + 'uploadTargets' : _this.getUploadTargets(), 'remoteSearchDriver' : this, 'selectUploadProviderCb' : function( uploadProvider ){ _this.$resultsContainer.find( '.upload-a-file-msg' ).html( gM( 'mwe-upload-a-file-to', uploadProvider.title ) ); } - } ); + } ); }, - + /** * Show recent user uploads */ showRecentUserUploads: function( target ){ - var _this = this; - var uploadTargets = this.getUploadTargets(); - + var _this = this; + var uploadTargets = this.getUploadTargets(); + $j( target ).empty(); - + // Show recent uploads for each upload target for( var uploadTargetId in uploadTargets ){ var uploadTarget = uploadTargets[ uploadTargetId ]; - + $j( target ).append( $j( '

' ) - .append( - gM( 'mwe-your-recent-uploads', uploadTarget.title ) + .append( + gM( 'mwe-your-recent-uploads', uploadTarget.title ) ), - + // Add the targetUpload container $j('
') - .attr( 'id', 'user-results-' + uploadTargetId ) + .attr( 'id', 'user-results-' + uploadTargetId ) ) // Issue the call to get the recent uploads: - _this.showUserRecentUploads( uploadTargetId ); + _this.showUserRecentUploads( uploadTargetId ); } - + }, - + /** * Show recent uploads - * @param {String} uploadTargetId The upload target id + * @param {String} uploadTargetId The upload target id */ - showUserRecentUploads: function( uploadTargetId ){ + showUserRecentUploads: function( uploadTargetId ){ var _this = this; var provider = _this.content_providers[ uploadTargetId ]; var uploadTargets = _this.getUploadTargets(); var uploadApiUrl = uploadTargets[ uploadTargetId ].apiUrl ; - + // Set the target to a loadingSpinner $j('#user-results-' + uploadTargetId ).loadingSpinner(); - + // If the target is not local or we don't have a userName - // ( try and grab the user name via api call (will be a proxy call if remote) ) + // ( try and grab the user name via api call (will be a proxy call if remote) ) mw.getUserName( uploadApiUrl, function( userName ) { if ( userName === false ) { - var logInLink = uploadApiUrl.replace( 'api.php', 'index.php' ) + '?title=Special:UserLogin'; - // Timed out or proxy not setup ( for remotes ) - $j( '#user-results-' + uploadTargetId ).html( - gM( "mwe-not-logged-in-uploads", + var logInLink = uploadApiUrl.replace( 'api.php', 'index.php' ) + '?title=Special:UserLogin'; + // Timed out or proxy not setup ( for remotes ) + $j( '#user-results-' + uploadTargetId ).html( + gM( "mwe-not-logged-in-uploads", $j( '' ) .attr( { 'href': logInLink, 'target' : '_new' }) .append( gM( 'mwe-loggin-link' ) ), - + $j( '' ) .attr( { 'href': '#' }) .addClass('try-again') - .append( gM( 'mwe-try-again-link' ) ) + .append( gM( 'mwe-try-again-link' ) ) ) ); - + // If using Internet Exploer it could be IE privacy settings ( aka "evil eye" ) // http://stackoverflow.com/questions/389456/cookie-blocked-not-saved-in-iframe-in-internet-explorer if( $j.browser.msie ){ - $j( '#user-results-' + uploadTargetId ).append( + $j( '#user-results-' + uploadTargetId ).append( $j('
'), $j('
'), - + $j('') .text( gM('mwe-ie-eye-permision' ) ), - + $j('
' ) .attr( { 'alt' : gM('mwe-ie-eye-permision' ) @@ -1234,113 +1234,113 @@ mw.RemoteSearchDriver.prototype = { .addClass( 'rsd_cookies_blocked_MSIE' ) ); } - - // Note if we updated gM to return jQuery ojbects then we could + + // Note if we updated gM to return jQuery ojbects then we could // bind above $j( '#user-results-' + uploadTargetId ) .find( '.try-again' ) .click(function(){ mw.log(" try again:: " + uploadTargetId); - $j( '#user-results-' + uploadTargetId ).empty().loadingSpinner(); + $j( '#user-results-' + uploadTargetId ).empty().loadingSpinner(); // Refresh the user uploads _this.showUserRecentUploads( uploadTargetId ); - }) + }) } else { _this.showUserRecentUploadsWithUser( uploadTargetId, userName ); } - } ); - }, - + } ); + }, + showUserRecentUploadsWithUser: function( uploadTargetId, userId ){ - var _this = this; + var _this = this; var provider = this.content_providers[ uploadTargetId ]; - - // Setup a local scope function to call the search - // ( since we may have to load the provider search lib ) + + // Setup a local scope function to call the search + // ( since we may have to load the provider search lib ) function doProviderSearch(){ - provider.sObj.getUserRecentUploads( userId, function( ) { + provider.sObj.getUserRecentUploads( userId, function( ) { _this.showResults( { - 'resultsContainer' : $j( '#user-results-' + uploadTargetId ), + 'resultsContainer' : $j( '#user-results-' + uploadTargetId ), 'provider' : provider, 'hideResultsHeader' : true }); } ); } - - // Make sure the provider has a search object: + + // Make sure the provider has a search object: if (!provider.sObj) { this.loadSearchLib( provider, function() { - doProviderSearch(); - } ); + doProviderSearch(); + } ); } else { doProviderSearch(); - } + } }, - + /** * Get the upload targets - * NOTE: this should be configurable + * NOTE: this should be configurable */ - getUploadTargets: function(){ + getUploadTargets: function(){ // Setup upload targets var uploadTargets = { }; - - // Always include commons upload target: + + // Always include commons upload target: // Setup commons upload target var commonsProvider = this.content_providers[ 'wiki_commons' ]; // Check for commons upload page - var commonsUploadPage = 'Commons:Upload'; - - // Add the user language of the commonsUploadPage link + var commonsUploadPage = 'Commons:Upload'; + + // Add the user language of the commonsUploadPage link if( typeof wgUserLanguage != 'undefined' && wgUserLanguage != 'en' ) { commonsUploadPage += '/' + wgUserLanguage; } - + uploadTargets[ 'wiki_commons' ] = { 'apiUrl' : commonsProvider.apiUrl, 'title' : gM( 'rsd-wiki_commons-title'), 'uploadPage' : commonsProvider.apiUrl.replace( 'api.php', 'index.php' ) + '?title=' + commonsUploadPage } - + // If we are ~on commons~ no other links needed: if( mw.parseUri( document.URL ).host == 'commons.wikimedia.org' ) { return uploadTargets; - } - + } + // Check if we have a link to commons for our t-upload toolbox link: - // ( ie the project does not support local uploads ) + // ( ie the project does not support local uploads ) $uploadLink = $j( '#t-upload' ).find('a'); if( $uploadLink.length && mw.parseUri( $uploadLink.attr('href') ).host == 'commons.wikimedia.org' ) { return uploadTargets; - } - + } + // Else this_wiki accepts uploads setup upload links: - // NOTE this should be set via setConfig calls - var thisWikiProvider = this.content_providers[ 'this_wiki' ]; + // NOTE this should be set via setConfig calls + var thisWikiProvider = this.content_providers[ 'this_wiki' ]; uploadTargets[ 'this_wiki' ] = { 'apiUrl' : thisWikiProvider.apiUrl, - // Add a warning that the user should really target commons: - 'providerDescription' : gM('mwe-warning-upload-to-commons', + // Add a warning that the user should really target commons: + 'providerDescription' : gM('mwe-warning-upload-to-commons', mw.parseUri( thisWikiProvider.apiUrl ).host, $j( '' ) - .attr( { + .attr( { 'href' : $uploadLink.attr('href'), 'target' : '_new' } ) .text( gM('mwe-local-upload-policy-link') ) ), - // Unfortunately mediaWiki pages don't expose the title of the wiki - // Could get in an api request ( just use domain for now) + // Unfortunately mediaWiki pages don't expose the title of the wiki + // Could get in an api request ( just use domain for now) 'title' : mw.parseUri( thisWikiProvider.apiUrl ).host, - 'uploadPage' : $uploadLink.attr('href') + 'uploadPage' : $uploadLink.attr('href') } return uploadTargets; }, - + /** - * Refresh the results container ( based on current_provider var ) + * Refresh the results container ( based on current_provider var ) */ updateResults: function() { if ( this.current_provider == 'upload' ) { @@ -1349,7 +1349,7 @@ mw.RemoteSearchDriver.prototype = { this.updateSearchResults( this.current_provider, false ); } }, - + /** * Show updated search results for a given providerName * @@ -1361,22 +1361,22 @@ mw.RemoteSearchDriver.prototype = { var draw_direct_flag = true; var provider = this.content_providers[ providerName ]; - + // Check if we need to update: if ( typeof provider.sObj != 'undefined' ) { - if ( provider.sObj.last_query == $j( this.target_search_input ).val() + if ( provider.sObj.last_query == $j( this.target_search_input ).val() && provider.sObj.last_offset == provider.offset ) { - - mw.log( 'last query is: ' + provider.sObj.last_query + - ' matches: ' + $j( this.target_search_input ).val() + ' no search needed'); - - // Show search results directly + + mw.log( 'last query is: ' + provider.sObj.last_query + + ' matches: ' + $j( this.target_search_input ).val() + ' no search needed'); + + // Show search results directly this.showResults( ); // Done with processing return true; } } - + // See if we should reset the paging if ( resetPaging ) { provider.offset = 0; @@ -1390,10 +1390,10 @@ mw.RemoteSearchDriver.prototype = { this.$resultsContainer.text( 'Please insert a search string above.' ); return; } - + // Set the content to loading while we do the search: this.$resultsContainer.loadingSpinner(); - + // Make sure the search library is loaded and issue the search request this.performProviderSearch( provider ); }, @@ -1401,9 +1401,9 @@ mw.RemoteSearchDriver.prototype = { /* * Issue a api request & cache the result this check can be avoided by setting the * this.import_url_mode = 'api' | 'form' | instead of 'autodetect' or 'none' - * - * @param {function} callback function to be called once we have checked for copy by url support - */ + * + * @param {function} callback function to be called once we have checked for copy by url support + */ checkForCopyURLSupport: function ( callback ) { var _this = this; mw.log( 'checkForCopyURLSupport:: ' ); @@ -1425,11 +1425,11 @@ mw.RemoteSearchDriver.prototype = { 'modules': 'upload' } mw.getJSON( _this.upload_api_target, request, function( data ) { - _this.checkCopyURLApiResult( data, callback ) + _this.checkCopyURLApiResult( data, callback ) } ); } }, - + /** * Evaluate the result of an api copyURL permision request * @@ -1443,7 +1443,7 @@ mw.RemoteSearchDriver.prototype = { var pname = data.paraminfo.modules[0].parameters[i].name; if ( pname == 'url' ) { mw.log( 'Autodetect Upload Mode: api: copy by url:: ' ); - // Check permission too: + // Check permission too: _this.checkForCopyURLPermission( function( canCopyUrl ) { if ( canCopyUrl ) { _this.import_url_mode = 'api'; @@ -1455,28 +1455,28 @@ mw.RemoteSearchDriver.prototype = { callback(); } } ); - // End the pname search once we found the the "url" param - break; + // End the pname search once we found the the "url" param + break; } } }, - + /** * checkForCopyURLPermission: - * not really necessary the api request to upload will return appropriate error + * not really necessary the api request to upload will return appropriate error * if the user lacks permission. or $wgAllowCopyUploads is set to false * (use this function if we want to issue a warning up front) * * @param {Function} callback Function to call with URL permission - * @return - * false callback user does not have permission + * @return + * false callback user does not have permission */ checkForCopyURLPermission: function( callback ) { var _this = this; // do api check: - var request = { - 'meta' : 'userinfo', - 'uiprop' : 'rights' + var request = { + 'meta' : 'userinfo', + 'uiprop' : 'rights' }; mw.getJSON( _this.upload_api_target, request, function( data ) { for ( var i=0; i < data.query.userinfo.rights.length; i++ ) { @@ -1490,18 +1490,18 @@ mw.RemoteSearchDriver.prototype = { callback( false ); } ); }, - + /** * Performs the search for a given content provider - * + * * Calls showResults once search results are ready - * - * @param {Object} provider the provider to be searched. + * + * @param {Object} provider the provider to be searched. */ performProviderSearch: function( provider ) { var _this = this; mw.log( 'f: performProviderSearch ' ); - // First check if we should even run the search at all (can we import / insert + // First check if we should even run the search at all (can we import / insert // into the page? ) if ( !this.isProviderLocal( provider ) && this.import_url_mode == 'autodetect' ) { // provider is not local check if we can support the import mode: @@ -1510,12 +1510,12 @@ mw.RemoteSearchDriver.prototype = { } ); return false; } else if ( !this.isProviderLocal( provider ) && this.import_url_mode == 'none' ) { - if ( this.current_provider == 'combined' ) { + if ( this.current_provider == 'combined' ) { // Combined results are harder to error handle just ignore that repo provider.sObj.loading = false; } else { this.$resultsContainer.html ( - gM( 'mwe-no-import-by-url', + gM( 'mwe-no-import-by-url', $j('') .attr({ 'href' : 'http:\/\/www.mediawiki.org\/wiki\/Manual:$wgAllowCopyUploads', @@ -1527,7 +1527,7 @@ mw.RemoteSearchDriver.prototype = { } return false; } - + if (!provider.sObj) { this.loadSearchLib( provider, this.getProviderCallback() ); } @@ -1535,78 +1535,78 @@ mw.RemoteSearchDriver.prototype = { this.getProviderCallback()( provider ); } }, - + /** * Callback for performing a search, given to providers for provider-activated - * searches e.g. filter state changes. This is probably also the future way to + * searches e.g. filter state changes. This is probably also the future way to * implement "pushing" results. - * - * The returned callback accepts two arguments. - * + * + * The returned callback accepts two arguments. + * * The first, mandatory, is the - * provider object. This should be curried with the current provider object + * provider object. This should be curried with the current provider object * before handing over. (i.e. this.curry(this.getProviderCallback(), provider). - * + * * The second, optional, is the current results list to be replaced by a spinner. */ getProviderCallback: function() { - + var _this = this; return function ( provider, $location ) { var d = new Date(); var searchTime = d.getMilliseconds(); - + // If we are given a result location, we hide them. if ($location) { $location.loadingSpinner(); } - + var d = new Date(); var context = _this.storeContext( d.getTime() ); _this.currentRequest = context(); mw.log( "ProviderCallBack Generated " + context() ) - provider.sObj.getSearchResults( $j( _this.target_search_input ).val() , - function( resultStatus ) { - mw.log( "ProviderCallBack Received " + context() ); + provider.sObj.getSearchResults( $j( _this.target_search_input ).val() , + function( resultStatus ) { + mw.log( "ProviderCallBack Received " + context() ); if( _this.currentRequest != context() ) { mw.log( "Context mismatch for request " + _this.currentRequest + ' != ' + context ); - // do not update the results this.currentRequest + // do not update the results this.currentRequest // does not match the interface request state. - return false; - } + return false; + } //else update search results _this.showResults(); } ); - + // Set a timeout of 20 seconds setTimeout( function() { }, 20 * 1000 ); }; }, - + /** * Persists an object via closure to enable later context checking. * This can be used e.g. when sending multiple getJSON requests and * wanting to act only on the last request sent. - * + * * @param {Object} Object to store in context. - * + * * @return {function} A callback to retrieve the context. */ storeContext: function( contextObject ) { var context = contextObject; - return function() { + return function() { return context; } }, - + /** * Loads a providers search library - * + * * @param {Object} provider content provider to be loaded - * @param {Function} callback Function to call once provider is loaded + * @param {Function} callback Function to call once provider is loaded * ( provider is passed back in callback to avoid possible concurancy issues in multiple load calls) */ loadSearchLib: function( provider, callback ) { @@ -1632,17 +1632,17 @@ mw.RemoteSearchDriver.prototype = { // inherit defaults if not set: provider.limit = provider.limit ? provider.limit : provider.sObj.limit; provider.offset = provider.offset ? provider.offset : provider.sObj.offset; - + callback( provider ); } ); }, - + /** - * Get a resource from a url loads the provider if not already initialized + * Get a resource from a url loads the provider if not already initialized */ - getResourceFromUrl: function ( provider, url, callback){ + getResourceFromUrl: function ( provider, url, callback){ if (!provider.sObj) { - this.loadSearchLib( provider, function( provider ){ + this.loadSearchLib( provider, function( provider ){ provider.sObj.getResourceFromUrl( url, callback); }); } @@ -1650,13 +1650,13 @@ mw.RemoteSearchDriver.prototype = { provider.sObj.getResourceFromUrl( url, callback); } }, - + /** - * Get a resource from a titleKey loads the provider if not already initialized + * Get a resource from a titleKey loads the provider if not already initialized */ - getResourceFromTitleKey: function ( provider, title, callback){ + getResourceFromTitleKey: function ( provider, title, callback){ if (!provider.sObj) { - this.loadSearchLib( provider, function( provider ){ + this.loadSearchLib( provider, function( provider ){ provider.sObj.getByTitle( title, callback); }); } @@ -1690,39 +1690,39 @@ mw.RemoteSearchDriver.prototype = { // TODO: turn this into a global helper function. curry: function ( fn ) { - var args = []; - for (var i = 1, len = arguments.length; i ' ).addClass( 'rsd_results_body' ); var $resultsList = $j( '
' ).addClass( 'rsd_results_list' ); - + // Add the results header: - $resultsContainer.empty(); - + $resultsContainer.empty(); + if( ! options.hideResultsHeader ){ $resultsContainer.append( this.createResultsHeader() ) } - + // Enable search filters, if the provider supports them. if ( provider.sObj.filters && !(provider.disable_filters) ) { - provider.sObj.filters.filterChangeCallBack = + provider.sObj.filters.filterChangeCallBack = this.curry( this.getProviderCallback(), provider, $resultsList ); $resultsBody.append( provider.sObj.filters.getHTML().attr ({ id: 'rsd_filters_container' })); } - + var numResults = 0; // Output all the results for the current current_provider @@ -1764,74 +1764,74 @@ mw.RemoteSearchDriver.prototype = { // Put in the tab output (plus clear the output) $resultsList.append( '
' ); } - + $resultsBody.append( $resultsList ); $resultsContainer.append( $resultsBody ); - - // @@TODO should abstract footer and header ~outside~ of search results + + // @@TODO should abstract footer and header ~outside~ of search results // to have less leakage with upload tab if ( this.current_provider != 'upload' ) { $resultsContainer.append( _this.createResultsFooter() ); } - - mw.log( 'did numResults :: ' + numResults + ' append: ' + $j( this.target_search_input ).val() ); - + + mw.log( 'did numResults :: ' + numResults + ' append: ' + $j( this.target_search_input ).val() ); + // Add "no search results" text $j( '#rsd_no_search_res' ).remove(); if ( numResults == 0 ) { // NOTE: we should handle no-results with a callback not with condition check if( _this.current_provider == 'upload' ) { - $resultsContainer.append( + $resultsContainer.append( gM( 'mwe-no_recent_uploads' ) ); } else { - $resultsContainer.append( + $resultsContainer.append( gM( 'rsd_no_results', $j( this.target_search_input ).val() ) ) ; } } this.addResultBindings(); - + if( typeof this.displaySearchResultsCallback == 'function'){ this.displaySearchResultsCallback(); } }, - + /** - * Show failure + * Show failure */ showFailure : function( resultStatus ) { - //only one type of resultStatus right now: + //only one type of resultStatus right now: if( resultStatus == 'timeout' ) $j( '#tab-' + this.current_provider ).text( - gM('rsd-search-timeout') + gM('rsd-search-timeout') ) }, - + /** * Get result html, calls getResultHtmlBox or - + * @param {Object} provider the content provider for result * @param {Number} resIndex the resource index to build unique ids - * @param {Object} resource the resource object + * @param {Object} resource the resource object */ getResultHtml: function( provider, resIndex, resource ) { if ( this.displayMode == 'box' ) { return this.getResultHtmlBox( provider, resIndex, resource ); }else{ - return this.getResultHtmlList( provider, resIndex, resource ); + return this.getResultHtmlList( provider, resIndex, resource ); } }, - + /** - * Get result html for box layout + * Get result html for box layout * * @param {Object} provider the content provider for result * @param {Number} resIndex the resource index to build unique ids - * @param {Object} resource the resource object + * @param {Object} resource the resource object */ getResultHtmlBox: function( provider, resIndex, resource ) { - + var $resultBox = $j( '
' ) .addClass( 'mv_clip_box_result rsd_box_result' ) .attr( { @@ -1839,12 +1839,12 @@ mw.RemoteSearchDriver.prototype = { } ) .width( this.thumb_width ) .height( this.thumb_width - 20 ); - - // TODO we need to move these images sound_music_icon-80.png etc into the - // AddMedia module and use the style sheet to refrence them - + + // TODO we need to move these images sound_music_icon-80.png etc into the + // AddMedia module and use the style sheet to refrence them + // Check for missing poster types for audio - if ( (resource.mime == 'audio/ogg' || resource.mime == 'application/ogg') + if ( (resource.mime == 'audio/ogg' || resource.mime == 'application/ogg') && !resource.poster ) { resource.poster = mw.getConfig( 'imagesPath' ) + 'sound_music_icon-80.png'; } @@ -1854,63 +1854,63 @@ mw.RemoteSearchDriver.prototype = { .attr( { id: 'res_' + provider.id + '__' + resIndex, title: resource.title, - src: provider.sObj.getImageTransform( resource, { - 'width': this.thumb_width + src: provider.sObj.getImageTransform( resource, { + 'width': this.thumb_width } ) } ) .width( this.thumb_width ) - .height( parseInt( this.thumb_width * ( resource.height / resource.width ) ) ) - + .height( parseInt( this.thumb_width * ( resource.height / resource.width ) ) ) + $resultBox.append( $resultThumb ); - + if ( resource.link && this.displayResourceInfoIcons ) { var $resultPageLink = $j( '
' ) .addClass( 'rsd_linkback ui-corner-all ui-state-default ui-widget-content' ) .append( $j( '' ) - .attr( { - 'target' : '_new', - 'title' : gM( 'mwe-resource_description_page' ), - 'href' : resource.link - } ) - .append( gM( 'mwe-link' ))); - + .attr( { + 'target' : '_new', + 'title' : gM( 'mwe-resource_description_page' ), + 'href' : resource.link + } ) + .append( gM( 'mwe-link' ))); + $resultBox.append( $resultPageLink ); - } - + } + if ( resource.mime && this.displayResourceInfoIcons ) { $resultBox.append( this.getTypeIcon( resource.mime ) ); } - + // Add license icons if present if ( resource.license && this.displayResourceInfoIcons ) { $resultBox.append( this.getLicenseIconHtml( resource.license ) ); } - + $resultBox.append( '
' ); - + return $resultBox; }, - + /** * Get result html for list layout * * @param {Object} provider the content provider for result * @param {Number} resIndex the resource index to build unique ids - * @param {Object} resource the resource object + * @param {Object} resource the resource object */ getResultHtmlList:function( provider, resIndex, resource ) { - + var $resultBox = $j( '
' ) .addClass( 'mv_clip_list_result' ) .attr( { id: 'mv_result_' + resIndex } ) .width( '90%' ); - + if ( resource.description ) { $resultBox.text( resource.description ); } - + var $resultThumb = $j( '' ) .addClass( 'rsd_res_item rsd_list_item' ) .attr( { @@ -1919,28 +1919,28 @@ mw.RemoteSearchDriver.prototype = { src: provider.sObj.getImageTransform( resource, { 'width': this.thumb_width } ) } ) .width( this.thumb_width ); - + $resultBox.prepend( $resultThumb ); - + // Add license icons if present - if ( resource.license && this.displayResourceInfoIcons ) { + if ( resource.license && this.displayResourceInfoIcons ) { $resultBox.append( this.getLicenseIconHtml( resource.license ) ); } - + $resultBox.append( '
' ); return $resultBox; }, - + /** * Add result bindings * * called after results have been displayed - * Set bindings to showResourceEditor + * Set bindings to showResourceEditor */ addResultBindings: function() { var _this = this; - $j( '.mv_clip_' + _this.displayMode + '_result' ).hover( + $j( '.mv_clip_' + _this.displayMode + '_result' ).hover( function() { $j( this ).addClass( 'mv_clip_' + _this.displayMode + '_result_over' ); // Also set the animated image if available @@ -1949,25 +1949,25 @@ mw.RemoteSearchDriver.prototype = { if ( resource.poster_ani ) $j( '#' + res_id ).attr( 'src', resource.poster_ani ); }, function() { - $j( this ).removeClass( + $j( this ).removeClass( 'mv_clip_' + _this.displayMode + '_result_over' ); var res_id = $j( this ).children( '.rsd_res_item' ).attr( 'id' ); var resource = _this.getResourceFromId( res_id ); // Restore the original (non animated) if ( resource.poster_ani ) $j( '#' + res_id ).attr( 'src', resource.poster ); - } + } ); - + // Resource click action: (bring up the resource editor) - $j( '.rsd_res_item' ).unbind().click( function() { + $j( '.rsd_res_item' ).unbind().click( function() { var resource = _this.getResourceFromId( $j( this ).attr( "id" ) ); - - // xxx These hooks should really be managed via bindings not options like this: + + // xxx These hooks should really be managed via bindings not options like this: var showResourceEditor = true; if( typeof _this.resourceSelectionCallback == 'function' ){ showResourceEditor = _this.resourceSelectionCallback( resource ); - } + } if( showResourceEditor ){ _this.showResourceEditor( resource ); } @@ -1976,7 +1976,7 @@ mw.RemoteSearchDriver.prototype = { // Add a "bind" class .addClass( 'rsd_res_item_bind' ) ; }, - + /** * Add Resource edit layout and display a loader. */ @@ -1986,10 +1986,10 @@ mw.RemoteSearchDriver.prototype = { editWidth = 400; // Remove any old instance: $j( _this.target_container ).find( '#rsd_resource_edit' ).remove(); - + // Hide the results container - this.$resultsContainer.hide(); - + this.$resultsContainer.hide(); + // Set up the interface compoents: var $clipEditControl = $j('
') .attr( 'id', 'clip_edit_ctrl' ) @@ -1998,15 +1998,15 @@ mw.RemoteSearchDriver.prototype = { 'position' : 'absolute', 'left' : '2px', 'top' : '5px', - 'bottom' : '10px', + 'bottom' : '10px', 'width' : ( editWidth + 5 ) + 'px', 'overflow' : 'auto', 'padding' : '5px' } ) .loadingSpinner(); - + mw.log(" clip edit control "); - + var $clipEditDisplay = $j('
') .attr( 'id', 'clip_edit_disp' ) .addClass( 'ui-widget ui-widget-content ui-corner-all' ) @@ -2014,35 +2014,35 @@ mw.RemoteSearchDriver.prototype = { 'position' : 'absolute', 'overflow' : 'auto', 'left' : ( editWidth + 25 ) + 'px', - 'right' :'0px', + 'right' :'0px', 'top' : '5px', 'bottom' : '10px', - 'padding' : '5px' + 'padding' : '5px' }) - .loadingSpinner(); - + .loadingSpinner(); + // Add the edit layout window with loading place holders - $j( _this.target_container ).append( + $j( _this.target_container ).append( $j('
') .attr( 'id', 'rsd_resource_edit' ) .css( { 'position' : 'absolute', 'top' : '0px', - 'left' : '0px', + 'left' : '0px', 'bottom' : '30px', 'right' : '4px', 'background-color' : '#FFF' } ) - .append( + .append( $clipEditControl, $clipEditDisplay ) ); }, - + /** * Get the edit width of a resource - * + * * @param {Object} resource get width of resource */ getDefaultEditWidth: function( resource ) { @@ -2053,13 +2053,13 @@ mw.RemoteSearchDriver.prototype = { return this.defaultVideoEditWidth; } }, - + /** * Get the media Type of a resource * * @param {Object} resource get media type of resource */ - getMediaType: function( resource ) { + getMediaType: function( resource ) { var types = [ 'image', 'audio', 'video']; for( var i=0; i < types.length ; i++ ) { if ( resource.mime.indexOf( types[i] ) !== -1) { @@ -2071,7 +2071,7 @@ mw.RemoteSearchDriver.prototype = { // Media type not found: return false; }, - + /** * Removes the resource editor */ @@ -2083,49 +2083,49 @@ mw.RemoteSearchDriver.prototype = { /** * Show the resource editor * @param {Object} resource Resource to be edited - */ + */ showResourceEditor: function( resource ) { mw.log( 'f:showResourceEditor:' + resource.title ); var _this = this; - + // Remove any existing resource edit interface _this.removeResourceEditor(); mw.log(" removed old resource "); - + // Append to the top level of model window: _this.addResourceEditLoader(); mw.log("done adding resource editor"); var mediaType = _this.getMediaType( resource ); var targetWidth = _this.getDefaultEditWidth( resource ); - - var targetHeight = parseInt( targetWidth * ( resource.height / resource.width ) ); - + + var targetHeight = parseInt( targetWidth * ( resource.height / resource.width ) ); + if( targetHeight > $j('#clip_edit_disp').height() ){ - targetHeight = $j('#clip_edit_disp').height(); + targetHeight = $j('#clip_edit_disp').height(); targetWidth = targetHeight * ( resource.width / resource.height); - } - + } + //mw.log("org h/w" + resource.width + ' / ' + resource.height +' new w' + width + ' new h:' + height ); - + // Update add media wizard title: var dialogTitle = gM( 'mwe-add_media_wizard' ) + ': ' + gM( 'rsd_resource_edit', resource.title ); - + $j( _this.target_container ).dialog( 'option', 'title', dialogTitle ); - + mw.log( 'did append to: ' + _this.target_container ); - + // issue a loadResourceImage request if needed ( image is > than target display resolution ) - if ( mediaType == 'image' && resource.width > targetWidth ) { - _this.loadResourceImage( - resource, + if ( mediaType == 'image' && resource.width > targetWidth ) { + _this.loadResourceImage( + resource, { 'width': targetWidth, 'height' : targetHeight - }, + }, function( img_src ) { - $j('#clip_edit_disp').empty().append( + $j('#clip_edit_disp').empty().append( $j( '' ) .attr( { 'id' : 'rsd_edit_img', @@ -2133,7 +2133,7 @@ mw.RemoteSearchDriver.prototype = { 'width': targetWidth, 'height' : targetHeight } ) - ); + ); } ); } else if ( mediaType == 'image' ) { @@ -2145,10 +2145,10 @@ mw.RemoteSearchDriver.prototype = { 'src' : resource.src, 'width' : resource.width, 'height' : resource.height - } ) + } ) ) } - + // Also fade in the container: $j( '#rsd_resource_edit' ).animate( { 'opacity': 1, @@ -2161,18 +2161,18 @@ mw.RemoteSearchDriver.prototype = { _this.showImageEditor( resource ); } else if ( mediaType == 'video' || mediaType == 'audio' ) { _this.showVideoEditor( resource ); - } + } }, - + /* - * Loads a resource image of set size + * Loads a resource image of set size * * @param {Object} resource requested resource for higher quality image * @param {Object} size the requested size of the higher quality image - * @param {Function} callback the function to be calle once the image is loaded + * @param {Function} callback the function to be calle once the image is loaded */ loadResourceImage: function( resource, size, callback ) { - mw.log( "loadResourceImage" ); + mw.log( "loadResourceImage" ); // Get the image url: resource.pSobj.getImageObj( resource, size, function( imObj ) { resource['edit_url'] = imObj.url; @@ -2181,10 +2181,10 @@ mw.RemoteSearchDriver.prototype = { // Update the resource:: resource['width'] = imObj.width; resource['height'] = imObj.height; - + var width = imObj.width; - var height = imObj.height; - + var height = imObj.height; + // Don't swap it in until its loaded var img = new Image(); // Load the image @@ -2192,23 +2192,23 @@ mw.RemoteSearchDriver.prototype = { // Update changes using the callback callback( resource.edit_url ); } ).error( function () { - mw.log( "Error with: " + resource.edit_url ); + mw.log( "Error with: " + resource.edit_url ); } ).attr( 'src', resource.edit_url ); } ); }, - + /** - * Do cancel edit callbacks and interface updates. + * Do cancel edit callbacks and interface updates. */ onCancelResourceEdit: function() { var _this = this; mw.log( 'onCancelResourceEdit' ); var b_target = _this.target_container + '~ .ui-dialog-buttonpane'; $j( '#rsd_resource_edit' ).remove(); - + // Remove preview if its 'on' $j( '#rsd_preview_display' ).remove(); - + // Remove resource import if present $j( '#rsd_resource_import' ).remove(); // Restore the resource container: @@ -2228,9 +2228,9 @@ mw.RemoteSearchDriver.prototype = { } ); }, - /** + /** * Get the control actions for clipEdit with relevant callbacks - * @param {Object} provider the provider object to + * @param {Object} provider the provider object to */ getClipEditControlActions: function( provider ) { var _this = this; @@ -2250,7 +2250,7 @@ mw.RemoteSearchDriver.prototype = { } return actions; }, - + /** * Clip edit options */ @@ -2274,11 +2274,11 @@ mw.RemoteSearchDriver.prototype = { showImageEditor: function( resource ) { var _this = this; var options = _this.getClipEditOptions( resource ); - - mw.load( [ + + mw.load( [ 'mw.ClipEdit', 'mw.style.ClipEdit' - ], function() { + ], function() { _this.clipEdit = new mw.ClipEdit( options ); }); }, @@ -2294,22 +2294,22 @@ mw.RemoteSearchDriver.prototype = { var mediaType = this.getMediaType( resource ); mw.log( 'media type:: ' + mediaType ); - + // Get any additional embedding helper meta data prior to doing the actual embed - // normally this meta should be provided in the search result + // normally this meta should be provided in the search result // (but archive.org has another query for more media meta) - resource.pSobj.addResourceInfoCallback( resource, function() { + resource.pSobj.addResourceInfoCallback( resource, function() { var runFlag = false; - + // Embed the video html - var embedHtml = resource.pSobj.getEmbedHTML( resource, - { - 'id' : 'embed_vid' - } - ); + var embedHtml = resource.pSobj.getEmbedHTML( resource, + { + 'id' : 'embed_vid' + } + ); mw.log( 'append html: ' + embedHtml ); - $j( '#clip_edit_disp' ).html( embedHtml ); - + $j( '#clip_edit_disp' ).html( embedHtml ); + // Make sure we have the 'EmbedPlayer' module: mw.load( 'EmbedPlayer', function() { // Strange concurrency issue with callbacks @@ -2319,24 +2319,24 @@ mw.RemoteSearchDriver.prototype = { } else { mw.log( 'Error: embedPlayerCheck run twice' ); return false; - } - + } + mw.log( "about to call $j.embedPlayer::embed_vid" ); - - // Rewrite by id - $j( '#embed_vid' ).embedPlayer ( function() { + + // Rewrite by id + $j( '#embed_vid' ).embedPlayer ( function() { // Add extra space at the top if the embed player is less than 90px high - // bug 22189 + // bug 22189 if( $j('#embed_vid').get(0).getPlayerHeight() < 90 ) { - $j( '#clip_edit_disp' ).prepend( + $j( '#clip_edit_disp' ).prepend( $j( '' ) .css({ 'height': '90px', 'display': 'block' - }) + }) ); } - + // Grab information available from the embed instance resource.pSobj.addEmbedInfo( resource, 'embed_vid' ); @@ -2346,7 +2346,7 @@ mw.RemoteSearchDriver.prototype = { 'mw.style.ClipEdit', '$j.ui.resizable' ]; - mw.load( librarySet, function() { + mw.load( librarySet, function() { // Make sure the rsd_edit_img is removed: $j( '#rsd_edit_img' ).remove(); // Run the image clip tools @@ -2356,11 +2356,11 @@ mw.RemoteSearchDriver.prototype = { } ); } ); }, - + /** - * Check if a given content provider is local. + * Check if a given content provider is local. * @param {Object} provider Provider object to be checked - * @return + * @return */ isProviderLocal: function( provider ) { if ( provider.local ) { @@ -2380,12 +2380,12 @@ mw.RemoteSearchDriver.prototype = { }, /** - * Check if the file is either a local upload, or if it has already been - * imported under the standard filename scheme. + * Check if the file is either a local upload, or if it has already been + * imported under the standard filename scheme. * * @param {Object} resource Resouce to check for local file * @param {Function} callback Function to call once check is done - * + * * Calls the callback with two parameters: * callback( resource, status ) * @@ -2411,14 +2411,14 @@ mw.RemoteSearchDriver.prototype = { var provider = resource.pSobj.provider; var _this = this; - // Clone the resource. Not sure why this not-working clone was put here... + // Clone the resource. Not sure why this not-working clone was put here... // using the actual resource should be fine /* var proto = {}; proto.prototype = resource; var myRes = new proto; - */ - + */ + // Update base target_resource_title: resource.target_resource_title = resource.titleKey.replace( /^(File:|Image:)/ , '' ) @@ -2434,7 +2434,7 @@ mw.RemoteSearchDriver.prototype = { if ( provider.check_shared ) { var fileTitle =_this.canonicalFileNS + ':' + resource.target_resource_title; _this.findFileInLocalWiki( fileTitle, function( imagePage ) { - if ( imagePage && imagePage['imagerepository'] == 'shared' || + if ( imagePage && imagePage['imagerepository'] == 'shared' || imagePage['imagerepository'] == 'commons') { resource.commonsShareRepoFlag = true; myCallback( 'shared' ); @@ -2445,7 +2445,7 @@ mw.RemoteSearchDriver.prototype = { } else { _this.isFileAlreadyImported( resource, myCallback ); } - } + } }, /** @@ -2457,15 +2457,15 @@ mw.RemoteSearchDriver.prototype = { * If the image is found, the status will be 'imported' and the resource * will be the new local resource. * - * If the image is not found, the status will be 'missing' and the resource + * If the image is not found, the status will be 'missing' and the resource * will be false. */ isFileAlreadyImported: function( resource, callback ) { mw.log( '::isFileAlreadyImported:: ' ); var _this = this; - // Clone the resource - //( not really needed and confuses the resource pointer role) + // Clone the resource + //( not really needed and confuses the resource pointer role) /*var proto = {}; proto.prototype = resource; var myRes = new proto; @@ -2474,14 +2474,14 @@ mw.RemoteSearchDriver.prototype = { // Update target_resource_title with resource repository prefix: resource.target_resource_title = provider.resource_prefix + resource.target_resource_title; - + // Check if the file exists: - _this.findFileInLocalWiki( resource.target_resource_title, function( imagePage ) { - if ( imagePage ) { + _this.findFileInLocalWiki( resource.target_resource_title, function( imagePage ) { + if ( imagePage ) { // Update to local src - resource.local_src = imagePage['imageinfo'][0].url; - // @@todo maybe update poster too? - resource.local_poster = imagePage['imageinfo'][0].thumburl; + resource.local_src = imagePage['imageinfo'][0].url; + // @@todo maybe update poster too? + resource.local_poster = imagePage['imageinfo'][0].thumburl; // Update the title: resource.target_resource_title = imagePage.title.replace(/^(File:|Image:)/ , '' ); callback( 'imported' ); @@ -2490,33 +2490,33 @@ mw.RemoteSearchDriver.prototype = { } } ); }, - + /** - * Show Import User Interface - * + * Show Import User Interface + * * @param {Object} resource Resource Object to be imported - * @param {Function} callback Function to be called once the resource is imported + * @param {Function} callback Function to be called once the resource is imported */ showImportUI: function( resource, callback ) { var _this = this; - mw.log( "showImportUI:: update:" + _this.canonicalFileNS + ':' + + mw.log( "showImportUI:: update:" + _this.canonicalFileNS + ':' + resource.target_resource_title ); - - var description = _this.getTemplateDescription( resource ); - - + + var description = _this.getTemplateDescription( resource ); + + // Remove any old resource imports $j( '#rsd_resource_import' ).remove(); - + // Update the interface - $j( _this.target_container ).append( - _this.getResourceImportInterface( resource , description ) + $j( _this.target_container ).append( + _this.getResourceImportInterface( resource , description ) ); - + var buttonPaneSelector = _this.target_container + '~ .ui-dialog-buttonpane'; $j( buttonPaneSelector ).html ( // Add the buttons to the bottom: - $j.btnHtml( gM( 'mwe-do_import_resource' ), 'rsd_import_doimport', 'check' ) + + $j.btnHtml( gM( 'mwe-do_import_resource' ), 'rsd_import_doimport', 'check' ) + ' ' + $j.btnHtml( gM( 'mwe-return-search-results' ), 'rsd_import_acancel', 'close' ) + ' ' ); @@ -2529,12 +2529,12 @@ mw.RemoteSearchDriver.prototype = { // Load the preview text: mw.parseWikiText( - description, _this.canonicalFileNS + ':' + resource.target_resource_title, + description, _this.canonicalFileNS + ':' + resource.target_resource_title, function( descHtml ) { $j( '#rsd_import_desc' ).html( descHtml ); - } + } ); - + // Add bindings: $j( _this.target_container + ' .rsd_import_apreview' ) .buttonHover() @@ -2543,22 +2543,22 @@ mw.RemoteSearchDriver.prototype = { $j( '#rsd_import_desc' ).loadingSpinner() ; // load the preview text: mw.parseWikiText( - $j( '#wpUploadDescription' ).val(), - _this.canonicalFileNS + ':' + resource.target_resource_title, + $j( '#wpUploadDescription' ).val(), + _this.canonicalFileNS + ':' + resource.target_resource_title, function( parseHtml ) { mw.log( 'got updated preview: ' ); $j( '#rsd_import_desc' ).html( parseHtml ); - } + } ); return false; } ); - + $j( buttonPaneSelector + ' .rsd_import_doimport' ) .buttonHover() .click( function() { mw.log( "do import asset:" + _this.import_url_mode ); // check import mode: - if ( _this.import_url_mode == 'api' ) { + if ( _this.import_url_mode == 'api' ) { _this.doApiImport( resource, function() { $j( '#rsd_resource_import' ).remove(); _this.clipEdit.updateInsertControlActions(); @@ -2582,9 +2582,9 @@ mw.RemoteSearchDriver.prototype = { return false; } ); }, - + /** - * Get the resource Import interface + * Get the resource Import interface */ getResourceImportInterface: function( resource, description ) { var _this = this; @@ -2599,7 +2599,7 @@ mw.RemoteSearchDriver.prototype = { 'bottom' : '0px', 'z-index' : '5' } ); - + var $rsdPreviewContainer = $j( '
') .attr( 'id', 'rsd_preview_import_container' ) .css( { @@ -2610,15 +2610,15 @@ mw.RemoteSearchDriver.prototype = { 'overflow' : 'auto', 'top' : '30px' } ) - .append( + .append( // Get embedHTML with small thumb: resource.pSobj.getEmbedHTML( resource, { 'id': _this.target_container + '_rsd_pv_vid', 'max_height': '220', 'only_poster': true - } ) + } ) ) - .append( + .append( $j('
') .css( 'clear', 'both' ), $j( '' ) @@ -2629,20 +2629,20 @@ mw.RemoteSearchDriver.prototype = { .css( 'display', 'inline' ) .loadingSpinner() ) - + var $importResourceTitle = $j( '

' ) .css( { 'color' : 'red', 'padding' : '5px' } ) .text( - gM( 'mwe-resource-needs-import', [resource.title, _this.upload_api_name] ) + gM( 'mwe-resource-needs-import', [resource.title, _this.upload_api_name] ) ); - + var $importTitle = $j( '' ) .css( { 'font-weight' : 'bold' } ) - .text( gM( 'mwe-local_resource_title' ) ); - + .text( gM( 'mwe-local_resource_title' ) ); + var $importDestFile = $j( '' ) .attr( { 'id' : 'wpDestFile', @@ -2650,21 +2650,21 @@ mw.RemoteSearchDriver.prototype = { 'size' : '30' } ) .val ( resource.target_resource_title ); - + var $importUploadDescription = $j('
') - .append( + .append( $j( '' ) - .css( { 'font-weight' : 'bold' } ) + .css( { 'font-weight' : 'bold' } ) .text( gM( 'mwe-edit_resource_desc' ) ), $j( ' - - - - - - - diff --git a/modules/EmbedPlayer/tests/Player_IncludeJQuery.html b/modules/EmbedPlayer/tests/Player_IncludeJQuery.html index a04c29a775..147e10f2ff 100644 --- a/modules/EmbedPlayer/tests/Player_IncludeJQuery.html +++ b/modules/EmbedPlayer/tests/Player_IncludeJQuery.html @@ -17,9 +17,9 @@ diff --git a/modules/EmbedPlayer/tests/Player_Sources.html b/modules/EmbedPlayer/tests/Player_Sources.html index 1f5ca91e55..dc66908402 100644 --- a/modules/EmbedPlayer/tests/Player_Sources.html +++ b/modules/EmbedPlayer/tests/Player_Sources.html @@ -3,20 +3,17 @@ Player sources - - + - + diff --git a/modules/EmbedPlayer/tests/Player_Themable.html b/modules/EmbedPlayer/tests/Player_Themable.html index 1c439e3eef..2874e1e6f8 100644 --- a/modules/EmbedPlayer/tests/Player_Themable.html +++ b/modules/EmbedPlayer/tests/Player_Themable.html @@ -3,14 +3,14 @@ Sample Themed Player - Pre-loading demo ( stuff ) likely needed for video display - - + @@ -19,50 +19,50 @@

Sample Themable Player:

To play with dynamic Themes install Themeroller

- - Source Code used:
-
- - - + + (kskin) Source Code used:
-
diff --git a/modules/MiroSubs/MiroSubs.i18n.php b/modules/MiroSubs/MiroSubs.i18n.php index f3595acf39..cc1956d161 100755 --- a/modules/MiroSubs/MiroSubs.i18n.php +++ b/modules/MiroSubs/MiroSubs.i18n.php @@ -9,10 +9,10 @@ $messages = array(); $messages['en'] = array( - 'mwe-mirosubs-add-universal-subtitles' => 'Universal subtitles editor', + 'mwe-mirosubs-add-universal-subtitles' => 'Universal subtitles editor', 'mwe-mirosubs-loading-universal-subtitles' => 'Loading universal subtitles editor', 'mwe-mirosubs-save-summary' => 'Summary of subtitle edits', - 'mwe-mirosubs-save-default' => 'Edited subtitles', + 'mwe-mirosubs-save-default' => 'Edited subtitles', 'mwe-mirosubs-save-subs' => 'Save subtitles', 'mwe-mirosubs-saving-subs' => 'Saving subtitles ...', 'mwe-mirosubs-subs-saved' => 'Subtitles saved', diff --git a/modules/MiroSubs/README b/modules/MiroSubs/README new file mode 100644 index 0000000000..d44ae05768 --- /dev/null +++ b/modules/MiroSubs/README @@ -0,0 +1,13 @@ +This module integrated miro subs support. +http://universalsubtitles.org/ + +The source code to base google closures library: +http://code.google.com/closure/ + +The source code to miro subs: +http://github.com/8planes/mirosubs + +To remain compact, we only include the minifed sources in this module. + +Miros subs code is: +GNU AFFERO GENERAL PUBLIC LICENSE diff --git a/modules/MiroSubs/css/universal-subs-icon-small.png b/modules/MiroSubs/css/universal-subs-icon-small.png new file mode 100644 index 0000000000000000000000000000000000000000..462089b029f30f45fccac934937d0671dca23433 GIT binary patch literal 701 zcmV;u0z&Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2igh< z7A!GCE5L~!W`~d|+2%&_EStvrS5Ht#|j3uP{(&XKlaq-?uUMiW*9WHYY zGv~}G5mE5P+fSF~Y|~jK;T*H1SO8`;SyWl;#P;2*jSv2MrLzU>g31r`A@z%F<|;v)nms)T~9douDOr`y|StB-SXB^Sg z?-Vo%<%nI87*L2jIspa%+{@NmN`=?iS4+$}O)M!-I1=DgY^H=UaXLCvCRbQu0kNcl zL$Lr7fgv7;2MG^EcFF{rL^T~&=kxH-m;5+_R_7o$VzZ#BnRVHj$8n%%tj(9Zv&oa- zXXVRNebe0-S}PFIW%a5yJ>Rw4b-&*tx}j8bJsF=Z*<_=2bdYzzlpfeE;8P*gxlg8|mBz0yCN3=Azxm!8xkfLZmZs;r{i9W4&Urh+f+i$T jo(LwkAKv~xa?bw%&FbZE0Ub@%00000NkvXXu0mjf_AoKA literal 0 HcmV?d00001 diff --git a/modules/MiroSubs/loader.js b/modules/MiroSubs/loader.js index 5ee5d7a005..b64ffd66fd 100755 --- a/modules/MiroSubs/loader.js +++ b/modules/MiroSubs/loader.js @@ -5,49 +5,49 @@ // Wrap in mw to not pollute global namespace ( function( mw ) { mw.addMessages( { - "mwe-mirosubs-add-universal-subtitles" : "Universal subtitles editor", + "mwe-mirosubs-add-universal-subtitles" : "Universal subtitles editor", "mwe-mirosubs-loading-universal-subtitles" : "Loading universal subtitles editor" }); - // add as loader dependency 'mw.style.mirosubsMenu' - - mw.addResourcePaths( { + // add as loader dependency 'mw.style.mirosubsMenu' + + mw.addResourcePaths( { "mirosubs" : "mirosubs/mirosubs-api.min.js", "mw.MiroSubsConfig" : "mw.MiroSubsConfig.js", "mw.style.mirosubsMenu" : "css/mw.style.mirosubsMenu.css", "mw.style.mirosubswidget" : "mirosubs/media/css/mirosubs-widget.css" }); - + mw.setDefaultConfig( { 'MiroSubs.EnableUniversalSubsEditor': true }) - + mw.addModuleLoader( 'MiroSubs', function(){ var resourceList = [ "mirosubs", "mw.style.mirosubswidget", "mw.MiroSubsConfig" ]; return resourceList; }); - - $j( mw ).bind( 'newEmbedPlayerEvent', function( event, embedPlayer ){ - // Check if the Miro Editor is enabled and the player has an apiTitleKey - if( mw.getConfig( 'MiroSubs.EnableUniversalSubsEditor' ) - && + + $j( mw ).bind( 'newEmbedPlayerEvent', function( event, embedPlayer ){ + // Check if the Miro Editor is enabled and the player has an apiTitleKey + if( mw.getConfig( 'MiroSubs.EnableUniversalSubsEditor' ) + && embedPlayer.apiTitleKey - ){ + ){ // Build out the menu in the loader ( to load mirosubs interface on-demand ) $j( embedPlayer ).bind( 'TimedText.BuildCCMenu', function( event, langMenu ){ - - // Load the miro subs menu style ( will be part of the loader dependency later on) - mw.load( 'mw.style.mirosubsMenu' ); - - $j( langMenu ).append( - $j.getLineItem( gM( 'mwe-mirosubs-add-universal-subtitles'), 'mirosubs', function() { + + // Load the miro subs menu style ( will be part of the loader dependency later on) + mw.load( 'mw.style.mirosubsMenu' ); + + $j( langMenu ).append( + $j.getLineItem( gM( 'mwe-mirosubs-add-universal-subtitles'), 'mirosubs', function() { // Show loader - mw.addLoaderDialog( gM('mwe-mirosubs-loading-universal-subtitles') ); + mw.addLoaderDialog( gM('mwe-mirosubs-loading-universal-subtitles') ); // Load miro subs: mw.load( 'MiroSubs', function(){ - // Open the mirosubs dialog: + // Open the mirosubs dialog: mw.MiroSubsConfig.openDialog( embedPlayer, function(){ // dialog Ready close loader - mw.closeLoaderDialog(); + mw.closeLoaderDialog(); }); }); return false; @@ -56,6 +56,6 @@ }); }; }); - - + + } )( window.mw ); \ No newline at end of file diff --git a/modules/MiroSubs/mw.MiroSubsConfig.js b/modules/MiroSubs/mw.MiroSubsConfig.js index 847c4a1cfe..8951d8bf48 100755 --- a/modules/MiroSubs/mw.MiroSubsConfig.js +++ b/modules/MiroSubs/mw.MiroSubsConfig.js @@ -1,12 +1,11 @@ - // include all module messages mw.includeAllModuleMessages(); -/** +/** * Generates a miro subs config also see: * http://dev.universalsubtitles.org/widget/api_demo.html */ -mw.MiroSubsConfig = { +mw.MiroSubsConfig = { openDialog: function( embedPlayer, dialogReadyCallback ){ var _this = this; this.getConfig( embedPlayer , function( config ){ @@ -14,34 +13,34 @@ mw.MiroSubsConfig = { return ; } // xxx NOTE there are some weird async display issues - // that only seem to be resolvable with timeouts for DOM actions + // that only seem to be resolvable with timeouts for DOM actions setTimeout(function(){ - dialogReadyCallback(); + dialogReadyCallback(); }, 100); - // Show the dialog + // Show the dialog setTimeout(function(){ _this.mirosubs = mirosubs.api.openDialog( config ); }, 800); - }); + }); }, /** * @param {Function} callback is called with two arguments 'status', 'config' */ getConfig : function( embedPlayer, callback ){ var _this = this; - + if( _this.isConfigReady( callback ) ){ // if config is ready stop chain return true; } - + //Set up a local pointer to the embedPlayer: this.embedPlayer = embedPlayer; - + // Set initial config this.config = this.getDefaultConfig(); - - // Make sure we are logged in:: + + // Make sure we are logged in:: mw.getUserName( function( userName ){ mw.log( "MiroSubsConfig::getUserName: " + userName ); if( !userName ){ @@ -49,76 +48,76 @@ mw.MiroSubsConfig = { 'title' : gM('mwe-mirosubs-subs-please-login'), 'content' : gM('mwe-mirosubs-subs-please-login-desc') }); - callback( false ); + callback( false ); return false; } else { - _this.config.username = userName; + _this.config.username = userName; if( _this.isConfigReady( callback ) ){ return true; } } }); - // Get the subtitles + // Get the subtitles _this.getSubsInMiroFormat( function( miroSubs ){ mw.log("MiroSubsConfig::getSubsInMiroFormat: got" + miroSubs.length + ' subs'); // no failure for miro subs ( just an empty object ) _this.config.subtitles = miroSubs; - + // Once everything is setup issue the callback with the miro config: if( _this.isConfigReady( callback ) ){ return true; } - }); + }); }, // Check all async values for config ready run the callback if its ready isConfigReady: function( callback ){ if( !this.config ){ return false; } - if( this.config.subtitles + if( this.config.subtitles && - this.config.username + this.config.username ){ callback( this.config ) return true; } - return false; + return false; }, getDefaultConfig: function(){ var _this = this; return { // By default the config status is 'ok' 'status' : 'ok', - + // Default language key 'en': 'languageKey' : 'en', - + 'closeListener': function(){ - // close event refresh page? + // close event refresh page? // make sure any close dialog is 'closed' mw.closeLoaderDialog(); }, 'videoURL' : _this.getVideoURL(), - 'save': function( miroSubs, doneSaveCallback, cancelCallback) { - // Close down the editor + 'save': function( miroSubs, doneSaveCallback, cancelCallback) { + // Close down the editor doneSaveCallback(); - // Close the miro subs widget: - _this.mirosubs.close(); + // Close the miro subs widget: + _this.mirosubs.close(); // Convert the miroSubs to srt // again strange issues with miroSubs give it time to close setTimeout( function(){ - var srtText = _this.miroSubs2Srt( miroSubs ); + var srtText = _this.miroSubs2Srt( miroSubs ); $saveDialog = _this.getSaveDialogSummary( function( summary ){ if( summary === false ){ - // Return to current page without saving the text - location.reload(true); + // Return to current page without saving the text + location.reload(true); return ; } - _this.saveSrtText( srtText, summary, function(status){ + _this.saveSrtText( srtText, summary, function(status){ // No real error handling right now - // refresh page regardless of save or cancel - + // refresh page regardless of save or cancel + if( status ){ $saveDialog .dialog("option", 'title', gM('mwe-mirosubs-subs-saved') ) @@ -134,32 +133,32 @@ mw.MiroSubsConfig = { location.reload(true); }; $saveDialog.dialog("option", "buttons", button ); - }); + }); }); }, 100 ); }, - 'mediaURL': mw.getMwEmbedPath() + 'modules/MiroSubs/mirosubs/media/', + 'mediaURL': mw.getMwEmbedPath() + 'modules/MiroSubs/mirosubs/media/', 'permalink': 'http://commons.wikimedia.org', // not sure if this is needed 'login': function( ){ mirosubs.api.loggedIn( wgUserName ); - }, + }, 'embedCode' : 'some code to embed' - }; + }; }, getSaveDialogSummary: function( callback ){ // Add a dialog to get save summary var buttons ={}; buttons[ gM('mwe-mirosubs-save-subs') ] = function(){ var summary = $j('#mwe-mirosubs-save-summary').val(); - // Append link to gadget: + // Append link to gadget: summary+= ' using [[Commons:Universal_Subtitles|UniversalSubs]]'; - callback( summary ); + callback( summary ); // set dialog to loading - $j( this ).html( $j('
').append( - gM('mwe-mirosubs-saving-subs'), + $j( this ).html( $j('
').append( + gM('mwe-mirosubs-saving-subs'), $j('
') - .loadingSpinner() + .loadingSpinner() ) ) .dialog( "option", "buttons", false ) @@ -169,10 +168,10 @@ mw.MiroSubsConfig = { callback( false ); $j( this ).dialog( 'close' ); }; - // Reduce the z-index so we can put the model ontop: + // Reduce the z-index so we can put the model ontop: //$j('.mirosubs-modal-widget-bg,.mirosubs-modal-widget').css( 'z-index', 10 ); var $dialog = mw.addDialog( { - 'title' : gM("mwe-mirosubs-save-summary"), + 'title' : gM("mwe-mirosubs-save-summary"), 'width' : 450, 'content' : $j('
').append( $j('

').text( gM("mwe-mirosubs-save-summary") ), @@ -182,25 +181,25 @@ mw.MiroSubsConfig = { }).val( gM('mwe-mirosubs-save-default') ) ), 'buttons' : buttons - }); + }); return $dialog; }, saveSrtText: function( srtText, summary, callback ){ - var _this = this; - var timedTextTitle = 'TimedText:' + - this.embedPlayer.apiTitleKey + + var _this = this; + var timedTextTitle = 'TimedText:' + + this.embedPlayer.apiTitleKey + '.' + this.config.languageKey + '.srt'; - + // Try to get sources from text provider: - var provider_id = ( this.embedPlayer.apiProvider ) ? this.embedPlayer.apiProvider : 'local'; + var provider_id = ( this.embedPlayer.apiProvider ) ? this.embedPlayer.apiProvider : 'local'; var apiUrl = mw.getApiProviderURL( provider_id ); - + mw.getToken( apiUrl, timedTextTitle, function( token ) { var request = { 'action':'edit', 'title': timedTextTitle, 'text': srtText, - 'summary': summary, + 'summary': summary, 'token': token }; mw.getJSON( apiUrl, request, function(data){ @@ -210,45 +209,45 @@ mw.MiroSubsConfig = { callback( false ); } }); - }); - }, - getVideoURL: function(){ - // xxx todo: grab other sources ( WebM ) if supported. + }); + }, + getVideoURL: function(){ + // xxx todo: grab other sources ( WebM ) if supported. // grab the first ogg source - var source = this.embedPlayer.mediaElement.getSources( 'video/ogg' )[0]; + var source = this.embedPlayer.mediaElement.getSources( 'video/ogg' )[0]; if( ! source ){ - mw.log("Error: MiroSubsConfig Could not find video/ogg source to create subtitles"); + mw.log("Error: MiroSubsConfig Could not find video/ogg source to create subtitles"); return false; - } + } return source.getSrc(); }, - + // Convert miroSubs to srt string - miroSubs2Srt: function( miroSubs ){ + miroSubs2Srt: function( miroSubs ){ var srtString = ''; for(var i =0; i < miroSubs.length ; i ++ ){ var miroSub = miroSubs[i]; - var startStr = String( mw.seconds2npt( miroSub.start_time, true ) ).replace('.',','); + var startStr = String( mw.seconds2npt( miroSub.start_time, true ) ).replace('.',','); var endStr = String( mw.seconds2npt( miroSub.end_time, true ) ).replace( '.', ',' ); srtString += miroSub.sub_order + "\n" + - startStr + ' --> ' + endStr + "\n" + - miroSub.text + "\n\n"; + startStr + ' --> ' + endStr + "\n" + + miroSub.text + "\n\n"; } return srtString; }, - - // Get the existing subtitles in miro format + + // Get the existing subtitles in miro format getSubsInMiroFormat: function( callback ){ - var _this = this; + var _this = this; var playerTimedText = this.embedPlayer.timedText; - + playerTimedText.setupTextSources( function(){ var miroJsonSubs = []; // NOTE the autoselected default language is a tricky issue // We need to add support for language selection in the config object save callback - + // Get the current text source captions - playerTimedText.getCurrentSubSource( function( source ){ + playerTimedText.getCurrentSubSource( function( source ){ var captions = source.captions; _this.config.languageKey = source.srclang; for( var i = 0; i < captions.length ; i ++ ){ @@ -258,17 +257,17 @@ mw.MiroSubsConfig = { 'text': caption.content, 'sub_order': i+1 }; - if( caption.end == 0){ + if( caption.end == 0){ miroSub.start_time = -1; - miroSub.end_time = -1; + miroSub.end_time = -1; } else { - miroSub.start_time = caption.start; + miroSub.start_time = caption.start; miroSub.end_time = caption.end; } miroJsonSubs.push( miroSub ); } }); callback( miroJsonSubs ); - }); + }); } }; diff --git a/modules/PlayerThemer/loader.js b/modules/PlayerThemer/loader.js index 66f4c9b0bd..f3d20995ae 100644 --- a/modules/PlayerThemer/loader.js +++ b/modules/PlayerThemer/loader.js @@ -3,25 +3,22 @@ */ ( function( mw ) { - // Adds a jquery binding / loader for playerThemer + // Adds a jquery binding / loader for playerThemer mw.addResourcePaths({ - "mw.PlayerThemer" : "mw.PlayerThemer.js" + "mw.PlayerThemer" : "mw.PlayerThemer.js" }); - - // Add the mw.PlayerThemer to the EmbedPlayer loader request if we have special playerThemer class - /* $j( mw ).bind( 'LoaderEmbedPlayerUpdateRequest', function( event, playerElement, classRequest ) { - if( $j( playerElement ).hasClass('PlayerThemer') ){ + + // Add the mw.PlayerThemer to the embedPlayer loader request if we have special playerThemer class + $j( mw ).bind( 'LoaderEmbedPlayerUpdateRequest', function( event, playerElement, classRequest ) { + if( $j( playerElement ).hasClass('PlayerThemer') ){ // Set the player useNativeControls attribute - $j( playerElement ).attr('usenativecontrols', true); + $j( playerElement ).attr('usenativecontrols', true); - // Add playerThemer to the request: + // Add playerThemer to the request: if( $j.inArray( 'mw.PlayerThemer', classRequest ) == -1 ){ classRequest.push( 'mw.PlayerThemer'); } } - });*/ - - - + }); })( window.mw ); \ No newline at end of file diff --git a/modules/PlayerThemer/mw.PlayerThemer.js b/modules/PlayerThemer/mw.PlayerThemer.js index 6f84289a77..babad49675 100644 --- a/modules/PlayerThemer/mw.PlayerThemer.js +++ b/modules/PlayerThemer/mw.PlayerThemer.js @@ -1,30 +1,30 @@ // Setup the jquery binding -/** +/** * Define mw.PlayerThemer object: -* -* @@todo we need to do some updates to some mwEmbedPlayer bindings to make this work properly -* for now just target raw 'html5' +* +* @@todo we need to do some updates to some mwEmbedPlayer bindings to make this work properly +* for now just target raw 'html5' */ mw.PlayerThemer = function( themeContainer, options ) { return this.init( themeContainer, options); } mw.PlayerThemer.prototype = { - /** - * Master Theme Config: + * Master Theme Config: */ defaultComponentConfig: { /** * Component config has the following items: - * + * * @@todo we need tighter integration with controlBuilder / remaping - * + * * 'selector' target selector * 'visible' visible states: - * 'stop', 'playing', 'playerFocus', 'playerNoFocus', 'seeking' - */ - 'centerPlayButton': { + * 'stop', 'playing', 'playerFocus', 'playerNoFocus', 'seeking' + */ + + 'centerPlayButton': { 'show' : ['stop', 'paused'], 'hide' : ['playing', 'seeking'], 'doBind' : function( _this ){ @@ -43,7 +43,7 @@ mw.PlayerThemer.prototype = { }, 'widgetOverlay' : { 'show' : ['stop', 'paused'], - 'hide' : ['playing'] + 'hide' : ['playing'] }, 'bottomTitle' : { 'show' : ['stop'], @@ -62,25 +62,25 @@ mw.PlayerThemer.prototype = { // bind the progress bar } }, - // The full progress bar with sub components: + // The full progress bar with sub components: 'playControlFull': { 'show' : ['playerFocus'], 'hide' : ['playerNoFocus'], 'doBind' : function( _this ){ // Bind the progress bar time and buffer update - $j( _this.getEmbedPlayer() ).bind( 'updatePlayHeadPercent', function( event, perc ){ - _this.$getCompoent( 'playScrubber' ).slider( "option", "value", perc * 1000 ); + $j( _this.getEmbedPlayer() ).bind( 'updatePlayHeadPercent', function( event, perc ){ + _this.$getCompoent( 'playScrubber' ).slider( "option", "value", perc * 1000 ); }) $j( _this.getEmbedPlayer() ).bind('updateBufferPercent', function(event, perc ){ _this.$getCompoent( 'bufferProgress' ).css('width', ( perc * 100 ) + '%' ); }); - - // Add the handler css to the handler ( drives ui slider widget below ) + + // Add the handler css to the handler ( drives ui slider widget below ) if( ! _this.$getCompoent('playHandle').hasClass( 'ui-slider-handle' ) ){ - _this.$getCompoent('playHandle').addClass( 'ui-slider-handle' ); + _this.$getCompoent('playHandle').addClass( 'ui-slider-handle' ); } - - // Bind the playhead // @@todo clean up (just copied from controlBuilder for now ) + + // Bind the playhead // @@todo clean up (just copied from controlBuilder for now ) _this.$getCompoent( 'playScrubber' ) .slider( { range: "min", @@ -89,33 +89,33 @@ mw.PlayerThemer.prototype = { max: 1000, start: function( event, ui ) { _this.getEmbedPlayer().userSlide = true; - - _this.setDisplayState('seeking'); + + _this.setDisplayState('seeking'); }, slide: function( event, ui ) { var perc = ui.value / 1000; _this.getEmbedPlayer().jump_time = mw.seconds2npt( parseFloat( parseFloat( _this.getEmbedPlayer().getDuration() ) * perc ) + _this.getEmbedPlayer().start_time_sec ); - // mw.log('perc:' + perc + ' * ' + embedPlayer.getDuration() + ' jt:'+ this.jump_time); + // mw.log('perc:' + perc + ' * ' + embedPlayer.getDuration() + ' jt:'+ this.jump_time); if ( _this.longTimeDisp ) { //ctrlObj.setStatus( gM( 'mwe-embedplayer-seek_to', embedPlayer.jump_time ) ); } else { //ctrlObj.setStatus( embedPlayer.jump_time ); - } + } }, change:function( event, ui ) { - // Only run the onChange event if done by a user slide + // Only run the onChange event if done by a user slide // (otherwise it runs times it should not) if ( _this.getEmbedPlayer().userSlide ) { _this.getEmbedPlayer().userSlide = false; _this.getEmbedPlayer().seeking = true; - + var perc = ui.value / 1000; // set seek time (in case we have to do a url seek) _this.getEmbedPlayer().seek_time_sec = mw.npt2seconds( _this.getEmbedPlayer().jump_time, true ); mw.log( 'do jump to: ' + _this.getEmbedPlayer().jump_time + ' perc:' + perc + ' sts:' + _this.getEmbedPlayer().seek_time_sec ); //ctrlObj.setStatus( gM( 'mwe-embedplayer-seeking' ) ); _this.getEmbedPlayer().doSeek( perc ); - _this.setDisplayState('playing'); + _this.setDisplayState('playing'); } } } ) @@ -123,7 +123,7 @@ mw.PlayerThemer.prototype = { // @@todo need a clean way to not have jquery ui themes get in the way .find('.playHandle').removeClass('ui-corner-all ui-state-default'); } - }, + }, 'playHandle' : { 'show' : ['stop'] }, @@ -148,8 +148,8 @@ mw.PlayerThemer.prototype = { _this.getEmbedPlayer().pause(); _this.setDisplayState('paused'); }) - } - }, + } + }, 'volumeButton' : { 'orientation': 'vertical', 'doBind': function( _this ) { @@ -168,13 +168,13 @@ mw.PlayerThemer.prototype = { .bind( 'touchstart', function(){ _this.$getCompoent('volumeSlider').fadeIn( 'fast' ) }); - - // Add the handler css to the slider ( drives ui slider widget below ) + + // Add the handler css to the slider ( drives ui slider widget below ) if( ! _this.$getCompoent('volumeHandle').hasClass( 'ui-slider-handle' ) ){ - _this.$getCompoent('volumeHandle').addClass( 'ui-slider-handle' ); + _this.$getCompoent('volumeHandle').addClass( 'ui-slider-handle' ); } - - // Setup volume slider: + + // Setup volume slider: _this.$getCompoent( 'volumeSlider' ).slider( { range: "min", @@ -194,14 +194,14 @@ mw.PlayerThemer.prototype = { } else { //_this.getEmbedPlayer().$interface.find( '.volume_control span' ).removeClass( 'ui-icon-volume-off' ).addClass( 'ui-icon-volume-on' ); } - mw.log('change::update volume:' + percent); + mw.log('change::update volume:' + percent); _this.getEmbedPlayer().setVolume( percent ); } } ) .removeClass('ui-widget-content') - .find('.volumeHandle') - .removeClass('ui-corner-all'); + .find('.volumeHandle') + .removeClass('ui-corner-all'); } }, 'volumeSliderContainer' :{ @@ -210,28 +210,28 @@ mw.PlayerThemer.prototype = { 'fullscreenButton' : { 'doBind' : function( _this ){ _this.$getCompoent( 'fullscreenButton' ).click( function(){ - + }); } - } - + } + }, - // Stores a json config set of components ( setup at init ) + // Stores a json config set of components ( setup at init ) components: {}, - - + + defaultConfig:{ 'classPrefix' : '' }, - config: {}, - + config: {}, + init: function( themeContainer, options){ var _this = this; if( $j( themeContainer ).length == 0 ){ mw.log("Error: PlayerThemer can't them empty target") } this.$target = $j( themeContainer ); - // set the id: + // set the id: if( !this.$target.attr('id') ){ this.$target.attr('id', 'playerThemer_' + Math.random() ); } @@ -243,31 +243,31 @@ mw.PlayerThemer.prototype = { mw.load('EmbedPlayer', function(){ _this.$target.find('video').embedPlayer(function(){ // Bind to the embedPlayer library: - _this.embedPlayer = $j('#' + playerId).get(0); - // Merge in the components + _this.embedPlayer = $j('#' + playerId).get(0); + // Merge in the components if(! options.components ) options.components = {}; - + _this.components = $j.extend( true, _this.defaultComponentConfig, options.components); - - // Merge in config ( everything but the components ) + + // Merge in config ( everything but the components ) delete options.components; _this.config = $j.extend( true, _this.defaultConfig, options); - - // Rewrite the player with the 'stop' state + + // Rewrite the player with the 'stop' state _this.setDisplayState( 'stop' ); - + // Bind all buttons _this.bindActions(); - + // Bind player events that update the interface _this.bindPlayerDisplayState(); - + // Check for 'ready' callback - if( options.ready ){ + if( options.ready ){ options.ready(); - } - }) + } + }) }) }, getEmbedPlayer:function( embedPlayer ){ @@ -280,33 +280,33 @@ mw.PlayerThemer.prototype = { if( this.components[componentId] && this.components[componentId].selector ){ return this.$target.find( this.components[componentId].selector ); } - // Return with classPrefix: + // Return with classPrefix: return this.$target.find( '.' + this.config.classPrefix + componentId ); }, - + getComponentConfig: function( componentId ){ if( this.components[componentId] ){ return this.components[componentId] } return false; }, - + /** * Hide all the elements that are not part of the default state: */ setDisplayState:function( displayState ){ _this = this; for( var componentId in this.components ){ - component = this.components[ componentId ]; + component = this.components[ componentId ]; if( $j.inArray( displayState, component.show ) != -1 ){ - // checkfor custom animation: + // checkfor custom animation: if( component.customShow ){ component.customShow( _this ); - } else { + } else { this.$getCompoent(componentId).show(); } - } - + } + if( $j.inArray( displayState, component.hide ) != -1 ){ if( component.customHide ){ component.customHide( _this ); @@ -316,50 +316,50 @@ mw.PlayerThemer.prototype = { } } }, - + /** * Set up player bindings for updating the interface */ bindPlayerDisplayState: function(){ var _this = this; - + $j( this.embedPlayer ).bind('play', function(){ _this.setDisplayState('playing') }); - + $j( this.embedPlayer ).bind('paused', function(){ _this.setDisplayState('paused'); }); - + $j( this.embedPlayer ).bind('ended', function(){ // xxx should support 'ended' state //_this.setDisplayState('ended'); _this.setDisplayState('stop'); - // reset the scrubber: - _this.$getCompoent( 'playScrubber' ).slider( "option", "value", 0 ); + // reset the scrubber: + _this.$getCompoent( 'playScrubber' ).slider( "option", "value", 0 ); }); - - // show stuff on player touch: + + // show stuff on player touch: _this.$target.bind('touchstart', function() { - _this.setDisplayState('playerFocus'); + _this.setDisplayState('playerFocus'); } ); - + // 'player focus' - var shouldDeFocus = true; + var shouldDeFocus = true; /*_this.$target.hoverIntent({ 'sensitivity': 4, 'timeout' : 2000, - 'over' : function(){ + 'over' : function(){ _this.setDisplayState('playerFocus'); }, 'out' : function(){ _this.setDisplayState('playerNoFocus'); } - }); */ + }); */ }, - + /** - * Binds all the button actions + * Binds all the button actions */ bindActions: function(){ var _this = this; @@ -369,5 +369,5 @@ mw.PlayerThemer.prototype = { } }); } - + } \ No newline at end of file diff --git a/modules/Playlist/loader.js b/modules/Playlist/loader.js index 611e76e479..3ab6f25042 100644 --- a/modules/Playlist/loader.js +++ b/modules/Playlist/loader.js @@ -1,5 +1,5 @@ /** -* MediaRssPlayer +* MediaRssPlayer */ // Wrap in mw to not pollute global namespace @@ -9,54 +9,54 @@ "mw.Playlist" : "mw.Playlist.js", "mw.PlaylistHandlerMediaRss" : "mw.PlaylistHandlerMediaRss.js" }); - + // Set the default config mw.setDefaultConfig( { - // Playlist layout 'vertical' or 'horizontal' + // Playlist layout 'vertical' or 'horizontal' 'Playlist.layout' : 'vertical', - + // Player aspect ratio 'Playlist.playerAspect' : '4:3', - - // Width of item thubmnails + + // Width of item thubmnails 'Playlist.itemThumbWidth' : '60', - + // Height of the mediaRss title 'Playlist.titleHeight' : '20', - + // Default playlist type: 'Playlist.defaultType' : 'application/rss+xml' } ); - - // Module loader + + // Module loader mw.addModuleLoader( 'Playlist', function(){ var resourceList = ["mw.Playlist", "mw.PlaylistHandlerMediaRss" ] return resourceList; }); - - + + } )( window.mw ); -// Add the jQuery hook: +// Add the jQuery hook: ( function( $ ) { $.fn.playlist = function( options ){ - var _this = this; + var _this = this; if ( !this.selector ) { mw.log( "Error: Calling mediaRssPlayer with empty selector " + this.selector); return ; } // Set the target to loading $j( this.selector ).loadingSpinner(); - - // Set the target + + // Set the target options[ 'target' ] = _this.selector; - - // Load the mediaRss class ( if not already loaded ) - mw.load ( ['EmbedPlayer', 'Playlist'], function(){ + + // Load the mediaRss class ( if not already loaded ) + mw.load ( ['EmbedPlayer', 'Playlist'], function(){ // load and display the media Rss var myPlaylist = new mw.Playlist( options ); - myPlaylist.drawUI(); - }); + myPlaylist.drawUI(); + }); } } )( jQuery ); diff --git a/modules/Playlist/mw.Playlist.js b/modules/Playlist/mw.Playlist.js index e558aa7b9b..9be9408741 100644 --- a/modules/Playlist/mw.Playlist.js +++ b/modules/Playlist/mw.Playlist.js @@ -1,6 +1,6 @@ /** -* Playlist Embed. Enables the embedding of a playlist playlist using the mwEmbed player -*/ +* Playlist Embed. Enables the embedding of a playlist playlist using the mwEmbed player +*/ //Get all our message text mw.includeAllModuleMessages(); @@ -11,108 +11,108 @@ mw.Playlist = function( options ){ mw.Playlist.prototype = { - // Stores the current clip index to be played + // Stores the current clip index to be played clipIndex: 0, - - // Stores the cached player size: + + // Stores the cached player size: targetPlayerSize: null, - + // constructor init: function( options ) { - - this.src = options.src; - - this.target = options.target; - + + this.src = options.src; + + this.target = options.target; + this.id = ( options.id )? options.id : $j( this.target ).attr( 'id' ); if( !this.id ){ // Give it a random id if unset: this.id = 'playlist_' + Math.random(); } - + // Set the sourceHandler if provided if( options.sourceHandler ) { this.sourceHandler = options.sourceHandler; } - + // Set binding to disable "waitForMeta" for playlist items ( we know the size and length ) - $j( mw ).bind( 'addElementWaitForMetaEvent', function(even, waitForMetaObject ){ + $j( mw ).bind( 'addElementWaitForMetaEvent', function(even, waitForMetaObject ){ if( $j( waitForMetaObject[ 'playerElement' ] ).hasClass( 'mwPlaylist') ){ waitForMetaObject[ 'waitForMeta' ] = false; } }); - - this.type = ( options.type ) ? - options.type: + + this.type = ( options.type ) ? + options.type: mw.getConfig('Playlist.defaultType' ); - - // Set default options or use layout - this.layout = ( options.layout ) ? - options.layout : + + // Set default options or use layout + this.layout = ( options.layout ) ? + options.layout : mw.getConfig( 'Playlist.layout' ); - + // Player aspect ratio - this.playerAspect = ( options.playerAspect ) ? - options.playerAspect : + this.playerAspect = ( options.playerAspect ) ? + options.playerAspect : mw.getConfig( 'Playlist.playerAspect' ); - - // Item thumb width - this.itemThumbWidth = ( options.itemThumbWidth ) ? - options.itemThumbWidth : + + // Item thumb width + this.itemThumbWidth = ( options.itemThumbWidth ) ? + options.itemThumbWidth : mw.getConfig('Playlist.itemThumbWidth'); - - // Default title height: - this.titleHeight = ( options.titleHeight ) ? + + // Default title height: + this.titleHeight = ( options.titleHeight ) ? options.titleHeight : mw.getConfig( 'Playlist.titleHeight' ); - + }, - + /** * Draw the media rss playlist ui */ drawUI: function(){ var _this = this; - // Set the target to loadingSpinner: + // Set the target to loadingSpinner: $j( this.target ).empty().loadingSpinner(); - - this.loadPlaylistHandler( function( sourceHandler ){ + + this.loadPlaylistHandler( function( sourceHandler ){ mw.log("mw.Playlist::loaded playlist set"); // Check if load failed or empty playlist if( sourceHandler.getClipList().length == 0 ){ $j( _this.target ).empty().text( gM('mwe-playlist-empty') ) - return ; + return ; } - + // Empty the target and setup player and playerList divs $j( _this.target ) .empty() .css('position', 'relative' ) .append( - $j( '' ) + $j( '' ) .addClass( 'media-rss-video-player') .css({ 'float' : 'left' }) - , + , $j( '
') .addClass( 'media-rss-video-list' ) .attr('id', _this.id + '_videolist') .css({ 'position' : 'absolute', - 'z-index' : '1', - 'overflow' : 'auto', - 'bottom': '0px', - 'right' : '0px' + 'z-index' : '1', + 'overflow' : 'auto', + 'bottom': '0px', + 'right' : '0px' }) - .hide() + .hide() ); - + // Check if we have multiple playlist and setup the list and bindings - if( _this.sourceHandler.hasMultiplePlaylists() ){ - var playlistSet = _this.sourceHandler.getPlaylistSet(); - + if( _this.sourceHandler.hasMultiplePlaylists() ){ + var playlistSet = _this.sourceHandler.getPlaylistSet(); + var $plListContainer =$j('
') .addClass( 'playlistSet-container ui-state-default ui-widget-header ui-corner-all' ) .css({ @@ -122,15 +122,15 @@ mw.Playlist.prototype = { 'right' : '0px', 'height' : '20px' }) - .append( + .append( $j('
') .addClass( 'playlistSetList' ) .css("width", '200px') ); $j( _this.target ).append( $plListContainer ); - + var $plListSet = $j( _this.target ).find( '.playlistSetList' ); - + $j.each( playlistSet, function( inx, playlist){ // Add a divider if( inx != 0 ){ @@ -140,114 +140,114 @@ mw.Playlist.prototype = { $j('') .attr('href', '#') .text( playlist.name ) - .click( function(){ + .click( function(){ _this.sourceHandler.setPlaylistIndex( inx ); $j( _this.target + ' .media-rss-video-list').loadingSpinner(); - _this.sourceHandler.loadPlaylist( function(){ + _this.loadPlaylist( function(){ $j( _this.target + ' .media-rss-video-list').empty(); - _this.addMediaList(); + _this.addMediaList(); }); return false; }) - .buttonHover() - ) + .buttonHover() + ) }); - // Check playlistSet width and add scroll left / scroll right buttons + // Check playlistSet width and add scroll left / scroll right buttons if( $plListSet.width() > $plListContainer.width() ){ var baseButtonWidth = 24; $plListSet.css( { 'position': 'absolute', 'left' : baseButtonWidth + 'px' }); - var $scrollButton = $j('
') + var $scrollButton = $j('
') .addClass( 'ui-corner-all ui-state-default' ) .css({ 'position' : 'absolute', 'top' : '-1px', - 'cursor' : 'pointer', + 'cursor' : 'pointer', 'margin' :'0px', 'padding' : '2px', 'width' : '16px', 'height' : '16px' }) - + var $buttonSpan = $j('') .addClass( 'ui-icon' ) .css('margin', '2px' ); - + var plScrollPos = 0; var scrollToListPos = function( pos ){ - - listSetLeft = $plListSet.find('a').eq( pos ).offset().left - + + listSetLeft = $plListSet.find('a').eq( pos ).offset().left - $plListSet.offset().left ; - + mw.log("scroll to: " + pos + ' left: ' + listSetLeft); $plListSet.animate({'left': -( listSetLeft - baseButtonWidth) + 'px'} ); } - + $plListContainer - .append( + .append( $scrollButton.clone() .css('left', '0px') - .append( $buttonSpan.clone().addClass('ui-icon-circle-arrow-w') ) - .click( function(){ - //slide right + .append( $buttonSpan.clone().addClass('ui-icon-circle-arrow-w') ) + .click( function(){ + //slide right if( plScrollPos >= 0){ mw.log("scroll right"); plScrollPos-- scrollToListPos( plScrollPos ); - } + } }) .buttonHover(), - + $scrollButton.clone() .css('right', '0px') .append( $buttonSpan.clone().addClass('ui-icon-circle-arrow-e') ) - .click( function(){ - //slide left + .click( function(){ + //slide left if( plScrollPos < $plListSet.find('a').length-1 ){ plScrollPos++; scrollToListPos( plScrollPos ); - } + } }) .buttonHover() ) } } - + // Add the selectable media list - _this.addMediaList(); - + _this.addMediaList(); + // Add the player - _this.updatePlayer( _this.clipIndex, function(){ + _this.updatePlayer( _this.clipIndex, function(){ // Update the list height ( vertical layout ) - if( _this.layout == 'vertical' ){ + if( _this.layout == 'vertical' ){ $j( _this.target + ' .media-rss-video-list' ).css( { 'top' : $j( _this.target + ' .media-rss-video-player' ).height() + 4, 'width' : '100%' } ) - // Add space for the multi-playlist selector: - if( _this.sourceHandler.hasMultiplePlaylists() ){ + // Add space for the multi-playlist selector: + if( _this.sourceHandler.hasMultiplePlaylists() ){ // also adjust .playlistSet-container if present $j( _this.target + ' .playlistSet-container').css( { 'top' : $j( _this.target + ' .media-rss-video-player' ).height() + 4 - }) + }) $j( _this.target + ' .media-rss-video-list' ).css({ 'top' : $j( _this.target + ' .media-rss-video-player' ).height() + 26 }) } - + } else { - // Update horizontal layout + // Update horizontal layout $j( _this.target + ' .media-rss-video-list').css( { 'top' : '0px', 'left' : $j( _this.target + ' .media-rss-video-player' ).width() + 4 - } ) - // Add space for the multi-playlist selector: - if( _this.sourceHandler.hasMultiplePlaylists() ){ + } ) + // Add space for the multi-playlist selector: + if( _this.sourceHandler.hasMultiplePlaylists() ){ $j( _this.target + ' .playlistSet-container').css( { 'left' : $j( _this.target + ' .media-rss-video-player' ).width() + 4 - }) + }) $j( _this.target + ' .media-rss-video-list').css( { 'top' : '26px' }) @@ -255,16 +255,16 @@ mw.Playlist.prototype = { } var $videoList = $j( _this.target + ' .media-rss-video-list' ); $videoList.show() - // show the video list and apply the swipe binding - $j( _this.target ).find('.media-rss-video-list-wrapper').fadeIn(); - if( mw.isHTML5FallForwardNative() ){ + // show the video list and apply the swipe binding + $j( _this.target ).find('.media-rss-video-list-wrapper').fadeIn(); + if( mw.isMobileHTML5() ){ // iScroll is buggy with current version of iPad / iPhone use scroll buttons instead /* - document.addEventListener('touchmove', function(e){ e.preventDefault(); }); - var myScroll = iScroll( _this.id + '_videolist' ); + document.addEventListener('touchmove', function(e){ e.preventDefault(); }); + var myScroll = iScroll( _this.id + '_videolist' ); setTimeout(function () { myScroll.refresh(); }, 0); - */ - // Add space for scroll buttons: + */ + // Add space for scroll buttons: var curTop = $j( _this.target + ' .media-rss-video-list' ).css('top'); if(!curTop) curTop = '0px'; $j( _this.target + ' .media-rss-video-list' ).css( { @@ -276,11 +276,11 @@ mw.Playlist.prototype = { }) if( _this.layout == 'vertical' ){ $j( _this.target + ' .media-rss-video-list' ).css({ - 'top' : $j( _this.target + ' .media-rss-video-player' ).height() + 8 + 'top' : $j( _this.target + ' .media-rss-video-player' ).height() + 8 }) } // Add scroll buttons: - $j( _this.target ).append( + $j( _this.target ).append( $j( '
').css({ 'position' : 'absolute', 'bottom' : '0px', @@ -288,25 +288,25 @@ mw.Playlist.prototype = { 'height' : '30px', 'width' : $j( _this.target + ' .media-rss-video-list').width() }) - .append( - $j.button({ + .append( + $j.button({ 'text' : 'scroll down', - 'icon_id' : 'circle-arrow-s' + 'icon_id' : 'circle-arrow-s' }) .css('float', 'right') .click(function(){ var clipListCount = $videoList.children().length; var clipSize = $videoList.children(':first').height(); - var curTop = $videoList.attr('scrollTop'); - - var targetPos = curTop + (clipSize * 3); + var curTop = $videoList.attr('scrollTop'); + + var targetPos = curTop + (clipSize * 3); if( targetPos > clipListCount * clipSize ){ targetPos = ( clipListCount * ( clipSize -1 ) ); - } + } //mw.log(" animate to: " +curTop + ' + ' + (clipSize * 3) + ' = ' + targetPos ); $videoList.animate({'scrollTop': targetPos }, 500 ); - - return false; + + return false; }), $j.button({ 'text' : 'scroll up', @@ -316,147 +316,147 @@ mw.Playlist.prototype = { .click(function(){ var clipListCount = $videoList.children().length; var clipSize = $videoList.children(':first').height(); - var curTop = $videoList.attr('scrollTop'); - - var targetPos = curTop - (clipSize * 3); + var curTop = $videoList.attr('scrollTop'); + + var targetPos = curTop - (clipSize * 3); if( targetPos < 0 ){ targetPos = 0 - } + } mw.log(" animate to: " +curTop + ' + ' + (clipSize * 3) + ' = ' + targetPos ); $videoList.animate({'scrollTop': targetPos }, 500 ); - + return false; }) ) ) } - + }); - - - }); + + + }); }, - + /** * Update the target size of the player */ - getTargetPlayerSize: function( ){ - var _this = this; + getTargetPlayerSize: function( ){ + var _this = this; if( this.targetPlayerSize ){ return this.targetPlayerSize; - } - - // Get the target width and height: ( should be based on layout or + } + + // Get the target width and height: ( should be based on layout or this.targetWidth = $j( this.target ).width(); - this.targetHeight = $j( this.target ).height(); - + this.targetHeight = $j( this.target ).height(); + /* vertical layout */ - if( _this.layout == 'vertical' ){ + if( _this.layout == 'vertical' ){ var pa = this.playerAspect.split(':'); this.targetPlayerSize = { 'width' : this.targetWidth + 'px', - 'height' : parseInt( ( pa[1] / pa[0] ) * this.targetWidth ) + 'height' : parseInt( ( pa[1] / pa[0] ) * this.targetWidth ) }; } else { /* horizontal layout */ var pa = this.playerAspect.split(':'); this.targetPlayerSize = { 'height' : ( this.targetHeight - this.titleHeight ) + 'px', - 'width' : parseInt( ( pa[0] / pa[1] ) * this.targetHeight ) + 'width' : parseInt( ( pa[0] / pa[1] ) * this.targetHeight ) }; - } + } if( this.targetPlayerSize.width > this.targetWidth ){ var pa = this.playerAspect.split(':'); - this.targetPlayerSize.width = this.targetWidth; - this.targetPlayerSize.height = parseInt( ( pa[1] / pa[0] ) * this.targetWidth ); + this.targetPlayerSize.width = this.targetWidth; + this.targetPlayerSize.height = parseInt( ( pa[1] / pa[0] ) * this.targetWidth ); } return this.targetPlayerSize; }, - + /** * update the player */ updatePlayer: function( clipIndex , callback ){ - var _this = this; + var _this = this; var playerSize = _this.getTargetPlayerSize() ; - + // Build and output the title var $title = $j('
' ) - .addClass( 'playlist-title ui-state-default ui-widget-header ui-corner-all') - .css( { + .addClass( 'playlist-title ui-state-default ui-widget-header ui-corner-all') + .css( { 'top' : '0px', 'height' : _this.titleHeight, - 'width' : playerSize.width + 'width' : playerSize.width } ) - .text( - _this.sourceHandler.getClipTitle( clipIndex ) + .text( + _this.sourceHandler.getClipTitle( clipIndex ) ) - + $j( _this.target + ' .media-rss-video-player' ).find('.playlist-title').remove( ); - $j( _this.target + ' .media-rss-video-player' ).prepend( $title ); - - // Update the player list if present: + $j( _this.target + ' .media-rss-video-player' ).prepend( $title ); + + // Update the player list if present: $j( _this.target + ' .clipItemBlock') .removeClass( 'ui-state-active' ) .addClass( 'ui-state-default' ) - .eq( clipIndex ) - .addClass( 'ui-state-active' ) - - // Build the video tag object: + .eq( clipIndex ) + .addClass( 'ui-state-active' ) + + // Build the video tag object: var $video = $j( '

') .css( { 'border': '0px', - 'width' : '100%' + 'width' : '100%' }) .append( - $j('') - .append( + $j('') + .append( $j( '
') .css('width', _this.itemThumbWidth + 'px' ) - .append( + .append( $j('') - .attr({ + .attr({ 'alt' : _this.sourceHandler.getClipTitle( inx ), 'src' : _this.sourceHandler.getClipPoster( inx ) }) - .css( 'width', _this.itemThumbWidth + 'px') + .css( 'width', _this.itemThumbWidth + 'px') ), $j( '') .text( _this.sourceHandler.getClipTitle( inx ) ), - + $j( '') - .css( 'width', '50px') - .text( + .css( 'width', '50px') + .text( mw.seconds2npt( _this.sourceHandler.getClipDuration( inx ) ) ) - - ) + + ) ) // table row ) // table block .data( 'clipIndex', inx ) .buttonHover() .addClass( 'clipItemBlock' ) .css( { - 'cursor': 'pointer' + 'cursor': 'pointer' } ) .click( function(){ - mw.log( 'clicked on: ' + $j( this ).data( 'clipIndex') ); + mw.log( 'clicked on: ' + $j( this ).data( 'clipIndex') ); // Make sure the existing player is "playing " (safari can't play async with javascript ) - /*if( mw.isHTML5FallForwardNative() ){ + /*if( mw.isMobileHTML5() ){ var embedPlayer = $j('#' + _this.getVideoPlayerId() ).get(0); //embedPlayer.playerElement.play(); - }*/ - + }*/ + // Update _this.clipIndex _this.clipIndex = $j( this ).data( 'clipIndex' ); - + _this.updatePlayer( _this.clipIndex, function(){ _this.play(); } ); - + }) //close $itemBlock // Add the itemBlock to the targetItem list - $targetItemList.append( + $targetItemList.append( $itemBlock ) mw.log("added item block : " + $targetItemList.children().length ); }); - }, - + }, + play: function(){ var embedPlayer = $j('#' + this.getVideoPlayerId() ).get(0); - if( mw.isHTML5FallForwardNative() ){ + if( mw.isMobileHTML5() ){ embedPlayer.playerElement.play(); - } else{ + } else{ embedPlayer.play(); } }, - + /** * Load the playlist driver from a source */ loadPlaylistHandler: function( callback ){ - var _this = this; + var _this = this; if( !_this.sourceHandler ){ switch( this.type ){ - case 'application/rss+xml': + case 'application/rss+xml': _this.sourceHandler = new mw.PlaylistHandlerMediaRss( this ); break; } - }; - // load the playlist - _this.sourceHandler.loadPlaylist( function(){ + }; + // load the playlist + _this.sourceHandler.loadPlaylist( function(){ callback( _this.sourceHandler ); }); - }, - + }, + /** * Set the playlsit source handler */ diff --git a/modules/Playlist/mw.PlaylistHandlerMediaRss.js b/modules/Playlist/mw.PlaylistHandlerMediaRss.js index 978bc5a17c..9f8c505fd3 100644 --- a/modules/Playlist/mw.PlaylistHandlerMediaRss.js +++ b/modules/Playlist/mw.PlaylistHandlerMediaRss.js @@ -1,4 +1,3 @@ - mw.PlaylistHandlerMediaRss = function( Playlist ){ return this.init( Playlist ); } @@ -6,16 +5,16 @@ mw.PlaylistHandlerMediaRss = function( Playlist ){ mw.PlaylistHandlerMediaRss.prototype = { // Set the media rss namespace mediaNS: 'http://search.yahoo.com/mrss/', - + // If playback should continue to the next clip on clip complete autoContinue: true, - + init: function ( Playlist ){ this.playlist = Playlist; }, - + /** - * load the playlist source file with a callback + * load the playlist source file with a callback */ loadPlaylist: function( callback ){ var _this = this; @@ -24,15 +23,15 @@ mw.PlaylistHandlerMediaRss.prototype = { callback( this.$rss ); return ; } - - // Show an error if a cross domain request: + + // Show an error if a cross domain request: if( ! mw.isLocalDomain( this.getSrc() ) ) { mw.log("Error: trying to get cross domain playlist source: " + this.getSrc() ); } - + // Note this only works with local sources $j.get( mw.absoluteUrl( this.getSrc() ), function( data ){ - _this.$rss = $j( data ); + _this.$rss = $j( data ); callback( _this.$rss ); }); }, @@ -49,19 +48,19 @@ mw.PlaylistHandlerMediaRss.prototype = { } return this.$rss.find('item').length; }, - + getClipSources: function( clipIndex, callback ){ var _this = this; var $item = $j( this.$rss.find('item')[ clipIndex ] ); var clipSources = []; $j.each( $item.get(0).getElementsByTagNameNS( _this.mediaNS, 'content' ), function( inx, mediaContent){ - if( $j( mediaContent ).get(0).nodeName == 'media:content' ){ + if( $j( mediaContent ).get(0).nodeName == 'media:content' ){ clipSource = {} if( $j( mediaContent ).attr('url' ) ){ clipSource.src = $j( mediaContent ).attr('url' ); } if( $j( mediaContent ).attr('type' ) ){ - clipSource.type = $j( mediaContent ).attr('type' ); + clipSource.type = $j( mediaContent ).attr('type' ); } if( $j( mediaContent ).attr( 'duration' ) ) { clipSource.durationHint = $j( mediaContent ).attr('duration' ); @@ -70,34 +69,34 @@ mw.PlaylistHandlerMediaRss.prototype = { } }); callback( clipSources ); - }, - + }, + applyCustomClipData: function( embedPlayer, clipIndex ){ return {}; }, - + getClipList: function(){ - return this.$rss.find('item'); + return this.$rss.find('item'); }, /** * Get an items poster image ( return missing thumb src if not found ) - */ - getClipPoster: function ( clipIndex ){ - var $item = this.$rss.find('item').eq( clipIndex ); + */ + getClipPoster: function ( clipIndex ){ + var $item = this.$rss.find('item').eq( clipIndex ); var mediaThumb = $item.get(0).getElementsByTagNameNS( this.mediaNS, 'thumbnail' ); mw.log( 'mw.PlaylistMediaRss::getClipPoster: ' + $j( mediaThumb ).attr('url' ) ); - if( mediaThumb && $j( mediaThumb ).attr('url' ) ){ + if( mediaThumb && $j( mediaThumb ).attr('url' ) ){ return $j( mediaThumb ).attr('url' ); - } - + } + // return missing thumb url return mw.getConfig( 'imagesPath' ) + 'vid_default_thumb.jpg'; - }, - /** + }, + /** * Get an item title from the $rss source */ getClipTitle: function( clipIndex ){ - var $item = this.$rss.find('item').eq( clipIndex ) ; + var $item = this.$rss.find('item').eq( clipIndex ) ; var mediaTitle = $item.get(0).getElementsByTagNameNS( this.mediaNS, 'title' ); if( mediaTitle ){ return $j( mediaTitle ).text(); @@ -105,18 +104,18 @@ mw.PlaylistHandlerMediaRss.prototype = { mw.log("Error could not find title for clip: " + clipIndex ); return gM('mwe-mediarss-untitled'); }, - - getClipDuration: function ( clipIndex ) { - // return the first found media duration - var $item = this.$rss.find('item').eq( clipIndex ) ; - var itemDuration = 0; + + getClipDuration: function ( clipIndex ) { + // return the first found media duration + var $item = this.$rss.find('item').eq( clipIndex ) ; + var itemDuration = 0; $j( $item.get(0).getElementsByTagNameNS( this.mediaNS, 'content' ) ).each( function( inx, mediaContent ){ if( $j( mediaContent ).attr( 'duration' ) ) { itemDuration = $j( mediaContent ).attr( 'duration' ); // end for loop return false; } - }); + }); return mw.seconds2npt( itemDuration ) } } \ No newline at end of file diff --git a/modules/Playlist/tests/Player_MediaRss.html b/modules/Playlist/tests/Player_MediaRss.html index 68b0a19628..1600732d2a 100644 --- a/modules/Playlist/tests/Player_MediaRss.html +++ b/modules/Playlist/tests/Player_MediaRss.html @@ -6,25 +6,25 @@ - + - - + + +

Sample Swarm transport:

-Install the swarmTransport add-on and this video will be served via p2p next swarm transport
+Install the swarmTransport add-on and this video will be served via p2p next swarm transport
- - - diff --git a/modules/SwarmTransport/tests/SwarmTransprot_Url.html b/modules/SwarmTransport/tests/SwarmTransprot_Url.html index 13430ae98a..fa9a546dbc 100644 --- a/modules/SwarmTransport/tests/SwarmTransprot_Url.html +++ b/modules/SwarmTransport/tests/SwarmTransprot_Url.html @@ -3,46 +3,46 @@ Sample swarm transport - - - + + +

Sample Swarm transport:

-Install the swarmTransport add-on and this video will be served via p2p next swarm transport
+Install the swarmTransport add-on and this video will be served via p2p next swarm transport
- + - Commons Video API based timedText discovery
+ Commons Video API based timedText discovery
+ +
- - - + diff --git a/modules/TimedText/TimedText.i18n.php b/modules/TimedText/TimedText.i18n.php index 8cda5e68c2..1c7e1cb341 100644 --- a/modules/TimedText/TimedText.i18n.php +++ b/modules/TimedText/TimedText.i18n.php @@ -59,7 +59,7 @@ 'mwe-timedtext-request-subs-desc' => 'Add a request for this video file to be transcribed', 'mwe-timedtext-request-subs-done' => 'Transcription request added. [$1 See all transcribe requests]', 'mwe-timedtext-request-subs-fail' => 'Failed to add transcription request, Are you logged in? ', - 'mwe-timedtext-request-already-done' => 'A transcription of this video has already been requested. [$1 See all transcribe requests]', + 'mwe-timedtext-request-already-done' => 'A transcription of this video has already been requested. [$1 See all transcribe requests]', ); /** Message documentation (Message documentation) diff --git a/modules/TimedText/css/mw.style.TimedText.css b/modules/TimedText/css/mw.style.TimedText.css index bf062c71bf..9f14d8f560 100644 --- a/modules/TimedText/css/mw.style.TimedText.css +++ b/modules/TimedText/css/mw.style.TimedText.css @@ -1,19 +1,19 @@ .track span { - color: white; - letter-spacing: 0.04em; + color: white; + letter-spacing: 0.04em; text-align: center; padding: 0.2em; /* // Text shadow is too slow with current browsers use background-color text-shadow:0 2px 1px #000000, -1px 3px 1px #000000, -2px 2px 1px #000000, -2px 1px 1px #000000, -2px 0 1px #000000, 2px 2px 1px #000000, 1px 2px 1px #000000, 0 -2px 1px #000000, 2px -2px 1px #000000, -2px -1px 1px #000000, -1px -3px 1px #000000, -3px -2px 1px #000000, 0 0 25px #000000, 0 0 35px #000000, 0 0 35px #000000, 0 0 31px #FFFFFF, 0 0 31px #FFFFFF, 0 0 31px #FFFFFF; - */ + */ background-color: #333; } .track span a { text-decoration: none; - color : #BBF; + color : #BBF; } .track span a:visited{ - color : #BBF; + color : #BBF; } diff --git a/modules/TimedText/css/mw.style.TimedTextEdit.css b/modules/TimedText/css/mw.style.TimedTextEdit.css index 8607f94cbb..bf25cbca21 100644 --- a/modules/TimedText/css/mw.style.TimedTextEdit.css +++ b/modules/TimedText/css/mw.style.TimedTextEdit.css @@ -1,22 +1,22 @@ .TimedTextEdit .leftcolumn #textinput textarea { - width:512px; - height:200px; + width:512px; + height:200px; } .TimedTextEdit .leftcolumn #textinput { - display: block; - margin: auto; - position:absolute; - top: 340px; + display: block; + margin: auto; + position:absolute; + top: 340px; } .TimedTextEdit .leftcolumn { - padding: 10px; - width: 890px; - margin: auto; + padding: 10px; + width: 890px; + margin: auto; } .TimedTextEdit .rightcolumn { @@ -35,156 +35,156 @@ .TimedTextEdit .tabs { - position:absolute; - top: 530px; + position:absolute; + top: 530px; } .TimedTextEdit .tab{ - position:absolute; - background:#888; - border:1px solid black; - height:30px; - width:160px; - padding:4px; - text-align: center; + position:absolute; + background:#888; + border:1px solid black; + height:30px; + width:160px; + padding:4px; + text-align: center; } .TimedTextEdit .selected{ - background:#bbb; - height:40px; + background:#bbb; + height:40px; } .TimedTextEdit #step1tab { - left: 0px; + left: 0px; } .TimedTextEdit #step2tab { - left: 171px; + left: 171px; } .TimedTextEdit #step3tab { - left: 342px; + left: 342px; } .TimedTextEdit .nextstep { - position:absolute; - top: 600px; - left:197px; - width:100px; - height:25px; - text-align:center; - background:#77bb40; - color:white; - font-weight:bold; - padding:12px; - border: 1px solid black; + position:absolute; + top: 600px; + left:197px; + width:100px; + height:25px; + text-align:center; + background:#77bb40; + color:white; + font-weight:bold; + padding:12px; + border: 1px solid black; } .TimedTextEdit #titles_list { - background: #ddd; - padding: 12px; - text-align:center; - position:absolute; - top:340px; - width:488px; - height:164px; + background: #ddd; + padding: 12px; + text-align:center; + position:absolute; + top:340px; + width:488px; + height:164px; } .TimedTextEdit .current_title { - font-size: larger; - background: #dd8 + font-size: larger; + background: #dd8 } .TimedTextEdit .time_in { - font-size: xx-small; - position:absolute; - margin-top:2px; - margin-left:2em; -} + font-size: xx-small; + position:absolute; + margin-top:2px; + margin-left:2em; +} .TimedTextEdit .time_out { - font-size: xx-small; - position:absolute; - margin-top:2px; - margin-left:438px; -} + font-size: xx-small; + position:absolute; + margin-top:2px; + margin-left:438px; +} .TimedTextEdit a { - color:#aaa; + color:#aaa; } .TimedTextEdit video { - height:290px; - width:512px; + height:290px; + width:512px; } .TimedTextEdit .videodiv { - display: block; - margin: auto; - position:absolute; + display: block; + margin: auto; + position:absolute; } .TimedTextEdit .subtitles { - width: 80%; - margin: auto; - position: relative; - text-align: center; - font-family: sans-serif; - line-height: 2em; - color: rgba(255,255,128, 1); - text-shadow: rgba(0,0,0, 0.6) 1px 1px; - background: rgba(0,0,0, 0.6); + width: 80%; + margin: auto; + position: relative; + text-align: center; + font-family: sans-serif; + line-height: 2em; + color: rgba(255,255,128, 1); + text-shadow: rgba(0,0,0, 0.6) 1px 1px; + background: rgba(0,0,0, 0.6); } .TimedTextEdit .subtitleslines1 { - top: -4.8em; + top: -4.8em; } .TimedTextEdit.subtitleslines2 { - top: -6.8em; + top: -6.8em; } .TimedTextEdit.subtitleslines3 { - top: -8.8em; + top: -8.8em; } .TimedTextEdit input[type=number] { - width:1.2em; - padding:2px; - background: #ffd; - border:none; + width:1.2em; + padding:2px; + background: #ffd; + border:none; } /* .TimedTextEdit input[type=text] { - background: #ffd; - border:none; + background: #ffd; + border:none; } */ .TimedTextEdit .hotkeybox { - background: #333; - padding: 5px; - line-height: 200%; - font-size: small; - position:absolute; - width:340px; - bottom:10px; + background: #333; + padding: 5px; + line-height: 200%; + font-size: small; + position:absolute; + width:340px; + bottom:10px; } .TimedTextEdit #titles_textarea { diff --git a/modules/TimedText/loader.js b/modules/TimedText/loader.js index 7a8dc53e8b..ad71d09e30 100644 --- a/modules/TimedText/loader.js +++ b/modules/TimedText/loader.js @@ -1,63 +1,63 @@ /** -* TimedText loader. +* TimedText loader. */ -// Scope everything in "mw" ( keeps the global namespace clean ) +// Scope everything in "mw" ( keeps the global namespace clean ) ( function( mw ) { - + mw.addResourcePaths( { "mw.TimedText" : "mw.TimedText.js", "mw.style.TimedText" : "css/mw.style.TimedText.css", - + "mw.TimedTextEdit" : "mw.TimedTextEdit.js", "mw.style.TimedTextEdit" : "css/mw.style.TimedTextEdit.css", - + "RemoteMwTimedText" : "remotes/RemoteMwTimedText.js" } ); - + mw.setDefaultConfig( { - // If the Timed Text interface should be displayed: + // If the Timed Text interface should be displayed: // 'always' Displays link and call to contribute always // 'auto' Looks for child timed text elements or "apiTitleKey" & load interface // 'off' Does not display the timed text interface "TimedText.showInterface" : "auto", - + /** * If the "add timed text" link / interface should be exposed */ 'TimedText.showAddTextLink' : true, - + // The category for listing videos that need transcription: 'TimedText.NeedsTranscriptCategory' : 'Videos needing subtitles' }); - - var mwTimedTextRequestSet = [ - '$j.fn.menu', + + var mwTimedTextRequestSet = [ + '$j.fn.menu', 'mw.TimedText', 'mw.style.TimedText', 'mw.style.jquerymenu' ]; - - // TimedText module + + // TimedText module mw.addModuleLoader( 'TimedText', mwTimedTextRequestSet ); - + /** - * Setup the load embedPlayer visit tag addSetupHook function + * Setup the load embedPlayer visit tag addSetupHook function * * Check if the video tags in the page support timed text - * this way we can add our timed text libraries to the player + * this way we can add our timed text libraries to the player * library request. */ - + // Update the player loader request with timedText library if the embedPlayer - // includes timedText tracks. + // includes timedText tracks. $j( mw ).bind( 'LoaderEmbedPlayerUpdateRequest', function( event, playerElement, classRequest ) { - + var mwLoadTimedTextFlag = false; - // Check for the TimedText.showInterface config flag + // Check for the TimedText.showInterface config flag if( mw.getConfig( 'TimedText.showInterface' ) == 'always' ) { - mwLoadTimedTextFlag = true; + mwLoadTimedTextFlag = true; } - + // If add timed text flag not already set check for track, and sources if( ! mwLoadTimedTextFlag ) { if( $j( playerElement ).find( 'track' ).length != 0 ) { @@ -65,34 +65,34 @@ mwLoadTimedTextFlag = true; } // Check for ROE pointer or apiTitleKey - if ( $j( playerElement ).attr('roe') + if ( $j( playerElement ).attr('roe') || $j( playerElement ).attr( 'apiTitleKey' ) ) { mwLoadTimedTextFlag = true; } - } - - // Add timed text items if flag set. + } + + // Add timed text items if flag set. // its oky if we merge in multiple times the loader can handle it - if( mwLoadTimedTextFlag ) { + if( mwLoadTimedTextFlag ) { $j.merge( classRequest, mwTimedTextRequestSet ); - } + } } ); - - + + // TimedText editor: - mw.addModuleLoader( 'TimedText.Edit', [ + mw.addModuleLoader( 'TimedText.Edit', [ [ '$j.ui', '$j.widget', '$j.ui.mouse', '$j.ui.position', - '$j.fn.menu', + '$j.fn.menu', "mw.style.jquerymenu", - + 'mw.TimedText', 'mw.style.TimedText', - + 'mw.TimedTextEdit', 'mw.style.TimedTextEdit' ], diff --git a/modules/TimedText/mw.TimedText.js b/modules/TimedText/mw.TimedText.js index 3eca722f76..2ad848a5c7 100644 --- a/modules/TimedText/mw.TimedText.js +++ b/modules/TimedText/mw.TimedText.js @@ -1,74 +1,74 @@ /** * The Core timed Text interface object - * - * handles class mappings for: + * + * handles class mappings for: * menu display ( jquery.ui themeable ) * timed text loading request * timed text edit requests - * timed text search & seek interface ( version 2 ) + * timed text search & seek interface ( version 2 ) * * @author: Michael Dale * - */ + */ mw.includeAllModuleMessages(); -// Bind to mw ( for uncluttered global namespace ) +// Bind to mw ( for uncluttered global namespace ) ( function( $ ) { - - /** + + /** * Timed Text Object - * @param embedPlayer Host player for timedText interfaces + * @param embedPlayer Host player for timedText interfaces */ mw.TimedText = function( embedPlayer, options ) { return this.init( embedPlayer, options); }; mw.TimedText.prototype = { - - /** - * Preferences config order is presently: + + /** + * Preferences config order is presently: * 1) user cookie - * 2) defaults provided in this config var: + * 2) defaults provided in this config var: */ config: { // Layout for basic "timedText" type can be 'ontop', 'off', 'below' 'layout' : 'ontop', - + //Set the default local ( should be grabbed from the browser ) 'userLanugage' : 'en', - - //Set the default category of timedText to display ( un-categorized timed-text is by default "SUB" ) + + //Set the default category of timedText to display ( un-categorized timed-text is by default "SUB" ) 'userCategory' : 'SUB' }, - + /** - * The list of enabled sources + * The list of enabled sources */ enabledSources: null, - - + + /** - * Stores the last text string per category to avoid dom checks - * for updated text + * Stores the last text string per category to avoid dom checks + * for updated text */ prevText: null, - + /** * Text sources ( a set of textSource objects ) */ textSources: null, - + /** * Text Source(s) Setup Flag */ textSourceSetupFlag: null, - + /* * Hard coded to "commons" right now .. but we will want to support per-asset provider id's * in addition to a standard "callback" system from cross domain grabbing of srt's */ textProviderId : 'commons', - + /** * Valid "Track" categories */ @@ -86,7 +86,7 @@ mw.includeAllModuleMessages(); "LIN", "CUE" ], - + /** * Timed text extension to mime map */ @@ -95,51 +95,51 @@ mw.includeAllModuleMessages(); 'mw-srt': 'text/mw-srt', 'cmml': 'text/cmml' }, - + /** * @constructor - * @param {Object} embedPlayer Host player for timedText interfaces + * @param {Object} embedPlayer Host player for timedText interfaces */ init: function( embedPlayer, options ) { var _this = this; mw.log("TimedText: init() "); - this.embedPlayer = embedPlayer; + this.embedPlayer = embedPlayer; this.options = options; - - //Init internal variables: + + //Init internal variables: this.enabledSources = []; this.prevText = ''; this.textSources = []; this.textSourceSetupFlag = false; - + //Set default language via wgUserLanguage if set if( typeof wgUserLanguage != 'undefined') { this.config.userLanugage = wgUserLanguage; } - - // Load user preferences config: + + // Load user preferences config: preferenceConfig = mw.getUserConfig( 'timedTextConfig' ); if( typeof preferenceConfig == 'object' ) { this.config = preferenceConfig; } - - // Set up embedPlayer hooks: - $j( embedPlayer ).bind( 'monitorEvent', function() { + + // Set up embedPlayer hooks: + $j( embedPlayer ).bind( 'monitorEvent', function() { _this.monitor(); return false; } ); - + $j( embedPlayer ).bind( 'play', function() { // Will load and setup timedText sources (if not loaded already loaded ) _this.setupTextSources(); } ); }, - + /** * Setups available text sources * loads text sources * auto-selects a source based on the user language - * @param {Function} callback Function to be called once text sources are setup. + * @param {Function} callback Function to be called once text sources are setup. */ setupTextSources: function( callback ) { mw.log( 'mw.TimedText::setupTextSources'); @@ -151,46 +151,46 @@ mw.includeAllModuleMessages(); return ; } this.textSourceSetupFlag = true; - - // Load textSources + + // Load textSources _this.loadTextSources( function() { - + // Enable a default source and issue a request to "load it" _this.autoSelectSource(); - + // Load and parse the text value of enabled text sources: _this.loadEnabledSources(); - + if( callback ) { callback(); } } ); }, - + /** - * Binds the timed text menu + * Binds the timed text menu * and updates its content from "getMainMenu" * * @param {Object} target to display the menu - * @param {Boolean} autoShow If the menu should be displayed + * @param {Boolean} autoShow If the menu should be displayed */ bindMenu: function( target , autoShow) { var _this = this; mw.log( "TimedText:bindMenu:" + target ); _this.menuTarget = target; var $menuButton = this.embedPlayer.$interface.find( '.timed-text' ); - + var positionOpts = { }; if( this.embedPlayer.supports[ 'overlays' ] ){ var positionOpts = { - 'directionV' : 'up', + 'directionV' : 'up', 'offsetY' : this.embedPlayer.controlBuilder.getHeight(), 'directionH' : 'left', 'offsetX' : -28 - }; + }; } - - // Else bind and show the menu + + // Else bind and show the menu // We already have a loader in embedPlayer so the delay of // setupTextSources is already taken into account _this.setupTextSources( function() { @@ -206,25 +206,25 @@ mw.includeAllModuleMessages(); } ); }); }, - + /** * Monitor video time and update timed text filed[s] - */ + */ monitor: function( ) { //mw.log(" timed Text monitor: " + this.enabledSources.length ); embedPlayer = this.embedPlayer; - // Setup local reference to currentTime: + // Setup local reference to currentTime: var currentTime = embedPlayer.currentTime; - + // Get the text per category var textCategories = [ ]; - - for( var i = 0; i < this.enabledSources.length ; i++ ) { - var source = this.enabledSources[ i ]; + + for( var i = 0; i < this.enabledSources.length ; i++ ) { + var source = this.enabledSources[ i ]; this.updateSourceDisplay( source, currentTime ); } }, - + /** * Load all the available text sources from the inline embed * or from a apiProvider @@ -240,17 +240,17 @@ mw.includeAllModuleMessages(); // make a new textSource: var source = new TextSource( inlineSources[i] ); this.textSources.push( source ); - } - + } + //If there are no inline sources check & apiTitleKey if( !this.embedPlayer.apiTitleKey ) { //no other sources just issue the callback: callback(); return ; } - + // Try to get sources from text provider: - var provider_id = ( this.embedPlayer.apiProvider ) ? this.embedPlayer.apiProvider : 'local'; + var provider_id = ( this.embedPlayer.apiProvider ) ? this.embedPlayer.apiProvider : 'local'; var apiUrl = mw.getApiProviderURL( provider_id ); var assetKey = this.embedPlayer.apiTitleKey; if( !apiUrl || !assetKey ) { @@ -263,12 +263,12 @@ mw.includeAllModuleMessages(); 'apiUrl': apiUrl, 'embedPlayer': this.embedPlayer } ); - + // Load the textProvider sources - this.textProvider.loadSources( assetKey, function( textSources ) { + this.textProvider.loadSources( assetKey, function( textSources ) { for( var i=0; i < textSources.length; i++ ) { var textSource = textSources[ i ]; - // Try to insert the track source: + // Try to insert the track source: var textElm = document.createElement( 'track' ); $j( textElm ).attr({ 'category' : 'SUB', @@ -276,63 +276,63 @@ mw.includeAllModuleMessages(); 'type' : _this.timedTextExtMime[ textSource.extension ], 'titleKey' : textSource.titleKey }); - - // Build the url for downloading the text: - $j( textElm ).attr('src', + + // Build the url for downloading the text: + $j( textElm ).attr('src', _this.textProvider.apiUrl.replace('api.php', 'index.php?title=') + encodeURIComponent( textSource.titleKey ) + '&action=raw&ctype=text/x-srt' ); - + // Add a title - $j( textElm ).attr('title', + $j( textElm ).attr('title', gM('mwe-timedtext-key-language', [textSource.srclang, mw.Language.names[ textSource.srclang ] ] ) ); - // Add the sources to the parent embedPlayer + // Add the sources to the parent embedPlayer // ( in case other interfaces want to access them ) - var embedSource = _this.embedPlayer.mediaElement.tryAddSource( textElm ); + var embedSource = _this.embedPlayer.mediaElement.tryAddSource( textElm ); // Get a "textSource" object: var source = new TextSource( embedSource, _this.textProvider ); _this.textSources.push( source ); } - // All sources loaded run callback: + // All sources loaded run callback: callback(); - } ); + } ); }, - + /** * Get the layout mode - * - * Takes into consideration: + * + * Takes into consideration: * Playback method overlays support ( have to put subtitles bellow video ) - * + * */ getLayoutMode: function() { - // Re-map "ontop" to "below" if player does not support - if( this.config.layout == 'ontop' && !this.embedPlayer.supports['overlays'] ) { + // Re-map "ontop" to "below" if player does not support + if( this.config.layout == 'ontop' && !this.embedPlayer.supports['overlays'] ) { this.config.layout = 'below'; - } - return this.config.layout; + } + return this.config.layout; }, - + /** - * Auto selects a source given the local configuration - * - * NOTE: presently this selects a "single" source. - * In the future we could support multiple "enabled sources" + * Auto selects a source given the local configuration + * + * NOTE: presently this selects a "single" source. + * In the future we could support multiple "enabled sources" */ autoSelectSource: function() { this.enabledSources = []; - + // Check if any source matches our "local" for( var i=0; i < this.textSources.length; i++ ) { - var source = this.textSources[ i ]; - if( this.config.userLanugage && + var source = this.textSources[ i ]; + if( this.config.userLanugage && this.config.userLanugage == source.srclang.toLowerCase() ) { - // Check for category if available + // Check for category if available this.enabledSources.push( source ); return ; - } + } } // If no userLang, source try enabling English: if( this.enabledSources.length == 0 ) { @@ -342,18 +342,18 @@ mw.includeAllModuleMessages(); this.enabledSources.push( source ); return ; } - } + } } - // If still no source try the first source we get; + // If still no source try the first source we get; if( this.enabledSources.length == 0 ) { for( var i=0; i < this.textSources.length; i++ ) { var source = this.textSources[ i ]; this.enabledSources.push( source ); return ; - } + } } }, - + // Get the current source sub captions getCurrentSubSource: function( callback ){ mw.log("getCurrentSubSource:: enabled source:" + this.enabledSources.length); @@ -368,7 +368,7 @@ mw.includeAllModuleMessages(); } return false; }, - + // Get sub captions by language key: getSubCaptions: function( langKey, callback ){ for( var i=0; i < this.textSources.length; i++ ) { @@ -381,7 +381,7 @@ mw.includeAllModuleMessages(); } } }, - + /** * Issue a request to load all enabled Sources * Should be called anytime enabled Source list is updated @@ -392,23 +392,23 @@ mw.includeAllModuleMessages(); if( ! enabledSource.loaded ) enabledSource.load(); } - }, - + }, + /** * Selection of a menu item - * + * * @param {Element} item Item selected */ selectMenuItem: function( item ) { mw.log("selectMenuItem: " + $j( item ).find('a').attr('class') ); - }, - + }, + /** * Checks if a source is "on" * @return {Boolean} * true if source is on * false if source is off - */ + */ isSourceEnabled: function( source ) { for(var i=0; i < this.enabledSources.length; i++ ) { var enabledSource = this.enabledSources[i]; @@ -420,10 +420,10 @@ mw.includeAllModuleMessages(); if( source.srclang == enabledSource.srclang ) return true; } - } + } return false; }, - + /** * Get a source object by language, returns "false" if not found */ @@ -435,77 +435,77 @@ mw.includeAllModuleMessages(); } return false; }, - + /** - * Builds the core timed Text menu and + * Builds the core timed Text menu and * returns the binded jquery object / dom set * - * Assumes text sources have been setup: ( _this.setupTextSources() ) - * + * Assumes text sources have been setup: ( _this.setupTextSources() ) + * * calls a few sub-functions: * Basic menu layout: * Chose Language - * All Subtiles here ( if we have categories list them ) - * Layout + * All Subtiles here ( if we have categories list them ) + * Layout * Bellow video * Ontop video ( only available to supported plugins ) * [ Search Text ] - * [ This video ] + * [ This video ] * [ All videos ] * [ Chapters ] seek to chapter */ getMainMenu: function() { var _this = this; - - - // Build the source list menu item: + + + // Build the source list menu item: $menu = $j( '
+ +
- Simple Video Tag usage
+ Simple Video Tag usage
+ +
- - - - - + + - + - +
- + + class="kskin"> - Commons Video API based timedText discovery
+ Commons Video API based timedText discovery
- +
- - - + -

Text track inline embed example

+

Text track inline embed example

see: HTML5 timed text spec
+
diff --git a/mwEmbed.i18n.php b/mwEmbed.i18n.php index ab65c51252..eb6ae24840 100644 --- a/mwEmbed.i18n.php +++ b/mwEmbed.i18n.php @@ -2,7 +2,7 @@ /** * Localization file for mwEmbed.js */ - + $messages = array(); $messages['en'] = array( diff --git a/mwEmbed.js b/mwEmbed.js index bec42223a0..0db266f92e 100644 --- a/mwEmbed.js +++ b/mwEmbed.js @@ -1,4 +1,4 @@ -// Add support for html5 / mwEmbed elements to browsers that do not support the elements natively +// Add support for html5 / mwEmbed elements to browsers that do not support the elements natively // For discussion and comments, see: http://ejohn.org/blog/html5-shiv/ 'video audio source track'.replace(/\w+/g, function(n){ document.createElement(n); }); @@ -6,10 +6,10 @@ * @license * mwEmbed * Dual licensed under the MIT or GPL Version 2 licenses. - * - * @copyright (C) 2010 Kaltura + * + * @copyright (C) 2010 Kaltura * @author Michael Dale ( michael.dale at kaltura.com ) - * + * * @url http://www.kaltura.org/project/HTML5_Video_Media_JavaScript_Library * * Libraries used include code license in headers @@ -29,7 +29,7 @@ var MW_EMBED_VERSION = '1.1h'; // Globals to pre-set ready functions in dynamic loading of mwEmbed if( typeof preMwEmbedReady == 'undefined'){ - var preMwEmbedReady = []; + var preMwEmbedReady = []; } // Globals to pre-set config values in dynamic loading of mwEmbed if( typeof preMwEmbedConfig == 'undefined') { @@ -42,30 +42,30 @@ if( typeof preMwEmbedConfig == 'undefined') { ( function( mw ) { // The version of mwEmbed mw.version = MW_EMBED_VERSION; - + // List valid skins here: mw.validSkins = [ 'mvpcf', 'kskin' ]; - + // Storage variable for loaded style sheet keys if( ! mw.style ){ mw.style = { }; } - + /** * Configuration System: - */ - + */ + // Local scope configuration var: if( !mwConfig ){ var mwConfig = { }; } - + // mw scope mwUserConfig var. Stores user configuration var mwUserConfig = { }; - + /** * Setter for configuration values - * + * * @param [Mixed] * name Name of configuration value {Object} Will iderate through * each key and call setConfig {String} Will set configuration by @@ -81,65 +81,61 @@ if( typeof preMwEmbedConfig == 'undefined') { } return ; } - mwConfig[ name ] = value; - }; - /** - * Merge in a configuration value: - */ - mw.mergeConfig = function( name, value ){ - if( typeof name == 'object' ) { - $j.each( name, function( inx, val) { - mw.setConfig( inx, val ); - }); - return ; - } // Check if we should "merge" the config if( typeof value == 'object' && typeof mwConfig[ name ] == 'object' ) { - if ( $j.isArray( value ) ){ - // merge in the array - mwConfig[ name ] = mwConfig[ name ].concat( value ); - } else { + if ( value.constructor.toString().indexOf("Array") == -1 ){ for( var i in value ){ mwConfig[ name ][ i ] = value[ i ]; } + } else { + // merge in the array + mwConfig[ name ] = mwConfig[ name ].concat( value ); } - return ; + } else { + mwConfig[ name ] = value; } - // else do a normal setConfig - mwConfig[ name ] = value; }; - + /** * Set a default config value Will only update configuration if no value is * present - * + * * @param [Mixed] * value Set configuration name to value {Object} Will iderate * through each key and call setDefaultConfig {String} Will set * configuration by string name to value */ - mw.setDefaultConfig = function( name, value ) { + mw.setDefaultConfig = function( name, value ) { if( typeof name == 'object' ) { for( var i in name ) { - mw.setDefaultConfig( i, name[ i ] ); + mw.setDefaultConfig( i, name[ i ] ); } return ; - } - // Only update the controls if undefined - - if( typeof mwConfig[ name ] == 'undefined' ) { - mwConfig[ name ] = value; + } + // Only update the controls if undefined + + if( typeof mwConfig[ name ] == 'undefined' ) { + mwConfig[ name ] = value; return ; } // Check if we should "merge" the config if( typeof value == 'object' && typeof mwConfig[ name ] == 'object' ) { - mw.mergeConfig( name, value); + if ( value.constructor.toString().indexOf("Array") == -1 ){ + for( var i in value ){ + if( typeof mwConfig[ name ][ i ] == 'undefined' ){ + mwConfig[ name ][ i ] = value[ i ]; + } + } + } else { + // merge in the array + mwConfig[ name ] = mwConfig[ name ].concat( value); + } } }; - + /** * Getter for configuration values - * + * * @param {String} * name of configuration value to get * @return {Mixed} value of configuration key returns "false" if key not @@ -153,92 +149,92 @@ if( typeof preMwEmbedConfig == 'undefined') { /** * Loads the mwUserConfig from a cookie. - * + * * Modules that want to use "User Config" should call this setup function in * their moduleLoader code. - * + * * For performance interfaces using "user config" should load '$j.cookie' & * 'JSON' in their module loader - * + * * By abstracting user preference we could eventually integrate a persistent * per-account preference system on the server. - * + * * @parma {Function} callback Function to be called once userPrefrences are * loaded */ var setupUserConfigFlag = false; - mw.setupUserConfig = function( callback ) { + mw.setupUserConfig = function( callback ) { if( setupUserConfigFlag ) { - if( callback ) { + if( callback ) { callback(); } return ; } // Do Setup user config: - mw.load( [ '$j.cookie', 'JSON' ], function() { + mw.load( [ '$j.cookie', 'JSON' ], function() { if( $j.cookie( 'mwUserConfig' ) ) { mwUserConfig = JSON.parse( $j.cookie( 'mwUserConfig' ) ); - } + } setupUserConfigFlag = true; if( callback ) { - callback(); - } - }); + callback(); + } + }); }; /** * Save a user configuration var to a cookie & local global variable Loads * the cookie plugin if not already loaded - * + * * @param {String} * name Name of user configuration value * @param {String} * value Value of configuration name */ mw.setUserConfig = function ( name, value, cookieOptions ) { - if( ! setupUserConfigFlag ) { + if( ! setupUserConfigFlag ) { mw.log( "Error: userConfig not setup" ); - return false; - } + return false; + } // Update local value mwUserConfig[ name ] = value; - + // Update the cookie ( '$j.cookie' & 'JSON' should already be loaded ) $j.cookie( 'mwUserConfig', JSON.stringify( mwUserConfig ) ); }; - + /** * Save a user configuration var to a cookie & local global variable - * + * * @param {String} * name Name of user configuration value * @return value of the configuration name false if the configuration name * could not be found - */ + */ mw.getUserConfig = function ( name ) { if( mwUserConfig[ name ] ) return mwUserConfig[ name ]; return false; }; - + /** * Add a hook system for a target object / interface - * + * * depricated you should instead use jQuery's bind and trigger - * + * * @param {Object} * targetObj Interface Object to add hook system to. */ mw.addHookSystem = function( targetObj ) { - + // Setup the target object hook holder: targetObj[ 'hooks' ] = { }; - + /** * Adds a hook to the target object - * + * * Should be called by clients to setup named hooks - * + * * @param {String} * hookName Name of hook to be added * @param {Function} @@ -250,12 +246,12 @@ if( typeof preMwEmbedConfig == 'undefined') { } this.hooks[ hookName ].push( hookFunction ); }; - + /** * Runs all the hooks by a given name with reference to the host object - * + * * Should be called by the host object at named execution points - * + * * @param {String} * hookName Name of hook to be called * @return Value of hook result true interface should continue function @@ -271,89 +267,89 @@ if( typeof preMwEmbedConfig == 'undefined') { } }; }; - + // Add hooks system to the core "mw" object mw.addHookSystem( mw ); - + // Stores callbacks for resource loader loading var mwLoadDoneCB = { }; - - + + /** * Top level loader prototype: */ mw.loader = { /** * Javascript Module Loader functions - * + * * @key Name of Module * @value function code to load module */ moduleLoaders : [], - + /** * Module resource list queue. - * + * * @key Name of Module * @value .resourceList list of resources to be loaded .functionQueue * list of functions to be run once module is ready */ - moduleLoadQueue: { }, - + moduleLoadQueue: { }, + /** * Javascript Class Paths - * + * * @key Name of resource * @value Class file path */ resourcePaths : { }, - + /** * Stores resources that have been requested ( to avoid re-requesting the same resources ) * in concurrent requests ) */ - requestedResourceQueue: { }, - + requestedResourceQueue: { }, + /** * javascript Resource Paths - * + * * @key Name of resource * @value Name of depenent style sheet */ - resourceStyleDependency: { }, - + resourceStyleDependency: { }, + /** * Core load function: - * + * * @param {Mixed} * loadRequest: - * + * * {String} Name of a module to be loaded Modules are added via * addModuleLoader and can define custom code needed to check config and * return a list of resources to be loaded - * + * * {String} Name of a resource to loaded. Resources are added via * addResourcePaths function Using defined resource names avoids loading * the same resource twice by first checking if the named resource is * defined in the global javascript scope variable - * + * * {String} Absolute or relative to url path The same file won't be * loaded twice - * + * * {Array} can be an array of any combination of the above strings. Will * be loaded in-order or in a single resource loader request if * scriptLoader is available. - * + * * {Array} {Array} Can be a set of Arrays for loading. Some browsers * execute included scripts out of order. This lets you chain sets of * request for those browsers. If using the server side resource loader * order is preserved in output and a single request will be used. - * + * * @param {Function} * callback Function called once loading is complete - * - */ - load: function( loadRequest, instanceCallback ) { + * + */ + load: function( loadRequest, instanceCallback ) { // mw.log("mw.load:: " + loadRequest ); var _this = this; @@ -372,34 +368,34 @@ if( typeof preMwEmbedConfig == 'undefined') { instanceCallback = null; } }; - + // Check for empty loadRequest ( directly return the callback ) if( mw.isEmpty( loadRequest ) ) { mw.log( 'Empty load request: ( ' + loadRequest + ' ) ' ); callback( loadRequest ); return ; - } - - + } + + // Check if its a multi-part request: if( typeof loadRequest == 'object' ) { - if( loadRequest.length > 1 ) { - this.loadMany ( loadRequest, callback ); + if( loadRequest.length > 1 ) { + this.loadMany ( loadRequest, callback ); return ; }else{ // If an array of length 1 set as first element loadRequest = loadRequest[0]; - } - } - + } + } + // Check for the module name loader function - if( this.moduleLoaders[ loadRequest ] ) { - var resourceSet = this.getModuleResourceSet( loadRequest ); + if( this.moduleLoaders[ loadRequest ] ) { + var resourceSet = this.getModuleResourceSet( loadRequest ); if( !resourceSet ){ mw.log( "mw.load:: Error with module loader: " + loadRequest + ' ( no resource set defined )' ); return ; - } - + } + // xxx should use refactor "ready" stuff into a "domReady" class // So we would not have local scope globals like this: //if ( mwReadyFlag ) { @@ -408,61 +404,61 @@ if( typeof preMwEmbedConfig == 'undefined') { this.load( resourceSet, callback ); //} else { // this.addToModuleLoaderQueue( - // loadRequest, + // loadRequest, // resourceSet, // callback // ); //} return ; } - + // Check for javascript resource - if( this.getResourcePath( loadRequest ) ) { - this.loadResource( loadRequest, callback ); + if( this.getResourcePath( loadRequest ) ) { + this.loadResource( loadRequest, callback ); return ; } - + // Try loading as a "file" or via ScriptLoader - if( loadRequest ) { + if( loadRequest ) { // Check if this resource was already requested - if( typeof this.requestedResourceQueue[ loadRequest ] == 'object' ){ + if( typeof this.requestedResourceQueue[ loadRequest ] == 'object' ){ this.requestedResourceQueue[ loadRequest ].push( callback ); - return ; + return ; } else { this.requestedResourceQueue[ loadRequest ] = []; } - + if( loadRequest.indexOf( '.js' ) == -1 && !mw.getResourceLoaderPath() ) { mw.log( 'Error: are you sure ' + loadRequest + ' is a file ( is it missing a resource path? ) ' ); - } + } mw.getScript( loadRequest, function(){ - // Check if we have requestedResources queue items: - while( _this.requestedResourceQueue[ loadRequest ].length ){ + // Check if we have requestedResources queue items: + while( _this.requestedResourceQueue[ loadRequest ].length ){ _this.requestedResourceQueue[ loadRequest ].shift()( loadRequest ); } - callback( loadRequest ); - // empty the load request queue: + callback( loadRequest ); + // empty the load request queue: _this.requestedResourceQueue[ loadRequest ] = []; }); return ; } - + // Possible error? - mw.log( "Error could not handle load request: " + loadRequest ); + mw.log( "Error could not handle load request: " + loadRequest ); }, - + getModuleResourceSet: function( moduleName ){ // Check if the module loader is a function ~run that function~ if( typeof ( this.moduleLoaders[ moduleName ] ) == 'function' ) { // Add the result of the module loader function - return this.moduleLoaders[ moduleName ](); + return this.moduleLoaders[ moduleName ](); } else if( typeof ( this.moduleLoaders[ moduleName ] ) == 'object' ){ // set resourceSet directly - return this.moduleLoaders[ moduleName ]; + return this.moduleLoaders[ moduleName ]; } return false; }, - + /** * Clean the loadRequest ( throw out any non-string items ) */ @@ -472,9 +468,9 @@ if( typeof preMwEmbedConfig == 'undefined') { return loadRequest; for( var i =0;i < loadRequest.length; i++ ){ if( typeof loadRequest[i] == 'object' ) { - cleanRequest[i] = this.cleanLoadRequest( loadRequest[i] ); + cleanRequest[i] = this.cleanLoadRequest( loadRequest[i] ); } else if( typeof loadRequest[i] == 'string' ){ - cleanRequest[i] = $j.trim( loadRequest[i] ); + cleanRequest[i] = $j.trim( loadRequest[i] ); } else{ // bad request type skip } @@ -484,119 +480,119 @@ if( typeof preMwEmbedConfig == 'undefined') { /** * Load a set of scripts. Will issue many load requests or package the * request for the resource loader - * + * * @param {Object} * loadSet Set of scripts to be loaded * @param {Function} * callback Function to call once all scripts are loaded. - */ - loadMany: function( loadSet, callback ) { + */ + loadMany: function( loadSet, callback ) { var _this = this; // Setup up the local "loadStates" var loadStates = { }; - + // Check if we can load via the "resource loader" ( mwEmbed was // included via scriptLoader ) - if( mw.getResourceLoaderPath() ) { + if( mw.getResourceLoaderPath() ) { // Get the grouped loadStates variable loadStates = this.getGroupLoadState( loadSet ); if( mw.isEmpty( loadStates ) ) { // mw.log( 'loadMany:all resources already loaded'); callback(); return ; - } - }else{ + } + }else{ // Check if its a dependency set ( nested objects ) - if( typeof loadSet [ 0 ] == 'object' ) { + if( typeof loadSet [ 0 ] == 'object' ) { _this.dependencyChainCallFlag[ loadSet ] = false; // Load sets of resources ( to preserver order for some // browsers ) _this.loadDependencyChain( loadSet, callback ); return ; - } - + } + // Set the initial load state for every item in the loadSet - for( var i = 0; i < loadSet.length ; i++ ) { - var loadName = loadSet[ i ]; - loadStates[ loadName ] = 0; - } - } - + for( var i = 0; i < loadSet.length ; i++ ) { + var loadName = loadSet[ i ]; + loadStates[ loadName ] = 0; + } + } + // We are infact loading many: //mw.log("mw.load: LoadMany:: " + loadSet ); - + // Issue the load request check check loadStates to see if we are // "done" - for( var loadName in loadStates ) { + for( var loadName in loadStates ) { //mw.log("loadMany: load: " + loadName ); - this.load( loadName, function ( loadName ) { + this.load( loadName, function ( loadName ) { loadStates[ loadName ] = 1; - + /* * for( var i in loadStates ) { mw.log( loadName + ' * finished of: ' + i + ' : ' + loadStates[i] ); } */ - + // Check if all load request states are set 1 var loadDone = true; for( var j in loadStates ) { if( loadStates[ j ] === 0 ) - loadDone = false; - } + loadDone = false; + } // Run the parent scope callback for "loadMany" - if( loadDone ) { - callback( loadName ); + if( loadDone ) { + callback( loadName ); } } ); } }, - + /** * Get grouped load state for script loader - * + * * Groups the scriptRequest where possible: Modules include "loader * code" so they are separated into pre-condition code to be run for * subsequent requests - * + * * @param {Object} * loadSet Loadset to return grouped * @return {Object} grouped loadSet */ getGroupLoadState: function( loadSet ) { - var groupedLoadSet = []; + var groupedLoadSet = []; var loadStates = { }; // Merge load set into new groupedLoadSet if( typeof loadSet[0] == 'object' ) { for( var i = 0; i < loadSet.length ; i++ ) { for( var j = 0; j < loadSet[i].length ; j++ ) { // Make sure we have not already included it: - groupedLoadSet.push( loadSet[i][j] ); + groupedLoadSet.push( loadSet[i][j] ); } } } else { // Use the loadSet directly: groupedLoadSet = loadSet; } - + // Setup grouped loadStates Set: - var groupClassKey = ''; - var coma = ''; + var groupClassKey = ''; + var coma = ''; var uniqueResourceName = {}; - for( var i=0; i < groupedLoadSet.length; i++ ) { - var loadName = groupedLoadSet[ i ]; - if( this.getResourcePath( loadName ) ) { + for( var i=0; i < groupedLoadSet.length; i++ ) { + var loadName = groupedLoadSet[ i ]; + if( this.getResourcePath( loadName ) ) { // Check if not already in request queue and not defined in global namespace if( !mw.isset( loadName ) && ! uniqueResourceName[ loadName] ){ groupClassKey += coma + loadName; coma = ','; - + // Check for style sheet dependencies if( this.resourceStyleDependency[ loadName ] ){ groupClassKey += coma + this.resourceStyleDependency[ loadName ]; - } - } + } + } } else if ( this.moduleLoaders[ loadName ] ) { - + // Module loaders break up grouped script requests ( add the // current groupClassKey ) if( groupClassKey != '' ) { @@ -607,34 +603,34 @@ if( typeof preMwEmbedConfig == 'undefined') { // Add the module to the loadSate loadStates[ loadName ] = 0; } - } + } uniqueResourceName[ loadName] = true; - } - + } + // Add groupClassKey if set: if( groupClassKey != '' ) { loadStates [ groupClassKey ] = 0; } - + return loadStates; }, - + // Array to register that a callback has been called dependencyChainCallFlag: { }, - + /** * Load a sets of scripts satisfy dependency order for browsers that * execute dynamically included scripts out of order - * + * * @param {Object} * loadChain A set of javascript arrays to be loaded. Sets * are requested in array order. - */ + */ loadDependencyChain: function( loadChain, callback ) { - var _this = this; + var _this = this; // Load with dependency checks var callSet = loadChain.shift(); - this.load( callSet, function( cbname ) { + this.load( callSet, function( cbname ) { if ( loadChain.length != 0 ) { _this.loadDependencyChain( loadChain, callback ); } else { @@ -644,12 +640,12 @@ if( typeof preMwEmbedConfig == 'undefined') { mw.log("... already called this callback for " + callSet ); return ; } - _this.dependencyChainCallFlag[ callSet ] = callback; - callback( ); + _this.dependencyChainCallFlag[ callSet ] = callback; + callback( ); } } ); }, - + /** * Add to the module loader queue */ @@ -658,38 +654,38 @@ if( typeof preMwEmbedConfig == 'undefined') { if( this.moduleLoadQueue[ moduleName ] ){ // If the module is already in the queue just add its callback: this.moduleLoadQueue[ moduleName ].functionQueue.push( callback ); - } else { + } else { // create the moduleLoadQueue item this.moduleLoadQueue[ moduleName ] = { 'resourceSet' : resourceSet, 'functionQueue' : [ callback ], - 'loaded' : false + 'loaded' : false }; } }, - + /** * Loops over all modules in queue, builds request sets based on config * request type - */ - runModuleLoadQueue: function(){ - var _this = this; - mw.log( "mw.runModuleLoadQueue:: " ); - var runModuleFunctionQueue = function(){ + */ + runModuleLoadQueue: function(){ + var _this = this; + mw.log( "mw.runModuleLoadQueue:: " ); + var runModuleFunctionQueue = function(){ // Run all the callbacks for( var moduleName in _this.moduleLoadQueue ){ while( _this.moduleLoadQueue[moduleName].functionQueue.length ) { - _this.moduleLoadQueue[moduleName].functionQueue.shift()(); + _this.moduleLoadQueue[moduleName].functionQueue.shift()(); } } }; - + // Check for single request or javascript debug based loading: - if( !mw.getResourceLoaderPath() || mw.getConfig( 'loader.groupStrategy' ) == 'single' ){ + if( !mw.getResourceLoaderPath() || mw.getConfig( 'loader.groupStrategy' ) == 'single' ){ // if not using the resource load just do a normal array merge // ( for browsers like IE that don't follow first append first // execute rule ) - var fullResourceList = []; + var fullResourceList = []; for( var moduleName in this.moduleLoadQueue ) { var resourceSet = this.moduleLoadQueue[ moduleName ].resourceSet; // Lets try a global merge @@ -700,20 +696,20 @@ if( typeof preMwEmbedConfig == 'undefined') { }); return ; } - + // Else do per module group loading - if( mw.getConfig( 'loader.groupStrategy' ) == 'module' ) { + if( mw.getConfig( 'loader.groupStrategy' ) == 'module' ) { var fullResourceList = []; - var sharedResourceList = []; - - for( var moduleName in this.moduleLoadQueue ) { + var sharedResourceList = []; + + for( var moduleName in this.moduleLoadQueue ) { // Build a shared dependencies list and load that separately // "first" // ( in IE we have to wait until its "ready" since it does // not follow dom order ) var moduleResourceList = this.getFlatModuleResourceList( moduleName ); // Build the sharedResourceList - for( var i=0; i < moduleResourceList.length; i++ ){ + for( var i=0; i < moduleResourceList.length; i++ ){ var moduleResource = moduleResourceList[i]; // Check if already in the full resource list if so add // to shared. @@ -721,39 +717,39 @@ if( typeof preMwEmbedConfig == 'undefined') { if( $j.inArray( moduleResource, sharedResourceList ) == -1 ){ sharedResourceList.push( moduleResource ); } - } + } // Add to the fullResourceList fullResourceList[ moduleResource ] = true; } } - + // Local module request set ( stores the actual request we will // make after grouping shared resources - var moduleRequestSet = {}; - + var moduleRequestSet = {}; + // Only add non-shared to respective modules load requests for( var moduleName in this.moduleLoadQueue ) { - moduleRequestSet[ moduleName ] = []; + moduleRequestSet[ moduleName ] = []; var moduleResourceList = this.getFlatModuleResourceList( moduleName ); for( var i =0; i < moduleResourceList.length; i++ ){ var moduleResource = moduleResourceList[i]; if( $j.inArray( moduleResource, sharedResourceList ) == -1 ){ moduleRequestSet[ moduleName ].push( moduleResource ); } - } + } } var sharedResourceLoadDone = false; // Check if modules are done - var checkModulesDone = function(){ + var checkModulesDone = function(){ if( !sharedResourceLoadDone ){ - return false; + return false; } for( var moduleName in _this.moduleLoadQueue ) { if( ! _this.moduleLoadQueue[ moduleName ].loaded ){ return false; } } - runModuleFunctionQueue(); + runModuleFunctionQueue(); }; // Local instance of load requests to retain resourceSet // context: @@ -763,38 +759,38 @@ if( typeof preMwEmbedConfig == 'undefined') { checkModulesDone(); }); }; - + // Load the shared resources mw.load( sharedResourceList, function(){ // mw.log("Shared Resources loaded"); // xxx check if we are in "IE" and dependencies need to be // loaded "first" sharedResourceLoadDone = true; - checkModulesDone(); - }); + checkModulesDone(); + }); // Load all module Request Set for( var moduleName in moduleRequestSet ){ - localLoadCallInstance( moduleName, moduleRequestSet[ moduleName ] ); + localLoadCallInstance( moduleName, moduleRequestSet[ moduleName ] ); } - } + } // xxx Here we could also do some "intelligent" grouping - }, - + }, + getFlatModuleResourceList: function( moduleName ){ var moduleList = []; for( var j in this.moduleLoadQueue[moduleName].resourceSet ){ // Check if we have a multi-set array: - if( typeof this.moduleLoadQueue[moduleName].resourceSet[j] == 'object' ){ - moduleList = $j.merge( moduleList, this.moduleLoadQueue[moduleName].resourceSet[j] ); + if( typeof this.moduleLoadQueue[moduleName].resourceSet[j] == 'object' ){ + moduleList = $j.merge( moduleList, this.moduleLoadQueue[moduleName].resourceSet[j] ); } else { - moduleList = $j.merge( moduleList, [ this.moduleLoadQueue[moduleName].resourceSet[j] ] ); + moduleList = $j.merge( moduleList, [ this.moduleLoadQueue[moduleName].resourceSet[j] ] ); } } return moduleList; }, /** * Loads javascript or css associated with a resourceName - * + * * @param {String} * resourceName Name of resource to load * @param {Function} @@ -802,89 +798,89 @@ if( typeof preMwEmbedConfig == 'undefined') { */ loadResource: function( resourceName , callback) { // mw.log("LoadResource:" + resourceName ); - var _this = this; - + var _this = this; + // Check for css dependency on resource name - if( this.resourceStyleDependency[ resourceName ] ) { + if( this.resourceStyleDependency[ resourceName ] ) { if( ! mw.isset( this.resourceStyleDependency[ resourceName ] )){ - mw.log("loadResource:: dependent css resource: " + this.resourceStyleDependency[ resourceName ] ); + mw.log("loadResource:: dependent css resource: " + this.resourceStyleDependency[ resourceName ] ); _this.loadResource( this.resourceStyleDependency[ resourceName ] , function() { // Continue the original loadResource request. _this.loadResource( resourceName, callback ); }); return ; } - } - + } + // Make sure the resource is not already defined: if ( mw.isset( resourceName ) ) { // mw.log( 'Class ( ' + resourceName + ' ) already defined ' ); callback( resourceName ); - return ; + return ; } - + // Setup the Script Request var: - var scriptRequest = null; - - + var scriptRequest = null; + + // If the scriptloader is enabled use the resourceName as the // scriptRequest: - if( mw.getResourceLoaderPath() ) { - scriptRequest = resourceName; - }else{ + if( mw.getResourceLoaderPath() ) { + scriptRequest = resourceName; + }else{ // Get the resource url: - var baseClassPath = this.getResourcePath( resourceName ); + var baseClassPath = this.getResourcePath( resourceName ); // Add the mwEmbed path if not a root path or a full url - if( baseClassPath.indexOf( '/' ) !== 0 && + if( baseClassPath.indexOf( '/' ) !== 0 && baseClassPath.indexOf( '://' ) === -1 ) { scriptRequest = mw.getMwEmbedPath() + baseClassPath; }else{ scriptRequest = baseClassPath; - } + } if( ! scriptRequest ) { - mw.log( "Error Could not get url for resource " + resourceName ); + mw.log( "Error Could not get url for resource " + resourceName ); return false; - } - } + } + } // Include resource defined check for older browsers var resourceDone = false; - + // Set the loadDone callback per the provided resourceName mw.setLoadDoneCB( resourceName, callback ); // Issue the request to load the resource (include resource name in // result callback: - mw.getScript( scriptRequest, function( scriptRequest ) { + mw.getScript( scriptRequest, function( scriptRequest ) { // If its a "style sheet" manually set its resource to true var ext = scriptRequest.substr( scriptRequest.split('?')[0].lastIndexOf( '.' ), 4 ).toLowerCase(); - if( ext == '.css' && resourceName.substr(0,8) == 'mw.style' ){ + if( ext == '.css' && resourceName.substr(0,8) == 'mw.style' ){ mw.style[ resourceName.substr( 9 ) ] = true; - } - + } + // Send warning if resourceName is not defined if(! mw.isset( resourceName ) && mwLoadDoneCB[ resourceName ] != 'done' ) { - mw.log( 'Possible Error: ' + resourceName +' not set in time, or not defined in:' + "\n" - + _this.getResourcePath( resourceName ) ); + mw.log( 'Possible Error: ' + resourceName +' not set in time, or not defined in:' + "\n" + + _this.getResourcePath( resourceName ) ); } - + // If ( debug mode ) and the script include is missing resource // messages // do a separate request to retrieve the msgs if( mw.currentClassMissingMessages ) { - mw.log( " resourceName " + resourceName + " is missing messages" ); + mw.log( " resourceName " + resourceName + " is missing messages" ); // Reset the currentClassMissingMessages flag mw.currentClassMissingMessages = false; - + // Load msgs for this resource: - mw.loadResourceMessages( resourceName, function() { + mw.loadResourceMessages( resourceName, function() { // Run the onDone callback mw.loadDone( resourceName ); } ); - } else { + } else { // If not using the resource loader make sure the // resourceName is available before firing the loadDone if( !mw.getResourceLoaderPath() ) { - mw.waitForObject( resourceName, function( resourceName ) { + mw.waitForObject( resourceName, function( resourceName ) { // Once object is ready run loadDone mw.loadDone( resourceName ); } ); @@ -894,52 +890,52 @@ if( typeof preMwEmbedConfig == 'undefined') { // mw.loadDone( resourceName ); } } - } ); - }, - + } ); + }, + /** * Adds a module to the mwLoader object - * + * * @param {String} * name Name of module * @param {Function} * moduleLoader Function that loads dependencies for a module */ - addModuleLoader: function( name, moduleLoader ) { + addModuleLoader: function( name, moduleLoader ) { this.moduleLoaders [ name ] = moduleLoader; }, - + /** * Adds resource file path key value pairs - * + * * @param {Object} * resourceSet JSON formated list of resource name file path * pairs. - * + * * resourceSet must be strict JSON to allow the php scriptLoader to * parse the file paths. */ - addResourcePaths: function( resourceSet ) { + addResourcePaths: function( resourceSet ) { var prefix = ( mw.getConfig( 'loaderContext' ) )? mw.getConfig( 'loaderContext' ): ''; - + for( var i in resourceSet ) { this.resourcePaths[ i ] = prefix + resourceSet[ i ]; - } + } }, - + /* * Adds a named style sheet dependency to a named resource - * + * * @parma {Object} resourceSet JSON formated list of resource names and * associated style sheet names - */ + */ addStyleResourceDependency: function( resourceSet ){ for( var i in resourceSet ){ this.resourceStyleDependency[ i ] = resourceSet[i]; } }, - + /** * Get a resource path from a resourceName if no resource found return * false @@ -948,17 +944,17 @@ if( typeof preMwEmbedConfig == 'undefined') { if( this.resourcePaths[ resourceName ] ) return this.resourcePaths[ resourceName ]; return false; - } + } }; - + /** * Load done callback for script loader - * + * * @param {String} * requestName Name of the load request - */ - mw.loadDone = function( requestName ) { - if( !mwLoadDoneCB[ requestName ] ) { + */ + mw.loadDone = function( requestName ) { + if( !mwLoadDoneCB[ requestName ] ) { return true; } while( mwLoadDoneCB[ requestName ].length ) { @@ -968,7 +964,7 @@ if( typeof preMwEmbedConfig == 'undefined') { { break; } - var func = mwLoadDoneCB[ requestName ].pop(); + var func = mwLoadDoneCB[ requestName ].pop(); if( typeof func == 'function' ) { // mw.log( "LoadDone: " + requestName + ' run callback::' + // func); @@ -980,10 +976,10 @@ if( typeof preMwEmbedConfig == 'undefined') { // Set the load request name to done mwLoadDoneCB[ requestName ] = 'done'; }; - + /** * Set a load done callback - * + * * @param {String} * requestName Name of resource or request set * @param {Function} @@ -998,56 +994,56 @@ if( typeof preMwEmbedConfig == 'undefined') { if( typeof mwLoadDoneCB[ requestName ] != 'object' ) { mwLoadDoneCB[ requestName ] = []; } - mwLoadDoneCB[ requestName ].push( callback ); + mwLoadDoneCB[ requestName ].push( callback ); }; - + /** * Shortcut entry points / convenience functions: Lets you write mw.load() * instead of mw.loader.load() only these entry points should be used. - * + * * future closure optimizations could minify internal function names */ - + /** * Load Object entry point: Loads a requested set of javascript - */ + */ mw.load = function( loadRequest, callback ) { return mw.loader.load( loadRequest, callback ); }; - + /** * Add module entry point: Adds a module to the mwLoader object */ mw.addModuleLoader = function ( name, loaderFunction ) { - return mw.loader.addModuleLoader( name, loaderFunction ); + return mw.loader.addModuleLoader( name, loaderFunction ); }; - + /** * Add Class File Paths entry point: */ - mw.addResourcePaths = function ( resourceSet ) { + mw.addResourcePaths = function ( resourceSet ) { return mw.loader.addResourcePaths( resourceSet ); }; - + mw.addStyleResourceDependency = function ( resourceSet ) { return mw.loader.addStyleResourceDependency( resourceSet ); }; - + /** * Get Class File Path entry point: */ mw.getResourcePath = function( resourceName ) { return mw.loader.getResourcePath( resourceName ); }; - - + + /** * Utility Functions - */ - + */ + /** * addLoaderDialog small helper for displaying a loading dialog - * + * * @param {String} * dialogHtml text Html of the loader msg */ @@ -1056,15 +1052,15 @@ if( typeof preMwEmbedConfig == 'undefined') { dialogHtml =''; } var $dialog = mw.addDialog( { - 'title' : dialogHtml, - 'content' : dialogHtml + '
' + + 'title' : dialogHtml, + 'content' : dialogHtml + '
' + $j('
') .loadingSpinner() - .html() + .html() }); return $dialog; }; - + /** * Close the loader dialog created with addLoaderDialog */ @@ -1073,32 +1069,32 @@ if( typeof preMwEmbedConfig == 'undefined') { if( !mw.isset( '$j.ui.dialog' ) ) { return false; } - // Close with timeout since jquery ui binds with timeout: + // Close with timeout since jquery ui binds with timeout: // ui dialog line 530 setTimeout( function(){ $j( '#mwTempLoaderDialog' ) .dialog( 'destroy' ); - } , 10); + } , 10); }; - + /** * Add a (temporary) dialog window: - * - * @param {Object} with following keys: + * + * @param {Object} with following keys: * title: {String} Title string for the dialog * content: {String} to be inserted in msg box * buttons: {Object} A button object for the dialog Can be a string * for the close button - * any jquery.ui.dialog option + * any jquery.ui.dialog option */ mw.addDialog = function ( options ) { // Remove any other dialog - $j( '#mwTempLoaderDialog' ).remove(); - + $j( '#mwTempLoaderDialog' ).remove(); + if( !options){ options = {}; } - + // Extend the default options with provided options var options = $j.extend({ 'bgiframe': true, @@ -1107,15 +1103,15 @@ if( typeof preMwEmbedConfig == 'undefined') { 'modal': true, 'position' : ['center', 'center'] }, options ); - + if( ! options.title || ! options.content ){ mw.log("Error: mwEmbed addDialog missing required options ( title, content ) "); return ; } - + // Append the dialog div on top: - $j( 'body' ).append( - $j('
') + $j( 'body' ).append( + $j('
') .attr( { 'id' : "mwTempLoaderDialog", 'title' : options.title @@ -1123,131 +1119,106 @@ if( typeof preMwEmbedConfig == 'undefined') { .hide() .append( options.content ) ); - + // Build the uiRequest var uiRequest = [ '$j.ui.dialog' ]; if( options.draggable ){ uiRequest.push( '$j.ui.mouse' ); - uiRequest.push( '$j.ui.draggable' ); + uiRequest.push( '$j.ui.draggable' ); } if( options.resizable ){ uiRequest.push( '$j.ui.resizable' ); } - - // Special button string + + // Special button string if ( typeof options.buttons == 'string' ) { var buttonMsg = options.buttons; buttons = { }; options.buttons[ buttonMsg ] = function() { $j( this ).dialog( 'close' ); }; - } - + } + // Load the dialog resources mw.load([ [ '$j.ui', '$j.widget', - '$j.ui.mouse', + '$j.ui.mouse', '$j.ui.position' ], uiRequest ], function() { - var $dialog = $j( '#mwTempLoaderDialog' ).show().dialog( options ); + var $dialog = $j( '#mwTempLoaderDialog' ).show().dialog( options ); + // center the dialog + // xxx figure out why jquery ui is messing up here + /*$j( '#mwTempLoaderDialog' ).parent('.ui-dialog').css({ + 'position' : 'absolute', + 'left' : '50%', + 'margin-left': -1 * $dialog.width()/2, + 'top' : '50%', + 'margin-top': -1 * $dialog.height()/2 + }); */ } ); return $j( '#mwTempLoaderDialog' ); }; - + /** - * Fallforward system by default prefers flash. - * - * This is separate from the EmbedPlayer library detection to provide package loading control + * Mobile HTML5 has special properties for html5 video:: + * * NOTE: should be phased out in favor of browser feature detection where possible - * */ - mw.isHTML5FallForwardNative = function(){ - // Check for a mobile html5 user agent: - if ( (navigator.userAgent.indexOf('iPhone') != -1) || - (navigator.userAgent.indexOf('iPod') != -1) || - (navigator.userAgent.indexOf('iPad') != -1) || - (navigator.userAgent.indexOf('Android 2.') != -1) || - // to debug in chrome / desktop safari - (document.URL.indexOf('forceMobileHTML5') != -1 ) - ) { + mw.isMobileHTML5 = function() { + // check mobile safari foce ( for debug ) + if( mw.getConfig( 'forceMobileHTML5' ) || document.URL.indexOf('forceMobileHTML5') != -1 ){ return true; } - - // Check if the client does not have flash and has the video tag - if ( navigator.mimeTypes && navigator.mimeTypes.length > 0 ) { - for ( var i = 0; i < navigator.mimeTypes.length; i++ ) { - var type = navigator.mimeTypes[i].type; - var semicolonPos = type.indexOf( ';' ); - if ( semicolonPos > -1 ) { - type = type.substr( 0, semicolonPos ); - } - if (type == 'application/x-shockwave-flash' ) { - // flash is installed don't use html5 - return false; - } - } - } - - // For IE: - var hasObj = true; - try { - var obj = new ActiveXObject( 'ShockwaveFlash.ShockwaveFlash' ); - } catch ( e ) { - hasObj = false; - } - if( hasObj ){ - return false; - } - // No flash return true if the browser supports html5 video tag with basic support for canPlayType: - var dummyvid = document.createElement( "video" ); - // temporary hack firefox does not work well with native player: - if( dummyvid.canPlayType && !$j.browser.mozilla) { + if (( navigator.userAgent.indexOf('iPhone') != -1) || + ( navigator.userAgent.indexOf('iPod') != -1) || + ( navigator.userAgent.indexOf('iPad') != -1) || + ( mw.isAndroid2() ) + ) { return true; } - // No video tag or flash, return false ( normal "install flash" user flow ) return false; - } - // Android 2 has some restrictions vs other mobile platforms + }; + // Android 2 has some restrictions vs other mobile platforms mw.isAndroid2 = function(){ if ( navigator.userAgent.indexOf('Android 2.') != -1) { return true; } return false; }; - + /** * Similar to php isset function checks if the variable exists. Does a safe * check of a descendant method or variable - * + * * @param {String} * objectPath * @return {Boolean} true if objectPath exists false if objectPath is * undefined - */ + */ mw.isset = function( objectPath ) { if ( !objectPath || typeof objectPath != 'string') { return false; - } + } var pathSet = objectPath.split( '.' ); var cur_path = ''; - + for ( var p = 0; p < pathSet.length; p++ ) { cur_path = ( cur_path == '' ) ? cur_path + pathSet[p] : cur_path + '.' + pathSet[p]; eval( 'var ptest = typeof ( ' + cur_path + ' ); ' ); - if ( ptest == 'undefined' ) { + if ( ptest == 'undefined' ) { return false; } } return true; }; - + /** * Wait for a object to be defined and the call the callback - * + * * @param {Object} * objectName Name of object to be defined * @param {Function} @@ -1257,24 +1228,24 @@ if( typeof preMwEmbedConfig == 'undefined') { * waitForObject has been called */ var waitTime = 1200; // About 30 seconds - mw.waitForObject = function( objectName, callback, _callNumber) { + mw.waitForObject = function( objectName, callback, _callNumber) { // mw.log( 'waitForObject: ' + objectName + ' cn: ' + _callNumber); - + // Increment callNumber: - if( !_callNumber ) { + if( !_callNumber ) { _callNumber = 1; } else { _callNumber++; } - + if( _callNumber > waitTime ) { mw.log( "Error: waiting for object: " + objectName + ' timeout ' ); - callback( false ); + callback( false ); return ; } - + // If the object is defined ( or we are done loading from a callback ) - if ( mw.isset( objectName ) || mwLoadDoneCB[ objectName ] == 'done' ) { + if ( mw.isset( objectName ) || mwLoadDoneCB[ objectName ] == 'done' ) { callback( objectName ); }else{ setTimeout( function( ) { @@ -1282,127 +1253,127 @@ if( typeof preMwEmbedConfig == 'undefined') { }, 25); } }; - + /** * Check if an object is empty or if its an empty string. - * + * * @param {Object} * object Object to be checked - */ - mw.isEmpty = function( object ) { - if( typeof object == 'string' ) { + */ + mw.isEmpty = function( object ) { + if( typeof object == 'string' ) { if( object == '' ) return true; // Non empty string: return false; } - + // If an array check length: if( Object.prototype.toString.call( object ) === "[object Array]" && object.length == 0 ) { return true; } - + // Else check as an object: for( var i in object ) { return false; } - + // Else object is empty: return true; }; - + /** * Log a string msg to the console - * + * * all mw.log statements will be removed on minification so lots of mw.log * calls will not impact performance in non debug mode - * + * * @param {String} * string String to output to console */ mw.log = function( string ) { // Add any prepend debug strings if necessary if ( mw.getConfig( 'Mw.LogPrepend' ) ){ - string = mw.getConfig( 'Mw.LogPrepend' ) + string; + string = mw.getConfig( 'Mw.LogPrepend' ) + string; } - + if ( window.console ) { window.console.log( string ); } else { /** * Old IE and non-Firebug debug: ( commented out for now ) - */ - - /*var log_elm = document.getElementById('mv_js_log'); - if(!log_elm) { + */ + + /*var log_elm = document.getElementById('mv_js_log'); + if(!log_elm) { document.getElementsByTagName("body")[0].innerHTML += '
' + - '' + + 'style="position:absolute;z-index:500;bottom:0px;left:0px;right:0px;height:200px;">' + + '' + '
'; } - var log_elm = document.getElementById('mv_js_log'); + var log_elm = document.getElementById('mv_js_log'); if(log_elm) { - log_elm.value+=string+"\n"; - // scroll to bottom: + log_elm.value+=string+"\n"; + // scroll to bottom: log_elm.scrollTop = log_elm.scrollHeight; }*/ } }; - + // Setup the local mwOnLoadFunctions array: var mwOnLoadFunctions = []; - + // mw Ready flag ( set once mwEmbed is ready ) var mwReadyFlag = false; - + /** * Enables load hooks to run once mwEmbeed is "ready" Will ensure jQuery is * available, is in the $j namespace and mw interfaces and configuration has * been loaded and applied - * + * * This is different from jQuery(document).ready() ( jQuery ready is not * friendly with dynamic includes and not friendly with core interface * asynchronous build out. ) - * + * * @param {Function} * callback Function to run once DOM and jQuery are ready */ - mw.ready = function( callback ) { - if( mwReadyFlag === false ) { + mw.ready = function( callback ) { + if( mwReadyFlag === false ) { // Add the callbcak to the onLoad function stack - mwOnLoadFunctions.push ( callback ); - } else { + mwOnLoadFunctions.push ( callback ); + } else { // If mwReadyFlag is already "true" issue the callback directly: callback(); - } + } }; - + /** * Runs all the queued functions called by mwEmbedSetup - */ + */ mw.runReadyFunctions = function ( ) { - mw.log('mw.runReadyFunctions: ' + mwOnLoadFunctions.length ); + mw.log('mw.runReadyFunctions: ' + mwOnLoadFunctions.length ); // Run any pre-setup ready functions while( preMwEmbedReady.length ){ preMwEmbedReady.shift()(); - } + } // Run all the queued functions: while( mwOnLoadFunctions.length ) { mwOnLoadFunctions.shift()(); - } - + } + // Sets mwReadyFlag to true so that future mw.ready run the // callback directly mwReadyFlag = true; - + // Once we have run all the queued functions mw.loader.runModuleLoadQueue(); - + }; - - + + /** * Wrapper for jQuery getScript, Uses the scriptLoader if enabled - * - * + * + * * @param {String} * scriptRequest The requested path or resourceNames for the * scriptLoader @@ -1421,62 +1392,62 @@ if( typeof preMwEmbedConfig == 'undefined') { // scriptRequest // ( presently script loader only handles "classes" not relative urls: var scriptLoaderPath = mw.getResourceLoaderPath(); - + // Check if its a resource name, ( ie does not start with "/" and does // not include :// - var isResourceName = ( scriptRequest.indexOf('://') == -1 && scriptRequest.indexOf('/') !== 0 )? true : false; - + var isResourceName = ( scriptRequest.indexOf('://') == -1 && scriptRequest.indexOf('/') !== 0 )? true : false; + var ext = scriptRequest.substr( scriptRequest.lastIndexOf( '.' ), 4 ).toLowerCase(); var isCssFile = ( ext == '.css') ? true : false ; - - if( scriptLoaderPath && isResourceName ) { - url = scriptLoaderPath + '?class=' + scriptRequest ; + + if( scriptLoaderPath && isResourceName ) { + url = scriptLoaderPath + '?class=' + scriptRequest ; } else { // Add the mwEmbed path if a relative path request url = ( isResourceName ) ? mw.getMwEmbedPath() : ''; - url+= scriptRequest; + url+= scriptRequest; } - + // Add on the request parameters to the url: - url += ( url.indexOf( '?' ) == -1 )? '?' : '&'; - url += mw.getUrlParam(); - + url += ( url.indexOf( '?' ) == -1 )? '?' : '&'; + url += mw.getUrlParam(); + // Only log sciprts ( Css is logged via "add css" ) - if( !isCssFile ){ + if( !isCssFile ){ mw.log( 'mw.getScript: ' + url ); } - + // If jQuery is available and debug is off load the script via jQuery // ( will use XHR if on same domain ) if( mw.isset( 'window.jQuery' ) && mw.getConfig( 'debug' ) === false && typeof $j != 'undefined' && mw.parseUri( url ).protocal != 'file' - && !isCssFile ) + && !isCssFile ) { - $j.getScript( url, myCallback); + $j.getScript( url, myCallback); return ; - } - + } + /** * No jQuery OR In debug mode OR Is css file * :: inject the script instead of doing an XHR eval - */ - + */ + // load style sheet directly if requested loading css if( isCssFile ){ mw.getStyleSheet( url, myCallback); return ; } - + // Load and bind manually: ( copied from jQuery ajax function ) var head = document.getElementsByTagName("head")[ 0 ]; var script = document.createElement("script"); - script.setAttribute( 'src', url ); - + script.setAttribute( 'src', url ); + // Attach handlers ( if using script loader it issues onDone callback as // well ) - script.onload = script.onreadystatechange = function() { + script.onload = script.onreadystatechange = function() { if (!this.readyState || this.readyState == "loaded" || this.readyState == "complete") { myCallback(); } @@ -1484,17 +1455,17 @@ if( typeof preMwEmbedConfig == 'undefined') { // mw.log(" append script: " + script.src ); // Append the script to the DOM: head.appendChild( script ); - }; - + }; + /** * Add a style sheet string to the document head - * + * * @param {String} * cssResourceName Name of style sheet that has been defined * @param {String} * cssString Css Payload to be added to head of document */ - mw.addStyleString = function( cssResourceName, cssString ) { + mw.addStyleString = function( cssResourceName, cssString ) { if( mw.style[ cssResourceName ] ) { mw.log(" Style: ( " + cssResourceName + ' ) already set' ); return true; @@ -1513,48 +1484,48 @@ if( typeof preMwEmbedConfig == 'undefined') { var styleText = document.createTextNode( cssString ); styleNode.appendChild( styleText ); } - var head = document.getElementsByTagName("head")[0]; + var head = document.getElementsByTagName("head")[0]; head.appendChild( styleNode ); }; - + /** * Get a style sheet and append the style sheet to the DOM - * + * * @param {Mixed} * {String} url Url of the style sheet to be loaded {Function} * callback Function called once sheet is ready */ - mw.getStyleSheet = function( url , callback) { + mw.getStyleSheet = function( url , callback) { // Add URL params ( if not already included ) if ( url.indexOf( '?' ) == -1 ) { url += '?' + mw.getUrlParam(); } - + // Check if style sheet is already included: - var foundSheet = false; + var foundSheet = false; $j( 'link' ).each( function() { var currentSheet = $j( this) .attr( 'href' ); - var sheetParts = currentSheet.split('?'); + var sheetParts = currentSheet.split('?'); var urlParts = url.split('?'); // if the base url's match check the parameters: - if( sheetParts[0] == urlParts[0] && sheetParts[1]) { + if( sheetParts[0] == urlParts[0] && sheetParts[1]) { // Check if url params match ( sort to do string compare ) if( sheetParts[1].split( '&' ).sort().join('') == - urlParts[1].split('&').sort().join('') ) { + urlParts[1].split('&').sort().join('') ) { foundSheet = true; } } - } ); + } ); if( foundSheet ) { mw.log( 'skiped sheet: ' + url); - if( callback) { + if( callback) { callback(); } return ; } - - mw.log( ' add css: ' + url ); - $j( 'head' ).append( + + mw.log( ' add css: ' + url ); + $j( 'head' ).append( $j('').attr( { 'rel' : 'stylesheet', 'type' : 'text/css', @@ -1568,74 +1539,74 @@ if( typeof preMwEmbedConfig == 'undefined') { callback(); } }; - + mw.getRelativeMwEmbedPath = function(){ return mw.getMwEmbedPath(true); - }; + }; /** * Get the path to the mwEmbed folder */ - mw.getMwEmbedPath = function( relativePath ) { + mw.getMwEmbedPath = function( relativePath ) { // Get mwEmbed src: var src = mw.getMwEmbedSrc(); var mwpath = null; - + // Check for direct include of the mwEmbed.js if ( src.indexOf( 'mwEmbed.js' ) !== -1 ) { - mwpath = src.substr( 0, src.indexOf( 'mwEmbed.js' ) ); + mwpath = src.substr( 0, src.indexOf( 'mwEmbed.js' ) ); } - + // Check for scriptLoader include of mwEmbed: if ( src.indexOf( 'mwResourceLoader.php' ) !== -1 ) { // Script loader is in the root of MediaWiki, Include the default // mwEmbed extension path: - mwpath = src.substr( 0, src.indexOf( 'mwResourceLoader.php' ) ) + mw.getConfig( 'mediaWikiEmbedPath' ); + mwpath = src.substr( 0, src.indexOf( 'mwResourceLoader.php' ) ) + mw.getConfig( 'mediaWikiEmbedPath' ); } - + // resource loader has ResourceLoader name when local: if( src.indexOf( 'ResourceLoader.php' ) !== -1 ) { - mwpath = src.substr( 0, src.indexOf( 'ResourceLoader.php' ) ); - } - + mwpath = src.substr( 0, src.indexOf( 'ResourceLoader.php' ) ); + } + // For static packages mwEmbed packages start with: "mwEmbed-" if( src.indexOf( 'mwEmbed-' ) !== -1 && src.indexOf( '-static' ) !== -1 ) { mwpath = src.substr( 0, src.indexOf( 'mwEmbed-' ) ); } - + // Error out if we could not get the path: if( mwpath === null ) { mw.log( "Error could not get mwEmbed path " ); return ; } - + // Update the cached var with the absolute path: if( !relativePath ){ mwpath = mw.absoluteUrl( mwpath ) ; } return mwpath; }; - + /** * Get Script loader path - * + * * @returns {String}|{Boolean} Url of the scriptLodaer false if the * scriptLoader is not used */ - mw.getResourceLoaderPath = function( ) { + mw.getResourceLoaderPath = function( ) { var src = mw.getMwEmbedSrc(); - if ( src.indexOf( 'mwResourceLoader.php' ) !== -1 || + if ( src.indexOf( 'mwResourceLoader.php' ) !== -1 || src.indexOf( 'ResourceLoader.php' ) !== -1 ) { // Return just the script part of the url - return src.split('?')[0]; + return src.split('?')[0]; } return false; }; - + /** * Given a float number of seconds, returns npt format response. ( ignore * days for now ) - * + * * @param {Float} * sec Seconds * @param {Boolean} @@ -1644,12 +1615,12 @@ if( typeof preMwEmbedConfig == 'undefined') { */ mw.seconds2npt = function( sec, verbose ) { if ( isNaN( sec ) ) { - mw.log("Warning: trying to get npt time on NaN:" + sec); + mw.log("Warning: trying to get npt time on NaN:" + sec); return '0:00:00'; } - + var tm = mw.seconds2Measurements( sec ); - + // Round the number of seconds to the required number of significant // digits if ( verbose ) { @@ -1660,25 +1631,25 @@ if( typeof preMwEmbedConfig == 'undefined') { if ( tm.seconds < 10 ){ tm.seconds = '0' + tm.seconds; } - if( tm.hours == 0 && !verbose ){ + if( tm.hours == 0 && !verbose ){ hoursStr = ''; } else { if ( tm.minutes < 10 && verbose) { tm.minutes = '0' + tm.minutes; } - + if( tm.hours < 10 && verbose){ - tm.hours = '0' + tm.hours; + tm.hours = '0' + tm.hours; } - + hoursStr = tm.hours + ':'; } return hoursStr + tm.minutes + ":" + tm.seconds; }; - + /** * Given seconds return array with 'days', 'hours', 'min', 'seconds' - * + * * @param {float} * sec Seconds to be converted into time measurements */ @@ -1690,10 +1661,10 @@ if( typeof preMwEmbedConfig == 'undefined') { tm.seconds = sec % 60; return tm; }; - + /** * Take hh:mm:ss,ms or hh:mm:ss.ms input, return the number of seconds - * + * * @param {String} * npt_str NPT time string * @return {Float} Number of seconds @@ -1705,11 +1676,11 @@ if( typeof preMwEmbedConfig == 'undefined') { } // Strip {npt:}01:02:20 or 32{s} from time if present npt_str = npt_str.replace( /npt:|s/g, '' ); - + var hour = 0; var min = 0; var sec = 0; - + times = npt_str.split( ':' ); if ( times.length == 3 ) { sec = times[2]; @@ -1726,10 +1697,10 @@ if( typeof preMwEmbedConfig == 'undefined') { // Return seconds float return parseInt( hour * 3600 ) + parseInt( min * 60 ) + parseFloat( sec ); }; - + // Local mwEmbedSrc variable ( for cache of mw.getMwEmbedSrc ) - var mwEmbedSrc = null; - + var mwEmbedSrc = null; + /** * Gets the mwEmbed script src attribute */ @@ -1737,7 +1708,7 @@ if( typeof preMwEmbedConfig == 'undefined') { if ( mwEmbedSrc ) { return mwEmbedSrc; } - + // Get all the javascript includes: var js_elements = document.getElementsByTagName( "script" ); for ( var i = 0; i < js_elements.length; i++ ) { @@ -1747,10 +1718,10 @@ if( typeof preMwEmbedConfig == 'undefined') { if ( // Check for mwEmbed.js ( debug mode ) ( src.indexOf( 'mwEmbed.js' ) !== -1 && src.indexOf( 'MediaWiki:Gadget') == -1 ) || // Check for resource loader - ( + ( ( src.indexOf( 'mwResourceLoader.php' ) !== -1 || src.indexOf( 'ResourceLoader.php' ) !== -1 ) - && - src.indexOf( 'mwEmbed' ) !== -1 + && + src.indexOf( 'mwEmbed' ) !== -1 ) || // Check for static mwEmbed package ( src.indexOf( 'mwEmbed' ) !== -1 && src.indexOf( 'static' ) !== -1 ) @@ -1763,10 +1734,10 @@ if( typeof preMwEmbedConfig == 'undefined') { mw.log( 'Error: getMwEmbedSrc failed to get script path' ); return false; }; - + // Local mwUrlParam variable ( for cache of mw.getUrlParam ) var mwUrlParam = null; - + /** * Get URL Parameters per parameters in the host script include */ @@ -1774,154 +1745,154 @@ if( typeof preMwEmbedConfig == 'undefined') { if ( mwUrlParam ) { return mwUrlParam; } - - var mwEmbedSrc = mw.getMwEmbedSrc(); + + var mwEmbedSrc = mw.getMwEmbedSrc(); var req_param = ''; - + // If we already have a URI, add it to the param request: var urid = mw.parseUri( mwEmbedSrc ).queryKey['urid']; - + // If we're in debug mode, get a fresh unique request key and pass on // "debug" param - if ( mw.parseUri( mwEmbedSrc ).queryKey['debug'] == 'true' ) { - mw.setConfig( 'debug', true ); + if ( mw.parseUri( mwEmbedSrc ).queryKey['debug'] == 'true' ) { + mw.setConfig( 'debug', true ); var d = new Date(); - req_param += 'urid=' + d.getTime() + '&debug=true'; - + req_param += 'urid=' + d.getTime() + '&debug=true'; + } else if ( urid ) { // Just pass on the existing urid: - req_param += 'urid=' + urid; + req_param += 'urid=' + urid; } else { // Otherwise, Use the mwEmbed version req_param += 'urid=' + mw.version; } - + // Add the language param if present: var langKey = mw.parseUri( mwEmbedSrc ).queryKey['uselang']; if ( langKey ) req_param += '&uselang=' + langKey; - + // Update the local cache and return the value - mwUrlParam = req_param; + mwUrlParam = req_param; return mwUrlParam; }; - + /** * Replace url parameters via newParams key value pairs - * + * * @param {String} * url Source url to be updated * @param {Object} * newParams key, value paris to swap in * @return {String} the updated url - */ + */ mw.replaceUrlParams = function( url, newParams ) { - var parsedUrl = mw.parseUri( url ); - + var parsedUrl = mw.parseUri( url ); + if ( parsedUrl.protocol != '' ) { var new_url = parsedUrl.protocol + '://' + parsedUrl.authority + parsedUrl.path + '?'; } else { var new_url = parsedUrl.path + '?'; } - + // Merge new params: for( var key in newParams ) { - parsedUrl.queryKey[ key ] = newParams[ key ]; + parsedUrl.queryKey[ key ] = newParams[ key ]; } - + // Output to new_url var amp = ''; - for ( var key in parsedUrl.queryKey ) { - var val = parsedUrl.queryKey[ key ]; + for ( var key in parsedUrl.queryKey ) { + var val = parsedUrl.queryKey[ key ]; new_url += amp + key + '=' + val; amp = '&'; } return new_url; }; - + /** * parseUri 1.2.2 (c) Steven Levithan MIT License - */ + */ mw.parseUri = function (str) { var o = mw.parseUri.options, m = o.parser[o.strictMode ? "strict" : "loose"].exec(str), uri = {}, i = 14; - + while (i--) uri[o.key[i]] = m[i] || ""; - + uri[o.q.name] = {}; uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) { if ($1) uri[o.q.name][$1] = $2; }); - + return uri; }; - + /** * Parse URI function - * + * * For documentation on its usage see: * http://stevenlevithan.com/demo/parseuri/js/ */ mw.parseUri.options = { strictMode: false, - key: ["source", "protocol", "authority", "userInfo", "user", "password", "host", + key: ["source", "protocol", "authority", "userInfo", "user", "password", "host", "port", "relative", "path", "directory", "file", "query", "anchor"], - q: { - name: "queryKey", + q: { + name: "queryKey", parser: /(?:^|&)([^&=]*)=?([^&]*)/g }, parser: { strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/, loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/ } - }; - + }; + /** * getAbsoluteUrl takes a src and returns the absolute location given the * document.URL or a contextUrl param - * + * * @param {String} src path or url - * @param {String} contextUrl The domain / context for creating an absolute url + * @param {String} contextUrl The domain / context for creating an absolute url * from a relative path * @return {String} absolute url */ - mw.absoluteUrl = function( src, contextUrl ) { - - var parsedSrc = mw.parseUri( src ); +mw.absoluteUrl = function( src, contextUrl ) { + + var parsedSrc = mw.parseUri( src ); // Source is already absolute return: if( parsedSrc.protocol != '') { - return src; + return src; } - + // Get parent Url location the context URL - if( !contextUrl ) { + if( !contextUrl ) { contextUrl = document.URL; - } - var parsedUrl = mw.parseUri( contextUrl ); - - // Check for IE local file that does not flip the slashes - if( parsedUrl.directory == '' && parsedUrl.protocol == 'file' ){ + } + var parsedUrl = mw.parseUri( contextUrl ); + + // Check for IE local file that does not flip the slashes + if( parsedUrl.directory == '' && parsedUrl.protocol == 'file' ){ // pop off the file var fileUrl = contextUrl.split( '\\'); fileUrl.pop(); - return fileUrl.join('\\') + '\\' + src; + return fileUrl.join('\\') + '\\' + src; } // Check for leading slash: if( src.indexOf( '/' ) === 0 ) { return parsedUrl.protocol + '://' + parsedUrl.authority + src; - }else{ + }else{ return parsedUrl.protocol + '://' + parsedUrl.authority + parsedUrl.directory + src; } }; /** - * Check if a given source string is likely a url - * - * @return {boolean} - * true if a url + * Check if a given source string is likely a url + * + * @return {boolean} + * true if a url * false if a string */ mw.isUrl = function( src ){ @@ -1929,10 +1900,10 @@ if( typeof preMwEmbedConfig == 'undefined') { // if the url is just a string source and host will match return ( parsedSrc.host != parsedSrc.source ); }; - + /** * Escape quotes in a text string - * + * * @param {String} * text String to be escaped * @return {string} escaped text string @@ -1944,10 +1915,10 @@ if( typeof preMwEmbedConfig == 'undefined') { text = text.replace(re,"\\n"); return mw.escapeQuotesHTML(text); }; - + /** * Escape an HTML text string - * + * * @param {String} * text String to be escaped * @return {string} escaped text html string @@ -1962,18 +1933,18 @@ if( typeof preMwEmbedConfig == 'undefined') { for( var i in replaceMap ){ text = text.split(i).join( replaceMap[i]); } - return text; + return text; }; - - + + // Array of setup functions var mwSetupFunctions = []; - + /** * Add a function to be run during setup ( prior to mw.ready) this is useful * for building out interfaces that should be ready before mw.ready is * called. - * + * * @param {callback} * Function Callback function must accept a ready function * callback to be called once setup is done @@ -1981,84 +1952,84 @@ if( typeof preMwEmbedConfig == 'undefined') { mw.addSetupHook = function( callback ) { mwSetupFunctions.push ( callback ) ; }; - + /** * One time "setup" for mwEmbed run onDomReady ( so calls to setConfg apply * to setup ) */ // Flag to ensure setup is only run once: - var mwSetupFlag = false; - mw.setupMwEmbed = function ( ) { + var mwSetupFlag = false; + mw.setupMwEmbed = function ( ) { // Only run the setup once: if( mwSetupFlag ) { return ; - } - mwSetupFlag = true; - - // Apply any pre-setup config: - mw.setConfig( preMwEmbedConfig ); - - - mw.log( 'mw:setupMwEmbed SRC:: ' + mw.getMwEmbedSrc() ); - + } + mwSetupFlag = true; + + // Apply any pre-setup config: + mw.setConfig( preMwEmbedConfig ); + + + mw.log( 'mw:setupMwEmbed SRC:: ' + mw.getMwEmbedSrc() ); + // Check core mwEmbed loader.js file ( to get configuration and paths ) - mw.checkCoreLoaderFile( function(){ + mw.checkCoreLoaderFile( function(){ // Make sure we have jQuery - mw.load( 'window.jQuery', function() { - + mw.load( 'window.jQuery', function() { + // Add jQuery to $j var. if ( ! window[ '$j' ] ) { - window[ '$j' ] = jQuery.noConflict(); + window[ '$j' ] = jQuery.noConflict(); } - // Setup user config: + // Setup user config: mw.setupUserConfig( function(){ // Get module loader.js, and language files // ( will hit callback directly if set via resource loader ) mw.checkModuleLoaderFiles( function() { - + // Set the User language - if( typeof wgUserLanguage != 'undefined' && mw.isValidLang( wgUserLanguage) ) { + if( typeof wgUserLanguage != 'undefined' && mw.isValidLang( wgUserLanguage) ) { mw.setConfig( 'userLanguage', wgUserLanguage ); }else{ // Grab it from the included url var langKey = mw.parseUri( mw.getMwEmbedSrc() ).queryKey['uselang']; - if ( langKey && mw.isValidLang( langKey ) ) { + if ( langKey && mw.isValidLang( langKey ) ) { mw.setConfig( 'userLanguage', langKey); } - } - + } + // Update the image path - mw.setConfig( 'imagesPath', mw.getMwEmbedPath() + 'skins/common/images/' ); - + mw.setConfig( 'imagesPath', mw.getMwEmbedPath() + 'skins/common/images/' ); + // Set up AJAX to not send dynamic URLs for loading scripts $j.ajaxSetup( { cache: true } ); - + // Update the magic keywords mw.Language.magicSetup(); - + // Set up mvEmbed utility jQuery bindings - mw.dojQueryBindings(); - - + mw.dojQueryBindings(); + + // Special Hack for conditional jquery ui inclusion ( once // Usability extension - // registers the jquery.ui skin in mw.style + // registers the jquery.ui skin in mw.style if( mw.hasJQueryUiCss() ){ - mw.style[ 'ui_' + mw.getConfig( 'jQueryUISkin' ) ] = true; - } - - + mw.style[ 'ui_' + mw.getConfig( 'jQueryUISkin' ) ] = true; + } + + // Make sure style sheets are loaded: - mw.load( ['mw.style.mwCommon'] , function(){ + mw.load( ['mw.style.mwCommon'] , function(){ // Run all the setup function hooks // NOTE: setup functions are added via addSetupHook // calls // and must include a callback. // // Once complete we can run .ready() queued functions - function runSetupFunctions() { + function runSetupFunctions() { if( mwSetupFunctions.length ) { mwSetupFunctions.shift()( function() { runSetupFunctions(); @@ -2067,27 +2038,27 @@ if( typeof preMwEmbedConfig == 'undefined') { mw.runReadyFunctions(); } } - runSetupFunctions(); + runSetupFunctions(); } ); - - } ); + + } ); }); }); }); }; - + /** * Checks for jquery ui css by name jquery-ui-1.7.2.css NOTE: this is a hack * for usability jquery-ui in the future usability should register a * resource in mw.skin - * + * * @return true if found, return false if not found */ mw.hasJQueryUiCss = function(){ var hasUiCss = false; var cssStyleSheetNames = ['jquery-ui-1.7.2.css', 'jquery-ui.css']; // Load the jQuery ui skin if usability skin not set - $j( 'link' ).each( function( na, linkNode ){ + $j( 'link' ).each( function( na, linkNode ){ $j.each( cssStyleSheetNames, function(inx, sheetName ){ if( $j( linkNode ).attr( 'href' ).indexOf( sheetName ) != -1 ){ hasUiCss = true; @@ -2099,24 +2070,24 @@ if( typeof preMwEmbedConfig == 'undefined') { // xxx Note: we could do this a bit cleaner with regEx $j( 'style' ).each( function( na, styleNode ){ $j.each( cssStyleSheetNames, function(inx, sheetName ){ - if( $j( styleNode ).text().indexOf( '@import' ) != -1 - && - $j( styleNode ).text().indexOf( sheetName ) != -1 ) + if( $j( styleNode ).text().indexOf( '@import' ) != -1 + && + $j( styleNode ).text().indexOf( sheetName ) != -1 ) { hasUiCss=true; return true; } }); - }); - return hasUiCss; + }); + return hasUiCss; }; - + /** * Loads the core mwEmbed "loader.js" file config - * + * * NOTE: if using the ScriptLoader all the loaders and localization * converters are included automatically - * + * * @param {Function} * callback Function called once core loader file is loaded */ @@ -2127,7 +2098,7 @@ if( typeof preMwEmbedConfig == 'undefined') { callback(); return ; } - + // Check if we are using a static package ( mwEmbed path includes // -static ) if( mw.isStaticPackge() ){ @@ -2139,62 +2110,62 @@ if( typeof preMwEmbedConfig == 'undefined') { // The follow code is ONLY RUN in debug / raw file mode mw.load( 'loader.js', callback ); }; - + /** * Checks if the javascript is a static package ( not using resource loader ) - * + * * @return {boolean} true the included script is static false the included * script - */ + */ mw.isStaticPackge = function(){ var src = mw.getMwEmbedSrc(); - if( src.indexOf('-static') !== -1 ){ - return true; + if( src.indexOf('-static') !== -1 ){ + return true; } return false; }; - + /** * Check for resource loader module loaders, and localization files - * + * * NOTE: if using the ScriptLoader all the loaders and localization * converters are included automatically. */ mw.checkModuleLoaderFiles = function( callback ) { mw.log( 'doLoaderCheck::' ); - + // Check if we are using scriptloader ( handles loader include // automatically ) // Or if mwEmbed is a static package ( all resources are already loaded // ) if( mw.getResourceLoaderPath() || mw.isStaticPackge() ) { - callback(); + callback(); return ; } - + // Load the configured modules / components // The follow code is ONLY RUN in debug / raw file mode - var loaderRequest = []; - + var loaderRequest = []; + // Load enabled components var enabledComponents = mw.getConfig( 'coreComponents' ); - function loadEnabledComponents( enabledComponents ){ + function loadEnabledComponents( enabledComponents ){ if( ! enabledComponents.length ){ // If no more components load modules:: - + // Add the enabledModules loaders: var enabledModules = mw.getConfig( 'enabledModules' ); loadEnabledModules( enabledModules ); - return ; + return ; } var componentName = enabledComponents.shift(); mw.load( componentName, function(){ loadEnabledComponents( enabledComponents ); } ); } - loadEnabledComponents( enabledComponents ); - - + loadEnabledComponents( enabledComponents ); + + // Set the loader context and get each loader individually function loadEnabledModules( enabledModules ){ if( ! enabledModules.length ){ @@ -2203,66 +2174,66 @@ if( typeof preMwEmbedConfig == 'undefined') { return ; } var moduleName = enabledModules.shift(); - mw.setConfig( 'loaderContext', 'modules/' + moduleName + '/' ); + mw.setConfig( 'loaderContext', 'modules/' + moduleName + '/' ); mw.load( 'modules/' + moduleName + '/loader.js', function(){ - loadEnabledModules( enabledModules ); + loadEnabledModules( enabledModules ); } ); - } - + } + function addLanguageFile(){ // Add the language file var langLoaderRequest = []; - + if( mw.getConfig( 'userLanguage' ) ) { var langCode = mw.getConfig( 'userLanguage' ); - + // Load the language resource if not default 'en' - var transformKey = mw.getLangTransformKey( langCode ); - if( transformKey != 'en' ){ + var transformKey = mw.getLangTransformKey( langCode ); + if( transformKey != 'en' ){ // Upper case the first letter: langCode = langCode.substr(0,1).toUpperCase() + langCode.substr( 1, langCode.length ); langLoaderRequest.push( 'languages/classes/Language' + langCode + '.js' ); } - + } if ( ! langLoaderRequest.length ) { addLocalSettings(); return ; } - + // Load the language if set - mw.load( langLoaderRequest, function(){ - mw.log( 'Done moduleLoaderCheck request' ); + mw.load( langLoaderRequest, function(){ + mw.log( 'Done moduleLoaderCheck request' ); addLocalSettings(); } ); - } + } function addLocalSettings(){ var continueCallback = function(){ // Set the mwModuleLoaderCheckFlag flag to true - mwModuleLoaderCheckFlag = true; + mwModuleLoaderCheckFlag = true; callback(); }; if( mw.getConfig( 'LoadLocalSettings') != true ){ continueCallback(); - return; + return; } mw.log("Load loacal settings"); mw.load( 'localSettings.js', function(){ continueCallback(); }); } - + }; - + /** * Checks if a css style rule exists - * + * * On a page with lots of rules it can take some time so avoid calling this * function where possible and cache its result - * + * * NOTE: this only works for style sheets on the same domain :( - * + * * @param {String} * styleRule Style rule name to check * @return {Boolean} true if the rule exists false if the rule does not @@ -2271,30 +2242,30 @@ if( typeof preMwEmbedConfig == 'undefined') { mw.styleRuleExists = function ( styleRule ) { // Set up the skin paths configuration for( var i=0 ; i < document.styleSheets.length ; i++ ) { - var rules = null; + var rules = null; try{ if ( document.styleSheets[i].cssRules ) rules = document.styleSheets[i].cssRules; else if (document.styleSheets[0].rules) rules = document.styleSheets[i].rules; for(var j=0 ; j < rules.length ; j++ ) { - var rule = rules[j].selectorText; + var rule = rules[j].selectorText; if( rule && rule.indexOf( styleRule ) != -1 ) { return true; - } + } } }catch ( e ) { mw.log( 'Error: cant check rule on cross domain style sheet:' + document.styleSheets[i].href ); } } - return false; + return false; }; - + // Flag to register the domReady has been called var mwDomReadyFlag = false; - + // Flag to register if the domreadyHooks have been called - var mwModuleLoaderCheckFlag = false; + var mwModuleLoaderCheckFlag = false; /** * This will get called when the DOM is ready Will check configuration and @@ -2302,12 +2273,12 @@ if( typeof preMwEmbedConfig == 'undefined') { */ mw.domReady = function ( ) { if( mwDomReadyFlag ) { - return ; - } + return ; + } mw.log( 'run:domReady:: ' + document.getElementsByTagName('video').length ); // Set the onDomReady Flag - mwDomReadyFlag = true; - + mwDomReadyFlag = true; + // Give us a chance to get to the bottom of the script. // When loading mwEmbed asynchronously the dom ready gets called // directly and in some browsers beets the $j = jQuery.noConflict(); @@ -2317,25 +2288,25 @@ if( typeof preMwEmbedConfig == 'undefined') { mw.setupMwEmbed(); },1); }; - + /** * A version comparison utility function Handles version of types * {Major}.{MinorN}.{Patch} - * + * * Note this just handles version numbers not patch letters. - * + * * @param {String} * minVersion Minnium version needed * @param {String} * clientVersion Client version to be checked - * + * * @return true if the version is at least of minVersion false if the * version is less than minVersion */ mw.versionIsAtLeast = function( minVersion, clientVersion ) { var minVersionParts = minVersion.split('.'); var clientVersionParts = clientVersion.split('.'); - for( var i =0; i < minVersionParts.length; i++ ) { + for( var i =0; i < minVersionParts.length; i++ ) { if( parseInt( clientVersionParts[i] ) > parseInt( minVersionParts[i] ) ) { return true; } @@ -2346,48 +2317,48 @@ if( typeof preMwEmbedConfig == 'undefined') { // Same version: return true; }; - + /** * Runs all the triggers on a given object with a single "callback" - * + * * Normal tirgger calls will run the callback directly multiple times for * every binded function. - * + * * With runTriggersCallback() callback is not called until all the binded * events have been run. - * + * * @param {object} * targetObject Target object to run triggers on * @param {string} * triggerName Name of trigger to be run * @param {function} * callback Function called once all triggers have been run - * + * */ - mw.runTriggersCallback = function( targetObject, triggerName, callback ){ - mw.log( 'mw.runTriggersCallback:: ' + triggerName ); + mw.runTriggersCallback = function( targetObject, triggerName, callback ){ + mw.log( 'mw.runTriggersCallback:: ' + triggerName ); // If events are not present directly run callback if( ! $j( targetObject ).data( 'events' ) || ! $j( targetObject ).data( 'events' )[ triggerName ] ) { - mw.log( ' trigger name not found: ' + triggerName ); + mw.log( ' trigger name not found: ' + triggerName ); callback(); return ; - } - var callbackSet = $j( targetObject ).data( 'events' )[ triggerName ]; - if( !callbackSet || callbackSet.length === 0 ){ - mw.log( ' No events run the callback directly: ' + triggerName ); + } + var callbackSet = $j( targetObject ).data( 'events' )[ triggerName ]; + if( !callbackSet || callbackSet.length === 0 ){ + mw.log( ' No events run the callback directly: ' + triggerName ); // No events run the callback directly callback(); return ; } // Set the callbackCount var callbackCount = ( callbackSet.length )? callbackSet.length : 1; - + mw.log(" runTriggersCallback:: " + callbackCount ); var callInx = 0; - $j( targetObject ).trigger( triggerName, function() { + $j( targetObject ).trigger( triggerName, function() { callInx++; - if( callInx == callbackCount ){ + if( callInx == callbackCount ){ //mw.log(" callbackCountReached run:: " + callback); // Run callback callback(); @@ -2400,7 +2371,7 @@ if( typeof preMwEmbedConfig == 'undefined') { mw.dojQueryBindings = function() { mw.log( 'mw.dojQueryBindings' ); ( function( $ ) { - + /** * Set a given selector html to the loading spinner: */ @@ -2418,17 +2389,17 @@ if( typeof preMwEmbedConfig == 'undefined') { * element does not display child elements, ( images, video ) */ $.fn.getAbsoluteOverlaySpinner = function(){ - var pos = $j( this ).offset(); - var posLeft = ( $j( this ).width() ) ? - parseInt( pos.left + ( .5 * $j( this ).width() ) -16 ) : + var pos = $j( this ).offset(); + var posLeft = ( $j( this ).width() ) ? + parseInt( pos.left + ( .5 * $j( this ).width() ) -16 ) : pos.left + 30; - - var posTop = ( $j( this ).height() ) ? - parseInt( pos.top + ( .5 * $j( this ).height() ) -16 ) : + + var posTop = ( $j( this ).height() ) ? + parseInt( pos.top + ( .5 * $j( this ).height() ) -16 ) : pos.top + 30; - + var $spinner = $j('
') - .loadingSpinner() + .loadingSpinner() .css({ 'width' : 32, 'height' : 32, @@ -2439,7 +2410,7 @@ if( typeof preMwEmbedConfig == 'undefined') { $j('body').append( $spinner ); return $spinner; }; - + /** * dragDrop file loader */ @@ -2451,8 +2422,8 @@ if( typeof preMwEmbedConfig == 'undefined') { $j( _this.selector ).dragDropFile(); } ); } - }; - + }; + /** * Shortcut to a themed button Should be depreciated for $.button * bellow @@ -2468,53 +2439,53 @@ if( typeof preMwEmbedConfig == 'undefined') { styleClass + '">' + '' + msg + ''; }; - + // Shortcut to jQuery button ( should replace all btnHtml with // button ) var mw_default_button_options = { // The class name for the button link 'class' : '', - + // The style properties for the button link 'style' : { }, - + // The text of the button link 'text' : '', - + // The icon id that precedes the button link: - 'icon' : 'carat-1-n' + 'icon' : 'carat-1-n' }; - + $.button = function( options ) { var options = $j.extend( {}, mw_default_button_options, options); - + // Button: - var $button = $j('') + var $button = $j('') .attr('href', '#') .addClass( 'ui-state-default ui-corner-all ui-icon_link' ); // Add css if set: if( options.css ) { $button.css( options.css ); } - + if( options['class'] ) { $button.addClass( options['class'] ); - } - - - // return the button: + } + + + // return the button: $button.append( $j('').addClass( 'ui-icon ui-icon-' + options.icon ), - $j('').addClass( 'btnText' ) + $j('').addClass( 'btnText' ) .text( options.text ) ) - .buttonHover(); // add buttonHover binding; + .buttonHover(); // add buttonHover binding; if( !options.text ){ $button.css('padding', '1em'); } return $button; }; - + // Shortcut to bind hover state $.fn.buttonHover = function() { $j( this ).hover( @@ -2527,10 +2498,10 @@ if( typeof preMwEmbedConfig == 'undefined') { ); return this; }; - + /** * Resize a dialog to fit the window - * + * * @param {Object} * options horizontal and vertical space ( default 50 ) */ @@ -2551,10 +2522,10 @@ if( typeof preMwEmbedConfig == 'undefined') { 'bottom':'0px' } ); }; - + } )( $j ); }; - + } )( window.mw ); @@ -2566,7 +2537,7 @@ if( typeof preMwEmbedConfig == 'undefined') { */ var mwDomIsReady = false; function runMwDomReady(){ - mwDomIsReady = true; + mwDomIsReady = true; if( mw.domReady ){ mw.domReady(); } @@ -2597,7 +2568,7 @@ if ( document.addEventListener ) { if ( document.addEventListener ) { // Use the handy event callback document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); - + // A fallback to window.onload, that will always work window.addEventListener( "load", mw.domReady, false ); @@ -2606,7 +2577,7 @@ if ( document.addEventListener ) { // ensure firing before onload, // maybe late but safe also for iframes document.attachEvent("onreadystatechange", DOMContentLoaded); - + // A fallback to window.onload, that will always work window.attachEvent( "onload", runMwDomReady ); @@ -2656,10 +2627,10 @@ if( mw.isStaticPackge() && !window.jQuery ){ /** * Hack to keep jQuery in $ when its already there, but also use noConflict to * get $j = jQuery - * + * * This way sites that use $ for jQuery continue to work after including mwEmbed * javascript. - * + * * Also if jQuery is included prior to mwEmbed we ensure $j is set */ @@ -2669,11 +2640,11 @@ if( window.jQuery ){ console.log( 'Error mwEmbed requires jQuery 1.4 or above' ); } } - var dollarFlag = false; + var dollarFlag = false; if( $ && $.fn && $.fn.jquery ) { // NOTE we could check the version of // jQuery and do a removal call if too old - dollarFlag = true; + dollarFlag = true; } window[ '$j' ] = jQuery.noConflict(); if( dollarFlag ) { diff --git a/mwEmbedFrame.php b/mwEmbedFrame.php index 39bc73fae5..32e580a939 100644 --- a/mwEmbedFrame.php +++ b/mwEmbedFrame.php @@ -1,4 +1,4 @@ -outputIFrame(); +// Do mwEmbedFrame output: +$myMwEmbedFrame->outputFrame(); /** * mwEmbed iFrame class @@ -29,11 +29,10 @@ class mwEmbedFrame { 'poster', 'kentryid', 'kwidgetid', - 'kuiconfid', - 'kplaylistid', - 'skin' + 'skin' ); var $playerIframeId = 'iframeVid'; + var $debug = false; // When used in direct source mode the source asset. // NOTE: can be an array of sources in cases of "many" sources set @@ -43,55 +42,39 @@ function __construct(){ //parse input: $this->parseRequest(); } - + function outputFrame(){ + // Presently only video frame supported: + $this->outputEmbedFrame(); + } + // Parse the embedFrame request and sanitize input - private function parseRequest(){ - // Check for / attribute type request and update "REQUEST" global - // ( uses kaltura standard entry_id/{entryId} request ) - // normalize to the REQUEST object - // @@FIXME: this should be moved over to a kaltura specific iframe implementation - if( $_SERVER['REQUEST_URI'] ){ - $kalturaUrlMap = Array( - 'entry_id' => 'kentryid', - 'uiconf_id' => 'kuiconfid', - 'wid' => 'kwidgetid', - 'playlist_id' => 'kplaylistid' - ); - $urlParts = explode( '/', $_SERVER['REQUEST_URI'] ); - foreach( $urlParts as $inx => $urlPart ){ - foreach( $kalturaUrlMap as $urlKey => $reqeustAttribute ){ - if( $urlPart == $reqeustAttribute && isset( $urlParts[$inx+1] ) ){ - $_REQUEST[ $reqeustAttribute ] = $urlParts[$inx+1]; - } - } - } - } + private function parseRequest(){ // Check for attributes foreach( $this->playerAttributes as $attributeKey){ - if( isset( $_REQUEST[ $attributeKey ] ) ){ - $this->$attributeKey = htmlspecialchars( $_REQUEST[$attributeKey] ); + if( isset( $_GET[ $attributeKey ] ) ){ + $this->$attributeKey = htmlspecialchars( $_GET[$attributeKey] ); } } // Check for debug flag - if( isset( $_REQUEST['debug'] ) ){ + if( isset( $_GET['debug'] ) ){ $this->debug = true; } - + // Process the special "src" attribute - if( isset( $_REQUEST['src'] ) ){ - if( is_array( $_REQUEST['src'] ) ){ - foreach($_REQUEST['src'] as $src ){ + if( isset( $_GET['src'] ) ){ + if( is_array( $_GET['src'] ) ){ + foreach($_GET['src'] as $src ){ $this->sources[] = htmlspecialchars( $src ); } } else { - $this->sources = array( htmlspecialchars( $_REQUEST['src'] ) ); + $this->sources = array( htmlspecialchars( $_GET['src'] ) ); } } - + } private function getVideoTag( ){ - // Add default video tag with 100% width / height + // Add default video tag with 100% width / height // ( parent embed is responsible for setting the iframe size ) $o = ''; + $o.= ''; return $o; - } - - function outputIFrame( ){ + } + private function outputEmbedFrame( ){ // Setup the embed string based on attribute set: $embedResourceList = 'window.jQuery,mwEmbed,mw.style.mwCommon,$j.fn.menu,mw.style.jquerymenu,mw.EmbedPlayer,mw.EmbedPlayerNative,mw.EmbedPlayerJava,mw.PlayerControlBuilder,$j.fn.hoverIntent,mw.style.EmbedPlayer,$j.cookie,$j.ui,mw.style.ui_redmond,$j.widget,$j.ui.mouse,mw.PlayerSkinKskin,mw.style.PlayerSkinKskin,mw.TimedText,mw.style.TimedText,$j.ui.slider'; - - if( $this->kentryid ){ - $embedResourceList.= ',' . implode(',', array( + + if( isset( $this->kentryid ) ){ + $embedResourceList.= ',' . implode(',', array( 'KalturaClientBase', 'KalturaClient', 'KalturaAccessControlService', @@ -124,69 +106,61 @@ function outputIFrame( ){ 'KalturaAccessControl', 'MD5', 'mw.KWidgetSupport', - 'mw.KAnalytics', + 'mw.KAnalytics', 'mw.KDPMapping', - 'mw.MobileAdTimeline', + 'mw.MobileAdTimeline', 'mw.KAds' ) ); } -?> +?> + mwEmbed iframe - - + - - - - apiTitleKey ) || isset( $this->kentryid ) || count( $this->sources ) != 0 ) { + + + apiTitleKey ) || isset( $this->kentryid ) || count( $this->sources ) != 0 ) { echo $this->getVideoTag(); - } else { - echo "Error: mwEmbedFrame missing required parameter for video sources"; - exit(1); - } - ?> - + } else { + echo "Error: mwEmbedFrame missing required parameter for video sources"; + } + ?> + ' ); - - $j( '#btn-add-media-wiz' ).attr( 'title', gM( 'mwe-loading-add-media-wiz' ) ); - mw.load( 'AddMedia.addMediaWizard', function() { + mw.getConfig( 'imagesPath' ) + 'Button_add_media.png">' ); + + $j( '#btn-add-media-wiz' ).attr( 'title', gM( 'mwe-loading-add-media-wiz' ) ); + mw.load( 'AddMedia.addMediaWizard', function() { $j( '#btn-add-media-wiz' ).addMediaWizard( amwConf ); }); - + } else { - // Make sure the wikieditor got binded: + // Make sure the wikieditor got binded: if ( !didWikiEditorBind ) { mw.log( 'Failed to bind via build section bind via target:' ); var $targetFileButton = $j( ".toolbar [rel='file']" ); - + $targetFileButton .attr( 'title', gM( 'mwe-loading-add-media-wiz' ) ) - .unbind() - + .unbind() + mw.load( 'AddMedia.addMediaWizard', function() { if( $targetFileButton.length != 0 ) { $targetFileButton.unbind().addMediaWizard( amwConf ); diff --git a/remotes/mediaWiki.js b/remotes/mediaWiki.js index 360fe3a65e..0238d9ade6 100644 --- a/remotes/mediaWiki.js +++ b/remotes/mediaWiki.js @@ -16,7 +16,7 @@ if( window.console ){ if( typeof window.mw == 'undefined'){ window.mw = {}; } -// Setup up request Params: +// Setup up request Params: var reqParts = urlparts[1].substring( 1 ).split( '&' ); var mwReqParam = { }; for ( var i = 0; i < reqParts.length; i++ ) { @@ -26,11 +26,11 @@ for ( var i = 0; i < reqParts.length; i++ ) { } } -// Allow the document.URL to trigger the debug flag with "debug=true" in its url +// Allow the document.URL to trigger the debug flag with "debug=true" in its url if( document.URL.indexOf( 'debug=true' ) !== -1 ){ mwReqParam['debug'] = true; } -// Check if debug mode and disable script grouping +// Check if debug mode and disable script grouping if( mwReqParam['debug'] ) { mwUseScriptLoader = false; } @@ -58,7 +58,7 @@ if( ! preMwEmbedConfig ) { if( !mw.setConfig ){ mw.setConfig = function( set, value ){ var valueQueue = {}; - if( typeof value != 'undefined' ) { + if( typeof value != 'undefined' ) { preMwEmbedConfig[ set ] = value; } else if ( typeof set == 'object' ){ for( var i in set ){ @@ -70,9 +70,9 @@ if( !mw.setConfig ){ /******************************* -* Wikimedia specific config +* Wikimedia specific config ********************************/ -// The player should attribute kaltura +// The player should attribute kaltura mw.setConfig( 'EmbedPlayer.KalturaAttribution', true ); //The sequencer clips should include attribution 'edit sequence' link on pause @@ -88,18 +88,18 @@ mw.setConfig( 'SmilPlayer.AssetDomainWhiteList', ['upload.wikimedia.org'] ); // NOTE this is REQUIRED for apiProxy to work across projects where the user has not universally enabled the gadget mw.setConfig( 'Mw.AppendWithJS', 'withJS=MediaWiki:MwEmbed.js'); -// Allow all wikimedia regEx domains matches to support api-proxy requests -// NOTE remember to put $ at the end of the domain or it would match en.wikipedia.org.evil.com -mw.setConfig( 'ApiProxy.DomainWhiteList', +// Allow all wikimedia regEx domains matches to support api-proxy requests +// NOTE remember to put $ at the end of the domain or it would match en.wikipedia.org.evil.com +mw.setConfig( 'ApiProxy.DomainWhiteList', [ /wikimedia\.org$/ , /wikipedia\.org$/ , /wiktionary.org$/ , /wikinews.org$/ , /wikibooks.org$/ , /wikisource.org$/ , /wikiversity.org$/ , /wikiquote.org$/ ] ); -// Use wikibits onLoad hook: ( since we don't have js2 / mw object loaded ) +// Use wikibits onLoad hook: ( since we don't have js2 / mw object loaded ) if( window.jQuery ){ jQuery( document ).ready( doPageSpecificRewrite ); } else { - addOnloadHook( function() { + addOnloadHook( function() { doPageSpecificRewrite(); } ); } @@ -107,44 +107,44 @@ if( window.jQuery ){ /** * Page specific rewrites for mediaWiki -*/ +*/ function doPageSpecificRewrite() { // Deal with multiple doPageSpecificRewrite if( typeof window.ranMwRewrites != 'undefined'){ return ; } window.ranMwRewrites = 'done'; - + // Add media wizard ( only if not on a sequence page if ( wgAction == 'edit' || wgAction == 'submit' ) { if( wgPageName.indexOf( "Sequence:" ) != 0 ){ - // Add a timeout to give a chance for wikieditor to build out. + // Add a timeout to give a chance for wikieditor to build out. setTimeout(function(){ - loadMwEmbed( [ + loadMwEmbed( [ 'mw.RemoteSearchDriver', 'mw.ClipEdit', 'mw.style.ClipEdit', - '$j.fn.textSelection', - '$j.ui', - '$j.widget', + '$j.fn.textSelection', + '$j.ui', + '$j.widget', '$j.ui.mouse', '$j.ui.button', '$j.ui.position', - '$j.ui.progressbar', - '$j.ui.dialog', + '$j.ui.progressbar', + '$j.ui.dialog', '$j.ui.draggable', '$j.ui.sortable', '$j.ui.datepicker' - ], function() { + ], function() { mw.load( mwEmbedHostPath + '/remotes/AddMediaWizardEditPage.js?' + mwGetReqArgs() ); - } ); - },200); + } ); + }, 200); } } - + // Timed text display: - if ( wgPageName.indexOf( "TimedText:" ) === 0 - && + if ( wgPageName.indexOf( "TimedText:" ) === 0 + && ( document.URL.indexOf('&diff=') == -1 && document.URL.indexOf('?diff=') == -1 @@ -152,8 +152,8 @@ function doPageSpecificRewrite() { ){ if( wgAction == 'view' ){ var orgBody = mwSetPageToLoading(); - //load the "player" ( includes call to loadMwEmbed ) - + //load the "player" ( includes call to loadMwEmbed ) + // Add a timeout to give a chance for ui core to build out ( bug with replace jquery ui ) setTimeout(function(){ mwLoadPlayer(function(){ @@ -165,7 +165,7 @@ function doPageSpecificRewrite() { 'title' : wgTitle, 'target': '#bodyContent', 'orgBody': orgBody - }); + }); // Update the UI myRemote.updateUI(); } ); @@ -173,15 +173,15 @@ function doPageSpecificRewrite() { }, 100 ); return ; } - } - + } + // Remote Sequencer - if( wgPageName.indexOf( "Sequence:" ) === 0 ){ + if( wgPageName.indexOf( "Sequence:" ) === 0 ){ //console.log( 'spl: ' + typeof mwSetPageToLoading ); - // If on a view page set content to "loading" - if( ( wgAction == 'view' || wgAction == 'edit' ) - && - ( + // If on a view page set content to "loading" + if( ( wgAction == 'view' || wgAction == 'edit' ) + && + ( document.URL.indexOf('&diff=') == -1 && document.URL.indexOf('?diff=') == -1 @@ -194,16 +194,16 @@ function doPageSpecificRewrite() { if( wgAction == 'edit' ){ mwAddCommonStyleSheet(); var body = document.getElementById( 'bodyContent' ); - body.innerHTML = "
" + body.innerHTML; + body.innerHTML = "
" + body.innerHTML; } - if( window.mwSequencerRemote ){ + if( window.mwSequencerRemote ){ window.mwSequencerRemote.drawUI(); } else { mwLoadPlayer(function(){ - // wait for wikieditor to do its thing + // wait for wikieditor to do its thing $j('#editform,.mw-newarticletext,#toolbar').hide(); $j('.sequenceLoader').hide(); - + window.mwSequencerRemote = new mw.MediaWikiRemoteSequencer({ 'action': wgAction, 'titleKey' : wgPageName, @@ -213,53 +213,53 @@ function doPageSpecificRewrite() { window.mwSequencerRemote.drawUI(); }); } - + } return ; } - - + + // Upload page -> Firefogg / upload API / uploadWizard integration if ( wgPageName == "Special:Upload" ) { var scriptUrl = null; var scriptName = null; - var libraries = []; + var libraries = []; scriptName = 'uploadPage.js'; - libraries = [ + libraries = [ 'mw.UploadInterface', - 'mw.Firefogg', + 'mw.Firefogg', '$j.ui', '$j.widget', '$j.ui.mouse', '$j.ui.position', - '$j.ui.progressbar', - '$j.ui.dialog', + '$j.ui.progressbar', + '$j.ui.dialog', '$j.ui.draggable' ]; var scriptUrl = mwEmbedHostPath + '/remotes/' + scriptName + '?' + mwGetReqArgs(); - loadMwEmbed(libraries, function() { + loadMwEmbed(libraries, function() { mw.load( scriptUrl ); } ); return ; } - + // Special api proxy page if ( wgPageName == 'MediaWiki:ApiProxy' ) { - var wgEnableIframeApiProxy = true; + var wgEnableIframeApiProxy = true; loadMwEmbed( [ 'mw.ApiProxy' ], function(){ mw.load( mwEmbedHostPath + '/modules/ApiProxy/ApiProxyPage.js?' + mwGetReqArgs() ); }); return ; } - + // Special api proxy page for nested callback of hash url - // Can be replaced with: + // Can be replaced with: if ( wgPageName == 'MediaWiki:ApiProxyNestedCb' ) { // Note top.mw.ApiProxy.nested frame needs to be on the same domain - top.mw.ApiProxy.nested( window.location.href.split("#")[1] || false ); + top.mw.ApiProxy.nested( window.location.href.split("#")[1] || false ); return ; } - + // OggHandler rewrite for view pages: var vidIdList = []; var divs = document.getElementsByTagName( 'div' ); @@ -267,22 +267,22 @@ function doPageSpecificRewrite() { if ( divs[i].id && divs[i].id.substring( 0, 11 ) == 'ogg_player_' ) { vidIdList.push( divs[i].getAttribute( "id" ) ); } - } - + } + if ( vidIdList.length > 0 ) { // Reverse order the array so videos at the "top" get swapped first: vidIdList = vidIdList.reverse(); // Add a timeout to give a chance for ui core to build out ( bug with replace jquery ui ) - setTimeout(function(){ - mwLoadPlayer( function(){ - - // Check for flat file page: + setTimeout(function(){ + mwLoadPlayer( function(){ + + // Check for flat file page: var flatFilePretext = "File:Sequence-"; - if( wgPageName.indexOf(flatFilePretext ) === 0 - && - wgPageName.indexOf('.ogv') !== -1 ) + if( wgPageName.indexOf(flatFilePretext ) === 0 + && + wgPageName.indexOf('.ogv') !== -1 ) { - var sequenceTitle = 'Sequence:' + wgPageName.substring( flatFilePretext.length, wgPageName.length - 4 ); + var sequenceTitle = 'Sequence:' + wgPageName.substring( flatFilePretext.length, wgPageName.length - 4 ); window.mwSequencerRemote = new mw.MediaWikiRemoteSequencer({ 'action': wgAction, 'titleKey' : sequenceTitle, @@ -290,34 +290,34 @@ function doPageSpecificRewrite() { }); window.mwSequencerRemote.showViewFlattenedFile(); } - + // Do utility rewrite of OggHandler content: rewrite_for_OggHandler( vidIdList ); - } ); + } ); }, 100); return ; } - + // IF we did not match any rewrite ( but we do have a ready function ) load mwEmbed if( preMwEmbedReady.length ){ loadMwEmbed( function(){ // mwEmbed loaded }); - } + } } /* -* Sets the mediaWiki content to "loading" +* Sets the mediaWiki content to "loading" */ function mwSetPageToLoading(){ mwAddCommonStyleSheet(); var body = document.getElementById( 'bodyContent' ); var oldBodyHTML = body.innerHTML; - body.innerHTML = '
'; + body.innerHTML = '
'; return oldBodyHTML; } function mwAddCommonStyleSheet(){ importStylesheetURI( mwEmbedHostPath + '/skins/common/mw.style.mwCommon.css?' + mwGetReqArgs() ); - // Set the style to defined ( so that when mw won't load the style sheet again) + // Set the style to defined ( so that when mw won't load the style sheet again) if( !mw.style ){ mw.style = { 'mwCommon' : true }; } else { @@ -330,55 +330,55 @@ function mwAddCommonStyleSheet(){ */ function mwLoadPlayer( callback ){ - // The jsPlayerRequest includes both javascript and style sheets for the embedPlayer + // The jsPlayerRequest includes both javascript and style sheets for the embedPlayer var jsPlayerRequest = [ '$j.ui', '$j.widget', '$j.ui.mouse', - + '$j.ui.button', - '$j.ui.draggable', - '$j.ui.position', + '$j.ui.draggable', + '$j.ui.position', '$j.ui.resizable', - '$j.ui.slider', - + '$j.ui.slider', + '$j.ui.dialog', - - '$j.cookie', - 'mw.EmbedPlayer', + + '$j.cookie', + 'mw.EmbedPlayer', 'mw.style.EmbedPlayer', - - 'mw.PlayerControlBuilder', - '$j.fn.hoverIntent', - 'JSON', - + + 'mw.PlayerControlBuilder', + '$j.fn.hoverIntent', + 'JSON', + 'mw.PlayerSkinKskin', 'mw.style.PlayerSkinKskin', - + '$j.fn.menu', 'mw.style.jquerymenu', - + // Timed Text module 'mw.TimedText', 'mw.style.TimedText', - + // mwSwarmTransport module 'mw.SwarmTransport', - - // Sequencer remote: + + // Sequencer remote: 'mw.MediaWikiRemoteSequencer', 'mw.style.SequencerRemote' - ]; - // Quick sniff use java if IE and native if firefox + ]; + // Quick sniff use java if IE and native if firefox // ( other browsers will run detect and get on-demand ) if (navigator.userAgent.indexOf("MSIE") != -1){ jsPlayerRequest.push( 'mw.EmbedPlayerJava' ); } - - if ( navigator.userAgent && navigator.userAgent.indexOf("Firefox") != -1 ){ + + if ( navigator.userAgent && navigator.userAgent.indexOf("Firefox") != -1 ){ jsPlayerRequest.push( 'mw.EmbedPlayerNative' ); } - + loadMwEmbed( jsPlayerRequest, function() { // hide the novideojs if present $j( '.videonojs' ).hide(); @@ -391,38 +391,38 @@ function mwLoadPlayer( callback ){ * @param {Object} vidIdList List of video ids to process */ function rewrite_for_OggHandler( vidIdList ) { - function procVidId( vidId ) { + function procVidId( vidId ) { // Don't process empty vids if ( !vidId ){ return ; - } - + } + tag_type = 'video'; - - // Check type: + + // Check type: var $pimg = $j( '#' + vidId + ' img:first' ); var pwidth = $pimg.width(); - var imgSring = $pimg.attr('src').split('/').pop(); - if( $pimg.attr('src') && imgSring == 'play.png' || imgSring == 'fileicon-ogg.png' ){ + var imgSring = $pimg.attr('src').split('/').pop(); + if( $pimg.attr('src') && imgSring == 'play.png' || imgSring == 'fileicon-ogg.png' ){ tag_type = 'audio'; - poster_attr = ''; + poster_attr = ''; pheight = 0; }else{ var poster_attr = ' poster = "' + $pimg.attr( 'src' ) + '" '; var pheight = $pimg.attr( 'height' ); } - + // Parsed values: var src = ''; var duration_attr = ''; var rewriteHTML = $j( '#' + vidId ).html(); - + if( rewriteHTML == ''){ mw.log( "Error: empty rewrite html" ); return ; }else{ //mw.log(" rewrite: " + rewriteHTML + "\n of type: " + typeof rewriteHTML); - } + } var re = new RegExp( /videoUrl(":?\s*)*([^&]*)/ ); src = re.exec( rewriteHTML )[2]; @@ -436,62 +436,60 @@ function rewrite_for_OggHandler( vidIdList ) { var re = new RegExp( /offset(":?\s*)*([^,&]*)/ ); offset = re.exec( rewriteHTML ); var offset_attr = ( offset && offset[2] )? 'startOffset="' + offset[2] + '" ' : ''; - - // Check if file is from commons and therefore should explicitly set apiProvider to commons: - var apiProviderAttr = ( src.indexOf( 'wikipedia\/commons' ) != -1 )?'apiProvider="commons" ': ''; - + + // Check if file is from commons and therefore should explicitly set apiProvider to commons: + var apiProviderAttr = ( src.indexOf( 'wikipedia\/commons' ) != -1 )?'apiProvider="commons" ': ''; + // If in a gallery box or filehistory we will be displaying the video larger in a lightbox if( $j( '#' + vidId ).parents( '.gallerybox,.filehistory' ).length ){ pwidth = 400; - // Update the width to 400 and keep scale + // Update the width to 400 and keep scale if( pheight != 0 ) { - pheight = pwidth * ( $j( '#' + vidId + ' img' ).height() / $j( '#' + vidId + ' img' ).width() ); - } + pheight = pwidth * ( $j( '#' + vidId + ' img' ).height() / $j( '#' + vidId + ' img' ).width() ); + } } - + if ( src ) { var html_out = ''; - + var common_attr = ' id="mwe_' + vidId + '" ' + 'apiTitleKey="' + apiTitleKey + '" ' + - 'src="' + src + '" ' + - apiProviderAttr + + 'src="' + src + '" ' + + apiProviderAttr + duration_attr + offset_attr + ' ' + 'class="kskin" '; - + if ( tag_type == 'audio' ) { if( pwidth < 250 ){ pwidth = 250; } - html_out = ''; + html_out = ''; } else { - html_out = '' + + html_out = ''; } - + // If the video is part of a "gallery box" use light-box linker instead - if( $j( '#' + vidId ).parents( '.gallerybox,.filehistory' ).length ){ + if( $j( '#' + vidId ).parents( '.gallerybox,.filehistory' ).length ){ $j( '#' + vidId ).after( $j( '
') - .css( { - 'width' : $pimg.attr('width' ), + .css( { + 'width' : $pimg.attr('width' ), 'height' :$pimg.attr( 'height' ), 'position' : 'relative' }) .addClass( 'k-player' ) .append( - // The poster image + // The poster image $j( '' ) .css( { 'width' : '100%', 'height' : '100%' }) .attr( 'src', $pimg.attr('src') ), - + // A play button: $j( '
' ) .css({ @@ -499,63 +497,63 @@ function rewrite_for_OggHandler( vidIdList ) { 'top' : ( parseInt( $pimg.attr( 'height' ) ) /2 ) -25, 'maring-left' : 'auto', 'maring-right' : 'auto' - }) - + }) + .addClass( 'play-btn-large' ) .buttonHover() - .click( function(){ - var _this = this; + .click( function(){ + var _this = this; var dialogHeight = ( pheight == 0 )? 175 : ( pheight + 130 ); var buttons = {}; - buttons[ gM( 'mwe-ok' ) ] = function(){ + buttons[ gM( 'mwe-ok' ) ] = function(){ // close the dialog $j(this).dialog( 'close' ).remove(); }; - var $dialog = mw.addDialog( { + var $dialog = mw.addDialog( { 'title' : decodeURIComponent( apiTitleKey.replace(/_/g, ' ') ), 'content' : html_out, 'buttons' : buttons, 'height' : dialogHeight, 'width' : 430, - 'close': function(event, ui) { + 'close': function(event, ui) { var embedPlayer = $j( '#mwe_' + vidId ).get(0); // stop the player before we close the dialog if( embedPlayer ) { embedPlayer.stop(); } - } - }); - - // Update the embed code to use the mwEmbed player: - $j( '#mwe_' + vidId ).embedPlayer( { 'autoplay' : true }, function(){ - var embedPlayer = $j( '#mwe_' + vidId ).get(0); + } + }); + + // Update the embed code to use the mwEmbed player: + $j( '#mwe_' + vidId ).embedPlayer( { 'autoplay' : true }, function(){ + var embedPlayer = $j( '#mwe_' + vidId ).get(0); // Show the control bar for two seconds (auto play is confusing without it ) embedPlayer.controlBuilder.showControlBar(); // hide the controls if they should they are overlayed on the video if( embedPlayer.controlBuilder.checkOverlayControls() ){ - setTimeout( function(){ + setTimeout( function(){ embedPlayer.controlBuilder.hideControlBar(); - }, 4000 ); + }, 4000 ); } - }); - }) - ) + }); + }) + ) ).remove(); - + } else { // Set the video tag inner html remove extra player - $j( '#' + vidId ).after( html_out ).remove(); + $j( '#' + vidId ).after( html_out ).remove(); $j( '#mwe_' + vidId ).embedPlayer(); - } + } // Issue an async request to rewrite the next clip if ( vidIdList.length != 0 ) { - setTimeout( function() { + setTimeout( function() { procVidId( vidIdList.pop() ); }, 1 ); } - } + } }; // Process current top item in vidIdList procVidId( vidIdList.pop() ); @@ -573,7 +571,7 @@ function getRemoteEmbedPath() { var scriptPath = ''; if ( s.src.indexOf( '?' ) != - 1 ) { reqStr = s.src.substr( s.src.indexOf( '?' ) ); - scriptPath = s.src.substr( 0, s.src.indexOf( '?' ) ).replace( '/mediaWiki.js', '' ); + scriptPath = s.src.substr( 0, s.src.indexOf( '?' ) ).replace( '/mediaWiki.js', '' ); } else { scriptPath = s.src.replace( '/mediaWiki.js', '' ); } @@ -585,21 +583,21 @@ function getRemoteEmbedPath() { /** * Get the request arguments -*/ +*/ function mwGetReqArgs() { var rurl = ''; if ( mwReqParam['debug'] ){ rurl += 'debug=true&'; } - if ( mwReqParam['uselang'] ){ + if ( mwReqParam['uselang'] ){ rurl += 'uselang=' + mwReqParam['uselang'] + '&'; } if ( mwReqParam['urid'] ) { rurl += 'urid=' + mwReqParam['urid']; } else { - // Make sure to use an urid + // Make sure to use an urid // This way remoteMwEmbed can control version of code being requested rurl += 'urid=' + mwRemoteVersion; } @@ -610,64 +608,64 @@ function mwGetReqArgs() { * Load the mwEmbed library: * * @param {mixed} function or classSet to preload -* classSet saves round trips to the server by grabbing things we will likely need in the first request. +* classSet saves round trips to the server by grabbing things we will likely need in the first request. * @param {callback} function callback to be called once mwEmbed is ready */ -function loadMwEmbed( classSet, callback ) { +function loadMwEmbed( classSet, callback ) { if( typeof classSet == 'function') { callback = classSet; - } + } if ( typeof MW_EMBED_VERSION != 'undefined' ) { mw.load( classSet, callback); return ; } - // Inject mwEmbed + // Inject mwEmbed if ( mwUseScriptLoader ) { var rurl = mwEmbedHostPath + '/ResourceLoader.php?class='; - + var coma = ''; - - - // Add jQuery too if we need it: - if ( typeof window.jQuery == 'undefined' + + + // Add jQuery too if we need it: + if ( typeof window.jQuery == 'undefined' || // force load jquery if version 1.3.2 ( issues with '1.3.2' .data handling ) - jQuery.fn.jquery == '1.3.2') - { + jQuery.fn.jquery == '1.3.2') + { rurl += 'window.jQuery'; coma = ','; - } + } // Add Core mwEmbed lib ( if not already defined ) - if( typeof MW_EMBED_VERSION == 'undefined' ){ + if( typeof MW_EMBED_VERSION == 'undefined' ){ rurl += coma + 'mwEmbed,mw.style.mwCommon'; coma = ','; } - + // Add requested classSet to scriptLoader request for( var i=0; i < classSet.length; i++ ){ - var cName = classSet[i]; - // always include our version of the library ( too many crazy conflicts with old library versions ) - rurl += ',' + cName; + var cName = classSet[i]; + // always include our version of the library ( too many crazy conflicts with old library versions ) + rurl += ',' + cName; /* if( !mwCheckObjectPath( cName ) ){ - - } else { + + } else { // Check for old version of jquery ui components if( $j.ui.version == '1.7.1' ){ if(cName.indexOf('$j.ui') != -1 ){ - rurl += ',' + cName; + rurl += ',' + cName; } } }*/ } - + // Add the remaining arguments rurl += '&' + mwGetReqArgs(); importScriptURI( rurl ); waitMwEmbedReady( callback ); - } else { - - // Force load jQuery for debug mode + } else { + + // Force load jQuery for debug mode var jQueryRequested = false; waitForJQueryUpgrade = function(){ if( jQuery && jQuery.fn.jquery== '1.3.2' ){ @@ -676,7 +674,7 @@ function loadMwEmbed( classSet, callback ) { importScriptURI( mwEmbedHostPath + '/libraries/jquery/jquery-1.4.2.js?' + mwGetReqArgs() ); } setTimeout( waitForJQueryUpgrade, 5); - } else { + } else { // load mwEmbed js importScriptURI( mwEmbedHostPath + '/mwEmbed.js?' + mwGetReqArgs() ); waitMwEmbedReady( function(){ @@ -688,7 +686,7 @@ function loadMwEmbed( classSet, callback ) { } }; waitForJQueryUpgrade(); - } + } } /** @@ -700,49 +698,49 @@ function waitMwEmbedReady( callback ) { setTimeout( function() { waitMwEmbedReady( callback ); }, 10 ); - } else { - // Make sure mwEmbed is "setup" by using the addOnLoadHook: - mw.ready( function(){ + } else { + // Make sure mwEmbed is "setup" by using the addOnLoadHook: + mw.ready( function(){ callback(); - - // All enabled pages should check if we have the gadget already installed + + // All enabled pages should check if we have the gadget already installed // if not offer a convenient button mwCheckForGadget(); }); } } /** - * Check if the gadget is installed - * run after mwEmbed setup so $j and mw interface is available: + * Check if the gadget is installed + * run after mwEmbed setup so $j and mw interface is available: */ function mwCheckForGadget(){ - //mw.log('mwCheckForGadget'); + //mw.log('mwCheckForGadget'); if( $j('#mwe-gadget-button').length != 0){ //Gadget button already in dom return false; } - - + + var scripts = document.getElementsByTagName( 'script' ); - + // Check for document paramater withJS and ignore found gadget if( typeof getParamValue == 'undefined' && typeof getURLParamValue == 'undefined'){ return false; } - + for( var i = 0 ; i < scripts.length ; i++ ){ if ( - scripts[i].src - && scripts[i].src.indexOf( 'MediaWiki:Gadget-mwEmbed.js' ) !== -1 + scripts[i].src + && scripts[i].src.indexOf( 'MediaWiki:Gadget-mwEmbed.js' ) !== -1 ){ //mw.log( 'gadget already installed: ' + scripts[i].src ); // Gadget found / enabled return false; - } + } } - - // No gadget found add enable button: - mw.log('gadget not installed, show install menu'); + + // No gadget found add enable button: + mw.log('gadget not installed, show install menu'); var $gadgetBtn = $j.button({ 'text' : gM( 'mwe-enable-gadget' ), 'icon': 'check' @@ -753,43 +751,43 @@ function mwCheckForGadget(){ .click(function (){ if( !wgUserName ){ $j( this ) - .after( gM('mwe-must-login-gadget', + .after( gM('mwe-must-login-gadget', wgArticlePath.replace( '$1', 'Special:UserLogin?returnto=' + wgPageName ) ) ) .remove(); return false; } - + // Else Add loader $j( this ) - .after( + .after( $j('
') .attr( 'id', 'gadget-form-loader' ) - .loadingSpinner() + .loadingSpinner() ) .remove(); // Load gadgets form: mwSubmitGadgetPref( 'mwEmbed' ); - + // return false to not follow link return false; } ); - - // Add the $gadgetBtn before the first heading: + + // Add the $gadgetBtn before the first heading: $j('#firstHeading').before( $j('
') .attr('id','mwe-gadget-button') .css({ 'margin': '10px' - }).html( + }).html( $gadgetBtn ) ); } function mwSubmitGadgetPref( gadget_id ){ $j.get( wgArticlePath.replace('$1', 'Special:Preferences'), function( pageHTML ){ - // get the form + // get the form var form = mwGetFormFromPage ( pageHTML ); if(!form){ return false; @@ -798,13 +796,13 @@ function mwSubmitGadgetPref( gadget_id ){ mw.log( gadget_id + ' is already enabled' ); return false; } - - // add mwEmbed to the formData + + // add mwEmbed to the formData form.data.push( { 'name' : 'wpgadgets[]', 'value' : gadget_id } ); - + // Submit the preferences $j.post( form.url, form.data, function( pageHTML ){ var form = mwGetFormFromPage ( pageHTML ); @@ -824,7 +822,7 @@ function mwGetFormFromPage( pageHTML ){ $j( pageHTML ).find('form').each( function( ){ form.url = $j( this ).attr('action'); if( form.url.indexOf( 'Special:Preferences') !== -1 ){ - form.data = $j( this ).serializeArray(); + form.data = $j( this ).serializeArray(); // break out of loop return false; } @@ -840,8 +838,8 @@ function mwCheckFormDatagadget( formData, gadget_id ){ if( formData[i].value == gadget_id ){ return true; } - } - } + } + } return false; } diff --git a/remotes/uploadPage.js b/remotes/uploadPage.js index 9381303257..6ea86e4422 100644 --- a/remotes/uploadPage.js +++ b/remotes/uploadPage.js @@ -12,48 +12,48 @@ var mwUploadHelper = { // If wgEnableFirefogg is not boolean false, set to true if ( typeof wgEnableFirefogg == 'undefined' ){ wgEnableFirefogg = true; - } - // NOTE: we should unify upload handler call so we don't have to call firefogg and - // UploadHandler separately. + } + // NOTE: we should unify upload handler call so we don't have to call firefogg and + // UploadHandler separately. if ( wgEnableFirefogg ) { mw.load( 'AddMedia.firefogg', function(){ // Set up the upload handler to Firefogg. Should work with the HTTP uploads too. $j( '#wpUploadFile' ).firefogg( { - + // An API URL (default is getLocalApiUrl but set here for clarity ) 'apiUrl': mw.getLocalApiUrl(), - - // MediaWiki API supports chunk uploads: - 'enableChunks' : false, - + + // MediaWiki API supports chunk uploads: + 'enableChunks' : false, + // Set the interface type 'interface_type' : 'dialog', - + 'form_selector': mwUploadFormSelector, - + // Set the select file callback: 'selectFileCb': function( fileName ) { // Check if we are on upload to new version page and don't update target // ( bug 23069 ) - if( mw.parseUri( document.URL ).queryKey['wpDestFile'] ){ + if( mw.parseUri( document.URL ).queryKey['wpDestFile'] ){ return false; } $j( '#wpDestFile' ).val( fileName ); } } ); } ) - } else { + } else { // Add basic upload profile support ( http status monitoring, progress box for // browsers that support it, etc.) - mw.load( 'AddMedia.UploadHandler', function(){ - $j( mwUploadFormSelector ).uploadHandler( { + mw.load( 'AddMedia.UploadHandler', function(){ + $j( mwUploadFormSelector ).uploadHandler( { 'selectFileCb': function( fileName ) { $j( '#wpDestFile' ).val( fileName ); $j( '#wpDestFile' ).doDestCheck( { 'warn_target': '#wpDestFile-warning' } ); } - }); + }); }); } @@ -75,12 +75,12 @@ var mwUploadHelper = { _this.toggleUpType( this.id == 'wpSourceTypeFile' ); } ); } - + $j( '#wpUploadFile,#wpUploadFileURL' ) .focus( function() { _this.toggleUpType( this.id == 'wpUploadFile' ); } ) - + // Also setup the onChange event binding: .change( function() { if ( wgUploadAutoFill ) { @@ -88,7 +88,7 @@ var mwUploadHelper = { } } ); }, - + /** * Set the upload radio buttons * @@ -100,9 +100,9 @@ var mwUploadHelper = { $j( '#wpSourceTypeURL' ).attr( 'checked', !set ); $j( '#wpUploadFileURL' ).attr( 'disabled', set ); - + }, - + /** * Fill in a destination file-name based on a source asset name. * @param {Element} targetElm Target element to get destination name from @@ -124,7 +124,7 @@ var mwUploadHelper = { } else { fname = path.substring( backslash + 1, 10000 ); } - + // URLs are less likely to have a useful extension. Don't include them in the extension check. if ( wgFileExtensions && $j( targetElm ).attr( 'id' ) != 'wpUploadFileURL' ) { var found = false; diff --git a/skins/common/mw.style.mwCommon.css b/skins/common/mw.style.mwCommon.css index 15ba42cb0b..8ebab6accb 100644 --- a/skins/common/mw.style.mwCommon.css +++ b/skins/common/mw.style.mwCommon.css @@ -23,37 +23,37 @@ margin: auto ; } .cssLoadingSpinner { - position:relative; - width:100px; - height:100px; - //margin:25px; - -moz-border-radius:100px; - float:left; - -moz-transform:scale(0.3); - -webkit-transform:scale(0.3); - - /* not used right now: */ - -webkit-animation-name: rotateThis; - -webkit-animation-duration:2s; - -webkit-animation-iteration-count:infinite; - -webkit-animation-timing-function:linear; + position:relative; + width:100px; + height:100px; + //margin:25px; + -moz-border-radius:100px; + float:left; + -moz-transform:scale(0.3); + -webkit-transform:scale(0.3); + + /* not used right now: */ + -webkit-animation-name: rotateThis; + -webkit-animation-duration:2s; + -webkit-animation-iteration-count:infinite; + -webkit-animation-timing-function:linear; } .cssLoadingSpinner div { - width:15px; - height:30px; - position:absolute; - top:35px; - left:45px; + width:15px; + height:30px; + position:absolute; + top:35px; + left:45px; } .cssLoadingSpinner div { - -moz-border-radius:30px; - -webkit-border-radius:30px; - border-radius:30px; + -moz-border-radius:30px; + -webkit-border-radius:30px; + border-radius:30px; } /* uncomment this to use css animation in webkit browsers */ @-webkit-keyframes rotateThis { - from {-webkit-transform:scale(0.7) rotate(0deg);} - to {-webkit-transform:scale(0.7) rotate(360deg);} + from {-webkit-transform:scale(0.7) rotate(0deg);} + to {-webkit-transform:scale(0.7) rotate(360deg);} } /* jquery.ui overides */