r64434 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r64433‎ | r64434 | r64435 >
Date:12:09, 31 March 2010
Author:dale
Status:deferred
Tags:
Comment:
* Added css basic support to script-loader
* added basic css-minification support
* Moved player Skins into player module folder
* updated loaders to deal with css similar to how js is handled.
Modified paths:
  • /branches/js2-work/phase3/js/mwEmbed/includes/jsClassLoader.php (modified) (history)
  • /branches/js2-work/phase3/js/mwEmbed/includes/library/CSS (added) (history)
  • /branches/js2-work/phase3/js/mwEmbed/includes/library/CSS.php (added) (history)
  • /branches/js2-work/phase3/js/mwEmbed/includes/library/CSS/Compressor.php (added) (history)
  • /branches/js2-work/phase3/js/mwEmbed/includes/library/CSS/UriRewriter.php (added) (history)
  • /branches/js2-work/phase3/js/mwEmbed/includes/library/CommentPreserver.php (added) (history)
  • /branches/js2-work/phase3/js/mwEmbed/includes/noMediaWikiConfig.php (modified) (history)
  • /branches/js2-work/phase3/js/mwEmbed/jquery/plugins/jquery.browserTest.js (modified) (history)
  • /branches/js2-work/phase3/js/mwEmbed/jquery/plugins/jquery.textSelection.js (modified) (history)
  • /branches/js2-work/phase3/js/mwEmbed/jsScriptLoader.php (modified) (history)
  • /branches/js2-work/phase3/js/mwEmbed/loader.js (modified) (history)
  • /branches/js2-work/phase3/js/mwEmbed/modules/AddMedia/loader.js (modified) (history)
  • /branches/js2-work/phase3/js/mwEmbed/modules/AddMedia/mw.RemoteSearchDriver.js (modified) (history)
  • /branches/js2-work/phase3/js/mwEmbed/modules/ClipEdit/loader.js (modified) (history)
  • /branches/js2-work/phase3/js/mwEmbed/modules/ClipEdit/mw.ClipEdit.js (modified) (history)
  • /branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/javaEmbed.js (modified) (history)
  • /branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/loader.js (modified) (history)
  • /branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/mw.EmbedPlayer.js (modified) (history)
  • /branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/ctrlBuilder.js (added) (history)
  • /branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/kskin (added) (history)
  • /branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf (added) (history)
  • /branches/js2-work/phase3/js/mwEmbed/modules/TimedText/loader.js (modified) (history)
  • /branches/js2-work/phase3/js/mwEmbed/modules/UploadWizard/loader.js (modified) (history)
  • /branches/js2-work/phase3/js/mwEmbed/mwEmbed.js (modified) (history)
  • /branches/js2-work/phase3/js/mwEmbed/skins/ctrlBuilder.js (deleted) (history)
  • /branches/js2-work/phase3/js/mwEmbed/skins/kskin (deleted) (history)
  • /branches/js2-work/phase3/js/mwEmbed/skins/mvpcf (deleted) (history)

Diff [purge]

Index: branches/js2-work/phase3/js/mwEmbed/loader.js
@@ -43,9 +43,6 @@
4444 // Default enabled modules:
4545 "enabledModules" : mwEnabledModuleList,
4646
47 - // Default skin name
48 - "skinName" : "mvpcf",
49 -
5047 // Default jquery ui skin name
5148 "jQueryUISkin" : "redmond",
5249
@@ -118,18 +115,20 @@
119116 */
120117 mw.addClassFilePaths( {
121118 "mwEmbed" : "mwEmbed.js",
122 - "window.jQuery" : "jquery/jquery-1.4.2.js",
 119+ "window.jQuery" : "jquery/jquery-1.4.2.js",
123120
124 - "ctrlBuilder" : "skins/ctrlBuilder.js",
125 - "kskinConfig" : "skins/kskin/kskinConfig.js",
126 - "mvpcfConfig" : "skins/mvpcf/mvpcfConfig.js",
127 -
128121 "$j.fn.pngFix" : "jquery/plugins/jquery.pngFix.js",
129122 "$j.fn.autocomplete" : "jquery/plugins/jquery.autocomplete.js",
 123+ "mw.style.autocomplete" : "jquery/plugins/jquery.autocomplete.css",
 124+
130125 "$j.fn.hoverIntent" : "jquery/plugins/jquery.hoverIntent.js",
131126 "$j.fn.datePicker" : "jquery/plugins/jquery.datePicker.js",
132127 "$j.ui" : "jquery/jquery.ui/ui/ui.core.js",
133128
 129+ "mw.style.redmond" : "jquery/jquery.ui/themes/redmond/jquery-ui-1.7.1.custom.css",
 130+ "mw.style.smoothness" : "jquery/jquery.ui/themes/smoothness/jquery-ui-1.7.1.custom.css",
 131+ "mw.style.common" : "skins/common/common.css",
 132+
134133 "mw.testLang" : "tests/testLang.js",
135134
136135 "$j.cookie" : "jquery/plugins/jquery.cookie.js",
Index: branches/js2-work/phase3/js/mwEmbed/includes/jsClassLoader.php
@@ -156,8 +156,9 @@
157157 */
158158 private static function preg_classPathLoader( $jsvar ) {
159159 global $wgJSAutoloadClasses;
160 - if ( !isset( $jsvar[1] ) )
 160+ if ( !isset( $jsvar[1] ) ) {
161161 return false;
 162+ }
162163
163164 $jClassSet = FormatJson::decode( '{' . $jsvar[1] . '}', true );
164165 foreach ( $jClassSet as $jClass => $jPath ) {
Index: branches/js2-work/phase3/js/mwEmbed/includes/library/CSS.php
@@ -0,0 +1,80 @@
 2+<?php
 3+/**
 4+ * Class Minify_CSS
 5+ * @package Minify
 6+ */
 7+
 8+/**
 9+ * Minify CSS
 10+ *
 11+ * This class uses Minify_CSS_Compressor and Minify_CSS_UriRewriter to
 12+ * minify CSS and rewrite relative URIs.
 13+ *
 14+ * @package Minify
 15+ * @author Stephen Clay <steve@mrclay.org>
 16+ * @author http://code.google.com/u/1stvamp/ (Issue 64 patch)
 17+ */
 18+class Minify_CSS {
 19+
 20+ /**
 21+ * Minify a CSS string
 22+ *
 23+ * @param string $css
 24+ *
 25+ * @param array $options available options:
 26+ *
 27+ * 'preserveComments': (default true) multi-line comments that begin
 28+ * with "/*!" will be preserved with newlines before and after to
 29+ * enhance readability.
 30+ *
 31+ * 'prependRelativePath': (default null) if given, this string will be
 32+ * prepended to all relative URIs in import/url declarations
 33+ *
 34+ * 'currentDir': (default null) if given, this is assumed to be the
 35+ * directory of the current CSS file. Using this, minify will rewrite
 36+ * all relative URIs in import/url declarations to correctly point to
 37+ * the desired files. For this to work, the files *must* exist and be
 38+ * visible by the PHP process.
 39+ *
 40+ * 'symlinks': (default = array()) If the CSS file is stored in
 41+ * a symlink-ed directory, provide an array of link paths to
 42+ * target paths, where the link paths are within the document root. Because
 43+ * paths need to be normalized for this to work, use "//" to substitute
 44+ * the doc root in the link paths (the array keys). E.g.:
 45+ * <code>
 46+ * array('//symlink' => '/real/target/path') // unix
 47+ * array('//static' => 'D:\\staticStorage') // Windows
 48+ * </code>
 49+ *
 50+ * @return string
 51+ */
 52+ public static function minify($css, $options = array())
 53+ {
 54+ if (isset($options['preserveComments'])
 55+ && !$options['preserveComments']) {
 56+ $css = Minify_CSS_Compressor::process($css, $options);
 57+ } else {
 58+ $css = Minify_CommentPreserver::process(
 59+ $css
 60+ ,array('Minify_CSS_Compressor', 'process')
 61+ ,array($options)
 62+ );
 63+ }
 64+ if (! isset($options['currentDir']) && ! isset($options['prependRelativePath'])) {
 65+ return $css;
 66+ }
 67+ if (isset($options['currentDir'])) {
 68+ return Minify_CSS_UriRewriter::rewrite(
 69+ $css
 70+ ,$options['currentDir']
 71+ ,isset($options['docRoot']) ? $options['docRoot'] : $_SERVER['DOCUMENT_ROOT']
 72+ ,isset($options['symlinks']) ? $options['symlinks'] : array()
 73+ );
 74+ } else {
 75+ return Minify_CSS_UriRewriter::prepend(
 76+ $css
 77+ ,$options['prependRelativePath']
 78+ );
 79+ }
 80+ }
 81+}
Property changes on: branches/js2-work/phase3/js/mwEmbed/includes/library/CSS.php
___________________________________________________________________
Added: svn:executable
182 + *
Index: branches/js2-work/phase3/js/mwEmbed/includes/library/CommentPreserver.php
@@ -0,0 +1,90 @@
 2+<?php
 3+/**
 4+ * Class Minify_CommentPreserver
 5+ * @package Minify
 6+ */
 7+
 8+/**
 9+ * Process a string in pieces preserving C-style comments that begin with "/*!"
 10+ *
 11+ * @package Minify
 12+ * @author Stephen Clay <steve@mrclay.org>
 13+ */
 14+class Minify_CommentPreserver {
 15+
 16+ /**
 17+ * String to be prepended to each preserved comment
 18+ *
 19+ * @var string
 20+ */
 21+ public static $prepend = "\n";
 22+
 23+ /**
 24+ * String to be appended to each preserved comment
 25+ *
 26+ * @var string
 27+ */
 28+ public static $append = "\n";
 29+
 30+ /**
 31+ * Process a string outside of C-style comments that begin with "/*!"
 32+ *
 33+ * On each non-empty string outside these comments, the given processor
 34+ * function will be called. The first "!" will be removed from the
 35+ * preserved comments, and the comments will be surrounded by
 36+ * Minify_CommentPreserver::$preprend and Minify_CommentPreserver::$append.
 37+ *
 38+ * @param string $content
 39+ * @param callback $processor function
 40+ * @param array $args array of extra arguments to pass to the processor
 41+ * function (default = array())
 42+ * @return string
 43+ */
 44+ public static function process($content, $processor, $args = array())
 45+ {
 46+ $ret = '';
 47+ while (true) {
 48+ list($beforeComment, $comment, $afterComment) = self::_nextComment($content);
 49+ if ('' !== $beforeComment) {
 50+ $callArgs = $args;
 51+ array_unshift($callArgs, $beforeComment);
 52+ $ret .= call_user_func_array($processor, $callArgs);
 53+ }
 54+ if (false === $comment) {
 55+ break;
 56+ }
 57+ $ret .= $comment;
 58+ $content = $afterComment;
 59+ }
 60+ return $ret;
 61+ }
 62+
 63+ /**
 64+ * Extract comments that YUI Compressor preserves.
 65+ *
 66+ * @param string $in input
 67+ *
 68+ * @return array 3 elements are returned. If a YUI comment is found, the
 69+ * 2nd element is the comment and the 1st and 2nd are the surrounding
 70+ * strings. If no comment is found, the entire string is returned as the
 71+ * 1st element and the other two are false.
 72+ */
 73+ private static function _nextComment($in)
 74+ {
 75+ if (
 76+ false === ($start = strpos($in, '/*!'))
 77+ || false === ($end = strpos($in, '*/', $start + 3))
 78+ ) {
 79+ return array($in, false, false);
 80+ }
 81+ $ret = array(
 82+ substr($in, 0, $start)
 83+ ,self::$prepend . '/*' . substr($in, $start + 3, $end - $start - 1) . self::$append
 84+ );
 85+ $endChars = (strlen($in) - $end - 2);
 86+ $ret[] = (0 === $endChars)
 87+ ? ''
 88+ : substr($in, -$endChars);
 89+ return $ret;
 90+ }
 91+}
Index: branches/js2-work/phase3/js/mwEmbed/includes/library/CSS/Compressor.php
@@ -0,0 +1,250 @@
 2+<?php
 3+/**
 4+ * Class Minify_CSS_Compressor
 5+ * @package Minify
 6+ */
 7+
 8+/**
 9+ * Compress CSS
 10+ *
 11+ * This is a heavy regex-based removal of whitespace, unnecessary
 12+ * comments and tokens, and some CSS value minimization, where practical.
 13+ * Many steps have been taken to avoid breaking comment-based hacks,
 14+ * including the ie5/mac filter (and its inversion), but expect tricky
 15+ * hacks involving comment tokens in 'content' value strings to break
 16+ * minimization badly. A test suite is available.
 17+ *
 18+ * @package Minify
 19+ * @author Stephen Clay <steve@mrclay.org>
 20+ * @author http://code.google.com/u/1stvamp/ (Issue 64 patch)
 21+ */
 22+class Minify_CSS_Compressor {
 23+
 24+ /**
 25+ * Minify a CSS string
 26+ *
 27+ * @param string $css
 28+ *
 29+ * @param array $options (currently ignored)
 30+ *
 31+ * @return string
 32+ */
 33+ public static function process($css, $options = array())
 34+ {
 35+ $obj = new Minify_CSS_Compressor($options);
 36+ return $obj->_process($css);
 37+ }
 38+
 39+ /**
 40+ * @var array options
 41+ */
 42+ protected $_options = null;
 43+
 44+ /**
 45+ * @var bool Are we "in" a hack?
 46+ *
 47+ * I.e. are some browsers targetted until the next comment?
 48+ */
 49+ protected $_inHack = false;
 50+
 51+
 52+ /**
 53+ * Constructor
 54+ *
 55+ * @param array $options (currently ignored)
 56+ *
 57+ * @return null
 58+ */
 59+ private function __construct($options) {
 60+ $this->_options = $options;
 61+ }
 62+
 63+ /**
 64+ * Minify a CSS string
 65+ *
 66+ * @param string $css
 67+ *
 68+ * @return string
 69+ */
 70+ protected function _process($css)
 71+ {
 72+ $css = str_replace("\r\n", "\n", $css);
 73+
 74+ // preserve empty comment after '>'
 75+ // http://www.webdevout.net/css-hacks#in_css-selectors
 76+ $css = preg_replace('@>/\\*\\s*\\*/@', '>/*keep*/', $css);
 77+
 78+ // preserve empty comment between property and value
 79+ // http://css-discuss.incutio.com/?page=BoxModelHack
 80+ $css = preg_replace('@/\\*\\s*\\*/\\s*:@', '/*keep*/:', $css);
 81+ $css = preg_replace('@:\\s*/\\*\\s*\\*/@', ':/*keep*/', $css);
 82+
 83+ // apply callback to all valid comments (and strip out surrounding ws
 84+ $css = preg_replace_callback('@\\s*/\\*([\\s\\S]*?)\\*/\\s*@'
 85+ ,array($this, '_commentCB'), $css);
 86+
 87+ // remove ws around { } and last semicolon in declaration block
 88+ $css = preg_replace('/\\s*{\\s*/', '{', $css);
 89+ $css = preg_replace('/;?\\s*}\\s*/', '}', $css);
 90+
 91+ // remove ws surrounding semicolons
 92+ $css = preg_replace('/\\s*;\\s*/', ';', $css);
 93+
 94+ // remove ws around urls
 95+ $css = preg_replace('/
 96+ url\\( # url(
 97+ \\s*
 98+ ([^\\)]+?) # 1 = the URL (really just a bunch of non right parenthesis)
 99+ \\s*
 100+ \\) # )
 101+ /x', 'url($1)', $css);
 102+
 103+ // remove ws between rules and colons
 104+ $css = preg_replace('/
 105+ \\s*
 106+ ([{;]) # 1 = beginning of block or rule separator
 107+ \\s*
 108+ ([\\*_]?[\\w\\-]+) # 2 = property (and maybe IE filter)
 109+ \\s*
 110+ :
 111+ \\s*
 112+ (\\b|[#\'"]) # 3 = first character of a value
 113+ /x', '$1$2:$3', $css);
 114+
 115+ // remove ws in selectors
 116+ $css = preg_replace_callback('/
 117+ (?: # non-capture
 118+ \\s*
 119+ [^~>+,\\s]+ # selector part
 120+ \\s*
 121+ [,>+~] # combinators
 122+ )+
 123+ \\s*
 124+ [^~>+,\\s]+ # selector part
 125+ { # open declaration block
 126+ /x'
 127+ ,array($this, '_selectorsCB'), $css);
 128+
 129+ // minimize hex colors
 130+ $css = preg_replace('/([^=])#([a-f\\d])\\2([a-f\\d])\\3([a-f\\d])\\4([\\s;\\}])/i'
 131+ , '$1#$2$3$4$5', $css);
 132+
 133+ // remove spaces between font families
 134+ $css = preg_replace_callback('/font-family:([^;}]+)([;}])/'
 135+ ,array($this, '_fontFamilyCB'), $css);
 136+
 137+ $css = preg_replace('/@import\\s+url/', '@import url', $css);
 138+
 139+ // replace any ws involving newlines with a single newline
 140+ $css = preg_replace('/[ \\t]*\\n+\\s*/', "\n", $css);
 141+
 142+ // separate common descendent selectors w/ newlines (to limit line lengths)
 143+ $css = preg_replace('/([\\w#\\.\\*]+)\\s+([\\w#\\.\\*]+){/', "$1\n$2{", $css);
 144+
 145+ // Use newline after 1st numeric value (to limit line lengths).
 146+ $css = preg_replace('/
 147+ ((?:padding|margin|border|outline):\\d+(?:px|em)?) # 1 = prop : 1st numeric value
 148+ \\s+
 149+ /x'
 150+ ,"$1\n", $css);
 151+
 152+ // prevent triggering IE6 bug: http://www.crankygeek.com/ie6pebug/
 153+ $css = preg_replace('/:first-l(etter|ine)\\{/', ':first-l$1 {', $css);
 154+
 155+ return trim($css);
 156+ }
 157+
 158+ /**
 159+ * Replace what looks like a set of selectors
 160+ *
 161+ * @param array $m regex matches
 162+ *
 163+ * @return string
 164+ */
 165+ protected function _selectorsCB($m)
 166+ {
 167+ // remove ws around the combinators
 168+ return preg_replace('/\\s*([,>+~])\\s*/', '$1', $m[0]);
 169+ }
 170+
 171+ /**
 172+ * Process a comment and return a replacement
 173+ *
 174+ * @param array $m regex matches
 175+ *
 176+ * @return string
 177+ */
 178+ protected function _commentCB($m)
 179+ {
 180+ $hasSurroundingWs = (trim($m[0]) !== $m[1]);
 181+ $m = $m[1];
 182+ // $m is the comment content w/o the surrounding tokens,
 183+ // but the return value will replace the entire comment.
 184+ if ($m === 'keep') {
 185+ return '/**/';
 186+ }
 187+ if ($m === '" "') {
 188+ // component of http://tantek.com/CSS/Examples/midpass.html
 189+ return '/*" "*/';
 190+ }
 191+ if (preg_match('@";\\}\\s*\\}/\\*\\s+@', $m)) {
 192+ // component of http://tantek.com/CSS/Examples/midpass.html
 193+ return '/*";}}/* */';
 194+ }
 195+ if ($this->_inHack) {
 196+ // inversion: feeding only to one browser
 197+ if (preg_match('@
 198+ ^/ # comment started like /*/
 199+ \\s*
 200+ (\\S[\\s\\S]+?) # has at least some non-ws content
 201+ \\s*
 202+ /\\* # ends like /*/ or /**/
 203+ @x', $m, $n)) {
 204+ // end hack mode after this comment, but preserve the hack and comment content
 205+ $this->_inHack = false;
 206+ return "/*/{$n[1]}/**/";
 207+ }
 208+ }
 209+ if (substr($m, -1) === '\\') { // comment ends like \*/
 210+ // begin hack mode and preserve hack
 211+ $this->_inHack = true;
 212+ return '/*\\*/';
 213+ }
 214+ if ($m !== '' && $m[0] === '/') { // comment looks like /*/ foo */
 215+ // begin hack mode and preserve hack
 216+ $this->_inHack = true;
 217+ return '/*/*/';
 218+ }
 219+ if ($this->_inHack) {
 220+ // a regular comment ends hack mode but should be preserved
 221+ $this->_inHack = false;
 222+ return '/**/';
 223+ }
 224+ // Issue 107: if there's any surrounding whitespace, it may be important, so
 225+ // replace the comment with a single space
 226+ return $hasSurroundingWs // remove all other comments
 227+ ? ' '
 228+ : '';
 229+ }
 230+
 231+ /**
 232+ * Process a font-family listing and return a replacement
 233+ *
 234+ * @param array $m regex matches
 235+ *
 236+ * @return string
 237+ */
 238+ protected function _fontFamilyCB($m)
 239+ {
 240+ $m[1] = preg_replace('/
 241+ \\s*
 242+ (
 243+ "[^"]+" # 1 = family in double qutoes
 244+ |\'[^\']+\' # or 1 = family in single quotes
 245+ |[\\w\\-]+ # or 1 = unquoted family
 246+ )
 247+ \\s*
 248+ /x', '$1', $m[1]);
 249+ return 'font-family:' . $m[1] . $m[2];
 250+ }
 251+}
Property changes on: branches/js2-work/phase3/js/mwEmbed/includes/library/CSS/Compressor.php
___________________________________________________________________
Added: svn:executable
1252 + *
Index: branches/js2-work/phase3/js/mwEmbed/includes/library/CSS/UriRewriter.php
@@ -0,0 +1,270 @@
 2+<?php
 3+/**
 4+ * Class Minify_CSS_UriRewriter
 5+ * @package Minify
 6+ */
 7+
 8+/**
 9+ * Rewrite file-relative URIs as root-relative in CSS files
 10+ *
 11+ * @package Minify
 12+ * @author Stephen Clay <steve@mrclay.org>
 13+ */
 14+class Minify_CSS_UriRewriter {
 15+
 16+ /**
 17+ * Defines which class to call as part of callbacks, change this
 18+ * if you extend Minify_CSS_UriRewriter
 19+ * @var string
 20+ */
 21+ protected static $className = 'Minify_CSS_UriRewriter';
 22+
 23+ /**
 24+ * rewrite() and rewriteRelative() append debugging information here
 25+ * @var string
 26+ */
 27+ public static $debugText = '';
 28+
 29+ /**
 30+ * Rewrite file relative URIs as root relative in CSS files
 31+ *
 32+ * @param string $css
 33+ *
 34+ * @param string $currentDir The directory of the current CSS file.
 35+ *
 36+ * @param string $docRoot The document root of the web site in which
 37+ * the CSS file resides (default = $_SERVER['DOCUMENT_ROOT']).
 38+ *
 39+ * @param array $symlinks (default = array()) If the CSS file is stored in
 40+ * a symlink-ed directory, provide an array of link paths to
 41+ * target paths, where the link paths are within the document root. Because
 42+ * paths need to be normalized for this to work, use "//" to substitute
 43+ * the doc root in the link paths (the array keys). E.g.:
 44+ * <code>
 45+ * array('//symlink' => '/real/target/path') // unix
 46+ * array('//static' => 'D:\\staticStorage') // Windows
 47+ * </code>
 48+ *
 49+ * @return string
 50+ */
 51+ public static function rewrite($css, $currentDir, $docRoot = null, $symlinks = array())
 52+ {
 53+ self::$_docRoot = self::_realpath(
 54+ $docRoot ? $docRoot : $_SERVER['DOCUMENT_ROOT']
 55+ );
 56+ self::$_currentDir = self::_realpath($currentDir);
 57+ self::$_symlinks = array();
 58+
 59+ // normalize symlinks
 60+ foreach ($symlinks as $link => $target) {
 61+ $link = ($link === '//')
 62+ ? self::$_docRoot
 63+ : str_replace('//', self::$_docRoot . '/', $link);
 64+ $link = strtr($link, '/', DIRECTORY_SEPARATOR);
 65+ self::$_symlinks[$link] = self::_realpath($target);
 66+ }
 67+
 68+ self::$debugText .= "docRoot : " . self::$_docRoot . "\n"
 69+ . "currentDir : " . self::$_currentDir . "\n";
 70+ if (self::$_symlinks) {
 71+ self::$debugText .= "symlinks : " . var_export(self::$_symlinks, 1) . "\n";
 72+ }
 73+ self::$debugText .= "\n";
 74+
 75+ $css = self::_trimUrls($css);
 76+
 77+ // rewrite
 78+ $css = preg_replace_callback('/@import\\s+([\'"])(.*?)[\'"]/'
 79+ ,array(self::$className, '_processUriCB'), $css);
 80+ $css = preg_replace_callback('/url\\(\\s*([^\\)\\s]+)\\s*\\)/'
 81+ ,array(self::$className, '_processUriCB'), $css);
 82+
 83+ return $css;
 84+ }
 85+
 86+ /**
 87+ * Prepend a path to relative URIs in CSS files
 88+ *
 89+ * @param string $css
 90+ *
 91+ * @param string $path The path to prepend.
 92+ *
 93+ * @return string
 94+ */
 95+ public static function prepend($css, $path)
 96+ {
 97+ self::$_prependPath = $path;
 98+
 99+ $css = self::_trimUrls($css);
 100+
 101+ // append
 102+ $css = preg_replace_callback('/@import\\s+([\'"])(.*?)[\'"]/'
 103+ ,array(self::$className, '_processUriCB'), $css);
 104+ $css = preg_replace_callback('/url\\(\\s*([^\\)\\s]+)\\s*\\)/'
 105+ ,array(self::$className, '_processUriCB'), $css);
 106+
 107+ self::$_prependPath = null;
 108+ return $css;
 109+ }
 110+
 111+
 112+ /**
 113+ * @var string directory of this stylesheet
 114+ */
 115+ private static $_currentDir = '';
 116+
 117+ /**
 118+ * @var string DOC_ROOT
 119+ */
 120+ private static $_docRoot = '';
 121+
 122+ /**
 123+ * @var array directory replacements to map symlink targets back to their
 124+ * source (within the document root) E.g. '/var/www/symlink' => '/var/realpath'
 125+ */
 126+ private static $_symlinks = array();
 127+
 128+ /**
 129+ * @var string path to prepend
 130+ */
 131+ private static $_prependPath = null;
 132+
 133+ private static function _trimUrls($css)
 134+ {
 135+ return preg_replace('/
 136+ url\\( # url(
 137+ \\s*
 138+ ([^\\)]+?) # 1 = URI (assuming does not contain ")")
 139+ \\s*
 140+ \\) # )
 141+ /x', 'url($1)', $css);
 142+ }
 143+
 144+ private static function _processUriCB($m)
 145+ {
 146+ // $m matched either '/@import\\s+([\'"])(.*?)[\'"]/' or '/url\\(\\s*([^\\)\\s]+)\\s*\\)/'
 147+ $isImport = ($m[0][0] === '@');
 148+ // determine URI and the quote character (if any)
 149+ if ($isImport) {
 150+ $quoteChar = $m[1];
 151+ $uri = $m[2];
 152+ } else {
 153+ // $m[1] is either quoted or not
 154+ $quoteChar = ($m[1][0] === "'" || $m[1][0] === '"')
 155+ ? $m[1][0]
 156+ : '';
 157+ $uri = ($quoteChar === '')
 158+ ? $m[1]
 159+ : substr($m[1], 1, strlen($m[1]) - 2);
 160+ }
 161+ // analyze URI
 162+ if ('/' !== $uri[0] // root-relative
 163+ && false === strpos($uri, '//') // protocol (non-data)
 164+ && 0 !== strpos($uri, 'data:') // data protocol
 165+ ) {
 166+ // URI is file-relative: rewrite depending on options
 167+ $uri = (self::$_prependPath !== null)
 168+ ? (self::$_prependPath . $uri)
 169+ : self::rewriteRelative($uri, self::$_currentDir, self::$_docRoot, self::$_symlinks);
 170+ }
 171+ return $isImport
 172+ ? "@import {$quoteChar}{$uri}{$quoteChar}"
 173+ : "url({$quoteChar}{$uri}{$quoteChar})";
 174+ }
 175+
 176+ /**
 177+ * Rewrite a file relative URI as root relative
 178+ *
 179+ * <code>
 180+ * Minify_CSS_UriRewriter::rewriteRelative(
 181+ * '../img/hello.gif'
 182+ * , '/home/user/www/css' // path of CSS file
 183+ * , '/home/user/www' // doc root
 184+ * );
 185+ * // returns '/img/hello.gif'
 186+ *
 187+ * // example where static files are stored in a symlinked directory
 188+ * Minify_CSS_UriRewriter::rewriteRelative(
 189+ * 'hello.gif'
 190+ * , '/var/staticFiles/theme'
 191+ * , '/home/user/www'
 192+ * , array('/home/user/www/static' => '/var/staticFiles')
 193+ * );
 194+ * // returns '/static/theme/hello.gif'
 195+ * </code>
 196+ *
 197+ * @param string $uri file relative URI
 198+ *
 199+ * @param string $realCurrentDir realpath of the current file's directory.
 200+ *
 201+ * @param string $realDocRoot realpath of the site document root.
 202+ *
 203+ * @param array $symlinks (default = array()) If the file is stored in
 204+ * a symlink-ed directory, provide an array of link paths to
 205+ * real target paths, where the link paths "appear" to be within the document
 206+ * root. E.g.:
 207+ * <code>
 208+ * array('/home/foo/www/not/real/path' => '/real/target/path') // unix
 209+ * array('C:\\htdocs\\not\\real' => 'D:\\real\\target\\path') // Windows
 210+ * </code>
 211+ *
 212+ * @return string
 213+ */
 214+ public static function rewriteRelative($uri, $realCurrentDir, $realDocRoot, $symlinks = array())
 215+ {
 216+ // prepend path with current dir separator (OS-independent)
 217+ $path = strtr($realCurrentDir, '/', DIRECTORY_SEPARATOR)
 218+ . DIRECTORY_SEPARATOR . strtr($uri, '/', DIRECTORY_SEPARATOR);
 219+
 220+ self::$debugText .= "file-relative URI : {$uri}\n"
 221+ . "path prepended : {$path}\n";
 222+
 223+ // "unresolve" a symlink back to doc root
 224+ foreach ($symlinks as $link => $target) {
 225+ if (0 === strpos($path, $target)) {
 226+ // replace $target with $link
 227+ $path = $link . substr($path, strlen($target));
 228+
 229+ self::$debugText .= "symlink unresolved : {$path}\n";
 230+
 231+ break;
 232+ }
 233+ }
 234+ // strip doc root
 235+ $path = substr($path, strlen($realDocRoot));
 236+
 237+ self::$debugText .= "docroot stripped : {$path}\n";
 238+
 239+ // fix to root-relative URI
 240+
 241+ $uri = strtr($path, '/\\', '//');
 242+
 243+ // remove /./ and /../ where possible
 244+ $uri = str_replace('/./', '/', $uri);
 245+ // inspired by patch from Oleg Cherniy
 246+ do {
 247+ $uri = preg_replace('@/[^/]+/\\.\\./@', '/', $uri, 1, $changed);
 248+ } while ($changed);
 249+
 250+ self::$debugText .= "traversals removed : {$uri}\n\n";
 251+
 252+ return $uri;
 253+ }
 254+
 255+ /**
 256+ * Get realpath with any trailing slash removed. If realpath() fails,
 257+ * just remove the trailing slash.
 258+ *
 259+ * @param string $path
 260+ *
 261+ * @return mixed path with no trailing slash
 262+ */
 263+ protected static function _realpath($path)
 264+ {
 265+ $realPath = realpath($path);
 266+ if ($realPath !== false) {
 267+ $path = $realPath;
 268+ }
 269+ return rtrim($path, '/\\');
 270+ }
 271+}
Property changes on: branches/js2-work/phase3/js/mwEmbed/includes/library/CSS/UriRewriter.php
___________________________________________________________________
Added: svn:executable
1272 + *
Index: branches/js2-work/phase3/js/mwEmbed/includes/noMediaWikiConfig.php
@@ -57,6 +57,12 @@
5858 // Get the JSmin class:
5959 require_once( realpath( dirname( __FILE__ ) ) . '/library/JSMin.php' );
6060
 61+// Get the css class:
 62+require_once( realpath( dirname( __FILE__ ) ) . '/library/CSS.php' );
 63+require_once( realpath( dirname( __FILE__ ) ) . '/library/CSS/Compressor.php' );
 64+require_once( realpath( dirname( __FILE__ ) ) . '/library/CSS/UriRewriter.php' );
 65+require_once( realpath( dirname( __FILE__ ) ) . '/library/CommentPreserver.php' );
 66+
6167 // Get the messages file:
6268 require_once( realpath( dirname( __FILE__ ) ) . '/../languages/mwEmbed.i18n.php' );
6369
@@ -64,6 +70,10 @@
6571 return false;
6672 }
6773
 74+function wfTempDir(){
 75+ return realpath( dirname( __FILE__ ) ) . '/includes/cache';
 76+}
 77+
6878 /**
6979 * Make directory, and make all parent directories if they don't exist
7080 *
@@ -130,4 +140,31 @@
131141 function wfSuppressWarnings(){
132142 };
133143 function wfRestoreWarnings(){
134 -};
\ No newline at end of file
 144+};
 145+class Xml {
 146+ public static function escapeJsString( $string ) {
 147+ // See ECMA 262 section 7.8.4 for string literal format
 148+ $pairs = array(
 149+ "\\" => "\\\\",
 150+ "\"" => "\\\"",
 151+ '\'' => '\\\'',
 152+ "\n" => "\\n",
 153+ "\r" => "\\r",
 154+
 155+ # To avoid closing the element or CDATA section
 156+ "<" => "\\x3c",
 157+ ">" => "\\x3e",
 158+
 159+ # To avoid any complaints about bad entity refs
 160+ "&" => "\\x26",
 161+
 162+ # Work around https://bugzilla.mozilla.org/show_bug.cgi?id=274152
 163+ # Encode certain Unicode formatting chars so affected
 164+ # versions of Gecko don't misinterpret our strings;
 165+ # this is a common problem with Farsi text.
 166+ "\xe2\x80\x8c" => "\\u200c", // ZERO WIDTH NON-JOINER
 167+ "\xe2\x80\x8d" => "\\u200d", // ZERO WIDTH JOINER
 168+ );
 169+ return strtr( $string, $pairs );
 170+ }
 171+}
\ No newline at end of file
Index: branches/js2-work/phase3/js/mwEmbed/skins/ctrlBuilder.js
@@ -1,1573 +0,0 @@
2 -/**
3 -* Msg text is inherited from embedPlayer
4 -*/
5 -
6 -/**
7 -* ctrlBuilder object
8 -* @param the embedPlayer element we are targeting
9 -*/
10 -var ctrlBuilder = function( embedPlayer, options ) {
11 - return this.init( embedPlayer, options );
12 -};
13 -
14 -/**
15 - * ControlsBuilder prototype:
16 - */
17 -ctrlBuilder.prototype = {
18 - //Default Local values:
19 -
20 - // Parent css Class name
21 - playerClass : 'mv-player',
22 -
23 - // Long string display of time value
24 - longTimeDisp: true,
25 -
26 - // Default volume layout is "vertical"
27 - volume_layout : 'vertical',
28 -
29 - // Default control bar height
30 - height: 31,
31 -
32 - // Default supported components is merged with embedPlayer set of supported types
33 - supportedComponets: {
34 - // All playback types support options
35 - 'options': true
36 - },
37 -
38 - // Default supported menu items is merged with skin menu items
39 - supportedMenuItems: {
40 - // Player Select
41 - 'playerSelect' : true,
42 -
43 - // Download the file menu
44 - 'download' : true,
45 -
46 - // Share the video menu
47 - 'share' : true
48 - },
49 -
50 - // Flag to store the current fullscreen mode
51 - fullscreenMode: false,
52 -
53 - /**
54 - * Initialization Object for the control builder
55 - *
56 - * @param {Object} embedPlayer EmbedPlayer interface
57 - */
58 - init: function( embedPlayer ) {
59 - var _this = this;
60 - this.embedPlayer = embedPlayer;
61 -
62 - // Check for skin overrides for ctrlBuilder
63 - if ( window[ embedPlayer.skinName + 'Config' ] ) {
64 -
65 - // Clone as to not override prototype with the skin config
66 - var _this = $j.extend( true, { }, this, window[ embedPlayer.skinName + 'Config'] );
67 - return _this;
68 - }
69 - // Return the ctrlBuilder Object:
70 - return this;
71 - },
72 -
73 - /**
74 - * Get the control bar height
75 - * @return {Number} control bar height
76 - */
77 - getHeight: function(){
78 - return this.height;
79 - },
80 -
81 - /**
82 - * Get the controls html
83 - * @return {String} html output of controls
84 - */
85 - addControls: function() {
86 - // Set up local pointer to the embedPlayer
87 - var embedPlayer = this.embedPlayer;
88 -
89 - // Set up local ctrlBuilder
90 - var _this = this;
91 -
92 - // Remove any old controls & old overlays:
93 - embedPlayer.$interface.find( '.control-bar,.overlay-win' ).remove();
94 -
95 - // Setup the controlBar container
96 - var $controlBar = $j('<div />')
97 - .addClass( 'ui-state-default ui-widget-header ui-helper-clearfix control-bar' )
98 - .css( 'height', this.height )
99 -
100 - // Check for overlay controls:
101 - if( _this.checkOverlayControls() ) {
102 - $controlBar.css( {
103 - 'position': 'absolute',
104 - 'bottom' : '0px',
105 - 'left' : '0px',
106 - 'right' : '0px'
107 - } )
108 - .hide()
109 - // Make sure the interface is correct height:
110 - embedPlayer.$interface.css( {
111 - 'height' : parseInt( embedPlayer.height )
112 - } );
113 - } else {
114 - // Add some space to interface for the control bar ( if not overlaying controls )
115 - embedPlayer.$interface.css( {
116 - 'height' : parseInt( embedPlayer.height ) + parseInt( this.height ) +2
117 - } );
118 - // update the control bar display to "block"
119 - $controlBar.css( 'display', 'block' );
120 - }
121 -
122 - // Add the controls to the interface
123 - embedPlayer.$interface.append( $controlBar );
124 -
125 - // Add the Controls with their bindings
126 - this.addControlComponents();
127 -
128 - // Add hooks once Controls are in DOM
129 - this.addControlHooks();
130 - },
131 -
132 - /**
133 - * Builds the interface controls
134 - * @return the interface html string
135 - */
136 - addControlComponents: function( ) {
137 - var _this = this;
138 - mw.log( 'f:controlsBuilder:: opt:' + this.options );
139 -
140 - // Set up local pointer to the embedPlayer
141 - var embedPlayer = this.embedPlayer;
142 -
143 - //Set up local var to control container:
144 - var $controlBar = embedPlayer.$interface.find( '.control-bar' );
145 -
146 - this.available_width = embedPlayer.getPlayerWidth();
147 -
148 - // Make pointer to the embedPlayer
149 - this.embedPlayer = embedPlayer;
150 -
151 - // Build the supportedComponets list
152 - this.supportedComponets = $j.extend( this.supportedComponets, embedPlayer.supports );
153 -
154 - // Check for timed text support:
155 - if( embedPlayer.isTimedTextSupported() ){
156 - this.supportedComponets['timedText'] = true;
157 - }
158 - // Check for kalturaAttribution
159 - if( mw.getConfig( 'kalturaAttribution' ) ){
160 - this.supportedComponets[ 'kalturaAttribution' ] = true;
161 - }
162 -
163 - // Check global fullscreen enabled flag
164 - if( mw.getConfig( 'enableFullscreen' ) === false ){
165 - this.supportedComponets[ 'fullscreen'] = false;
166 - }
167 -
168 - // Output components
169 - for ( var component_id in this.components ) {
170 - // Check for (component === false ) and skip
171 - if( this.components[ component_id ] === false ){
172 - continue;
173 - }
174 -
175 - // Special case with playhead skip if we have > 30px of space for it
176 - if ( component_id == 'playHead' && this.available_width < 30 ){
177 - continue;
178 - }
179 -
180 - // Skip "fullscreen" button for assets or where height is 0px ( audio )
181 - if( component_id == 'fullscreen' && this.embedPlayer.height == 0 ){
182 - continue;
183 - }
184 -
185 - // Make sure the given components is supported:
186 - if ( this.supportedComponets[ component_id ] ) {
187 - if ( this.available_width > this.components[ component_id ].w ) {
188 - // Append the component
189 - $controlBar.append(
190 - _this.getComponent( component_id )
191 - );
192 - this.available_width -= this.components[ component_id ].w;
193 - } else {
194 - mw.log( 'Not enough space for control component:' + component_id );
195 - }
196 - }
197 - }
198 - },
199 -
200 - /**
201 - * Get the fullscreen player css
202 - */
203 - getFullscreenPlayerCss: function() {
204 - var embedPlayer = this.embedPlayer;
205 - // Setup target height width based on max window size
206 - var fullWidth = $j( window ).width() - 2 ;
207 - var fullHeight = $j( window ).height() ;
208 -
209 - // Set target width
210 - targetWidth = fullWidth;
211 - targetHeight = targetWidth * ( embedPlayer.getHeight() / embedPlayer.getWidth() )
212 - // Check if it exceeds the height constraint:
213 - if( targetHeight > fullHeight ){
214 - targetHeight = fullHeight;
215 - targetWidth = targetHeight * ( embedPlayer.getWidth() / embedPlayer.getHeight() );
216 - }
217 - var offsetTop = ( targetHeight < fullHeight )? ( fullHeight- targetHeight ) / 2 : 0;
218 - var offsetLeft = ( targetWidth < fullWidth )? ( fullWidth- targetWidth ) / 2 : 0;
219 -
220 - //mw.log(" targetWidth: " + targetWidth + ' fullwidth: ' + fullWidth + ' :: ' + ( fullWidth- targetWidth ) / 2 );
221 - return {
222 - 'height': targetHeight,
223 - 'width' : targetWidth,
224 - 'top' : offsetTop,
225 - 'left': offsetLeft
226 - }
227 - },
228 -
229 - /**
230 - * Get the fullscreen play button css
231 - */
232 - getFullscreenPlayButtonCss: function() {
233 - var pos = this.getFullscreenPlayerCss();
234 - return {
235 - 'left' : ( ( pos.width - this.getComponentWidth( 'playButtonLarge' ) ) / 2 ),
236 - 'top' : ( ( pos.height - this.getComponentHeight( 'playButtonLarge' ) ) / 2 )
237 - }
238 - },
239 -
240 - /**
241 - * Get the fullscreen text css
242 - */
243 - getFullscreenTextCss: function() {
244 - // Some arbitrary scale relative to window size
245 - var textSize = ( $j( window ).width() / 8 ) + 20;
246 - if( textSize < 95 ) textSize = 95;
247 - if( textSize > 250 ) textSize = 250;
248 - //mw.log(' win size is: ' + $j( window ).width() + ' ts: ' + textSize );
249 - return {
250 - 'font-size' : textSize + '%'
251 - }
252 - },
253 -
254 - /**
255 - * Toggles full screen by calling
256 - * doFullScreenPlayer to enable fullscreen mode
257 - * restoreWindowPlayer to restore window mode
258 - */
259 - toggleFullscreen: function() {
260 - if( this.fullscreenMode ){
261 - this.restoreWindowPlayer();
262 - }else{
263 - this.doFullScreenPlayer();
264 - }
265 - },
266 -
267 - /**
268 - * Do full-screen mode
269 - */
270 - doFullScreenPlayer: function() {
271 - mw.log(" ctrlBuilder :: toggle full-screen ");
272 - // Setup pointer to control builder :
273 - var _this = this;
274 -
275 - // Setup local reference to embed player:
276 - var embedPlayer = this.embedPlayer;
277 -
278 - // Setup a local reference to the player interface:
279 - var $interface = embedPlayer.$interface;
280 -
281 -
282 - // Check fullscreen state ( if already true do nothing )
283 - if( this.fullscreenMode == true ){
284 - return ;
285 - }
286 - this.fullscreenMode = true;
287 -
288 - //Remove any old mw-fullscreen-overlay
289 - $interface.find( '.mw-fullscreen-overlay' ).remove();
290 -
291 - // Special hack for mediawiki monobook skin search box
292 - if( $j( '#p-search,#p-logo' ).length ) {
293 - $j( '#p-search,#p-logo,#ca-nstab-project a' ).css('z-index', 1);
294 - }
295 -
296 - // Add the css fixed fullscreen black overlay as a sibling to the video element
297 - $interface.after(
298 - $j( '<div />' )
299 - .addClass( 'mw-fullscreen-overlay' )
300 - // Set some arbitrary high z-index
301 - .css('z-index', mw.getConfig( 'fullScreenIndex' ) )
302 - .hide()
303 - .fadeIn("slow")
304 - );
305 -
306 - // Change the interface to absolute positioned:
307 - this.windowPositionStyle = $interface.css( 'position' );
308 - this.windowZindex = $interface.css( 'z-index' );
309 -
310 - // Get the base offset:
311 - this.windowOffset = $interface.offset();
312 - this.windowOffset.top = this.windowOffset.top - $j(document).scrollTop();
313 - this.windowOffset.left = this.windowOffset.left - $j(document).scrollLeft();
314 -
315 - // Change the z-index of the interface
316 - $interface.css( {
317 - 'position' : 'fixed',
318 - 'z-index' : mw.getConfig( 'fullScreenIndex' ) + 1,
319 - 'top' : this.windowOffset.top,
320 - 'left' : this.windowOffset.left
321 - } );
322 -
323 -
324 -
325 - // Empty out the parent absolute index
326 - _this.parentsAbsolute = [];
327 -
328 - // Hide the body scroll bar
329 - $j('body').css( 'overflow', 'hidden' );
330 -
331 -
332 - var topOffset = '0px';
333 - var leftOffset = '0px';
334 -
335 - //Check if we have an offsetParent
336 - if( $interface.offsetParent().get(0).tagName.toLowerCase() != 'body' ) {
337 - topOffset = -this.windowOffset.top + 'px';
338 - leftOffset = -this.windowOffset.left + 'px';
339 - }
340 -
341 - // Resize interface container
342 - $interface.animate( {
343 - 'top' : topOffset,
344 - 'left' : leftOffset,
345 - 'width' : $j( window ).width(),
346 - 'height' : $j( window ).height(),
347 - 'overlow' : 'hidden'
348 - }, function(){
349 - // Remove absolute css of the interface parents
350 - $interface.parents().each( function() {
351 - //mw.log(' parent : ' + $j( this ).attr('id' ) + ' class: ' + $j( this ).attr('class') + ' pos: ' + $j( this ).css( 'position' ) );
352 - if( $j( this ).css( 'position' ) == 'absolute' ) {
353 - _this.parentsAbsolute.push( $j( this ) );
354 - $j( this ).css( 'position', null );
355 - mw.log(' should update position: ' + $j( this ).css( 'position' ) );
356 - }
357 - } );
358 - } )
359 -
360 - // Set the player height width:
361 - $j( embedPlayer ).css( {
362 - 'position' : 'relative'
363 - } )
364 - // Animate a zoom ( while keeping aspect )
365 - .animate( _this.getFullscreenPlayerCss() );
366 -
367 - // Resize the timed text font size per window width
368 - $interface.find( '.itext' ).css( _this.getFullscreenTextCss() );
369 -
370 - // Reposition play-btn-large ( this is unfortunately not easy to position with 'margin': 'auto'
371 - $interface.find('.play-btn-large').animate( _this.getFullscreenPlayButtonCss() )
372 -
373 - // Bind mouse move in interface to hide control bar
374 - _this.mouseMovedFlag = false;
375 - $interface.mousemove( function(e){
376 - _this.mouseMovedFlag = true;
377 - });
378 - // Check every 2 seconds reset flag status:
379 - function checkMovedMouse(){
380 - if( _this.fullscreenMode ){
381 - if( _this.mouseMovedFlag ){
382 - _this.mouseMovedFlag = false;
383 - _this.showControlBar();
384 - // Once we move the mouse keep displayed for 4 seconds
385 - setTimeout(checkMovedMouse, 4000);
386 - }else{
387 - // Check for mouse movement every 250ms
388 - _this.hideControlBar();
389 - setTimeout(checkMovedMouse, 250 );
390 - }
391 - }
392 - };
393 - checkMovedMouse();
394 -
395 - // Bind Scroll position update
396 -
397 - // Bind resize resize window to resize window
398 - $j( window ).resize( function() {
399 - if( _this.fullscreenMode ){
400 - // Update interface container:
401 - $interface.css( {
402 - 'top' : '0px',
403 - 'left' : '0px',
404 - 'width' : $j( window ).width(),
405 - 'height' : $j( window ).height()
406 - } )
407 - // Update player size
408 - $j( embedPlayer ).css( _this.getFullscreenPlayerCss() );
409 -
410 - // Update play button pos
411 - $interface.find('.play-btn-large').css( _this.getFullscreenPlayButtonCss() );
412 -
413 - // Update the timed text size
414 - $interface.find( '.itext' ).css( _this.getFullscreenTextCss() );
415 - }
416 - });
417 -
418 - // Bind escape to restore clip resolution
419 - $j( window ).keyup( function(event) {
420 - // Escape check
421 - if( event.keyCode == 27 ){
422 - _this.restoreWindowPlayer();
423 - }
424 - } );
425 - },
426 -
427 - /**
428 - * Restore the window player
429 - */
430 - restoreWindowPlayer: function() {
431 - var _this = this;
432 - var embedPlayer = this.embedPlayer;
433 -
434 - // Check fullscreen state
435 - if( this.fullscreenMode == false ){
436 - return ;
437 - }
438 - // Set fullscreen mode to false
439 - this.fullscreenMode = false;
440 -
441 - var $interface = embedPlayer.$interface;
442 - var interfaceHeight = ( _this.checkOverlayControls() )
443 - ? embedPlayer.getHeight()
444 - : embedPlayer.getHeight() + _this.getHeight();
445 -
446 - $j('.mw-fullscreen-overlay').fadeOut( 'slow' );
447 - $interface.animate( {
448 - 'top' : this.windowOffset.top,
449 - 'left' : this.windowOffset.left,
450 - // height is embedPlayer height + ctrlBuilder height:
451 - 'height' : interfaceHeight,
452 - 'width' : embedPlayer.getWidth()
453 - },function(){
454 - // Restore non-absolute layout:
455 - $interface.css( {
456 - 'position' : _this.windowPositionStyle,
457 - 'z-index' : _this.windowZindex,
458 - 'overlow' : 'visible',
459 - 'top' : null,
460 - 'left' : null
461 - } );
462 -
463 - //Restore absolute layout of parents:
464 - $j.each( _this.parentsAbsolute, function( na, element ){
465 - $j( element ).css( 'position', 'absolute' );
466 - } );
467 - _this.parentsAbsolute = null;
468 -
469 - // Restore the body scroll bar
470 - $j('body').css( 'overflow', 'auto' );
471 -
472 - } );
473 - // Restore the player:
474 - $j( embedPlayer ).animate( {
475 - 'top' : '0px',
476 - 'left' : '0px',
477 - 'width' : embedPlayer.getWidth(),
478 - 'height' : embedPlayer.getHeight()
479 - })
480 - // Restore the play button
481 - $interface.find('.play-btn-large').animate( {
482 - 'left' : ( ( embedPlayer.getPlayerWidth() - this.getComponentWidth( 'playButtonLarge' ) ) / 2 ),
483 - 'top' : ( ( embedPlayer.getPlayerHeight() -this.getComponentHeight( 'playButtonLarge' ) ) / 2 )
484 - } );
485 -
486 - // Restore text size:
487 - $interface.find( '.itext' ).css({
488 - 'font-size' : '100%'
489 - })
490 - },
491 -
492 - /**
493 - * Get minimal width for interface overlay
494 - */
495 - getOverlayWidth: function( ) {
496 - return ( this.embedPlayer.getPlayerWidth() < 300 )? 300 : this.embedPlayer.getPlayerWidth();
497 - },
498 -
499 - /**
500 - * Get minimal height for interface overlay
501 - */
502 - getOverlayHeight: function( ) {
503 - return ( this.embedPlayer.getPlayerHeight() < 200 )? 200 : this.embedPlayer.getPlayerHeight();
504 - },
505 -
506 - /**
507 - * addControlHooks
508 - * Adds control hooks once controls are in the DOM
509 - */
510 - addControlHooks: function( ) {
511 - // Set up local pointer to the embedPlayer
512 - var embedPlayer = this.embedPlayer;
513 - var _this = this;
514 -
515 - // Setup target shortcut to control-bar
516 - $target = embedPlayer.$interface;
517 - var mouseIn = false;
518 - // Add hide show bindings for control overlay (if overlay is enabled )
519 - if( _this.checkOverlayControls() ) {
520 - // Add a special absolute overlay for hover ( to keep menu displayed
521 - $j( embedPlayer.$interface ).hover(
522 - function(){
523 - // Show controls with a set timeout ( avoid fade in fade out on short mouse over )
524 - setTimeout( function() {
525 - if( mouseIn ){
526 - _this.showControlBar()
527 - }
528 - }, 250 );
529 - mouseIn = true;
530 - },
531 - function(){
532 - mouseIn = false;
533 - // Hide controls ( delay hide if menu is visible )
534 - function hideCheck(){
535 - if ( embedPlayer.$interface.find( '.overlay-win' ).length != 0
536 - || $j('.menuPositionHelper').is(':visible' ) ) {
537 - setTimeout( hideCheck, 250 );
538 - return ;
539 - }
540 - if( _this.checkOverlayControls() && !mouseIn ) {
541 - _this.hideControlBar();
542 - }
543 -
544 - }
545 - // Don't remove until user is out of player for 1 second
546 - setTimeout( hideCheck, 1000 );
547 - }
548 - );
549 - } else {
550 - $j( embedPlayer.$interface ).unbind().show();
551 - }
552 -
553 - // Add recommend firefox if we have non-native playback:
554 - if ( _this.checkNativeWarning( ) ) {
555 - _this.doNativeWarning();
556 - }
557 -
558 - // Do png fix for ie6
559 - if ( $j.browser.msie && $j.browser.version <= 6 ) {
560 - $j('#' + embedPlayer.id + ' .play-btn-large' ).pngFix();
561 - }
562 -
563 - this.doVolumeBinding();
564 -
565 - // Check if we have any custom skin Bindings to run
566 - if ( this.addSkinControlBindings && typeof( this.addSkinControlBindings ) == 'function' ){
567 - this.addSkinControlBindings();
568 - }
569 - },
570 -
571 - /**
572 - * Hide the control bar.
573 - */
574 - hideControlBar : function(){
575 - var animateDuration = 'slow'
576 - // Else hide the control bar ( if checkOverlayControls is still true )
577 - this.embedPlayer.$interface.find( '.control-bar').fadeOut( animateDuration );
578 - this.embedPlayer.$interface.find( '.itext' ).animate( {
579 - 'bottom' : 10
580 - }, animateDuration );
581 -
582 - },
583 -
584 - /**
585 - * Show the control bar
586 - */
587 - showControlBar : function(){
588 - var animateDuration = 'slow'
589 - // Show controls
590 - this.embedPlayer.$interface.find( '.control-bar').fadeIn( animateDuration );
591 - // Move up itext if present
592 - this.embedPlayer.$interface.find( '.itext' ).animate( {
593 - 'bottom' : this.getHeight() + 10
594 - }, animateDuration );
595 -
596 - },
597 -
598 - /**
599 - * Checks if the browser supports overlays and the controlsOverlay is
600 - * set to true for the player or via config
601 - */
602 - checkOverlayControls: function(){
603 - //if the player "supports" overlays:
604 - if( ! this.embedPlayer.supports['overlays'] ){
605 - return false;
606 - }
607 - // If the config is false
608 - if( mw.getConfig( 'overlayControls' ) === false){
609 - return false;
610 - }
611 - // If disabled via the player
612 - if( this.embedPlayer.overlayControls === false ){
613 - return false;
614 - }
615 - // don't hide controls when content "height" is 0 ( audio tags )
616 - if( this.embedPlayer.height == 0 ){
617 - return false;
618 - }
619 - // Past alll tests OverlayControls is true:
620 - return true;
621 - },
622 -
623 - /**
624 - * Check if a warning should be issued to non-native playback systems
625 - *
626 - * dependent on mediaElement being setup
627 - */
628 - checkNativeWarning: function( ) {
629 - // Check cookie to see if user requested to hide it
630 - if ( $j.cookie( 'show_player_warning' ) == 'false' ) {
631 - return false;
632 - }
633 -
634 - // If the resolution is too small don't display the warning
635 - if( this.embedPlayer.getPlayerHeight() < 199 ){
636 - return false;
637 - }
638 -
639 - // See if we have native support for ogg:
640 - var supportingPlayers = mw.EmbedTypes.players.getMIMETypePlayers( 'video/ogg' );
641 - for ( var i = 0; i < supportingPlayers.length; i++ ) {
642 - if ( supportingPlayers[i].id == 'oggNative' ) {
643 - return false;
644 - }
645 - }
646 -
647 - // Check for h264 source and playback support
648 - var supportingPlayers = mw.EmbedTypes.players.getMIMETypePlayers( 'video/h264' );
649 - var h264streams = this.embedPlayer.mediaElement.getSources( 'video/h264' );
650 - if( supportingPlayers.length && h264streams.length ){
651 - // No firefox link if a h.264 stream is present
652 - return false;
653 - }
654 -
655 - // Should issue the native warning
656 - return true;
657 - },
658 -
659 - /**
660 - * Does a native warning check binding to the player on mouse over.
661 - */
662 - doNativeWarning: function( ) {
663 - // Set up local pointer to the embedPlayer
664 - var embedPlayer = this.embedPlayer;
665 - var _this = this;
666 -
667 - $j( embedPlayer ).hover(
668 - function() {
669 - if ( $j( '#gnp_' + embedPlayer.id ).length == 0 ) {
670 - var toppos = ( embedPlayer.instanceOf == 'mvPlayList' ) ? 25 : 10;
671 -
672 - $j( this ).append(
673 - $j('<div />')
674 - .attr( {
675 - 'id': "gnp_" + embedPlayer.id
676 - } )
677 - .addClass( 'ui-state-highlight ui-corner-all' )
678 - .css({
679 - 'position' : 'absolute',
680 - 'display' : 'none',
681 - 'background' : '#FFF',
682 - 'color' : '#111',
683 - 'top' : toppos + 'px',
684 - 'left' : '10px',
685 - 'right' : '10px'
686 - })
687 - .html( gM( 'mwe-for_best_experience' ) )
688 - )
689 -
690 - $target_warning = $j( '#gnp_' + embedPlayer.id );
691 -
692 - $target_warning.append(
693 - $j('<br />')
694 - );
695 -
696 -
697 - $target_warning.append(
698 - $j( '<input />' )
699 - .attr({
700 - 'id' : 'ffwarn_' + embedPlayer.id,
701 - 'type' : "checkbox",
702 - 'name' : 'ffwarn_' + embedPlayer.id
703 - })
704 - .click( function() {
705 - if ( $j( this ).is( ':checked' ) ) {
706 - // Set up a cookie for 7 days:
707 - $j.cookie( 'show_player_warning', false, { expires: 7 } );
708 - // Set the current instance
709 - mw.setConfig( 'show_player_warning', false );
710 - $j( '#gnp_' + embedPlayer.id ).fadeOut( 'slow' );
711 - } else {
712 - mw.setConfig( 'show_player_warning', true );
713 - $j.cookie( 'show_player_warning', true );
714 - }
715 - } )
716 - );
717 - $target_warning.append(
718 - $j('<span />')
719 - .text( gM( 'mwe-do_not_warn_again' ) )
720 - )
721 - }
722 -
723 - // Only show the warning if cookie and config are true
724 - if ( mw.getConfig( 'show_player_warning' ) === true ){
725 - $j( '#gnp_' + embedPlayer.id ).fadeIn( 'slow' );
726 - }
727 - },
728 - function() {
729 - $j( '#gnp_' + embedPlayer.id ).fadeOut( 'slow' );
730 - }
731 - );
732 - },
733 -
734 - /**
735 - * Binds the volume controls
736 - */
737 - doVolumeBinding: function( ) {
738 - var embedPlayer = this.embedPlayer;
739 - var _this = this;
740 - embedPlayer.$interface.find( '.volume_control' ).unbind().buttonHover().click( function() {
741 - mw.log( 'Volume control toggle' );
742 - embedPlayer.toggleMute();
743 - } );
744 -
745 - // Add vertical volume display hover
746 - if ( this.volume_layout == 'vertical' ) {
747 - // Default volume binding:
748 - var hoverOverDelay = false;
749 - var $targetvol = embedPlayer.$interface.find( '.vol_container' );
750 - embedPlayer.$interface.find( '.volume_control' ).hover(
751 - function() {
752 - $targetvol.addClass( 'vol_container_top' );
753 - // Set to "below" if playing and embedType != native
754 - if ( embedPlayer && embedPlayer.isPlaying && embedPlayer.isPlaying() && !embedPlayer.supports['overlays'] ) {
755 - $targetvol.removeClass( 'vol_container_top' ).addClass( 'vol_container_below' );
756 - }
757 - $targetvol.fadeIn( 'fast' );
758 - hoverOverDelay = true;
759 - },
760 - function() {
761 - hoverOverDelay = false;
762 - setTimeout( function() {
763 - if ( !hoverOverDelay ) {
764 - $targetvol.fadeOut( 'fast' );
765 - }
766 - }, 500 );
767 - }
768 - );
769 - }
770 -
771 - // Setup play-head slider:
772 - var sliderConf = {
773 - range: "min",
774 - value: 80,
775 - min: 0,
776 - max: 100,
777 - slide: function( event, ui ) {
778 - var perc = ui.value / 100;
779 - // mw.log('update volume:' + perc);
780 - embedPlayer.updateVolumen( perc );
781 - },
782 - change:function( event, ui ) {
783 - var perc = ui.value / 100;
784 - if ( perc == 0 ) {
785 - embedPlayer.$interface.find( '.volume_control span' ).removeClass( 'ui-icon-volume-on' ).addClass( 'ui-icon-volume-off' );
786 - } else {
787 - embedPlayer.$interface.find( '.volume_control span' ).removeClass( 'ui-icon-volume-off' ).addClass( 'ui-icon-volume-on' );
788 - }
789 - var perc = ui.value / 100;
790 - embedPlayer.updateVolumen( perc );
791 - }
792 - }
793 -
794 - if ( this.volume_layout == 'vertical' ) {
795 - sliderConf[ 'orientation' ] = "vertical";
796 - }
797 -
798 - embedPlayer.$interface.find( '.volume-slider' ).slider( sliderConf );
799 - },
800 -
801 - /**
802 - * Get the options menu ul with li menu items
803 - */
804 - getOptionsMenu: function( ) {
805 - $optionsMenu = $j( '<ul />' );
806 - for( var i in this.optionMenuItems ){
807 -
808 - // Make sure its supported in the current ctrlBuilder config:
809 - if( ! this.supportedMenuItems[ i ] ) {
810 - continue;
811 - }
812 - $optionsMenu.append(
813 - this.optionMenuItems[i]( this )
814 - );
815 - }
816 - return $optionsMenu;
817 - },
818 -
819 - /**
820 - * Allow the ctrlBuilder to do interface actions onDone
821 - */
822 - onClipDone: function(){
823 - // Related videos could be shown here
824 - },
825 -
826 - /**
827 - * Option menu items
828 - *
829 - * @return
830 - * 'li' a li line item with click action for that menu item
831 - */
832 - optionMenuItems: {
833 - // Player select menu item
834 - 'playerSelect': function( ctrlObj ){
835 - return $j.getLineItem(
836 - gM( 'mwe-chose_player' ),
837 - 'gear',
838 - function( ) {
839 - ctrlObj.displayOverlay(
840 - ctrlObj.getPlayerSelect()
841 - );
842 - }
843 - )
844 - },
845 -
846 - // Download the file menu
847 - 'download': function( ctrlObj ) {
848 - return $j.getLineItem(
849 - gM( 'mwe-download' ),
850 - 'disk',
851 - function( ) {
852 - ctrlObj.displayOverlay( gM('mwe-loading_txt' ) );
853 - // Call show download with the target to be populated
854 - ctrlObj.showDownload(
855 - ctrlObj.embedPlayer.$interface.find( '.overlay-content' )
856 - );
857 - }
858 - )
859 - },
860 -
861 - // Share the video menu
862 - 'share': function( ctrlObj ) {
863 - return $j.getLineItem(
864 - gM( 'mwe-share' ),
865 - 'mail-closed',
866 - function( ) {
867 - ctrlObj.displayOverlay(
868 - ctrlObj.getShare()
869 - );
870 - }
871 - )
872 - }
873 - },
874 -
875 - /**
876 - * Close a menu overlay
877 - */
878 - closeMenuOverlay: function(){
879 - var _this = this;
880 - var embedPlayer = this.embedPlayer;
881 - var $overlay = embedPlayer.$interface.find( '.overlay-win,.ui-widget-overlay,.ui-widget-shadow' );
882 -
883 - $overlay.fadeOut( "slow", function() {
884 - $overlay.remove();
885 - } );
886 - // Show the big play button:
887 - embedPlayer.$interface.find( '.play-btn-large' ).fadeIn( 'slow' );
888 - return false; // onclick action return false
889 - },
890 -
891 - /**
892 - * Generic function to display custom HTML overlay
893 - * on video.
894 - *
895 - * @param {String} overlayContent content to be displayed
896 - */
897 - displayOverlay: function( overlayContent ) {
898 - var _this = this;
899 - var embedPlayer = this.embedPlayer;
900 -
901 - if ( !this.supportedComponets[ 'overlays' ] ) {
902 - embedPlayer.stop();
903 - }
904 - // Hide the big play button:
905 - embedPlayer.$interface.find( '.play-btn-large' ).hide();
906 -
907 - // Check if overlay window is already present:
908 - if ( embedPlayer.$interface.find( '.overlay-win' ).length != 0 ) {
909 - //Update the content
910 - embedPlayer.$interface.find( '.overlay-content' ).html(
911 - overlayContent
912 - );
913 - return ;
914 - }
915 -
916 - // Add an overlay
917 - embedPlayer.$interface.append(
918 - $j('<div />')
919 - .addClass( 'ui-widget-overlay' )
920 - .css( {
921 - 'height' : '100%',
922 - 'width' : '100%',
923 - 'z-index' : 2
924 - } )
925 - );
926 -
927 - // Setup the close button
928 - $closeButton = $j('<span />')
929 - .addClass( 'ui-icon ui-icon-closethick' )
930 - .css({
931 - 'position': 'absolute',
932 - 'cursor' : 'pointer',
933 - 'top' : '2px',
934 - 'right' : '2px'
935 - })
936 - .buttonHover()
937 - .click( function() {
938 - _this.closeMenuOverlay();
939 - } );
940 -
941 - var overlayMenuCss = {
942 - 'height' : 200,
943 - 'width' : 250,
944 - 'position' : 'absolute',
945 - 'left' : '10px',
946 - 'top': '15px',
947 - 'overflow' : 'auto',
948 - 'padding' : '4px',
949 - 'z-index' : 3
950 - };
951 - $overlayMenu = $j('<div />')
952 - .addClass( 'overlay-win ui-state-default ui-widget-header ui-corner-all' )
953 - .css( overlayMenuCss )
954 - .append(
955 - $closeButton,
956 - $j('<div />')
957 - .addClass( 'overlay-content' )
958 - .append( overlayContent )
959 - )
960 -
961 - // Clone the overlay menu css:
962 - var shadowCss = jQuery.extend( true, {}, overlayMenuCss );
963 - shadowCss['height' ] = 210;
964 - shadowCss['width' ] = 260;
965 - shadowCss[ 'z-index' ] = 2;
966 - $overlayShadow = $j( '<div />' )
967 - .addClass('ui-widget-shadow ui-corner-all')
968 - .css( shadowCss );
969 -
970 - // Append the overlay menu to the player interface
971 - embedPlayer.$interface.prepend(
972 - $overlayMenu,
973 - $overlayShadow
974 - )
975 - .find( '.overlay-win' )
976 - .fadeIn( "slow" );
977 -
978 - return false; // onclick action return false
979 - },
980 -
981 - /**
982 - * Get the "share" interface
983 - *
984 - * TODO share should be enabled via <embed> tag usage to be compatible
985 - * with sites social networking sites that allow <embed> tags but not js
986 - *
987 - * @param {Object} $target Target jQuery object to set share html
988 - */
989 - getShare: function( ) {
990 - var embedPlayer = this.embedPlayer;
991 - var embed_code = embedPlayer.getEmbeddingHTML();
992 - var _this = this;
993 -
994 - var $shareInterface = $j('<div />');
995 -
996 - $shareList = $j( '<ul />' );
997 -
998 - $shareList
999 - .append(
1000 - $j('<li />')
1001 - .append(
1002 - $j('<a />')
1003 - .attr('href', '#')
1004 - .addClass( 'active' )
1005 - .text(
1006 - gM( 'mwe-embed_site_or_blog' )
1007 - )
1008 - )
1009 - )
1010 -
1011 - $shareInterface.append(
1012 - $j( '<h2 />' )
1013 - .text( gM( 'mwe-share_this_video' ) )
1014 - .append(
1015 - $shareList
1016 - )
1017 - );
1018 -
1019 - $shareInterface.append(
1020 -
1021 - $j('<span />')
1022 - .addClass( 'source_wrap' )
1023 - .html(
1024 - $j( '<textarea />' )
1025 - .html( embed_code )
1026 - .click( function() {
1027 - $j( this ).select();
1028 - })
1029 - ),
1030 -
1031 - $j('<br />'),
1032 - $j('<br />'),
1033 -
1034 - $j('<button />')
1035 - .addClass( 'ui-state-default ui-corner-all copycode' )
1036 - .text( gM( 'mwe-copy-code' ) )
1037 - .click(function() {
1038 - $target.find( 'textarea' ).focus().select();
1039 - // Copy the text if supported:
1040 - if ( document.selection ) {
1041 - CopiedTxt = document.selection.createRange();
1042 - CopiedTxt.execCommand( "Copy" );
1043 - }
1044 - } )
1045 -
1046 - );
1047 - return $shareInterface;
1048 - },
1049 -
1050 - /**
1051 - * Shows the Player Select interface
1052 - *
1053 - * @param {Object} $target jQuery target for output
1054 - */
1055 - getPlayerSelect: function( ) {
1056 - mw.log('getPlayerSelect::');
1057 -
1058 - var embedPlayer = this.embedPlayer;
1059 -
1060 - var _this = this;
1061 -
1062 - $playerSelect = $j('<div />')
1063 - .append(
1064 - $j( '<h2 />' )
1065 - .text( gM( 'mwe-chose_player' ) )
1066 - );
1067 -
1068 - $j.each( embedPlayer.mediaElement.getPlayableSources(), function( source_id, source ) {
1069 - var playable = mw.EmbedTypes.players.defaultPlayer( source.getMIMEType() );
1070 -
1071 - var is_selected = ( source == embedPlayer.mediaElement.selected_source );
1072 -
1073 - $playerSelect.append(
1074 - $j( '<h2 />' )
1075 - .text( source.getTitle() )
1076 - );
1077 -
1078 - if ( playable ) {
1079 - $playerList = $j('<ul />');
1080 - // output the player select code:
1081 - var supportingPlayers = mw.EmbedTypes.players.getMIMETypePlayers( source.getMIMEType() );
1082 -
1083 - for ( var i = 0; i < supportingPlayers.length ; i++ ) {
1084 -
1085 - // Add link to select the player if not already selected )
1086 - if( embedPlayer.selected_player.id == supportingPlayers[i].id && is_selected ) {
1087 - // Active player ( no link )
1088 - $playerLine = $j( '<span />' )
1089 - .text(
1090 - supportingPlayers[i].getName()
1091 - )
1092 - .addClass( 'ui-state-highlight ui-corner-all' );
1093 - } else {
1094 - // Non active player add link to select:
1095 - $playerLine = $j( '<a />')
1096 - .attr({
1097 - 'href' : '#',
1098 - 'rel' : 'sel_source',
1099 - 'id' : 'sc_' + source_id + '_' + supportingPlayers[i].id
1100 - })
1101 - .addClass( 'ui-corner-all')
1102 - .text( supportingPlayers[i].getName() )
1103 - .click( function() {
1104 - var iparts = $j( this ).attr( 'id' ).replace(/sc_/ , '' ).split( '_' );
1105 - var source_id = iparts[0];
1106 - var default_player_id = iparts[1];
1107 - mw.log( 'source id: ' + source_id + ' player id: ' + default_player_id );
1108 -
1109 - embedPlayer.ctrlBuilder.closeMenuOverlay();
1110 -
1111 - // Close fullscreen if we are in fullscreen mode
1112 - if( _this.fullscreenMode ){
1113 - _this.restoreWindowPlayer()
1114 - }
1115 -
1116 - embedPlayer.mediaElement.selectSource( source_id );
1117 -
1118 - mw.EmbedTypes.players.setPlayerPreference(
1119 - default_player_id,
1120 - embedPlayer.mediaElement.sources[ source_id ].getMIMEType()
1121 - );
1122 -
1123 - // Issue a stop
1124 - embedPlayer.stop();
1125 -
1126 - // Don't follow the # link:
1127 - return false;
1128 - } )
1129 - .hover(
1130 - function(){
1131 - $j( this ).addClass('ui-state-active')
1132 - },
1133 - function(){
1134 - $j( this ).removeClass('ui-state-active')
1135 - }
1136 - );
1137 - }
1138 -
1139 - // Add the player line to the player list:
1140 - $playerList.append(
1141 - $j( '<li />' ).append(
1142 - $playerLine
1143 - )
1144 - );
1145 - }
1146 -
1147 - // Append the player list:
1148 - $playerSelect.append( $playerList );
1149 -
1150 - } else {
1151 - // No player available:
1152 - $playerSelect.append( gM( 'mwe-no-player', source.getTitle() ) )
1153 - }
1154 - } );
1155 -
1156 - // Return the player select elements
1157 - return $playerSelect;
1158 - },
1159 -
1160 - /**
1161 - * Loads sources and calls showDownloadWithSources
1162 - * @param {Object} $target jQuery target to output to
1163 - */
1164 - showDownload: function( $target ) {
1165 - var _this = this;
1166 - var embedPlayer = this.embedPlayer;
1167 - // Load the roe if available (to populate out download options:
1168 - // mw.log('f:showDownload '+ this.roe + ' ' + this.mediaElement.addedROEData);
1169 - if ( embedPlayer.roe && embedPlayer.mediaElement.addedROEData == false ) {
1170 - $target.html( gM( 'mwe-loading_txt' ) );
1171 - embedPlayer.getMvJsonUrl( this.roe, function( data ) {
1172 - embedPlayer.mediaElement.addROE( data );
1173 - _this.showDownloadWithSources( $target );
1174 - } );
1175 - } else {
1176 - _this.showDownloadWithSources( $target );
1177 - }
1178 - },
1179 -
1180 - /**
1181 - * Shows the download interface with sources loaded
1182 - * @param {Object} $target jQuery target to output to
1183 - */
1184 - showDownloadWithSources : function( $target ) {
1185 - var _this = this;
1186 - mw.log( 'showDownloadWithSources::' + $target.length );
1187 - var embedPlayer = this.embedPlayer;
1188 - // Empty the target:
1189 - $target.empty();
1190 -
1191 - var $mediaList = $j( '<ul />' );
1192 - var $textList = $j( '<ul />' );
1193 - $j.each( embedPlayer.mediaElement.getSources(), function( index, source ) {
1194 - if( source.getSrc() ) {
1195 - mw.log("add src: " + source.getTitle() );
1196 - var $dl_line = $j( '<li />').append(
1197 - $j('<a />')
1198 - .attr( 'href', source.getSrc() )
1199 - .text( source.getTitle() )
1200 - );
1201 - // Add link to correct "bucket"
1202 -
1203 - //Add link to time segment:
1204 - if ( source.getSrc().indexOf( '?t=' ) !== -1 ) {
1205 - $target.append( $dl_line );
1206 - } else if ( this.getMIMEType() == "text/cmml" || this.getMIMEType() == "text/x-srt" ) {
1207 - // Add link to text list
1208 - $textList.append( $dl_line );
1209 - } else {
1210 - // Add link to media list
1211 - $mediaList.append( $dl_line );
1212 - }
1213 -
1214 - }
1215 - } );
1216 - if( $mediaList.find('li').length != 0 ) {
1217 - $target.append(
1218 - $j('<h2 />')
1219 - .text( gM( 'mwe-download_full' ) ),
1220 - $mediaList
1221 - )
1222 - }
1223 -
1224 - if( $textList.find('li').length != 0 ) {
1225 - $target.append(
1226 - $j('<h2 />')
1227 - .text( gM( 'mwe-download_text' ) ),
1228 - $textList
1229 - )
1230 - }
1231 - },
1232 -
1233 -
1234 - /**
1235 - * Get component
1236 - *
1237 - * @param {String} component_id Component key to grab html output
1238 - */
1239 - getComponent: function( component_id ) {
1240 - if ( this.components[ component_id ] ) {
1241 - return this.components[ component_id ].o( this );
1242 - } else {
1243 - return false;
1244 - }
1245 - },
1246 -
1247 - /**
1248 - * Get a component height
1249 - *
1250 - * @param {String} component_id Component key to grab height
1251 - * @return height or false if not set
1252 - */
1253 - getComponentHeight: function( component_id ) {
1254 - if ( this.components[ component_id ]
1255 - && this.components[ component_id ].h )
1256 - {
1257 - return this.components[ component_id ].h
1258 - }
1259 - return false;
1260 - },
1261 -
1262 - /**
1263 - * Get a component width
1264 - * @param {String} component_id Component key to grab width
1265 - * @return width or false if not set
1266 - */
1267 - getComponentWidth: function( component_id ){
1268 - if ( this.components[ component_id ]
1269 - && this.components[ component_id ].w )
1270 - {
1271 - return this.components[ component_id ].w
1272 - }
1273 - return false;
1274 - },
1275 -
1276 - /**
1277 - * Components Object
1278 - * Take in the embedPlayer and return some html for the given component.
1279 - *
1280 - * components can be overwritten by skin javascript
1281 - *
1282 - * Component JSON structure is as follows:
1283 - * 'o' Function to return a binded jQuery object ( accepts the ctrlObject as a parameter )
1284 - * 'w' The width of the component
1285 - * 'h' The height of the component ( if height is undefined the height of the control bar is used )
1286 - */
1287 - components: {
1288 - /**
1289 - * The large play button in center of the player
1290 - */
1291 - 'playButtonLarge': {
1292 - 'w' : 130,
1293 - 'h' : 96,
1294 - 'o' : function( ctrlObj ) {
1295 -
1296 - return $j( '<div/>' )
1297 - .attr( {
1298 - 'title' : gM( 'mwe-play_clip' ),
1299 - 'class' : "ui-state-default play-btn-large"
1300 - } )
1301 - // Get dynamic position for big play button
1302 - .css( {
1303 - 'left' : ( ( ctrlObj.embedPlayer.getPlayerWidth() - this.w ) / 2 ),
1304 - 'top' : ( ( ctrlObj.embedPlayer.getPlayerHeight() - this.h ) / 2 )
1305 - } )
1306 - // Add play hook:
1307 - .buttonHover().click( function() {
1308 - ctrlObj.embedPlayer.play();
1309 - } );
1310 - }
1311 - },
1312 -
1313 - /**
1314 - * The kaltura attribution button
1315 - */
1316 - 'kalturaAttribution' : {
1317 - 'w' : 28,
1318 - 'o' : function( ctrlObj ){
1319 - return $j('<a />')
1320 - .attr({
1321 - 'href': 'http://kaltura.com',
1322 - 'title' : gM( 'mwe-kaltura-platform-title' ),
1323 - 'target' : '_new'
1324 - })
1325 - .append(
1326 - $j( '<div />' )
1327 - .addClass( 'rButton' )
1328 - .css({
1329 - 'top' : '9px',
1330 - 'left' : '2px'
1331 - })
1332 - .append(
1333 - $j('<span />')
1334 - .addClass( 'ui-icon kaltura-icon' )
1335 - )
1336 - )
1337 - }
1338 - },
1339 -
1340 - /**
1341 - * The options button, invokes display of the options menu
1342 - */
1343 - 'options': {
1344 - 'w': 28,
1345 - 'o': function( ctrlObj ) {
1346 - return $j( '<div />' )
1347 - .attr( 'title', gM( 'mwe-player_options' ) )
1348 - .addClass( 'ui-state-default ui-corner-all ui-icon_link rButton options-btn' )
1349 - .append(
1350 - $j('<span />')
1351 - .addClass( 'ui-icon ui-icon-wrench' )
1352 - )
1353 - .buttonHover()
1354 - // Options binding:
1355 - .menu( {
1356 - 'content' : ctrlObj.getOptionsMenu(),
1357 - 'zindex' : mw.getConfig( 'fullScreenIndex' ) + 1,
1358 - 'positionOpts': {
1359 - 'directionV' : 'up',
1360 - 'offsetY' : 30,
1361 - 'directionH' : 'left',
1362 - 'offsetX' : -28
1363 - }
1364 - } );
1365 - }
1366 - },
1367 -
1368 - /**
1369 - * The fullscreen button for displaying the video fullscreen
1370 - */
1371 - 'fullscreen': {
1372 - 'w': 28,
1373 - 'o': function( ctrlObj ) {
1374 -
1375 - // Setup "dobuleclick" fullscreen binding to embedPlayer
1376 - $j( ctrlObj.embedPlayer ).unbind("dblclick").bind("dblclick", function(){
1377 - ctrlObj.embedPlayer.fullscreen();
1378 - });
1379 -
1380 - return $j( '<div />' )
1381 - .attr( 'title', gM( 'mwe-player_fullscreen' ) )
1382 - .addClass( "ui-state-default ui-corner-all ui-icon_link rButton fullscreen-btn" )
1383 - .append(
1384 - $j( '<span />' )
1385 - .addClass( "ui-icon ui-icon-arrow-4-diag" )
1386 - )
1387 - // Fullscreen binding:
1388 - .buttonHover().click( function() {
1389 - ctrlObj.embedPlayer.fullscreen();
1390 - } );
1391 - }
1392 - },
1393 -
1394 -
1395 - /**
1396 - * The pause / play button
1397 - */
1398 - 'pause': {
1399 - 'w': 28,
1400 - 'o': function( ctrlObj ) {
1401 - return $j( '<div />' )
1402 - .attr( 'title', gM( 'mwe-play_clip' ) )
1403 - .addClass ( "ui-state-default ui-corner-all ui-icon_link lButton play-btn" )
1404 - .append(
1405 - $j( '<span />' )
1406 - .addClass( "ui-icon ui-icon-play" )
1407 - )
1408 - // Play / pause binding
1409 - .buttonHover()
1410 - .click( function() {
1411 - ctrlObj.embedPlayer.play();
1412 - });
1413 - }
1414 - },
1415 -
1416 - /**
1417 - * The closed captions button
1418 - */
1419 - 'timedText': {
1420 - 'w': 28,
1421 - 'o': function( ctrlObj ) {
1422 - return $j( '<div />' )
1423 - .attr( 'title', gM( 'mwe-timed_text' ) )
1424 - .addClass( "ui-state-default ui-corner-all ui-icon_link rButton timed-text" )
1425 - .append(
1426 - $j( '<span />' )
1427 - .addClass( "ui-icon ui-icon-comment" )
1428 - )
1429 - // Captions binding:
1430 - .buttonHover()
1431 - .click( function() {
1432 - ctrlObj.embedPlayer.showTextInterface();
1433 - } )
1434 - }
1435 - },
1436 -
1437 - /**
1438 - * The volume control interface html
1439 - */
1440 - 'volumeControl': {
1441 - 'w' : 28,
1442 - 'o' : function( ctrlObj ) {
1443 - mw.log(' set up volume out');
1444 - $volumeOut = $j( '<span />' );
1445 - if ( ctrlObj.volume_layout == 'horizontal' ) {
1446 - $volumeOut.append(
1447 - $j( '<div />' )
1448 - .addClass( "ui-slider ui-slider-horizontal rButton volume-slider" )
1449 - );
1450 - }
1451 - mw.log(' add up volume control icon');
1452 - // Add the volume control icon
1453 - $volumeOut.append(
1454 - $j('<div />')
1455 - .attr( 'title', gM( 'mwe-volume_control' ) )
1456 - .addClass( "ui-state-default ui-corner-all ui-icon_link rButton volume_control" )
1457 - .append(
1458 - $j( '<span />' )
1459 - .addClass( "ui-icon ui-icon-volume-on" )
1460 - )
1461 - );
1462 - mw.log(' if verticle add container ');
1463 - if ( ctrlObj.volume_layout == 'vertical' ) {
1464 - $volumeOut.find('.volume_control').append(
1465 - $j( '<div />' )
1466 - .css( {
1467 - 'position' : 'absolute',
1468 - 'left' : '0px'
1469 - })
1470 - .hide()
1471 - .addClass( "vol_container ui-corner-all" )
1472 - .append(
1473 - $j( '<div />' )
1474 - .addClass ( "volume-slider" )
1475 - )
1476 - );
1477 - }
1478 - mw.log('get inner volume html');
1479 - //Return the inner html
1480 - return $volumeOut.html();
1481 - }
1482 - },
1483 -
1484 - /*
1485 - * The time display area
1486 - */
1487 - 'timeDisplay': {
1488 - 'w' : 100,
1489 - 'o' : function( ctrlObj ) {
1490 - return $j( '<div />' )
1491 - .addClass( "ui-widget time-disp" )
1492 - .append(
1493 - ctrlObj.embedPlayer.getTimeRange()
1494 - )
1495 -
1496 - }
1497 - },
1498 -
1499 - /**
1500 - * The playhead component
1501 - */
1502 - 'playHead': {
1503 - 'w':0, // special case (takes up remaining space)
1504 - 'o':function( ctrlObj ) {
1505 - var embedPlayer = ctrlObj.embedPlayer;
1506 - var _this = this;
1507 - var $playHead = $j( '<div />' )
1508 - .addClass ( "play_head" )
1509 - .css({
1510 - "position" : 'absolute',
1511 - "left" : '33px',
1512 - "right" : ( ( embedPlayer.getPlayerWidth() - ctrlObj.available_width ) - 33) + 'px'
1513 - })
1514 - // Playhead binding
1515 - .slider( {
1516 - range: "min",
1517 - value: 0,
1518 - min: 0,
1519 - max: 1000,
1520 - start: function( event, ui ) {
1521 - var id = ( embedPlayer.pc != null ) ? embedPlayer.pc.pp.id:embedPlayer.id;
1522 - embedPlayer.userSlide = true;
1523 - $j( id + ' .play-btn-large' ).fadeOut( 'fast' );
1524 - // If playlist always start at 0
1525 - embedPlayer.start_time_sec = ( embedPlayer.instanceOf == 'mvPlayList' ) ? 0:
1526 - mw.npt2seconds( embedPlayer.getTimeRange().split( '/' )[0] );
1527 - },
1528 - slide: function( event, ui ) {
1529 - var perc = ui.value / 1000;
1530 - embedPlayer.jump_time = mw.seconds2npt( parseFloat( parseFloat( embedPlayer.getDuration() ) * perc ) + embedPlayer.start_time_sec );
1531 - // mw.log('perc:' + perc + ' * ' + embedPlayer.getDuration() + ' jt:'+ this.jump_time);
1532 - if ( _this.longTimeDisp ) {
1533 - embedPlayer.setStatus( gM( 'mwe-seek_to', embedPlayer.jump_time ) );
1534 - } else {
1535 - embedPlayer.setStatus( embedPlayer.jump_time );
1536 - }
1537 - // Update the thumbnail / frame
1538 - if ( embedPlayer.isPlaying == false ) {
1539 - embedPlayer.updateThumbPerc( perc );
1540 - }
1541 - },
1542 - change:function( event, ui ) {
1543 - // Only run the onChange event if done by a user slide
1544 - // (otherwise it runs times it should not)
1545 - if ( embedPlayer.userSlide ) {
1546 - embedPlayer.userSlide = false;
1547 - embedPlayer.seeking = true;
1548 -
1549 - var perc = ui.value / 1000;
1550 - // set seek time (in case we have to do a url seek)
1551 - embedPlayer.seek_time_sec = mw.npt2seconds( embedPlayer.jump_time, true );
1552 - mw.log( 'do jump to: ' + embedPlayer.jump_time + ' perc:' + perc + ' sts:' + embedPlayer.seek_time_sec );
1553 - embedPlayer.setStatus( gM( 'mwe-seeking' ) );
1554 - embedPlayer.doSeek( perc );
1555 - }
1556 - }
1557 - } );
1558 -
1559 - // Up the z-index of the default status indicator:
1560 - $playHead.find( 'ui-slider-handle' ).css( 'z-index', 4 );
1561 - $playHead.find( '.ui-slider-range' ).addClass( 'ui-corner-all' ).css( 'z-index', 2 );
1562 -
1563 - // Add buffer html:
1564 - $playHead.append(
1565 - $j('<div />')
1566 - .addClass( "ui-slider-range ui-slider-range-min ui-widget-header")
1567 - .addClass( "ui-state-highlight ui-corner-all mw_buffer")
1568 - );
1569 -
1570 - return $playHead;
1571 - }
1572 - }
1573 - }
1574 -};
Index: branches/js2-work/phase3/js/mwEmbed/modules/ClipEdit/loader.js
@@ -5,13 +5,8 @@
66 mw.addClassFilePaths( {
77 "mw.ClipEdit" : "modules/ClipEdit/mw.ClipEdit.js",
88 "$j.fn.ColorPicker" : "modules/ClipEdit/colorpicker/js/colorpicker.js",
9 - "$j.Jcrop" : "modules/ClipEdit/Jcrop/js/jquery.Jcrop.js"
10 -} );
11 -
12 -/*
13 -* Adds style sheets to be loaded with particular classes
14 -*/
15 -mw.addClassStyleSheets( {
16 - "$j.Jcrop" : "modules/ClipEdit/Jcrop/css/jquery.Jcrop.css",
17 - "$j.fn.ColorPicker" : "modules/ClipEdit/colorpicker/css/colorpicker.css"
 9+ "mw.style.colorpicker" : "modules/ClipEdit/colorpicker/css/colorpicker.css",
 10+
 11+ "$j.Jcrop" : "modules/ClipEdit/Jcrop/js/jquery.Jcrop.js",
 12+ "mw.style.Jcrop" : "modules/ClipEdit/Jcrop/css/jquery.Jcrop.css"
1813 } );
\ No newline at end of file
Index: branches/js2-work/phase3/js/mwEmbed/modules/ClipEdit/mw.ClipEdit.js
@@ -967,7 +967,8 @@
968968 $j( '.mw_crop_msg_load' ).show();
969969 // load the jcrop library if needed:
970970 mw.load( [
971 - '$j.Jcrop'
 971+ '$j.Jcrop',
 972+ 'mw.style.Jcrop'
972973 ], function() {
973974 _this.bindCrop();
974975 } );
Index: branches/js2-work/phase3/js/mwEmbed/modules/UploadWizard/loader.js
@@ -13,6 +13,8 @@
1414 mw.addClassFilePaths( {
1515 "mw.Language" : "modules/UploadWizard/mw.Language.js",
1616 "mw.UploadWizard" : "modules/UploadWizard/mw.UploadWizard.js",
 17+ "mw.style.uploadWizard" : "modules/UploadWizard/css/uploadWizard.css",
 18+
1719 "mw.UploadApiProcessor" : "modules/UploadWizard/mw.UploadApiProcessor.js",
1820 "mw.IframeTransport" : "modules/UploadWizard/mw.IframeTransport.js",
1921 "mw.ApiUploadHandler" : "modules/UploadWizard/mw.ApiUploadHandler.js",
@@ -21,11 +23,6 @@
2224 "mw.MockUploadHandler" : "modules/UploadWizard/mw.MockUploadHandler.js"
2325
2426 });
25 -
26 - mw.addClassStyleSheets( {
27 - 'mw.UploadWizard' : 'modules/UploadWizard/css/uploadWizard.css',
28 - '$j.fn.autocomplete' : 'jquery/plugins/jquery.autocomplete.css'
29 - } );
3027
3128 //Set a variable for the base upload interface for easy inclution
3229 //
@@ -57,13 +54,15 @@
5855 '$j.effects.core',
5956 '$j.effects.slide',
6057 '$j.fn.autocomplete',
 58+ 'mw.style.autocomplete'
6159 ],
6260 [
6361 'mw.Language',
6462 'mw.IframeTransport',
6563 'mw.ApiUploadHandler',
6664 'mw.DestinationChecker',
67 - 'mw.UploadWizard'
 65+ 'mw.UploadWizard',
 66+ 'mw.style.uploadWizard'
6867 ],
6968 ];
7069
Index: branches/js2-work/phase3/js/mwEmbed/modules/TimedText/loader.js
@@ -9,11 +9,13 @@
1010 "RemoteMwTimedText" : "modules/TimedText/remotes/RemoteMwTimedText.js"
1111 });
1212
13 -//Add css dependency:
14 -mw.addClassStyleSheets( {
 13+/*
 14+Add css dependency:
 15+mw.addClassStyleSheetDependency( {
1516 "$j.fn.menu" : "modules/TimedText/jquery.menu/jquery.menu.css",
1617 "mw.TimedTextEdit": "modules/TimedText/mw.TimedTextEdit.css"
1718 });
 19+*/
1820
1921 // TimedText module
2022 mw.addModuleLoader( 'TimedText', function( callback ) {
Index: branches/js2-work/phase3/js/mwEmbed/modules/AddMedia/loader.js
@@ -51,10 +51,12 @@
5252 //Setup the addMediaWizard module
5353 mw.addModuleLoader( 'AddMedia.addMediaWizard', function( callback ) {
5454 // Load all the required libs:
 55+
5556 var request = [
5657 [ 'mw.RemoteSearchDriver',
5758 '$j.cookie',
5859 '$j.fn.textSelection',
 60+ '$j.browserTest', // ( textSelection uses browserTest )
5961 '$j.ui'
6062 ], [
6163 '$j.ui.resizable',
Index: branches/js2-work/phase3/js/mwEmbed/modules/AddMedia/mw.RemoteSearchDriver.js
@@ -2216,6 +2216,16 @@
22172217 // (but archive.org has another query for more media meta)
22182218 resource.pSobj.addResourceInfoCallback( resource, function() {
22192219 var runFlag = false;
 2220+
 2221+ // Embed the video html
 2222+ var embedHtml = resource.pSobj.getEmbedHTML( resource,
 2223+ {
 2224+ 'id' : 'embed_vid'
 2225+ }
 2226+ );
 2227+ mw.log( 'append html: ' + embedHtml );
 2228+ $j( '#clip_edit_disp' ).html( embedHtml );
 2229+
22202230 // Make sure we have the 'EmbedPlayer' module:
22212231 mw.load( 'EmbedPlayer', function() {
22222232 // Strange concurrency issue with callbacks
@@ -2225,14 +2235,7 @@
22262236 } else {
22272237 mw.log( 'Error: embedPlayerCheck run twice' );
22282238 return false;
2229 - }
2230 - var embedHtml = resource.pSobj.getEmbedHTML( resource,
2231 - {
2232 - 'id' : 'embed_vid'
2233 - }
2234 - );
2235 - mw.log( 'append html: ' + embedHtml );
2236 - $j( '#clip_edit_disp' ).html( embedHtml );
 2239+ }
22372240
22382241 mw.log( "about to call $j.embedPlayer::embed_vid" );
22392242
@@ -2874,8 +2877,7 @@
28752878 */
28762879 insertResource: function( resource ) {
28772880 mw.log( 'insertResource: ' + resource.title );
2878 - var _this = this;
2879 -
 2881+ var _this = this;
28802882 // If doing a remote link jump directly to resource output:
28812883 if( this.import_url_mode == 'remote_link' ){
28822884 _this.insertResourceToOutput( resource );
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/mw.EmbedPlayer.js
@@ -360,7 +360,7 @@
361361
362362 // Load any skins we need then swap in the interface
363363 mw.load( skinClassRequest, function() {
364 - // set the wait for meta flag
 364+ // Set the wait for meta flag
365365 var waitForMeta = _this.waitForMetaCheck( element );
366366
367367 switch( element.tagName.toLowerCase() ) {
@@ -428,9 +428,16 @@
429429 && $j( element ).css( 'height' ) == '150px'
430430 ){
431431 waitForMeta = true;
432 - }else{
433 - // Css width height attribute has been set on the element return false
434 - return false;
 432+ } else {
 433+ // Check if we should wait for duration:
 434+ if( $j( element ).get(0).duration ||
 435+ $j( element ).get(0).durationHint
 436+ ){
 437+ // height, width and duration set; do not wait for meta data:
 438+ return false;
 439+ } else {
 440+ waitForMeta = true;
 441+ }
435442 }
436443
437444 //Firefox ~ sometimes ~ gives -1 for unloaded media
@@ -454,12 +461,12 @@
455462 $j(element).find("source[src]").filter('[type^=video],[type^=audio]').length != 0
456463 )
457464 ){
458 - // detect src type ( if no type set )
 465+ // Detect src type ( if no type set )
459466 return true;
460 - }
461 -
462 - // Element is not likely to update its resolution:
463 - return false;
 467+ } else {
 468+ // Element is not likely to update its meta data via video loader
 469+ return false;
 470+ }
464471 },
465472
466473 /**
@@ -869,35 +876,8 @@
870877 init: function( videoElement ) {
871878 var _this = this;
872879 mw.log( 'Initializing mediaElement...' );
873 - this.sources = new Array();
874 -
875 - if ( $j( videoElement ).attr( 'thumbnail' ) ) {
876 - _this.poster = $j( videoElement ).attr( 'thumbnail' );
877 - }
878 -
879 - if ( $j( videoElement ).attr( 'poster' ) ) {
880 - _this.poster = $j( videoElement ).attr( 'poster' );
881 - }
882 -
883 - if ( $j( videoElement ).attr( 'apiTitleKey' ) ) {
884 - _this.apiTitleKey = $j( videoElement ).attr( 'apiTitleKey' );
885 - }
886 -
887 - if ( $j( videoElement ).attr( 'apiProvider' ) ) {
888 - _this.apiProvider = $j( videoElement ).attr( 'apiTitleKey' );
889 - }
890 -
891 - if ( $j( videoElement ).attr( 'durationHint' ) ) {
892 - _this.durationHint = $j( videoElement ).attr( 'durationHint' );
893 - // Convert duration hint if needed:
894 - _this.duration = mw.npt2seconds( _this.durationHint );
895 - }
896 -
897 - // Set by default thumb value if not found
898 - if( ! _this.poster ) {
899 - _this.poster = mw.getConfig( 'images_path' ) + 'vid_default_thumb.jpg' ;
900 - }
901 -
 880+ this.sources = new Array();
 881+
902882 // Process the videoElement as a source element:
903883 if ( $j( videoElement ).attr( "src" ) ) {
904884 _this.tryAddSource( videoElement );
@@ -1274,8 +1254,20 @@
12751255 // string -> bollean
12761256 if( this[attr] == "false" ) this[attr] = false;
12771257 if( this[attr] == "true" ) this[attr] = true;
1278 - }
1279 -
 1258+ }
 1259+
 1260+ // Set the poster:
 1261+ if ( $j( element ).attr( 'thumbnail' ) ) {
 1262+ _this.poster = $j( element ).attr( 'thumbnail' );
 1263+ }
 1264+ if ( $j( element ).attr( 'poster' ) ) {
 1265+ _this.poster = $j( element ).attr( 'poster' );
 1266+ }
 1267+ // Set by default thumb value if not found
 1268+ if( ! _this.poster ) {
 1269+ _this.poster = mw.getConfig( 'images_path' ) + 'vid_default_thumb.jpg' ;
 1270+ }
 1271+
12801272 // Set the skin name from the class
12811273 var sn = $j(element).attr( 'class' );
12821274 if ( sn && sn != '' ) {
@@ -1288,26 +1280,35 @@
12891281
12901282 // Set the default skin if unset:
12911283 if ( !this.skinName ) {
1292 - this.skinName = mw.getConfig( 'skinName' );
 1284+ this.skinName = mw.getConfig( 'playerSkinName' );
12931285 }
12941286
12951287
12961288 // Make sure startOffset is cast as an float:
1297 - if ( this.startOffset && this.startOffset.split( ':' ).length >= 2 )
 1289+ if ( this.startOffset && this.startOffset.split( ':' ).length >= 2 ) {
12981290 this.startOffset = parseFloat( mw.npt2seconds( this.startOffset ) );
 1291+ }
12991292
13001293 // Make sure offset is in float:
13011294 this.startOffset = parseFloat( this.startOffset );
1302 -
1303 - if ( this.duration && this.duration.split( ':' ).length >= 2 )
1304 - this.duration = mw.npt2seconds( this.duration );
1305 -
1306 - // Make sure duration is in float:
 1295+
 1296+ // Set the source duration ( if provided in the element metaData or durationHint )
 1297+ if ( $j( element ).attr( 'duration' ) ) {
 1298+ _this.duration = $j( element ).attr( 'duration' );
 1299+ }
 1300+ if ( !_this.duration && $j( element ).attr( 'durationHint' ) ) {
 1301+ _this.durationHint = $j( videoElement ).attr( 'durationHint' );
 1302+ // Convert duration hint if needed:
 1303+ _this.duration = mw.npt2seconds( _this.durationHint );
 1304+ }
 1305+
 1306+ // Make sure duration is a float:
13071307 this.duration = parseFloat( this.duration );
13081308 mw.log( "duration is: " + this.duration );
13091309
1310 -
1311 - this.setPlayerSize( element );
 1310+ // Set the player size attributes based loaded video element:
 1311+ this.setPlayerSize( element );
 1312+
13121313 // Set the plugin id
13131314 this.pid = 'pid_' + this.id;
13141315
@@ -1332,10 +1333,7 @@
13331334 }
13341335 }
13351336 }
1336 - } );
1337 -
1338 - // Make sure we have the player skin css:
1339 - mw.getStyleSheet( mw.getMwEmbedPath() + 'skins/' + this.skinName + '/EmbedPlayer.css' );
 1337+ } );
13401338 },
13411339
13421340
@@ -1708,22 +1706,9 @@
17091707 },
17101708
17111709 /**
1712 - * Get the duration of the selected source media
 1710+ * Get the duration of the embed player
17131711 */
1714 - getDuration:function() {
1715 - // Update some local pointers for the selected source:
1716 - if ( this.mediaElement && this.mediaElement.selectedSource && this.mediaElement.selectedSource.duration ) {
1717 - this.duration = parseFloat( this.mediaElement.selectedSource.duration );
1718 - this.startOffset = parseFloat( this.mediaElement.selectedSource.startOffset );
1719 - this.start_npt = this.mediaElement.selectedSource.start_npt;
1720 - this.end_npt = this.mediaElement.selectedSource.end_npt;
1721 - }
1722 - // Update start end_npt if duration !=0 (set from plugin)
1723 - if ( !this.start_npt )
1724 - this.start_npt = '0:0:0';
1725 - if ( !this.end_npt && this.duration )
1726 - this.end_npt = mw.seconds2npt( this.duration );
1727 - // Return the duration
 1712+ getDuration: function() {
17281713 return this.duration;
17291714 },
17301715
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/mvpcfConfig.js
@@ -0,0 +1,7 @@
 2+/*
 3+mvpcf skin config
 4+*/
 5+
 6+var mvpcfConfig = {
 7+ playerClass : 'mv-player'
 8+};
\ No newline at end of file
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/mvpcfConfig.js
___________________________________________________________________
Added: svn:mergeinfo
19 Merged /branches/REL1_15/phase3/js2/mwEmbed/skins/mvpcf/mvpcf.js:r51646
210 Merged /branches/sqlite/js2/mwEmbed/skins/mvpcf/mvpcf.js:r58211-58321
Added: svn:eol-style
311 + native
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/EmbedPlayer.css
@@ -0,0 +1,199 @@
 2+/*
 3+ * reference player skin
 4+ */
 5+
 6+/*Video player*/
 7+.mv-player {
 8+ color: #FFF;
 9+ background: #000;
 10+}
 11+
 12+/* large play button: */
 13+.mv-player .play-btn-large {
 14+ width:130px;
 15+ height:96px;
 16+ background: url(images/player_big_play_button.png) !important;
 17+ position:absolute;
 18+ cursor:pointer;
 19+ border:none !important;
 20+ z-index:1;
 21+}/*.ui-state-default */
 22+
 23+
 24+.mv-player a:link {color: #2060c1; text-decoration: underline;}
 25+.mv-player a:visited {color: #2060c1; text-decoration: underline;}
 26+/*a:visited {color: #75a5e4; text-decoration: underline;}*/ /*Not sure if you want this*/
 27+.mv-player a:hover {color: #75a5e4; text-decoration: underline;}
 28+.mv-player img, .mv-player img a, .mv-player img a:hover {border: 0;}
 29+
 30+
 31+.mv-player .video {
 32+ display: block;
 33+ position: relative;
 34+ font-size: 1px;
 35+ height: 305px;
 36+}
 37+.mv-player .control-bar {
 38+ height: 29px;
 39+}
 40+.mv-player .controlInnerSmall {
 41+/* width: 430px;*/
 42+ height: 29px;
 43+ float: left;
 44+ display: inline;
 45+}
 46+
 47+.mv-player .lButton {
 48+ cursor:pointer;
 49+ float:left;
 50+ list-style:none outside none;
 51+ margin:2px;
 52+ padding:4px 0;
 53+ width: 24px;
 54+ height:16px;
 55+ position:relative;
 56+}
 57+.mv-player .rButton {
 58+ cursor:pointer;
 59+ float:right;
 60+ list-style:none outside none;
 61+ margin:2px;
 62+ padding:4px 0;
 63+ width: 23px;
 64+ height:16px;
 65+ position:relative;
 66+}
 67+
 68+.controls a{
 69+ display: block;
 70+ height: 100%;
 71+ width: 100%;
 72+}
 73+.mv-player .volume_icon {
 74+ float: right;
 75+ display: inline;
 76+ width: 22px;
 77+ height: 29px;
 78+ padding: 0 0 0 0;
 79+
 80+}
 81+
 82+.mv-player .volume_on {
 83+ background: url(images/player_volume_tag.png) 0 8px no-repeat;
 84+}
 85+.mv-player .volume_off{
 86+ background: url(images/player_volume_tag_off.png) 0 8px no-repeat;
 87+}
 88+
 89+.mv-player .volume_knob {
 90+ background: url(images/player_slider.png) 0 0 no-repeat;
 91+ width: 14px;
 92+ height: 14px;
 93+ position: absolute;
 94+ z-index: 2;
 95+ margin: -1px 0 0 3px;
 96+ cursor: pointer;
 97+}
 98+.mv-player .vol_container{
 99+ z-index:99;
 100+ width:23px;
 101+ height:75px;
 102+ width:23px;
 103+ background: #CCC;
 104+}
 105+.mv-player .vol_container_below{
 106+ top:30px;
 107+}
 108+.mv-player .vol_container_top{
 109+ top:-77px;
 110+}
 111+.mv-player .vol_container .volume-slider{
 112+ margin-top:5px;
 113+ height:65px;
 114+ width:10px;
 115+ margin-left: auto ;
 116+ margin-right: auto ;
 117+}
 118+.mv-player .vol_container .ui-slider-handle{
 119+ cursor : pointer;
 120+ width:10px;
 121+ height:10px;
 122+ position:absolute;
 123+ left:-1px;
 124+}
 125+
 126+.mv-player .time-disp {
 127+ line-height: 32px;
 128+ height: 29px;
 129+ overflow: visible;
 130+ font-size: 10.2px;
 131+ width: 85px;
 132+ float: right;
 133+ display: inline;
 134+ border:none;
 135+}
 136+
 137+.mv-player .play_head{
 138+ float: left;
 139+ display: inline;
 140+ height: 10px;
 141+ margin-left:8px;
 142+ margin-top:10px;
 143+ position:relative;
 144+}
 145+
 146+.mv-player .play_head .ui-slider-handle{
 147+ width:10px;
 148+ height:15px;
 149+ margin-left:-5px;
 150+ margin-top: -1px;
 151+ z-index: 4;
 152+}
 153+
 154+.mv-player .inOutSlider .ui-slider-handle{
 155+ width:8px;
 156+ cusror: move;
 157+}
 158+
 159+
 160+.mv-player .overlay-win textarea {
 161+ background:none repeat scroll 0 0 transparent;
 162+ border-color:#333 -moz-use-text-color -moz-use-text-color #333;
 163+ border-style:solid none none solid;
 164+ border-width:2px medium medium 2px;
 165+ color:#222;
 166+ font:11px arial,sans-serif;
 167+ height:15px;
 168+ overflow:hidden;
 169+ padding-left:2px;
 170+ width:100%;
 171+}
 172+
 173+.mv-player .overlay-win div.ui-state-highlight {
 174+ background:none repeat scroll 0 0 transparent;
 175+ border-color:#554926;
 176+ color:#FFE96E;
 177+ float:left;
 178+ padding:2px 5px;
 179+}
 180+
 181+.mv-player .videoOptionsComplete div.ui-state-highlight a {
 182+ color:#eee;
 183+ font-weight:bold;
 184+}
 185+
 186+.mv-player .overlay-win h2{
 187+ font-size: 115%;
 188+}
 189+
 190+.mv-player .overlay-win{
 191+ font-family : arial,sans-serif;
 192+ font-size : 85%;
 193+}
 194+.mv-player .overlay-win a{
 195+ text-decoration: none;
 196+}
 197+
 198+.mv-player .overlay-win ul{
 199+ padding-left: 15px;
 200+}
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/EmbedPlayer.css
___________________________________________________________________
Added: svn:eol-style
1201 + native
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/ui-bg_glass_75_dadada_1x400.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/ui-bg_glass_75_dadada_1x400.png
___________________________________________________________________
Added: svn:mime-type
2202 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/ui-bg_glass_55_fbf9ee_1x400.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/ui-bg_glass_55_fbf9ee_1x400.png
___________________________________________________________________
Added: svn:mime-type
3203 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/ksprite.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/ksprite.png
___________________________________________________________________
Added: svn:mime-type
4204 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/clip_thumb_overlay.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/clip_thumb_overlay.png
___________________________________________________________________
Added: svn:mime-type
5205 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/player_volume_seek.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/player_volume_seek.png
___________________________________________________________________
Added: svn:mime-type
6206 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/tracker.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/tracker.png
___________________________________________________________________
Added: svn:mime-type
7207 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/player_button_cc.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/player_button_cc.png
___________________________________________________________________
Added: svn:mime-type
8208 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/flash_icon_bw.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/flash_icon_bw.png
___________________________________________________________________
Added: svn:mime-type
9209 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/player_big_play_button.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/player_big_play_button.png
___________________________________________________________________
Added: svn:mime-type
10210 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/player_seek_right.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/player_seek_right.png
___________________________________________________________________
Added: svn:mime-type
11211 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/logo.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/logo.png
___________________________________________________________________
Added: svn:mime-type
12212 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/plugin_edit.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/plugin_edit.png
___________________________________________________________________
Added: svn:mime-type
13213 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/flash_icon_color.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/flash_icon_color.png
___________________________________________________________________
Added: svn:mime-type
14214 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/ui-bg_flat_75_ffffff_40x100.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/ui-bg_flat_75_ffffff_40x100.png
___________________________________________________________________
Added: svn:mime-type
15215 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/ui-bg_glass_65_ffffff_1x400.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/ui-bg_glass_65_ffffff_1x400.png
___________________________________________________________________
Added: svn:mime-type
16216 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/carousel_top_left.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/carousel_top_left.png
___________________________________________________________________
Added: svn:mime-type
17217 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/button_grey_left.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/button_grey_left.png
___________________________________________________________________
Added: svn:mime-type
18218 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/player_bottom_right.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/player_bottom_right.png
___________________________________________________________________
Added: svn:mime-type
19219 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/search_suggest_bg.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/search_suggest_bg.png
___________________________________________________________________
Added: svn:mime-type
20220 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/other_results_top.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/other_results_top.png
___________________________________________________________________
Added: svn:mime-type
21221 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/plugin_disabled.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/plugin_disabled.png
___________________________________________________________________
Added: svn:mime-type
22222 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/embed_arrow.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/embed_arrow.png
___________________________________________________________________
Added: svn:mime-type
23223 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/carousel_left.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/carousel_left.png
___________________________________________________________________
Added: svn:mime-type
24224 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/player_options_top.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/player_options_top.png
___________________________________________________________________
Added: svn:mime-type
25225 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/player_bottom_left.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/player_bottom_left.png
___________________________________________________________________
Added: svn:mime-type
26226 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/button_grey_right.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/button_grey_right.png
___________________________________________________________________
Added: svn:mime-type
27227 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/Jcrop.gif
Cannot display: file marked as a binary type.
svn:mime-type = image/gif
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/Jcrop.gif
___________________________________________________________________
Added: svn:mime-type
28228 + image/gif
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/slider_handle_green.gif
Cannot display: file marked as a binary type.
svn:mime-type = image/gif
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/slider_handle_green.gif
___________________________________________________________________
Added: svn:mime-type
29229 + image/gif
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/font_truetype.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/font_truetype.png
___________________________________________________________________
Added: svn:mime-type
30230 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/player_volume_tag_off.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/player_volume_tag_off.png
___________________________________________________________________
Added: svn:mime-type
31231 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/html_page_icon.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/html_page_icon.png
___________________________________________________________________
Added: svn:mime-type
32232 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/ui-bg_flat_0_aaaaaa_40x100.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/ui-bg_flat_0_aaaaaa_40x100.png
___________________________________________________________________
Added: svn:mime-type
33233 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/carousel_right.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/carousel_right.png
___________________________________________________________________
Added: svn:mime-type
34234 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/player_button_play.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/player_button_play.png
___________________________________________________________________
Added: svn:mime-type
35235 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/ico_mail.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/ico_mail.png
___________________________________________________________________
Added: svn:mime-type
36236 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/player_seek_left.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/player_seek_left.png
___________________________________________________________________
Added: svn:mime-type
37237 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/ui-bg_glass_95_fef1ec_1x400.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/ui-bg_glass_95_fef1ec_1x400.png
___________________________________________________________________
Added: svn:mime-type
38238 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/player_options_bg.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/player_options_bg.png
___________________________________________________________________
Added: svn:mime-type
39239 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/ui-icons_888888_256x240.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/ui-icons_888888_256x240.png
___________________________________________________________________
Added: svn:mime-type
40240 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/fish_xiph_org_bw.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/fish_xiph_org_bw.png
___________________________________________________________________
Added: svn:mime-type
41241 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/archive_org_bw.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/archive_org_bw.png
___________________________________________________________________
Added: svn:mime-type
42242 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/kaltura_logo_sm.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/kaltura_logo_sm.png
___________________________________________________________________
Added: svn:mime-type
43243 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/image_thumb_overlay.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/image_thumb_overlay.png
___________________________________________________________________
Added: svn:mime-type
44244 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/logo2.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/logo2.png
___________________________________________________________________
Added: svn:mime-type
45245 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/player_seek_bg_loaded.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/player_seek_bg_loaded.png
___________________________________________________________________
Added: svn:mime-type
46246 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/player_seek_bg_normal.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/player_seek_bg_normal.png
___________________________________________________________________
Added: svn:mime-type
47247 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/player_button_pause.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/player_button_pause.png
___________________________________________________________________
Added: svn:mime-type
48248 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/flash_carousel.jpg
Cannot display: file marked as a binary type.
svn:mime-type = image/jpeg
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/flash_carousel.jpg
___________________________________________________________________
Added: svn:mime-type
49249 + image/jpeg
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/uni_edit_bw.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/uni_edit_bw.png
___________________________________________________________________
Added: svn:mime-type
50250 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/metavid_logo_100.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/metavid_logo_100.png
___________________________________________________________________
Added: svn:mime-type
51251 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/search_suggest_bottom.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/search_suggest_bottom.png
___________________________________________________________________
Added: svn:mime-type
52252 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/player_slider.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/player_slider.png
___________________________________________________________________
Added: svn:mime-type
53253 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/plugin.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/plugin.png
___________________________________________________________________
Added: svn:mime-type
54254 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/button_play.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/button_play.png
___________________________________________________________________
Added: svn:mime-type
55255 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/player_button_options.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/player_button_options.png
___________________________________________________________________
Added: svn:mime-type
56256 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/flash_player.jpg
Cannot display: file marked as a binary type.
svn:mime-type = image/jpeg
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/flash_player.jpg
___________________________________________________________________
Added: svn:mime-type
57257 + image/jpeg
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/player_video_options_bg.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/player_video_options_bg.png
___________________________________________________________________
Added: svn:mime-type
58258 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/other_results_top2.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/other_results_top2.png
___________________________________________________________________
Added: svn:mime-type
59259 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/firefogg_logo.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/firefogg_logo.png
___________________________________________________________________
Added: svn:mime-type
60260 + application/octet-stream
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/slider_handle_red.gif
Cannot display: file marked as a binary type.
svn:mime-type = image/gif
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/slider_handle_red.gif
___________________________________________________________________
Added: svn:mime-type
61261 + image/gif
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/player_button_fullscreen.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/player_button_fullscreen.png
___________________________________________________________________
Added: svn:mime-type
62262 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/pbar-ani.gif
Cannot display: file marked as a binary type.
svn:mime-type = image/gif
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/pbar-ani.gif
___________________________________________________________________
Added: svn:mime-type
63263 + image/gif
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/other_results_bg.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/other_results_bg.png
___________________________________________________________________
Added: svn:mime-type
64264 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/opened.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/opened.png
___________________________________________________________________
Added: svn:mime-type
65265 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/ui-icons_222222_256x240.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/ui-icons_222222_256x240.png
___________________________________________________________________
Added: svn:mime-type
66266 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/vid_prev_sm.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/vid_prev_sm.png
___________________________________________________________________
Added: svn:mime-type
67267 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/player_video.jpg
Cannot display: file marked as a binary type.
svn:mime-type = image/jpeg
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/player_video.jpg
___________________________________________________________________
Added: svn:mime-type
68268 + image/jpeg
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/ui-bg_glass_75_e6e6e6_1x400.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/ui-bg_glass_75_e6e6e6_1x400.png
___________________________________________________________________
Added: svn:mime-type
69269 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/wiki_commons_logo_80.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/wiki_commons_logo_80.png
___________________________________________________________________
Added: svn:mime-type
70270 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/fish_xiph_org_color.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/fish_xiph_org_color.png
___________________________________________________________________
Added: svn:mime-type
71271 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/search_suggest_top.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/search_suggest_top.png
___________________________________________________________________
Added: svn:mime-type
72272 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/ui-bg_highlight-soft_75_cccccc_1x100.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/ui-bg_highlight-soft_75_cccccc_1x100.png
___________________________________________________________________
Added: svn:mime-type
73273 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/img1.jpg
Cannot display: file marked as a binary type.
svn:mime-type = image/jpeg
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/img1.jpg
___________________________________________________________________
Added: svn:mime-type
74274 + image/jpeg
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/ui-icons_454545_256x240.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/ui-icons_454545_256x240.png
___________________________________________________________________
Added: svn:mime-type
75275 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/img2.jpg
Cannot display: file marked as a binary type.
svn:mime-type = image/jpeg
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/img2.jpg
___________________________________________________________________
Added: svn:mime-type
76276 + image/jpeg
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/player_options_bottom.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/player_options_bottom.png
___________________________________________________________________
Added: svn:mime-type
77277 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/thumb1.jpg
Cannot display: file marked as a binary type.
svn:mime-type = image/jpeg
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/thumb1.jpg
___________________________________________________________________
Added: svn:mime-type
78278 + image/jpeg
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/tab-bg.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/tab-bg.png
___________________________________________________________________
Added: svn:mime-type
79279 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/button_to_clipboard.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/button_to_clipboard.png
___________________________________________________________________
Added: svn:mime-type
80280 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/carousel_top_right.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/carousel_top_right.png
___________________________________________________________________
Added: svn:mime-type
81281 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/thumb2.jpg
Cannot display: file marked as a binary type.
svn:mime-type = image/jpeg
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/thumb2.jpg
___________________________________________________________________
Added: svn:mime-type
82282 + image/jpeg
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/uni_edit_color.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/uni_edit_color.png
___________________________________________________________________
Added: svn:mime-type
83283 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/thumb3.jpg
Cannot display: file marked as a binary type.
svn:mime-type = image/jpeg
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/thumb3.jpg
___________________________________________________________________
Added: svn:mime-type
84284 + image/jpeg
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/kaltura_open_source_video_platform.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/kaltura_open_source_video_platform.png
___________________________________________________________________
Added: svn:mime-type
85285 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/thumb4.jpg
Cannot display: file marked as a binary type.
svn:mime-type = image/jpeg
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/thumb4.jpg
___________________________________________________________________
Added: svn:mime-type
86286 + image/jpeg
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/ico_rss.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/ico_rss.png
___________________________________________________________________
Added: svn:mime-type
87287 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/transition_icon.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/transition_icon.png
___________________________________________________________________
Added: svn:mime-type
88288 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/ui-icons_cd0a0a_256x240.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/ui-icons_cd0a0a_256x240.png
___________________________________________________________________
Added: svn:mime-type
89289 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/button_subscribe.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/button_subscribe.png
___________________________________________________________________
Added: svn:mime-type
90290 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/ui-icons_2e83ff_256x240.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/ui-icons_2e83ff_256x240.png
___________________________________________________________________
Added: svn:mime-type
91291 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/slider_handle.gif
Cannot display: file marked as a binary type.
svn:mime-type = image/gif
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/slider_handle.gif
___________________________________________________________________
Added: svn:mime-type
92292 + image/gif
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/player_volume_tag.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/player_volume_tag.png
___________________________________________________________________
Added: svn:mime-type
93293 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/vid_next_sm.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/vid_next_sm.png
___________________________________________________________________
Added: svn:mime-type
94294 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/kaltura_open_source_video_platform.gif
Cannot display: file marked as a binary type.
svn:mime-type = image/gif
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/kaltura_open_source_video_platform.gif
___________________________________________________________________
Added: svn:mime-type
95295 + image/gif
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/selector.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf/images/selector.png
___________________________________________________________________
Added: svn:mime-type
96296 + image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/mvpcf
___________________________________________________________________
Added: svn:mergeinfo
97297 Merged /branches/REL1_15/phase3/js2/mwEmbed/skins/mvpcf:r51646
98298 Merged /branches/sqlite/js2/mwEmbed/skins/mvpcf:r58211-58321
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/kskin/EmbedPlayer.css
@@ -0,0 +1,418 @@
 2+/*
 3+* K-skin player
 4+*/
 5+.k-player {
 6+ color: #FFF;
 7+}
 8+.k-player .ui-widget-content {
 9+ color: #999;
 10+}
 11+.k-player .ui-widget-content a{
 12+ color: #999;
 13+}
 14+/* large play button */
 15+.k-player .play-btn-large {
 16+ width: 120px;
 17+ height: 55px;
 18+ background: url(images/ksprite.png) no-repeat 28px -433px;
 19+ position: absolute;
 20+ cursor: pointer;
 21+ border: none;
 22+} /*.ui-state-default */
 23+.k-player .play-btn-large.ui-state-hover {
 24+ background: url(images/ksprite.png) no-repeat 28px -377px;
 25+}
 26+
 27+/* control icons: */
 28+.k-player .ui-state-default .ui-icon,.k-player .ui-state-hover .ui-icon
 29+ {
 30+ background: transparent url(images/ksprite.png) no-repeat scroll 0 -48px
 31+ ;
 32+}
 33+
 34+.k-player .ui-state-default .ui-icon-arrow-4-diag {
 35+ background-position: 0 -32px;
 36+} /* fullscreen */
 37+.k-player .ui-state-hover .ui-icon-arrow-4-diag {
 38+ background-position: -16px -32px;
 39+}
 40+
 41+.k-player .ui-state-hover .ui-icon-volume-on{
 42+ background-position: -16px -48px;
 43+}
 44+
 45+/* cc icon */
 46+.k-player .ui-state-default .ui-icon-comment {
 47+ background-position: 0px -65px;
 48+}
 49+.k-player .ui-state-hover .ui-icon-comment {
 50+ background-position: -17px -65px;
 51+}
 52+
 53+.k-player .ui-state-default .ui-icon-play {
 54+ background: url(images/ksprite.png) no-repeat 0 0;
 55+}
 56+
 57+.k-player .ui-state-hover .ui-icon-play {
 58+ background-position: -16px 0;
 59+}
 60+
 61+.k-player .ui-state-default .ui-icon-pause {
 62+ background: url(images/ksprite.png) no-repeat 0 -17px;
 63+}
 64+
 65+.k-player .ui-state-hover .ui-icon-pause {
 66+ background-position: -16px -17px;
 67+}
 68+
 69+.k-player .control-bar {
 70+ border:1px solid #c8c8c8;
 71+ border-top: 0px;
 72+ border-right: 0px;
 73+ height: 21px;
 74+ padding: 2px 0 0 6px;
 75+ margin-top: 0px;
 76+ background: url(images/ksprite.png) repeat-x 0 -81px;
 77+ font: normal 11px arial, sans-serif;
 78+ color: #555;
 79+}
 80+
 81+.k-player .play_head {
 82+ background: url("images/ksprite.png") repeat-x scroll 0 -350px
 83+ transparent;
 84+ display: inline;
 85+ float: left;
 86+ margin-left: 10px;
 87+ border: 1px solid #EEEEEE;
 88+ height: 8px;
 89+ margin: 6px 2px 0 0px;
 90+ position: relative;
 91+}
 92+
 93+.k-player .play_head .ui-slider-handle {
 94+ background: url("images/ksprite.png") no-repeat scroll -67px -341px
 95+ transparent;
 96+ border: 1px solid #888888;
 97+ display: block;
 98+ height: 8px;
 99+ margin: -1px 0 0 -5px;
 100+ position: absolute;
 101+ top: 0;
 102+ width: 8px;
 103+ cursor: pointer;
 104+ -moz-border-radius:5px 5px 5px 5px;
 105+}
 106+.k-player .ui-corner-all {
 107+ -moz-border-radius:5px 5px 5px 5px;
 108+}
 109+.k-player .time-disp {
 110+ border: medium none;
 111+ display: inline;
 112+ color: #555555;
 113+ font: 11px arial, sans-serif;
 114+ line-height: 20px;
 115+ overflow: hidden;
 116+ width: 39px;
 117+ float: right;
 118+}
 119+
 120+.k-player .lButton {
 121+ cursor: pointer;
 122+ float: left;
 123+ list-style: none outside none;
 124+ margin: 2px;
 125+ padding: 0px 0;
 126+ width: 24px;
 127+ height: 16px;
 128+ position: relative;
 129+ background: none repeat scroll 0 0 transparent;
 130+ border: medium none;
 131+}
 132+
 133+.k-player .rButton {
 134+ cursor: pointer;
 135+ float: right;
 136+ list-style: none outside none;
 137+ margin-top: 2px;
 138+ padding: 0px 0;
 139+ width: 23px;
 140+ height: 16px;
 141+ position: relative;
 142+ background: none repeat scroll 0 0 transparent;
 143+ border: medium none;
 144+}
 145+
 146+.k-player .k-options {
 147+ border: 1px solid #AAAAAA !important;
 148+ color: #555555;
 149+ float: right;
 150+ height: 22px;
 151+ margin-top: -2px;
 152+ margin-right: 0px;
 153+ width: 50px;
 154+ float: right;
 155+ background: none repeat scroll 0 0 transparent;
 156+ font-family: Lucida Grande, Lucida Sans, Arial, sans-serif;
 157+ font-size: 11px;
 158+ text-transform: uppercase;
 159+}
 160+
 161+.k-player .k-options span {
 162+ position: relative;
 163+ top: 4px;
 164+ left: 7px;
 165+}
 166+
 167+.k-player .k-menu-screens {
 168+ float: left;
 169+ font-size: 11px;
 170+ padding: 13px 10px 15px 15px;
 171+}
 172+
 173+.k-player ul.k-menu-bar {
 174+ background: url("images/ksprite.png") no-repeat scroll -99px -104px
 175+ transparent;
 176+ bottom: 5px;
 177+ height: 128px;
 178+ list-style: none outside none;
 179+ padding: 0 0 5px;
 180+ position: absolute;
 181+ right: 0;
 182+}
 183+
 184+.k-player .k-menu {
 185+ background: none repeat scroll 0 0 #181818;
 186+ border: medium none;
 187+ display: none;
 188+ left: 0;
 189+ opacity: 0.9;
 190+ position: absolute;
 191+ top: 0;
 192+ z-index: 999;
 193+}
 194+
 195+.k-player .k-menu-bar li a {
 196+ background: url("images/ksprite.png") no-repeat scroll -51px -110px
 197+ transparent;
 198+ display: block;
 199+ height: 32px;
 200+ margin-left: 1px;
 201+ overflow: hidden;
 202+ text-indent: 99999px;
 203+ width: 49px;
 204+}
 205+
 206+.k-menu-bar li a:hover {
 207+ background-position: -1px -110px;
 208+}
 209+
 210+.k-menu-bar li.k-download-btn a {
 211+ background-position: -51px -203px;
 212+}
 213+
 214+.k-menu-bar li.k-download-btn a:hover {
 215+ background-position: -1px -203px;
 216+}
 217+
 218+.k-menu-bar li.k-share-btn a {
 219+ background-position: -51px -172px;
 220+}
 221+
 222+.k-menu-bar li.k-share-btn a:hover {
 223+ background-position: -1px -172px;
 224+}
 225+
 226+.k-menu-bar li.k-credits-btn a {
 227+ background-position: -51px -141px;
 228+}
 229+
 230+.k-menu-bar li.k-credits-btn a:hover {
 231+ background-position: -1px -141px;
 232+}
 233+
 234+
 235+
 236+.k-menu-screens p {
 237+ margin: 6px 0;
 238+}
 239+
 240+.k-menu-screens a img {
 241+ border: none;
 242+}
 243+
 244+.k-menu-screens ul {
 245+ padding: 0;
 246+ margin: 6px 0 0;
 247+ list-style: none outside none;
 248+}
 249+
 250+.k-edit-screen {
 251+ width: 370px;
 252+ height: 223px;
 253+ padding-top: 77px;
 254+ text-align: center;
 255+ background: #181818;
 256+ color: #fff;
 257+}
 258+
 259+.k-edit-screen div {
 260+
 261+}
 262+
 263+.k-edit-screen a {
 264+ color: #7BB8FC;
 265+}
 266+
 267+.k-edit-screen a img {
 268+ border: none;
 269+}
 270+
 271+
 272+.k-menu-screens h2 {
 273+ padding: 0 0 5px 1px;
 274+ clear: both;
 275+ font-size: 12px;
 276+ color: #999;
 277+}
 278+
 279+.k-menu-screens p {
 280+ margin: 6px 0;
 281+}
 282+
 283+.k-menu-screens a img {
 284+ border: none;
 285+}
 286+
 287+.k-menu-screens ul {
 288+ padding: 0;
 289+ margin: 6px 0 0;
 290+ list-style: none outside none;
 291+}
 292+
 293+.k-menu-screens li {
 294+ height: 14px;
 295+ margin-bottom: 6px;
 296+}
 297+
 298+.k-menu-screens li a {
 299+ padding-left: 22px;
 300+ background: url(images/ksprite.png) no-repeat -85px -274px;
 301+ text-decoration: none;
 302+ color: #BBB;
 303+}
 304+
 305+.k-menu-screens li a.active,.k-menu-screens li a:hover .active {
 306+ background-position: -85px -247px;
 307+}
 308+
 309+.k-menu-screens li a:hover {
 310+ background-position: -85px -260px;
 311+}
 312+
 313+.k-menu textarea {
 314+ background: none repeat scroll 0 0 transparent;
 315+ border-color: #000000 -moz-use-text-color -moz-use-text-color #000000;
 316+ border-style: solid none none solid;
 317+ border-width: 2px medium medium 2px;
 318+ color: #CCCCCC;
 319+ font: 11px arial, sans-serif;
 320+ height: 15px;
 321+ overflow: hidden;
 322+ padding-left: 2px;
 323+ width: 100%;
 324+}
 325+
 326+.menu-screen.menu-share button {
 327+ background: url("images/ksprite.png") no-repeat scroll 0 -81px #D4D4D4;
 328+ border: 1px solid #000000;
 329+ color: #000000;
 330+ float: right;
 331+ height: 34px;
 332+ padding: 0 5px 3px;
 333+ width: 84px;
 334+ font-size: 1em;
 335+}
 336+
 337+.k-player .menu-screen {
 338+ height: 100%;
 339+}
 340+
 341+.k-player .menu-screen.menu-share div.ui-state-highlight {
 342+ background: none repeat scroll 0 0 transparent;
 343+ border-color: #554926;
 344+ color: #FFE96E;
 345+ float: left;
 346+ padding: 2px 5px;
 347+}
 348+
 349+.k-player .menu-screen.menu-share div.ui-state-highlight a {
 350+ color: #FFE96E;
 351+ font-weight: bold;
 352+}
 353+
 354+.k-player .volume_control {
 355+ margin-right: 2px;
 356+ width: 16px;
 357+}
 358+
 359+.k-player .volume_control span {
 360+ margin-right: 0px;
 361+}
 362+
 363+.k-player .volume-slider {
 364+ width: 20px;
 365+}
 366+
 367+.k-player .volume-slider .ui-slider-range {
 368+ -moz-border-radius: 0 0 0 0;
 369+ background: url("images/ksprite.png") repeat-x scroll -66px -306px
 370+ transparent;
 371+ height: 17px;
 372+ position: absolute;
 373+}
 374+
 375+.k-player .volume-slider a.ui-slider-handle {
 376+ background: none repeat scroll 0 0 transparent;
 377+ border: medium none;
 378+ display: block;
 379+ height: 18px;
 380+ margin: -3px 5px 0 -1px;
 381+ position: absolute;
 382+ width: 8px;
 383+}
 384+
 385+.k-player .credits_box {
 386+ background-attachment:scroll;
 387+ background-color:white;
 388+ background-image:none;
 389+ background-position:0 0;
 390+ bottom:30px;
 391+ left:15px;
 392+ position:absolute;
 393+ right:30px;
 394+ top:48px;
 395+}
 396+.k-player .credits_box a{
 397+ color:#666;
 398+}
 399+.k-player .creditline img {
 400+ float: left;
 401+ width: 90px;
 402+ margin: 4px;
 403+}
 404+
 405+.k-player .k-attribution{
 406+ position:absolute;
 407+ bottom: 15px;
 408+ right : 30px;
 409+ background: url("images/kaltura_open_source_video_platform.png");
 410+ width : 51px;
 411+ height : 12px;
 412+ cursor: pointer;
 413+}
 414+.k-player .itext a{
 415+ color: #bbf;
 416+}
 417+.k-player .itext a:visited{
 418+ color: #aaf;
 419+}
\ No newline at end of file
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/kskin/EmbedPlayer.css
___________________________________________________________________
Added: svn:eol-style
1420 + native
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/kskin/kskinConfig.js
@@ -0,0 +1,441 @@
 2+/**
 3+* Skin js allows you to override contrlBuilder html/class output
 4+*/
 5+
 6+mw.addMessages( {
 7+ "mwe-credit-title" : "Title: $1"
 8+} );
 9+
 10+var kskinConfig = {
 11+
 12+ // The parent class for all kskin css:
 13+ playerClass: 'k-player',
 14+
 15+ // Display time string length
 16+ longTimeDisp: false,
 17+
 18+ // Default control bar height
 19+ height: 20,
 20+
 21+ // Volume control layout is horizontal
 22+ volume_layout: 'horizontal',
 23+
 24+ // Skin "kskin" is specific for wikimedia we have an
 25+ // api Title key so the "credits" menu item can be showed.
 26+ supportedMenuItems: {
 27+ 'credits': true
 28+ },
 29+
 30+ // Extends base components with kskin specific options:
 31+ components: {
 32+ 'playButtonLarge' : {
 33+ 'h' : 55
 34+ },
 35+ 'options': {
 36+ 'w':50,
 37+ 'o':function() {
 38+ return $j( '<div />' )
 39+ .attr( 'title', gM( 'mwe-player_options' ) )
 40+ .addClass( "ui-state-default ui-corner-bl rButton k-options" )
 41+ .append(
 42+ $j( '<span />' )
 43+ .text( gM( 'mwe-menu_btn' ) )
 44+ )
 45+ }
 46+ },
 47+ 'volumeControl': {
 48+ 'w':40
 49+ },
 50+ // No kalturaAttribution component for kSkin ( its integrated into the credits screen )
 51+ 'kalturaAttribution' : false,
 52+
 53+ // Time display:
 54+ 'timeDisplay': {
 55+ 'w':45
 56+ },
 57+
 58+ 'optionsMenu': {
 59+ 'w' : 0,
 60+ 'o' : function( ctrlObj ) {
 61+ var embedPlayer = ctrlObj.embedPlayer;
 62+
 63+ $menuOverlay = $j( '<div />')
 64+ .addClass( 'overlay-win k-menu ui-widget-content' )
 65+ .css( {
 66+ 'width' : '100%',
 67+ 'position': 'absolute',
 68+ 'top' : '0px',
 69+ 'bottom' : ( ctrlObj.getHeight() + 2 ) + 'px'
 70+ } );
 71+
 72+ // Setup menu offset ( if player height < getOverlayHeight )
 73+ // This displays the menu outside of the player on small embeds
 74+ if ( embedPlayer.getPlayerHeight() < ctrlObj.getOverlayHeight() ) {
 75+ var topPos = ( ctrlObj.checkOverlayControls() )
 76+ ? embedPlayer.getPlayerHeight()
 77+ : embedPlayer.getPlayerHeight() + ctrlObj.getHeight();
 78+
 79+ $menuOverlay.css( {
 80+ 'top' : topPos + 'px',
 81+ 'bottom' : null,
 82+ 'width' : ctrlObj.getOverlayWidth(),
 83+ 'height' : ctrlObj.getOverlayHeight() + 'px'
 84+ });
 85+ // Special common overflow hack for thumbnail display of player
 86+ $j( embedPlayer ).parents( '.thumbinner' ).css( 'overflow', 'visible' );
 87+ }
 88+
 89+ $menuBar = $j( '<ul />' )
 90+ .addClass( 'k-menu-bar' );
 91+
 92+ // Output menu item containers:
 93+ for ( var menuItem in ctrlObj.supportedMenuItems ) {
 94+ $menuBar.append(
 95+ $j( '<li />')
 96+ // Add the menu item class:
 97+ .addClass( 'k-' + menuItem + '-btn' )
 98+ .attr( 'rel', menuItem )
 99+ .append(
 100+ $j( '<a />' )
 101+ .attr( {
 102+ 'title' : gM( 'mwe-' + menuItem ),
 103+ 'href' : '#'
 104+ })
 105+ )
 106+ );
 107+ }
 108+
 109+ // Add the menuBar to the menuOverlay
 110+ $menuOverlay.append( $menuBar );
 111+
 112+ var $menuScreens = $j( '<div />' )
 113+ .addClass( 'k-menu-screens' )
 114+ .css( {
 115+ 'position' : 'absolute',
 116+ 'top' : '0px',
 117+ 'left' : '0px',
 118+ 'bottom' : '0px',
 119+ 'right' : '45px'
 120+ } )
 121+ for ( var menuItem in ctrlObj.supportedMenuItems ) {
 122+ $menuScreens.append(
 123+ $j( '<div />' )
 124+ .addClass( 'menu-screen menu-' + menuItem )
 125+ );
 126+ }
 127+
 128+ // Add the menuScreens to the menuOverlay
 129+ $menuOverlay.append( $menuScreens );
 130+
 131+ return $menuOverlay;
 132+
 133+ }
 134+ }
 135+ },
 136+
 137+ /**
 138+ * Get minimal width for interface overlay
 139+ */
 140+ getOverlayWidth: function(){
 141+ return ( this.embedPlayer.getPlayerWidth() < 200 )? 200 : this.embedPlayer.getPlayerWidth();
 142+ },
 143+
 144+ /**
 145+ * Get minimal height for interface overlay
 146+ */
 147+ getOverlayHeight: function(){
 148+ return ( this.embedPlayer.getPlayerHeight() < 160 )? 160 : this.embedPlayer.getPlayerHeight();
 149+ },
 150+
 151+ /**
 152+ * Adds the skin Control Bindings
 153+ */
 154+ addSkinControlBindings: function() {
 155+ var embedPlayer = this.embedPlayer;
 156+ var _this = this;
 157+
 158+ // Set up control bar pointer
 159+ this.$playerTarget = embedPlayer.$interface;
 160+ // Set the menu target:
 161+
 162+
 163+ // Options menu display:
 164+ this.$playerTarget.find( '.k-options' )
 165+ .unbind()
 166+ .click( function() {
 167+ _this.checkMenuOverlay();
 168+ var $kmenu = _this.$playerTarget.find( '.k-menu' );
 169+ if ( $kmenu.is( ':visible' ) ) {
 170+ _this.closeMenuOverlay( );
 171+ } else {
 172+ _this.showMenuOverlay( );
 173+ }
 174+ } );
 175+
 176+ },
 177+ /**
 178+ * checks for menu overlay and runs menu bindings if unset
 179+ */
 180+ checkMenuOverlay: function(){
 181+ var _this = this;
 182+ var embedPlayer = this.embedPlayer;
 183+ if ( _this.$playerTarget.find( '.k-menu' ).length == 0 ) {
 184+ // Stop the player if it does not support overlays:
 185+ if ( !embedPlayer.supports['overlays'] ) {
 186+ embedPlayer.stop();
 187+ }
 188+
 189+ // Add the menu binding
 190+ _this.addMeunBinding();
 191+ }
 192+ },
 193+
 194+ /**
 195+ * Close the menu overlay
 196+ */
 197+ closeMenuOverlay: function( ) {
 198+ mw.log(" close menu overlay" );
 199+ var $optionsMenu = this.$playerTarget.find( '.k-options' );
 200+ var $kmenu = this.$playerTarget.find( '.k-menu' );
 201+ $kmenu.fadeOut( "fast", function() {
 202+ $optionsMenu.find( 'span' )
 203+ .text ( gM( 'mwe-menu_btn' ) );
 204+ } );
 205+ this.$playerTarget.find( '.play-btn-large' ).fadeIn( 'fast' );
 206+ },
 207+
 208+ /**
 209+ * Show the menu overlay
 210+ */
 211+ showMenuOverlay: function( $ktxt ) {
 212+ var $optionsMenu = this.$playerTarget.find( '.k-options' );
 213+ var $kmenu = this.$playerTarget.find( '.k-menu' );
 214+ $kmenu.fadeIn( "fast", function() {
 215+ $optionsMenu.find( 'span' )
 216+ .text ( gM( 'mwe-close_btn' ) );
 217+ } );
 218+ this.$playerTarget.find( '.play-btn-large' ).fadeOut( 'fast' );
 219+ },
 220+
 221+ /**
 222+ * Adds binding for the options menu
 223+ *
 224+ * @param {Object} $tp Target video container for
 225+ */
 226+ addMeunBinding: function() {
 227+ var _this = this;
 228+ var embedPlayer = this.embedPlayer;
 229+ // Set local player target pointer:
 230+ var $playerTarget = embedPlayer.$interface;
 231+
 232+ // Check if k-menu already exists:
 233+ if ( $playerTarget.find( '.k-menu' ).length != 0 )
 234+ return false;
 235+
 236+ // Add options menu to top of player target children:
 237+ $playerTarget.prepend(
 238+ _this.getComponent( 'optionsMenu' )
 239+ );
 240+
 241+ // By default its hidden:
 242+ $playerTarget.find( '.k-menu' ).hide();
 243+
 244+ // Add menu-items bindings:
 245+ for ( var menuItem in _this.supportedMenuItems ) {
 246+ $playerTarget.find( '.k-' + menuItem + '-btn' ).click( function( ) {
 247+
 248+ // Grab the context from the "clicked" menu item
 249+ var mk = $j( this ).attr( 'rel' );
 250+
 251+ // hide all menu items
 252+ $targetItem = $playerTarget.find( '.menu-' + mk );
 253+
 254+ // call the function showMenuItem
 255+ _this.showMenuItem( mk );
 256+
 257+ // Hide the others
 258+ $playerTarget.find( '.menu-screen' ).hide();
 259+
 260+ // Show the target menu item:
 261+ $targetItem.fadeIn( "fast" );
 262+
 263+ // Don't follow the # link
 264+ return false;
 265+ } );
 266+ }
 267+ },
 268+
 269+ /**
 270+ * onClipDone action
 271+ * onClipDone for k-skin (with apiTitleKey) show the "credits" screen:
 272+ */
 273+ onClipDone: function(){
 274+ if( this.embedPlayer.apiTitleKey ){
 275+ this.checkMenuOverlay( );
 276+ this.showMenuOverlay();
 277+ this.showMenuItem( 'credits' );
 278+ }
 279+ },
 280+
 281+ /**
 282+ * Shows a selected menu_item
 283+ *
 284+ * NOTE: this should be merged with parent ctrlBuilder optionMenuItems
 285+ * binding mode
 286+ *
 287+ * @param {String} menu_itme Menu item key to display
 288+ */
 289+ showMenuItem:function( menuItem ) {
 290+ var embedPlayer = this.embedPlayer;
 291+ //handle special k-skin specific display;
 292+ switch( menuItem ){
 293+ case 'credits':
 294+ this.showCredits();
 295+ break;
 296+ case 'playerSelect':
 297+ embedPlayer.$interface.find( '.menu-playerSelect').html(
 298+ this.getPlayerSelect()
 299+ );
 300+ break;
 301+ case 'download' :
 302+ embedPlayer.$interface.find( '.menu-download').text(
 303+ gM('mwe-loading_txt' )
 304+ );
 305+ // Call show download with the target to be populated
 306+ this.showDownload(
 307+ embedPlayer.$interface.find( '.menu-download')
 308+ );
 309+ break;
 310+ case 'share':
 311+ embedPlayer.$interface.find( '.menu-share').html(
 312+ this.getShare()
 313+ );
 314+ break;
 315+ }
 316+ },
 317+
 318+ /**
 319+ * Show the credit screen (presently specific to kaltura skin )
 320+ */
 321+ showCredits: function() {
 322+ // Set up the shortcuts:
 323+ var embedPlayer = this.embedPlayer;
 324+ var _this = this;
 325+ var $target = embedPlayer.$interface.find( '.menu-credits' );
 326+
 327+ $target.empty().append(
 328+ $j('<h2 />')
 329+ .text( gM( 'mwe-credits' ) ),
 330+ $j('<div />')
 331+ .addClass( "credits_box ui-corner-all" )
 332+ .loadingSpinner()
 333+ );
 334+
 335+ if( mw.getConfig( 'kalturaAttribution' ) == true ){
 336+ $target.append(
 337+ $j( '<div />' )
 338+ .addClass( 'k-attribution' )
 339+ .attr({
 340+ 'title': gM('mwe-kaltura-platform-title')
 341+ })
 342+ .click( function( ) {
 343+ window.location = 'http://kaltura.com';
 344+ })
 345+ );
 346+ }
 347+
 348+ if( !embedPlayer.apiTitleKey ){
 349+ $target.find('.credits_box').text(
 350+ 'Error: no title key to grab credits with'
 351+ );
 352+ return ;
 353+ }
 354+
 355+ _this.getCredits();
 356+ },
 357+
 358+ /**
 359+ * Issues a request to populate the credits box
 360+ */
 361+ getCredits: function(){
 362+ // Setup shortcuts:
 363+ var embedPlayer = this.embedPlayer;
 364+ var _this = this;
 365+ var $target = embedPlayer.$interface.find( '.menu-credits' );
 366+
 367+ var apiUrl = mw.getApiProviderURL( embedPlayer.apiProvider );
 368+ var fileTitle = 'File:' + embedPlayer.apiTitleKey.replace(/File:|Image:/, '');
 369+
 370+ // Get the image info
 371+ var request = {
 372+ 'prop' : 'imageinfo',
 373+ 'titles' : fileTitle,
 374+ 'iiprop' : 'url'
 375+ };
 376+ var articleUrl = '';
 377+ mw.getJSON( apiUrl, request, function( data ){
 378+ if ( data.query.pages ) {
 379+ for ( var i in data.query.pages ) {
 380+ var imageProps = data.query.pages[i];
 381+ // Check properites for "missing"
 382+ if( imageProps.imageinfo && imageProps.imageinfo[0] && imageProps.imageinfo[0].descriptionurl ){
 383+ // Found page
 384+ $target.find( '.credits_box' ).html(
 385+ _this.doCreditLine( imageProps.imageinfo[0].descriptionurl )
 386+ );
 387+ }else{
 388+ // missing page descriptionurl
 389+ $target.find( '.credits_box' ).text(
 390+ 'Error: title key: ' + embedPlayer.apiTitleKey + ' not found'
 391+ );
 392+ }
 393+ }
 394+ }
 395+ } );
 396+ },
 397+
 398+ /**
 399+ * Build a clip credit from the resource wikiText page
 400+ *
 401+ * NOTE: in the future this should parse the resource page template
 402+ *
 403+ * @parm {String} wikiText Resource wiki text page contents
 404+ */
 405+ doCreditLine: function ( articleUrl ){
 406+ var embedPlayer = this.embedPlayer;
 407+
 408+ // Get the title str
 409+ var titleStr = embedPlayer.apiTitleKey.replace(/_/g, ' ');
 410+
 411+ var imgWidth = ( this.getOverlayWidth() < 250 )? 45 : 90;
 412+
 413+ return $j( '<div/>' ).addClass( 'creditline' )
 414+ .append(
 415+ $j('<a/>').attr({
 416+ 'href' : articleUrl,
 417+ 'title' : titleStr
 418+ }).html(
 419+ $j('<img/>').attr( {
 420+ 'border': 0,
 421+ 'src' : embedPlayer.poster
 422+ } ).css( {
 423+ 'width' : imgWidth,
 424+ 'height': parseInt( imgWidth * ( embedPlayer.height / embedPlayer.width ) )
 425+ } )
 426+ )
 427+ )
 428+ .append(
 429+ $j('<span>').html(
 430+ gM( 'mwe-credit-title' ,
 431+ // We use a div container to easialy get at the built out link
 432+ $j('<div>').html(
 433+ $j('<a/>').attr({
 434+ 'href' : articleUrl,
 435+ 'title' : titleStr
 436+ }).text( titleStr )
 437+ ).html()
 438+ )
 439+ )
 440+ );
 441+ }
 442+};
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/kskin/kskinConfig.js
___________________________________________________________________
Added: svn:mergeinfo
1443 Merged /branches/sqlite/js2/mwEmbed/skins/kskin/kskin.js:r58211-58321
2444 Merged /branches/REL1_15/phase3/js2/mwEmbed/skins/kskin/kskin.js:r51646
Added: svn:eol-style
3445 + native
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/kskin/images/ui-bg_flat_75_ffffff_40x100.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/kskin/images/ui-bg_flat_75_ffffff_40x100.png
___________________________________________________________________
Added: svn:mime-type
4446 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/kskin/images/ui-bg_glass_65_ffffff_1x400.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/kskin/images/ui-bg_glass_65_ffffff_1x400.png
___________________________________________________________________
Added: svn:mime-type
5447 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/kskin/images/ui-icons_cd0a0a_256x240.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/kskin/images/ui-icons_cd0a0a_256x240.png
___________________________________________________________________
Added: svn:mime-type
6448 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/kskin/images/ui-bg_flat_0_aaaaaa_40x100.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/kskin/images/ui-bg_flat_0_aaaaaa_40x100.png
___________________________________________________________________
Added: svn:mime-type
7449 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/kskin/images/ui-icons_222222_256x240.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/kskin/images/ui-icons_222222_256x240.png
___________________________________________________________________
Added: svn:mime-type
8450 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/kskin/images/ui-icons_2e83ff_256x240.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/kskin/images/ui-icons_2e83ff_256x240.png
___________________________________________________________________
Added: svn:mime-type
9451 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/kskin/images/ui-bg_glass_95_fef1ec_1x400.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/kskin/images/ui-bg_glass_95_fef1ec_1x400.png
___________________________________________________________________
Added: svn:mime-type
10452 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/kskin/images/kaltura_open_source_video_platform.gif
Cannot display: file marked as a binary type.
svn:mime-type = image/gif
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/kskin/images/kaltura_open_source_video_platform.gif
___________________________________________________________________
Added: svn:mime-type
11453 + image/gif
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/kskin/images/ui-icons_888888_256x240.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/kskin/images/ui-icons_888888_256x240.png
___________________________________________________________________
Added: svn:mime-type
12454 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/kskin/images/ksprite.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/kskin/images/ksprite.png
___________________________________________________________________
Added: svn:mime-type
13455 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/kskin/images/ui-bg_glass_55_fbf9ee_1x400.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/kskin/images/ui-bg_glass_55_fbf9ee_1x400.png
___________________________________________________________________
Added: svn:mime-type
14456 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/kskin/images/ui-bg_glass_75_dadada_1x400.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/kskin/images/ui-bg_glass_75_dadada_1x400.png
___________________________________________________________________
Added: svn:mime-type
15457 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/kskin/images/ui-bg_glass_75_e6e6e6_1x400.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/kskin/images/ui-bg_glass_75_e6e6e6_1x400.png
___________________________________________________________________
Added: svn:mime-type
16458 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/kskin/images/ui-bg_highlight-soft_75_cccccc_1x100.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/kskin/images/ui-bg_highlight-soft_75_cccccc_1x100.png
___________________________________________________________________
Added: svn:mime-type
17459 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/kskin/images/ui-icons_454545_256x240.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/kskin/images/ui-icons_454545_256x240.png
___________________________________________________________________
Added: svn:mime-type
18460 + image/png
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/kskin/images/kaltura_open_source_video_platform.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/kskin/images/kaltura_open_source_video_platform.png
___________________________________________________________________
Added: svn:mime-type
19461 + image/png
Added: svn:mergeinfo
20462 Merged /branches/sqlite/js2/mwEmbed/skins/kskin/images/kaltura_open_source_video_platform.png:r58211-58321
21463 Merged /branches/REL1_15/phase3/js2/mwEmbed/skins/kskin/images/kaltura_open_source_video_platform.png:r51646
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/kskin
___________________________________________________________________
Added: svn:mergeinfo
22464 Merged /branches/REL1_15/phase3/js2/mwEmbed/skins/kskin:r51646
23465 Merged /branches/sqlite/js2/mwEmbed/skins/kskin:r58211-58321
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/ctrlBuilder.js
@@ -0,0 +1,1573 @@
 2+/**
 3+* Msg text is inherited from embedPlayer
 4+*/
 5+
 6+/**
 7+* ctrlBuilder object
 8+* @param the embedPlayer element we are targeting
 9+*/
 10+var ctrlBuilder = function( embedPlayer, options ) {
 11+ return this.init( embedPlayer, options );
 12+};
 13+
 14+/**
 15+ * ControlsBuilder prototype:
 16+ */
 17+ctrlBuilder.prototype = {
 18+ //Default Local values:
 19+
 20+ // Parent css Class name
 21+ playerClass : 'mv-player',
 22+
 23+ // Long string display of time value
 24+ longTimeDisp: true,
 25+
 26+ // Default volume layout is "vertical"
 27+ volume_layout : 'vertical',
 28+
 29+ // Default control bar height
 30+ height: 31,
 31+
 32+ // Default supported components is merged with embedPlayer set of supported types
 33+ supportedComponets: {
 34+ // All playback types support options
 35+ 'options': true
 36+ },
 37+
 38+ // Default supported menu items is merged with skin menu items
 39+ supportedMenuItems: {
 40+ // Player Select
 41+ 'playerSelect' : true,
 42+
 43+ // Download the file menu
 44+ 'download' : true,
 45+
 46+ // Share the video menu
 47+ 'share' : true
 48+ },
 49+
 50+ // Flag to store the current fullscreen mode
 51+ fullscreenMode: false,
 52+
 53+ /**
 54+ * Initialization Object for the control builder
 55+ *
 56+ * @param {Object} embedPlayer EmbedPlayer interface
 57+ */
 58+ init: function( embedPlayer ) {
 59+ var _this = this;
 60+ this.embedPlayer = embedPlayer;
 61+
 62+ // Check for skin overrides for ctrlBuilder
 63+ if ( window[ embedPlayer.skinName + 'Config' ] ) {
 64+
 65+ // Clone as to not override prototype with the skin config
 66+ var _this = $j.extend( true, { }, this, window[ embedPlayer.skinName + 'Config'] );
 67+ return _this;
 68+ }
 69+ // Return the ctrlBuilder Object:
 70+ return this;
 71+ },
 72+
 73+ /**
 74+ * Get the control bar height
 75+ * @return {Number} control bar height
 76+ */
 77+ getHeight: function(){
 78+ return this.height;
 79+ },
 80+
 81+ /**
 82+ * Get the controls html
 83+ * @return {String} html output of controls
 84+ */
 85+ addControls: function() {
 86+ // Set up local pointer to the embedPlayer
 87+ var embedPlayer = this.embedPlayer;
 88+
 89+ // Set up local ctrlBuilder
 90+ var _this = this;
 91+
 92+ // Remove any old controls & old overlays:
 93+ embedPlayer.$interface.find( '.control-bar,.overlay-win' ).remove();
 94+
 95+ // Setup the controlBar container
 96+ var $controlBar = $j('<div />')
 97+ .addClass( 'ui-state-default ui-widget-header ui-helper-clearfix control-bar' )
 98+ .css( 'height', this.height )
 99+
 100+ // Check for overlay controls:
 101+ if( _this.checkOverlayControls() ) {
 102+ $controlBar.css( {
 103+ 'position': 'absolute',
 104+ 'bottom' : '0px',
 105+ 'left' : '0px',
 106+ 'right' : '0px'
 107+ } )
 108+ .hide()
 109+ // Make sure the interface is correct height:
 110+ embedPlayer.$interface.css( {
 111+ 'height' : parseInt( embedPlayer.height )
 112+ } );
 113+ } else {
 114+ // Add some space to interface for the control bar ( if not overlaying controls )
 115+ embedPlayer.$interface.css( {
 116+ 'height' : parseInt( embedPlayer.height ) + parseInt( this.height ) +2
 117+ } );
 118+ // update the control bar display to "block"
 119+ $controlBar.css( 'display', 'block' );
 120+ }
 121+
 122+ // Add the controls to the interface
 123+ embedPlayer.$interface.append( $controlBar );
 124+
 125+ // Add the Controls with their bindings
 126+ this.addControlComponents();
 127+
 128+ // Add hooks once Controls are in DOM
 129+ this.addControlHooks();
 130+ },
 131+
 132+ /**
 133+ * Builds the interface controls
 134+ * @return the interface html string
 135+ */
 136+ addControlComponents: function( ) {
 137+ var _this = this;
 138+ mw.log( 'f:controlsBuilder:: opt:' + this.options );
 139+
 140+ // Set up local pointer to the embedPlayer
 141+ var embedPlayer = this.embedPlayer;
 142+
 143+ //Set up local var to control container:
 144+ var $controlBar = embedPlayer.$interface.find( '.control-bar' );
 145+
 146+ this.available_width = embedPlayer.getPlayerWidth();
 147+
 148+ // Make pointer to the embedPlayer
 149+ this.embedPlayer = embedPlayer;
 150+
 151+ // Build the supportedComponets list
 152+ this.supportedComponets = $j.extend( this.supportedComponets, embedPlayer.supports );
 153+
 154+ // Check for timed text support:
 155+ if( embedPlayer.isTimedTextSupported() ){
 156+ this.supportedComponets['timedText'] = true;
 157+ }
 158+ // Check for kalturaAttribution
 159+ if( mw.getConfig( 'kalturaAttribution' ) ){
 160+ this.supportedComponets[ 'kalturaAttribution' ] = true;
 161+ }
 162+
 163+ // Check global fullscreen enabled flag
 164+ if( mw.getConfig( 'enableFullscreen' ) === false ){
 165+ this.supportedComponets[ 'fullscreen'] = false;
 166+ }
 167+
 168+ // Output components
 169+ for ( var component_id in this.components ) {
 170+ // Check for (component === false ) and skip
 171+ if( this.components[ component_id ] === false ){
 172+ continue;
 173+ }
 174+
 175+ // Special case with playhead skip if we have > 30px of space for it
 176+ if ( component_id == 'playHead' && this.available_width < 30 ){
 177+ continue;
 178+ }
 179+
 180+ // Skip "fullscreen" button for assets or where height is 0px ( audio )
 181+ if( component_id == 'fullscreen' && this.embedPlayer.height == 0 ){
 182+ continue;
 183+ }
 184+
 185+ // Make sure the given components is supported:
 186+ if ( this.supportedComponets[ component_id ] ) {
 187+ if ( this.available_width > this.components[ component_id ].w ) {
 188+ // Append the component
 189+ $controlBar.append(
 190+ _this.getComponent( component_id )
 191+ );
 192+ this.available_width -= this.components[ component_id ].w;
 193+ } else {
 194+ mw.log( 'Not enough space for control component:' + component_id );
 195+ }
 196+ }
 197+ }
 198+ },
 199+
 200+ /**
 201+ * Get the fullscreen player css
 202+ */
 203+ getFullscreenPlayerCss: function() {
 204+ var embedPlayer = this.embedPlayer;
 205+ // Setup target height width based on max window size
 206+ var fullWidth = $j( window ).width() - 2 ;
 207+ var fullHeight = $j( window ).height() ;
 208+
 209+ // Set target width
 210+ targetWidth = fullWidth;
 211+ targetHeight = targetWidth * ( embedPlayer.getHeight() / embedPlayer.getWidth() )
 212+ // Check if it exceeds the height constraint:
 213+ if( targetHeight > fullHeight ){
 214+ targetHeight = fullHeight;
 215+ targetWidth = targetHeight * ( embedPlayer.getWidth() / embedPlayer.getHeight() );
 216+ }
 217+ var offsetTop = ( targetHeight < fullHeight )? ( fullHeight- targetHeight ) / 2 : 0;
 218+ var offsetLeft = ( targetWidth < fullWidth )? ( fullWidth- targetWidth ) / 2 : 0;
 219+
 220+ //mw.log(" targetWidth: " + targetWidth + ' fullwidth: ' + fullWidth + ' :: ' + ( fullWidth- targetWidth ) / 2 );
 221+ return {
 222+ 'height': targetHeight,
 223+ 'width' : targetWidth,
 224+ 'top' : offsetTop,
 225+ 'left': offsetLeft
 226+ }
 227+ },
 228+
 229+ /**
 230+ * Get the fullscreen play button css
 231+ */
 232+ getFullscreenPlayButtonCss: function() {
 233+ var pos = this.getFullscreenPlayerCss();
 234+ return {
 235+ 'left' : ( ( pos.width - this.getComponentWidth( 'playButtonLarge' ) ) / 2 ),
 236+ 'top' : ( ( pos.height - this.getComponentHeight( 'playButtonLarge' ) ) / 2 )
 237+ }
 238+ },
 239+
 240+ /**
 241+ * Get the fullscreen text css
 242+ */
 243+ getFullscreenTextCss: function() {
 244+ // Some arbitrary scale relative to window size
 245+ var textSize = ( $j( window ).width() / 8 ) + 20;
 246+ if( textSize < 95 ) textSize = 95;
 247+ if( textSize > 250 ) textSize = 250;
 248+ //mw.log(' win size is: ' + $j( window ).width() + ' ts: ' + textSize );
 249+ return {
 250+ 'font-size' : textSize + '%'
 251+ }
 252+ },
 253+
 254+ /**
 255+ * Toggles full screen by calling
 256+ * doFullScreenPlayer to enable fullscreen mode
 257+ * restoreWindowPlayer to restore window mode
 258+ */
 259+ toggleFullscreen: function() {
 260+ if( this.fullscreenMode ){
 261+ this.restoreWindowPlayer();
 262+ }else{
 263+ this.doFullScreenPlayer();
 264+ }
 265+ },
 266+
 267+ /**
 268+ * Do full-screen mode
 269+ */
 270+ doFullScreenPlayer: function() {
 271+ mw.log(" ctrlBuilder :: toggle full-screen ");
 272+ // Setup pointer to control builder :
 273+ var _this = this;
 274+
 275+ // Setup local reference to embed player:
 276+ var embedPlayer = this.embedPlayer;
 277+
 278+ // Setup a local reference to the player interface:
 279+ var $interface = embedPlayer.$interface;
 280+
 281+
 282+ // Check fullscreen state ( if already true do nothing )
 283+ if( this.fullscreenMode == true ){
 284+ return ;
 285+ }
 286+ this.fullscreenMode = true;
 287+
 288+ //Remove any old mw-fullscreen-overlay
 289+ $interface.find( '.mw-fullscreen-overlay' ).remove();
 290+
 291+ // Special hack for mediawiki monobook skin search box
 292+ if( $j( '#p-search,#p-logo' ).length ) {
 293+ $j( '#p-search,#p-logo,#ca-nstab-project a' ).css('z-index', 1);
 294+ }
 295+
 296+ // Add the css fixed fullscreen black overlay as a sibling to the video element
 297+ $interface.after(
 298+ $j( '<div />' )
 299+ .addClass( 'mw-fullscreen-overlay' )
 300+ // Set some arbitrary high z-index
 301+ .css('z-index', mw.getConfig( 'fullScreenIndex' ) )
 302+ .hide()
 303+ .fadeIn("slow")
 304+ );
 305+
 306+ // Change the interface to absolute positioned:
 307+ this.windowPositionStyle = $interface.css( 'position' );
 308+ this.windowZindex = $interface.css( 'z-index' );
 309+
 310+ // Get the base offset:
 311+ this.windowOffset = $interface.offset();
 312+ this.windowOffset.top = this.windowOffset.top - $j(document).scrollTop();
 313+ this.windowOffset.left = this.windowOffset.left - $j(document).scrollLeft();
 314+
 315+ // Change the z-index of the interface
 316+ $interface.css( {
 317+ 'position' : 'fixed',
 318+ 'z-index' : mw.getConfig( 'fullScreenIndex' ) + 1,
 319+ 'top' : this.windowOffset.top,
 320+ 'left' : this.windowOffset.left
 321+ } );
 322+
 323+
 324+
 325+ // Empty out the parent absolute index
 326+ _this.parentsAbsolute = [];
 327+
 328+ // Hide the body scroll bar
 329+ $j('body').css( 'overflow', 'hidden' );
 330+
 331+
 332+ var topOffset = '0px';
 333+ var leftOffset = '0px';
 334+
 335+ //Check if we have an offsetParent
 336+ if( $interface.offsetParent().get(0).tagName.toLowerCase() != 'body' ) {
 337+ topOffset = -this.windowOffset.top + 'px';
 338+ leftOffset = -this.windowOffset.left + 'px';
 339+ }
 340+
 341+ // Resize interface container
 342+ $interface.animate( {
 343+ 'top' : topOffset,
 344+ 'left' : leftOffset,
 345+ 'width' : $j( window ).width(),
 346+ 'height' : $j( window ).height(),
 347+ 'overlow' : 'hidden'
 348+ }, function(){
 349+ // Remove absolute css of the interface parents
 350+ $interface.parents().each( function() {
 351+ //mw.log(' parent : ' + $j( this ).attr('id' ) + ' class: ' + $j( this ).attr('class') + ' pos: ' + $j( this ).css( 'position' ) );
 352+ if( $j( this ).css( 'position' ) == 'absolute' ) {
 353+ _this.parentsAbsolute.push( $j( this ) );
 354+ $j( this ).css( 'position', null );
 355+ mw.log(' should update position: ' + $j( this ).css( 'position' ) );
 356+ }
 357+ } );
 358+ } )
 359+
 360+ // Set the player height width:
 361+ $j( embedPlayer ).css( {
 362+ 'position' : 'relative'
 363+ } )
 364+ // Animate a zoom ( while keeping aspect )
 365+ .animate( _this.getFullscreenPlayerCss() );
 366+
 367+ // Resize the timed text font size per window width
 368+ $interface.find( '.itext' ).css( _this.getFullscreenTextCss() );
 369+
 370+ // Reposition play-btn-large ( this is unfortunately not easy to position with 'margin': 'auto'
 371+ $interface.find('.play-btn-large').animate( _this.getFullscreenPlayButtonCss() )
 372+
 373+ // Bind mouse move in interface to hide control bar
 374+ _this.mouseMovedFlag = false;
 375+ $interface.mousemove( function(e){
 376+ _this.mouseMovedFlag = true;
 377+ });
 378+ // Check every 2 seconds reset flag status:
 379+ function checkMovedMouse(){
 380+ if( _this.fullscreenMode ){
 381+ if( _this.mouseMovedFlag ){
 382+ _this.mouseMovedFlag = false;
 383+ _this.showControlBar();
 384+ // Once we move the mouse keep displayed for 4 seconds
 385+ setTimeout(checkMovedMouse, 4000);
 386+ }else{
 387+ // Check for mouse movement every 250ms
 388+ _this.hideControlBar();
 389+ setTimeout(checkMovedMouse, 250 );
 390+ }
 391+ }
 392+ };
 393+ checkMovedMouse();
 394+
 395+ // Bind Scroll position update
 396+
 397+ // Bind resize resize window to resize window
 398+ $j( window ).resize( function() {
 399+ if( _this.fullscreenMode ){
 400+ // Update interface container:
 401+ $interface.css( {
 402+ 'top' : '0px',
 403+ 'left' : '0px',
 404+ 'width' : $j( window ).width(),
 405+ 'height' : $j( window ).height()
 406+ } )
 407+ // Update player size
 408+ $j( embedPlayer ).css( _this.getFullscreenPlayerCss() );
 409+
 410+ // Update play button pos
 411+ $interface.find('.play-btn-large').css( _this.getFullscreenPlayButtonCss() );
 412+
 413+ // Update the timed text size
 414+ $interface.find( '.itext' ).css( _this.getFullscreenTextCss() );
 415+ }
 416+ });
 417+
 418+ // Bind escape to restore clip resolution
 419+ $j( window ).keyup( function(event) {
 420+ // Escape check
 421+ if( event.keyCode == 27 ){
 422+ _this.restoreWindowPlayer();
 423+ }
 424+ } );
 425+ },
 426+
 427+ /**
 428+ * Restore the window player
 429+ */
 430+ restoreWindowPlayer: function() {
 431+ var _this = this;
 432+ var embedPlayer = this.embedPlayer;
 433+
 434+ // Check fullscreen state
 435+ if( this.fullscreenMode == false ){
 436+ return ;
 437+ }
 438+ // Set fullscreen mode to false
 439+ this.fullscreenMode = false;
 440+
 441+ var $interface = embedPlayer.$interface;
 442+ var interfaceHeight = ( _this.checkOverlayControls() )
 443+ ? embedPlayer.getHeight()
 444+ : embedPlayer.getHeight() + _this.getHeight();
 445+
 446+ $j('.mw-fullscreen-overlay').fadeOut( 'slow' );
 447+ $interface.animate( {
 448+ 'top' : this.windowOffset.top,
 449+ 'left' : this.windowOffset.left,
 450+ // height is embedPlayer height + ctrlBuilder height:
 451+ 'height' : interfaceHeight,
 452+ 'width' : embedPlayer.getWidth()
 453+ },function(){
 454+ // Restore non-absolute layout:
 455+ $interface.css( {
 456+ 'position' : _this.windowPositionStyle,
 457+ 'z-index' : _this.windowZindex,
 458+ 'overlow' : 'visible',
 459+ 'top' : null,
 460+ 'left' : null
 461+ } );
 462+
 463+ //Restore absolute layout of parents:
 464+ $j.each( _this.parentsAbsolute, function( na, element ){
 465+ $j( element ).css( 'position', 'absolute' );
 466+ } );
 467+ _this.parentsAbsolute = null;
 468+
 469+ // Restore the body scroll bar
 470+ $j('body').css( 'overflow', 'auto' );
 471+
 472+ } );
 473+ // Restore the player:
 474+ $j( embedPlayer ).animate( {
 475+ 'top' : '0px',
 476+ 'left' : '0px',
 477+ 'width' : embedPlayer.getWidth(),
 478+ 'height' : embedPlayer.getHeight()
 479+ })
 480+ // Restore the play button
 481+ $interface.find('.play-btn-large').animate( {
 482+ 'left' : ( ( embedPlayer.getPlayerWidth() - this.getComponentWidth( 'playButtonLarge' ) ) / 2 ),
 483+ 'top' : ( ( embedPlayer.getPlayerHeight() -this.getComponentHeight( 'playButtonLarge' ) ) / 2 )
 484+ } );
 485+
 486+ // Restore text size:
 487+ $interface.find( '.itext' ).css({
 488+ 'font-size' : '100%'
 489+ })
 490+ },
 491+
 492+ /**
 493+ * Get minimal width for interface overlay
 494+ */
 495+ getOverlayWidth: function( ) {
 496+ return ( this.embedPlayer.getPlayerWidth() < 300 )? 300 : this.embedPlayer.getPlayerWidth();
 497+ },
 498+
 499+ /**
 500+ * Get minimal height for interface overlay
 501+ */
 502+ getOverlayHeight: function( ) {
 503+ return ( this.embedPlayer.getPlayerHeight() < 200 )? 200 : this.embedPlayer.getPlayerHeight();
 504+ },
 505+
 506+ /**
 507+ * addControlHooks
 508+ * Adds control hooks once controls are in the DOM
 509+ */
 510+ addControlHooks: function( ) {
 511+ // Set up local pointer to the embedPlayer
 512+ var embedPlayer = this.embedPlayer;
 513+ var _this = this;
 514+
 515+ // Setup target shortcut to control-bar
 516+ $target = embedPlayer.$interface;
 517+ var mouseIn = false;
 518+ // Add hide show bindings for control overlay (if overlay is enabled )
 519+ if( _this.checkOverlayControls() ) {
 520+ // Add a special absolute overlay for hover ( to keep menu displayed
 521+ $j( embedPlayer.$interface ).hover(
 522+ function(){
 523+ // Show controls with a set timeout ( avoid fade in fade out on short mouse over )
 524+ setTimeout( function() {
 525+ if( mouseIn ){
 526+ _this.showControlBar()
 527+ }
 528+ }, 250 );
 529+ mouseIn = true;
 530+ },
 531+ function(){
 532+ mouseIn = false;
 533+ // Hide controls ( delay hide if menu is visible )
 534+ function hideCheck(){
 535+ if ( embedPlayer.$interface.find( '.overlay-win' ).length != 0
 536+ || $j('.menuPositionHelper').is(':visible' ) ) {
 537+ setTimeout( hideCheck, 250 );
 538+ return ;
 539+ }
 540+ if( _this.checkOverlayControls() && !mouseIn ) {
 541+ _this.hideControlBar();
 542+ }
 543+
 544+ }
 545+ // Don't remove until user is out of player for 1 second
 546+ setTimeout( hideCheck, 1000 );
 547+ }
 548+ );
 549+ } else {
 550+ $j( embedPlayer.$interface ).unbind().show();
 551+ }
 552+
 553+ // Add recommend firefox if we have non-native playback:
 554+ if ( _this.checkNativeWarning( ) ) {
 555+ _this.doNativeWarning();
 556+ }
 557+
 558+ // Do png fix for ie6
 559+ if ( $j.browser.msie && $j.browser.version <= 6 ) {
 560+ $j('#' + embedPlayer.id + ' .play-btn-large' ).pngFix();
 561+ }
 562+
 563+ this.doVolumeBinding();
 564+
 565+ // Check if we have any custom skin Bindings to run
 566+ if ( this.addSkinControlBindings && typeof( this.addSkinControlBindings ) == 'function' ){
 567+ this.addSkinControlBindings();
 568+ }
 569+ },
 570+
 571+ /**
 572+ * Hide the control bar.
 573+ */
 574+ hideControlBar : function(){
 575+ var animateDuration = 'slow'
 576+ // Else hide the control bar ( if checkOverlayControls is still true )
 577+ this.embedPlayer.$interface.find( '.control-bar').fadeOut( animateDuration );
 578+ this.embedPlayer.$interface.find( '.itext' ).animate( {
 579+ 'bottom' : 10
 580+ }, animateDuration );
 581+
 582+ },
 583+
 584+ /**
 585+ * Show the control bar
 586+ */
 587+ showControlBar : function(){
 588+ var animateDuration = 'slow'
 589+ // Show controls
 590+ this.embedPlayer.$interface.find( '.control-bar').fadeIn( animateDuration );
 591+ // Move up itext if present
 592+ this.embedPlayer.$interface.find( '.itext' ).animate( {
 593+ 'bottom' : this.getHeight() + 10
 594+ }, animateDuration );
 595+
 596+ },
 597+
 598+ /**
 599+ * Checks if the browser supports overlays and the controlsOverlay is
 600+ * set to true for the player or via config
 601+ */
 602+ checkOverlayControls: function(){
 603+ //if the player "supports" overlays:
 604+ if( ! this.embedPlayer.supports['overlays'] ){
 605+ return false;
 606+ }
 607+ // If the config is false
 608+ if( mw.getConfig( 'overlayControls' ) === false){
 609+ return false;
 610+ }
 611+ // If disabled via the player
 612+ if( this.embedPlayer.overlayControls === false ){
 613+ return false;
 614+ }
 615+ // don't hide controls when content "height" is 0 ( audio tags )
 616+ if( this.embedPlayer.height == 0 ){
 617+ return false;
 618+ }
 619+ // Past alll tests OverlayControls is true:
 620+ return true;
 621+ },
 622+
 623+ /**
 624+ * Check if a warning should be issued to non-native playback systems
 625+ *
 626+ * dependent on mediaElement being setup
 627+ */
 628+ checkNativeWarning: function( ) {
 629+ // Check cookie to see if user requested to hide it
 630+ if ( $j.cookie( 'show_player_warning' ) == 'false' ) {
 631+ return false;
 632+ }
 633+
 634+ // If the resolution is too small don't display the warning
 635+ if( this.embedPlayer.getPlayerHeight() < 199 ){
 636+ return false;
 637+ }
 638+
 639+ // See if we have native support for ogg:
 640+ var supportingPlayers = mw.EmbedTypes.players.getMIMETypePlayers( 'video/ogg' );
 641+ for ( var i = 0; i < supportingPlayers.length; i++ ) {
 642+ if ( supportingPlayers[i].id == 'oggNative' ) {
 643+ return false;
 644+ }
 645+ }
 646+
 647+ // Check for h264 source and playback support
 648+ var supportingPlayers = mw.EmbedTypes.players.getMIMETypePlayers( 'video/h264' );
 649+ var h264streams = this.embedPlayer.mediaElement.getSources( 'video/h264' );
 650+ if( supportingPlayers.length && h264streams.length ){
 651+ // No firefox link if a h.264 stream is present
 652+ return false;
 653+ }
 654+
 655+ // Should issue the native warning
 656+ return true;
 657+ },
 658+
 659+ /**
 660+ * Does a native warning check binding to the player on mouse over.
 661+ */
 662+ doNativeWarning: function( ) {
 663+ // Set up local pointer to the embedPlayer
 664+ var embedPlayer = this.embedPlayer;
 665+ var _this = this;
 666+
 667+ $j( embedPlayer ).hover(
 668+ function() {
 669+ if ( $j( '#gnp_' + embedPlayer.id ).length == 0 ) {
 670+ var toppos = ( embedPlayer.instanceOf == 'mvPlayList' ) ? 25 : 10;
 671+
 672+ $j( this ).append(
 673+ $j('<div />')
 674+ .attr( {
 675+ 'id': "gnp_" + embedPlayer.id
 676+ } )
 677+ .addClass( 'ui-state-highlight ui-corner-all' )
 678+ .css({
 679+ 'position' : 'absolute',
 680+ 'display' : 'none',
 681+ 'background' : '#FFF',
 682+ 'color' : '#111',
 683+ 'top' : toppos + 'px',
 684+ 'left' : '10px',
 685+ 'right' : '10px'
 686+ })
 687+ .html( gM( 'mwe-for_best_experience' ) )
 688+ )
 689+
 690+ $target_warning = $j( '#gnp_' + embedPlayer.id );
 691+
 692+ $target_warning.append(
 693+ $j('<br />')
 694+ );
 695+
 696+
 697+ $target_warning.append(
 698+ $j( '<input />' )
 699+ .attr({
 700+ 'id' : 'ffwarn_' + embedPlayer.id,
 701+ 'type' : "checkbox",
 702+ 'name' : 'ffwarn_' + embedPlayer.id
 703+ })
 704+ .click( function() {
 705+ if ( $j( this ).is( ':checked' ) ) {
 706+ // Set up a cookie for 7 days:
 707+ $j.cookie( 'show_player_warning', false, { expires: 7 } );
 708+ // Set the current instance
 709+ mw.setConfig( 'show_player_warning', false );
 710+ $j( '#gnp_' + embedPlayer.id ).fadeOut( 'slow' );
 711+ } else {
 712+ mw.setConfig( 'show_player_warning', true );
 713+ $j.cookie( 'show_player_warning', true );
 714+ }
 715+ } )
 716+ );
 717+ $target_warning.append(
 718+ $j('<span />')
 719+ .text( gM( 'mwe-do_not_warn_again' ) )
 720+ )
 721+ }
 722+
 723+ // Only show the warning if cookie and config are true
 724+ if ( mw.getConfig( 'show_player_warning' ) === true ){
 725+ $j( '#gnp_' + embedPlayer.id ).fadeIn( 'slow' );
 726+ }
 727+ },
 728+ function() {
 729+ $j( '#gnp_' + embedPlayer.id ).fadeOut( 'slow' );
 730+ }
 731+ );
 732+ },
 733+
 734+ /**
 735+ * Binds the volume controls
 736+ */
 737+ doVolumeBinding: function( ) {
 738+ var embedPlayer = this.embedPlayer;
 739+ var _this = this;
 740+ embedPlayer.$interface.find( '.volume_control' ).unbind().buttonHover().click( function() {
 741+ mw.log( 'Volume control toggle' );
 742+ embedPlayer.toggleMute();
 743+ } );
 744+
 745+ // Add vertical volume display hover
 746+ if ( this.volume_layout == 'vertical' ) {
 747+ // Default volume binding:
 748+ var hoverOverDelay = false;
 749+ var $targetvol = embedPlayer.$interface.find( '.vol_container' );
 750+ embedPlayer.$interface.find( '.volume_control' ).hover(
 751+ function() {
 752+ $targetvol.addClass( 'vol_container_top' );
 753+ // Set to "below" if playing and embedType != native
 754+ if ( embedPlayer && embedPlayer.isPlaying && embedPlayer.isPlaying() && !embedPlayer.supports['overlays'] ) {
 755+ $targetvol.removeClass( 'vol_container_top' ).addClass( 'vol_container_below' );
 756+ }
 757+ $targetvol.fadeIn( 'fast' );
 758+ hoverOverDelay = true;
 759+ },
 760+ function() {
 761+ hoverOverDelay = false;
 762+ setTimeout( function() {
 763+ if ( !hoverOverDelay ) {
 764+ $targetvol.fadeOut( 'fast' );
 765+ }
 766+ }, 500 );
 767+ }
 768+ );
 769+ }
 770+
 771+ // Setup play-head slider:
 772+ var sliderConf = {
 773+ range: "min",
 774+ value: 80,
 775+ min: 0,
 776+ max: 100,
 777+ slide: function( event, ui ) {
 778+ var perc = ui.value / 100;
 779+ // mw.log('update volume:' + perc);
 780+ embedPlayer.updateVolumen( perc );
 781+ },
 782+ change:function( event, ui ) {
 783+ var perc = ui.value / 100;
 784+ if ( perc == 0 ) {
 785+ embedPlayer.$interface.find( '.volume_control span' ).removeClass( 'ui-icon-volume-on' ).addClass( 'ui-icon-volume-off' );
 786+ } else {
 787+ embedPlayer.$interface.find( '.volume_control span' ).removeClass( 'ui-icon-volume-off' ).addClass( 'ui-icon-volume-on' );
 788+ }
 789+ var perc = ui.value / 100;
 790+ embedPlayer.updateVolumen( perc );
 791+ }
 792+ }
 793+
 794+ if ( this.volume_layout == 'vertical' ) {
 795+ sliderConf[ 'orientation' ] = "vertical";
 796+ }
 797+
 798+ embedPlayer.$interface.find( '.volume-slider' ).slider( sliderConf );
 799+ },
 800+
 801+ /**
 802+ * Get the options menu ul with li menu items
 803+ */
 804+ getOptionsMenu: function( ) {
 805+ $optionsMenu = $j( '<ul />' );
 806+ for( var i in this.optionMenuItems ){
 807+
 808+ // Make sure its supported in the current ctrlBuilder config:
 809+ if( ! this.supportedMenuItems[ i ] ) {
 810+ continue;
 811+ }
 812+ $optionsMenu.append(
 813+ this.optionMenuItems[i]( this )
 814+ );
 815+ }
 816+ return $optionsMenu;
 817+ },
 818+
 819+ /**
 820+ * Allow the ctrlBuilder to do interface actions onDone
 821+ */
 822+ onClipDone: function(){
 823+ // Related videos could be shown here
 824+ },
 825+
 826+ /**
 827+ * Option menu items
 828+ *
 829+ * @return
 830+ * 'li' a li line item with click action for that menu item
 831+ */
 832+ optionMenuItems: {
 833+ // Player select menu item
 834+ 'playerSelect': function( ctrlObj ){
 835+ return $j.getLineItem(
 836+ gM( 'mwe-chose_player' ),
 837+ 'gear',
 838+ function( ) {
 839+ ctrlObj.displayOverlay(
 840+ ctrlObj.getPlayerSelect()
 841+ );
 842+ }
 843+ )
 844+ },
 845+
 846+ // Download the file menu
 847+ 'download': function( ctrlObj ) {
 848+ return $j.getLineItem(
 849+ gM( 'mwe-download' ),
 850+ 'disk',
 851+ function( ) {
 852+ ctrlObj.displayOverlay( gM('mwe-loading_txt' ) );
 853+ // Call show download with the target to be populated
 854+ ctrlObj.showDownload(
 855+ ctrlObj.embedPlayer.$interface.find( '.overlay-content' )
 856+ );
 857+ }
 858+ )
 859+ },
 860+
 861+ // Share the video menu
 862+ 'share': function( ctrlObj ) {
 863+ return $j.getLineItem(
 864+ gM( 'mwe-share' ),
 865+ 'mail-closed',
 866+ function( ) {
 867+ ctrlObj.displayOverlay(
 868+ ctrlObj.getShare()
 869+ );
 870+ }
 871+ )
 872+ }
 873+ },
 874+
 875+ /**
 876+ * Close a menu overlay
 877+ */
 878+ closeMenuOverlay: function(){
 879+ var _this = this;
 880+ var embedPlayer = this.embedPlayer;
 881+ var $overlay = embedPlayer.$interface.find( '.overlay-win,.ui-widget-overlay,.ui-widget-shadow' );
 882+
 883+ $overlay.fadeOut( "slow", function() {
 884+ $overlay.remove();
 885+ } );
 886+ // Show the big play button:
 887+ embedPlayer.$interface.find( '.play-btn-large' ).fadeIn( 'slow' );
 888+ return false; // onclick action return false
 889+ },
 890+
 891+ /**
 892+ * Generic function to display custom HTML overlay
 893+ * on video.
 894+ *
 895+ * @param {String} overlayContent content to be displayed
 896+ */
 897+ displayOverlay: function( overlayContent ) {
 898+ var _this = this;
 899+ var embedPlayer = this.embedPlayer;
 900+
 901+ if ( !this.supportedComponets[ 'overlays' ] ) {
 902+ embedPlayer.stop();
 903+ }
 904+ // Hide the big play button:
 905+ embedPlayer.$interface.find( '.play-btn-large' ).hide();
 906+
 907+ // Check if overlay window is already present:
 908+ if ( embedPlayer.$interface.find( '.overlay-win' ).length != 0 ) {
 909+ //Update the content
 910+ embedPlayer.$interface.find( '.overlay-content' ).html(
 911+ overlayContent
 912+ );
 913+ return ;
 914+ }
 915+
 916+ // Add an overlay
 917+ embedPlayer.$interface.append(
 918+ $j('<div />')
 919+ .addClass( 'ui-widget-overlay' )
 920+ .css( {
 921+ 'height' : '100%',
 922+ 'width' : '100%',
 923+ 'z-index' : 2
 924+ } )
 925+ );
 926+
 927+ // Setup the close button
 928+ $closeButton = $j('<span />')
 929+ .addClass( 'ui-icon ui-icon-closethick' )
 930+ .css({
 931+ 'position': 'absolute',
 932+ 'cursor' : 'pointer',
 933+ 'top' : '2px',
 934+ 'right' : '2px'
 935+ })
 936+ .buttonHover()
 937+ .click( function() {
 938+ _this.closeMenuOverlay();
 939+ } );
 940+
 941+ var overlayMenuCss = {
 942+ 'height' : 200,
 943+ 'width' : 250,
 944+ 'position' : 'absolute',
 945+ 'left' : '10px',
 946+ 'top': '15px',
 947+ 'overflow' : 'auto',
 948+ 'padding' : '4px',
 949+ 'z-index' : 3
 950+ };
 951+ $overlayMenu = $j('<div />')
 952+ .addClass( 'overlay-win ui-state-default ui-widget-header ui-corner-all' )
 953+ .css( overlayMenuCss )
 954+ .append(
 955+ $closeButton,
 956+ $j('<div />')
 957+ .addClass( 'overlay-content' )
 958+ .append( overlayContent )
 959+ )
 960+
 961+ // Clone the overlay menu css:
 962+ var shadowCss = jQuery.extend( true, {}, overlayMenuCss );
 963+ shadowCss['height' ] = 210;
 964+ shadowCss['width' ] = 260;
 965+ shadowCss[ 'z-index' ] = 2;
 966+ $overlayShadow = $j( '<div />' )
 967+ .addClass('ui-widget-shadow ui-corner-all')
 968+ .css( shadowCss );
 969+
 970+ // Append the overlay menu to the player interface
 971+ embedPlayer.$interface.prepend(
 972+ $overlayMenu,
 973+ $overlayShadow
 974+ )
 975+ .find( '.overlay-win' )
 976+ .fadeIn( "slow" );
 977+
 978+ return false; // onclick action return false
 979+ },
 980+
 981+ /**
 982+ * Get the "share" interface
 983+ *
 984+ * TODO share should be enabled via <embed> tag usage to be compatible
 985+ * with sites social networking sites that allow <embed> tags but not js
 986+ *
 987+ * @param {Object} $target Target jQuery object to set share html
 988+ */
 989+ getShare: function( ) {
 990+ var embedPlayer = this.embedPlayer;
 991+ var embed_code = embedPlayer.getEmbeddingHTML();
 992+ var _this = this;
 993+
 994+ var $shareInterface = $j('<div />');
 995+
 996+ $shareList = $j( '<ul />' );
 997+
 998+ $shareList
 999+ .append(
 1000+ $j('<li />')
 1001+ .append(
 1002+ $j('<a />')
 1003+ .attr('href', '#')
 1004+ .addClass( 'active' )
 1005+ .text(
 1006+ gM( 'mwe-embed_site_or_blog' )
 1007+ )
 1008+ )
 1009+ )
 1010+
 1011+ $shareInterface.append(
 1012+ $j( '<h2 />' )
 1013+ .text( gM( 'mwe-share_this_video' ) )
 1014+ .append(
 1015+ $shareList
 1016+ )
 1017+ );
 1018+
 1019+ $shareInterface.append(
 1020+
 1021+ $j('<span />')
 1022+ .addClass( 'source_wrap' )
 1023+ .html(
 1024+ $j( '<textarea />' )
 1025+ .html( embed_code )
 1026+ .click( function() {
 1027+ $j( this ).select();
 1028+ })
 1029+ ),
 1030+
 1031+ $j('<br />'),
 1032+ $j('<br />'),
 1033+
 1034+ $j('<button />')
 1035+ .addClass( 'ui-state-default ui-corner-all copycode' )
 1036+ .text( gM( 'mwe-copy-code' ) )
 1037+ .click(function() {
 1038+ $target.find( 'textarea' ).focus().select();
 1039+ // Copy the text if supported:
 1040+ if ( document.selection ) {
 1041+ CopiedTxt = document.selection.createRange();
 1042+ CopiedTxt.execCommand( "Copy" );
 1043+ }
 1044+ } )
 1045+
 1046+ );
 1047+ return $shareInterface;
 1048+ },
 1049+
 1050+ /**
 1051+ * Shows the Player Select interface
 1052+ *
 1053+ * @param {Object} $target jQuery target for output
 1054+ */
 1055+ getPlayerSelect: function( ) {
 1056+ mw.log('getPlayerSelect::');
 1057+
 1058+ var embedPlayer = this.embedPlayer;
 1059+
 1060+ var _this = this;
 1061+
 1062+ $playerSelect = $j('<div />')
 1063+ .append(
 1064+ $j( '<h2 />' )
 1065+ .text( gM( 'mwe-chose_player' ) )
 1066+ );
 1067+
 1068+ $j.each( embedPlayer.mediaElement.getPlayableSources(), function( source_id, source ) {
 1069+ var playable = mw.EmbedTypes.players.defaultPlayer( source.getMIMEType() );
 1070+
 1071+ var is_selected = ( source == embedPlayer.mediaElement.selected_source );
 1072+
 1073+ $playerSelect.append(
 1074+ $j( '<h2 />' )
 1075+ .text( source.getTitle() )
 1076+ );
 1077+
 1078+ if ( playable ) {
 1079+ $playerList = $j('<ul />');
 1080+ // output the player select code:
 1081+ var supportingPlayers = mw.EmbedTypes.players.getMIMETypePlayers( source.getMIMEType() );
 1082+
 1083+ for ( var i = 0; i < supportingPlayers.length ; i++ ) {
 1084+
 1085+ // Add link to select the player if not already selected )
 1086+ if( embedPlayer.selected_player.id == supportingPlayers[i].id && is_selected ) {
 1087+ // Active player ( no link )
 1088+ $playerLine = $j( '<span />' )
 1089+ .text(
 1090+ supportingPlayers[i].getName()
 1091+ )
 1092+ .addClass( 'ui-state-highlight ui-corner-all' );
 1093+ } else {
 1094+ // Non active player add link to select:
 1095+ $playerLine = $j( '<a />')
 1096+ .attr({
 1097+ 'href' : '#',
 1098+ 'rel' : 'sel_source',
 1099+ 'id' : 'sc_' + source_id + '_' + supportingPlayers[i].id
 1100+ })
 1101+ .addClass( 'ui-corner-all')
 1102+ .text( supportingPlayers[i].getName() )
 1103+ .click( function() {
 1104+ var iparts = $j( this ).attr( 'id' ).replace(/sc_/ , '' ).split( '_' );
 1105+ var source_id = iparts[0];
 1106+ var default_player_id = iparts[1];
 1107+ mw.log( 'source id: ' + source_id + ' player id: ' + default_player_id );
 1108+
 1109+ embedPlayer.ctrlBuilder.closeMenuOverlay();
 1110+
 1111+ // Close fullscreen if we are in fullscreen mode
 1112+ if( _this.fullscreenMode ){
 1113+ _this.restoreWindowPlayer()
 1114+ }
 1115+
 1116+ embedPlayer.mediaElement.selectSource( source_id );
 1117+
 1118+ mw.EmbedTypes.players.setPlayerPreference(
 1119+ default_player_id,
 1120+ embedPlayer.mediaElement.sources[ source_id ].getMIMEType()
 1121+ );
 1122+
 1123+ // Issue a stop
 1124+ embedPlayer.stop();
 1125+
 1126+ // Don't follow the # link:
 1127+ return false;
 1128+ } )
 1129+ .hover(
 1130+ function(){
 1131+ $j( this ).addClass('ui-state-active')
 1132+ },
 1133+ function(){
 1134+ $j( this ).removeClass('ui-state-active')
 1135+ }
 1136+ );
 1137+ }
 1138+
 1139+ // Add the player line to the player list:
 1140+ $playerList.append(
 1141+ $j( '<li />' ).append(
 1142+ $playerLine
 1143+ )
 1144+ );
 1145+ }
 1146+
 1147+ // Append the player list:
 1148+ $playerSelect.append( $playerList );
 1149+
 1150+ } else {
 1151+ // No player available:
 1152+ $playerSelect.append( gM( 'mwe-no-player', source.getTitle() ) )
 1153+ }
 1154+ } );
 1155+
 1156+ // Return the player select elements
 1157+ return $playerSelect;
 1158+ },
 1159+
 1160+ /**
 1161+ * Loads sources and calls showDownloadWithSources
 1162+ * @param {Object} $target jQuery target to output to
 1163+ */
 1164+ showDownload: function( $target ) {
 1165+ var _this = this;
 1166+ var embedPlayer = this.embedPlayer;
 1167+ // Load the roe if available (to populate out download options:
 1168+ // mw.log('f:showDownload '+ this.roe + ' ' + this.mediaElement.addedROEData);
 1169+ if ( embedPlayer.roe && embedPlayer.mediaElement.addedROEData == false ) {
 1170+ $target.html( gM( 'mwe-loading_txt' ) );
 1171+ embedPlayer.getMvJsonUrl( this.roe, function( data ) {
 1172+ embedPlayer.mediaElement.addROE( data );
 1173+ _this.showDownloadWithSources( $target );
 1174+ } );
 1175+ } else {
 1176+ _this.showDownloadWithSources( $target );
 1177+ }
 1178+ },
 1179+
 1180+ /**
 1181+ * Shows the download interface with sources loaded
 1182+ * @param {Object} $target jQuery target to output to
 1183+ */
 1184+ showDownloadWithSources : function( $target ) {
 1185+ var _this = this;
 1186+ mw.log( 'showDownloadWithSources::' + $target.length );
 1187+ var embedPlayer = this.embedPlayer;
 1188+ // Empty the target:
 1189+ $target.empty();
 1190+
 1191+ var $mediaList = $j( '<ul />' );
 1192+ var $textList = $j( '<ul />' );
 1193+ $j.each( embedPlayer.mediaElement.getSources(), function( index, source ) {
 1194+ if( source.getSrc() ) {
 1195+ mw.log("add src: " + source.getTitle() );
 1196+ var $dl_line = $j( '<li />').append(
 1197+ $j('<a />')
 1198+ .attr( 'href', source.getSrc() )
 1199+ .text( source.getTitle() )
 1200+ );
 1201+ // Add link to correct "bucket"
 1202+
 1203+ //Add link to time segment:
 1204+ if ( source.getSrc().indexOf( '?t=' ) !== -1 ) {
 1205+ $target.append( $dl_line );
 1206+ } else if ( this.getMIMEType() == "text/cmml" || this.getMIMEType() == "text/x-srt" ) {
 1207+ // Add link to text list
 1208+ $textList.append( $dl_line );
 1209+ } else {
 1210+ // Add link to media list
 1211+ $mediaList.append( $dl_line );
 1212+ }
 1213+
 1214+ }
 1215+ } );
 1216+ if( $mediaList.find('li').length != 0 ) {
 1217+ $target.append(
 1218+ $j('<h2 />')
 1219+ .text( gM( 'mwe-download_full' ) ),
 1220+ $mediaList
 1221+ )
 1222+ }
 1223+
 1224+ if( $textList.find('li').length != 0 ) {
 1225+ $target.append(
 1226+ $j('<h2 />')
 1227+ .text( gM( 'mwe-download_text' ) ),
 1228+ $textList
 1229+ )
 1230+ }
 1231+ },
 1232+
 1233+
 1234+ /**
 1235+ * Get component
 1236+ *
 1237+ * @param {String} component_id Component key to grab html output
 1238+ */
 1239+ getComponent: function( component_id ) {
 1240+ if ( this.components[ component_id ] ) {
 1241+ return this.components[ component_id ].o( this );
 1242+ } else {
 1243+ return false;
 1244+ }
 1245+ },
 1246+
 1247+ /**
 1248+ * Get a component height
 1249+ *
 1250+ * @param {String} component_id Component key to grab height
 1251+ * @return height or false if not set
 1252+ */
 1253+ getComponentHeight: function( component_id ) {
 1254+ if ( this.components[ component_id ]
 1255+ && this.components[ component_id ].h )
 1256+ {
 1257+ return this.components[ component_id ].h
 1258+ }
 1259+ return false;
 1260+ },
 1261+
 1262+ /**
 1263+ * Get a component width
 1264+ * @param {String} component_id Component key to grab width
 1265+ * @return width or false if not set
 1266+ */
 1267+ getComponentWidth: function( component_id ){
 1268+ if ( this.components[ component_id ]
 1269+ && this.components[ component_id ].w )
 1270+ {
 1271+ return this.components[ component_id ].w
 1272+ }
 1273+ return false;
 1274+ },
 1275+
 1276+ /**
 1277+ * Components Object
 1278+ * Take in the embedPlayer and return some html for the given component.
 1279+ *
 1280+ * components can be overwritten by skin javascript
 1281+ *
 1282+ * Component JSON structure is as follows:
 1283+ * 'o' Function to return a binded jQuery object ( accepts the ctrlObject as a parameter )
 1284+ * 'w' The width of the component
 1285+ * 'h' The height of the component ( if height is undefined the height of the control bar is used )
 1286+ */
 1287+ components: {
 1288+ /**
 1289+ * The large play button in center of the player
 1290+ */
 1291+ 'playButtonLarge': {
 1292+ 'w' : 130,
 1293+ 'h' : 96,
 1294+ 'o' : function( ctrlObj ) {
 1295+
 1296+ return $j( '<div/>' )
 1297+ .attr( {
 1298+ 'title' : gM( 'mwe-play_clip' ),
 1299+ 'class' : "ui-state-default play-btn-large"
 1300+ } )
 1301+ // Get dynamic position for big play button
 1302+ .css( {
 1303+ 'left' : ( ( ctrlObj.embedPlayer.getPlayerWidth() - this.w ) / 2 ),
 1304+ 'top' : ( ( ctrlObj.embedPlayer.getPlayerHeight() - this.h ) / 2 )
 1305+ } )
 1306+ // Add play hook:
 1307+ .buttonHover().click( function() {
 1308+ ctrlObj.embedPlayer.play();
 1309+ } );
 1310+ }
 1311+ },
 1312+
 1313+ /**
 1314+ * The kaltura attribution button
 1315+ */
 1316+ 'kalturaAttribution' : {
 1317+ 'w' : 28,
 1318+ 'o' : function( ctrlObj ){
 1319+ return $j('<a />')
 1320+ .attr({
 1321+ 'href': 'http://kaltura.com',
 1322+ 'title' : gM( 'mwe-kaltura-platform-title' ),
 1323+ 'target' : '_new'
 1324+ })
 1325+ .append(
 1326+ $j( '<div />' )
 1327+ .addClass( 'rButton' )
 1328+ .css({
 1329+ 'top' : '9px',
 1330+ 'left' : '2px'
 1331+ })
 1332+ .append(
 1333+ $j('<span />')
 1334+ .addClass( 'ui-icon kaltura-icon' )
 1335+ )
 1336+ )
 1337+ }
 1338+ },
 1339+
 1340+ /**
 1341+ * The options button, invokes display of the options menu
 1342+ */
 1343+ 'options': {
 1344+ 'w': 28,
 1345+ 'o': function( ctrlObj ) {
 1346+ return $j( '<div />' )
 1347+ .attr( 'title', gM( 'mwe-player_options' ) )
 1348+ .addClass( 'ui-state-default ui-corner-all ui-icon_link rButton options-btn' )
 1349+ .append(
 1350+ $j('<span />')
 1351+ .addClass( 'ui-icon ui-icon-wrench' )
 1352+ )
 1353+ .buttonHover()
 1354+ // Options binding:
 1355+ .menu( {
 1356+ 'content' : ctrlObj.getOptionsMenu(),
 1357+ 'zindex' : mw.getConfig( 'fullScreenIndex' ) + 1,
 1358+ 'positionOpts': {
 1359+ 'directionV' : 'up',
 1360+ 'offsetY' : 30,
 1361+ 'directionH' : 'left',
 1362+ 'offsetX' : -28
 1363+ }
 1364+ } );
 1365+ }
 1366+ },
 1367+
 1368+ /**
 1369+ * The fullscreen button for displaying the video fullscreen
 1370+ */
 1371+ 'fullscreen': {
 1372+ 'w': 28,
 1373+ 'o': function( ctrlObj ) {
 1374+
 1375+ // Setup "dobuleclick" fullscreen binding to embedPlayer
 1376+ $j( ctrlObj.embedPlayer ).unbind("dblclick").bind("dblclick", function(){
 1377+ ctrlObj.embedPlayer.fullscreen();
 1378+ });
 1379+
 1380+ return $j( '<div />' )
 1381+ .attr( 'title', gM( 'mwe-player_fullscreen' ) )
 1382+ .addClass( "ui-state-default ui-corner-all ui-icon_link rButton fullscreen-btn" )
 1383+ .append(
 1384+ $j( '<span />' )
 1385+ .addClass( "ui-icon ui-icon-arrow-4-diag" )
 1386+ )
 1387+ // Fullscreen binding:
 1388+ .buttonHover().click( function() {
 1389+ ctrlObj.embedPlayer.fullscreen();
 1390+ } );
 1391+ }
 1392+ },
 1393+
 1394+
 1395+ /**
 1396+ * The pause / play button
 1397+ */
 1398+ 'pause': {
 1399+ 'w': 28,
 1400+ 'o': function( ctrlObj ) {
 1401+ return $j( '<div />' )
 1402+ .attr( 'title', gM( 'mwe-play_clip' ) )
 1403+ .addClass ( "ui-state-default ui-corner-all ui-icon_link lButton play-btn" )
 1404+ .append(
 1405+ $j( '<span />' )
 1406+ .addClass( "ui-icon ui-icon-play" )
 1407+ )
 1408+ // Play / pause binding
 1409+ .buttonHover()
 1410+ .click( function() {
 1411+ ctrlObj.embedPlayer.play();
 1412+ });
 1413+ }
 1414+ },
 1415+
 1416+ /**
 1417+ * The closed captions button
 1418+ */
 1419+ 'timedText': {
 1420+ 'w': 28,
 1421+ 'o': function( ctrlObj ) {
 1422+ return $j( '<div />' )
 1423+ .attr( 'title', gM( 'mwe-timed_text' ) )
 1424+ .addClass( "ui-state-default ui-corner-all ui-icon_link rButton timed-text" )
 1425+ .append(
 1426+ $j( '<span />' )
 1427+ .addClass( "ui-icon ui-icon-comment" )
 1428+ )
 1429+ // Captions binding:
 1430+ .buttonHover()
 1431+ .click( function() {
 1432+ ctrlObj.embedPlayer.showTextInterface();
 1433+ } )
 1434+ }
 1435+ },
 1436+
 1437+ /**
 1438+ * The volume control interface html
 1439+ */
 1440+ 'volumeControl': {
 1441+ 'w' : 28,
 1442+ 'o' : function( ctrlObj ) {
 1443+ mw.log(' set up volume out');
 1444+ $volumeOut = $j( '<span />' );
 1445+ if ( ctrlObj.volume_layout == 'horizontal' ) {
 1446+ $volumeOut.append(
 1447+ $j( '<div />' )
 1448+ .addClass( "ui-slider ui-slider-horizontal rButton volume-slider" )
 1449+ );
 1450+ }
 1451+ mw.log(' add up volume control icon');
 1452+ // Add the volume control icon
 1453+ $volumeOut.append(
 1454+ $j('<div />')
 1455+ .attr( 'title', gM( 'mwe-volume_control' ) )
 1456+ .addClass( "ui-state-default ui-corner-all ui-icon_link rButton volume_control" )
 1457+ .append(
 1458+ $j( '<span />' )
 1459+ .addClass( "ui-icon ui-icon-volume-on" )
 1460+ )
 1461+ );
 1462+ mw.log(' if verticle add container ');
 1463+ if ( ctrlObj.volume_layout == 'vertical' ) {
 1464+ $volumeOut.find('.volume_control').append(
 1465+ $j( '<div />' )
 1466+ .css( {
 1467+ 'position' : 'absolute',
 1468+ 'left' : '0px'
 1469+ })
 1470+ .hide()
 1471+ .addClass( "vol_container ui-corner-all" )
 1472+ .append(
 1473+ $j( '<div />' )
 1474+ .addClass ( "volume-slider" )
 1475+ )
 1476+ );
 1477+ }
 1478+ mw.log('get inner volume html');
 1479+ //Return the inner html
 1480+ return $volumeOut.html();
 1481+ }
 1482+ },
 1483+
 1484+ /*
 1485+ * The time display area
 1486+ */
 1487+ 'timeDisplay': {
 1488+ 'w' : 100,
 1489+ 'o' : function( ctrlObj ) {
 1490+ return $j( '<div />' )
 1491+ .addClass( "ui-widget time-disp" )
 1492+ .append(
 1493+ ctrlObj.embedPlayer.getTimeRange()
 1494+ )
 1495+
 1496+ }
 1497+ },
 1498+
 1499+ /**
 1500+ * The playhead component
 1501+ */
 1502+ 'playHead': {
 1503+ 'w':0, // special case (takes up remaining space)
 1504+ 'o':function( ctrlObj ) {
 1505+ var embedPlayer = ctrlObj.embedPlayer;
 1506+ var _this = this;
 1507+ var $playHead = $j( '<div />' )
 1508+ .addClass ( "play_head" )
 1509+ .css({
 1510+ "position" : 'absolute',
 1511+ "left" : '33px',
 1512+ "right" : ( ( embedPlayer.getPlayerWidth() - ctrlObj.available_width ) - 33) + 'px'
 1513+ })
 1514+ // Playhead binding
 1515+ .slider( {
 1516+ range: "min",
 1517+ value: 0,
 1518+ min: 0,
 1519+ max: 1000,
 1520+ start: function( event, ui ) {
 1521+ var id = ( embedPlayer.pc != null ) ? embedPlayer.pc.pp.id:embedPlayer.id;
 1522+ embedPlayer.userSlide = true;
 1523+ $j( id + ' .play-btn-large' ).fadeOut( 'fast' );
 1524+ // If playlist always start at 0
 1525+ embedPlayer.start_time_sec = ( embedPlayer.instanceOf == 'mvPlayList' ) ? 0:
 1526+ mw.npt2seconds( embedPlayer.getTimeRange().split( '/' )[0] );
 1527+ },
 1528+ slide: function( event, ui ) {
 1529+ var perc = ui.value / 1000;
 1530+ embedPlayer.jump_time = mw.seconds2npt( parseFloat( parseFloat( embedPlayer.getDuration() ) * perc ) + embedPlayer.start_time_sec );
 1531+ // mw.log('perc:' + perc + ' * ' + embedPlayer.getDuration() + ' jt:'+ this.jump_time);
 1532+ if ( _this.longTimeDisp ) {
 1533+ embedPlayer.setStatus( gM( 'mwe-seek_to', embedPlayer.jump_time ) );
 1534+ } else {
 1535+ embedPlayer.setStatus( embedPlayer.jump_time );
 1536+ }
 1537+ // Update the thumbnail / frame
 1538+ if ( embedPlayer.isPlaying == false ) {
 1539+ embedPlayer.updateThumbPerc( perc );
 1540+ }
 1541+ },
 1542+ change:function( event, ui ) {
 1543+ // Only run the onChange event if done by a user slide
 1544+ // (otherwise it runs times it should not)
 1545+ if ( embedPlayer.userSlide ) {
 1546+ embedPlayer.userSlide = false;
 1547+ embedPlayer.seeking = true;
 1548+
 1549+ var perc = ui.value / 1000;
 1550+ // set seek time (in case we have to do a url seek)
 1551+ embedPlayer.seek_time_sec = mw.npt2seconds( embedPlayer.jump_time, true );
 1552+ mw.log( 'do jump to: ' + embedPlayer.jump_time + ' perc:' + perc + ' sts:' + embedPlayer.seek_time_sec );
 1553+ embedPlayer.setStatus( gM( 'mwe-seeking' ) );
 1554+ embedPlayer.doSeek( perc );
 1555+ }
 1556+ }
 1557+ } );
 1558+
 1559+ // Up the z-index of the default status indicator:
 1560+ $playHead.find( 'ui-slider-handle' ).css( 'z-index', 4 );
 1561+ $playHead.find( '.ui-slider-range' ).addClass( 'ui-corner-all' ).css( 'z-index', 2 );
 1562+
 1563+ // Add buffer html:
 1564+ $playHead.append(
 1565+ $j('<div />')
 1566+ .addClass( "ui-slider-range ui-slider-range-min ui-widget-header")
 1567+ .addClass( "ui-state-highlight ui-corner-all mw_buffer")
 1568+ );
 1569+
 1570+ return $playHead;
 1571+ }
 1572+ }
 1573+ }
 1574+};
Property changes on: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/skins/ctrlBuilder.js
___________________________________________________________________
Added: svn:mergeinfo
11575 Merged /branches/sqlite/js2/mwEmbed/skins/ctrlBuilder.js:r58211-58321
21576 Merged /branches/REL1_15/phase3/js2/mwEmbed/skins/ctrlBuilder.js:r51646
Added: svn:eol-style
31577 + native
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/javaEmbed.js
@@ -1,4 +1,4 @@
2 -/*
 2+/**
33 * List of domains and hosted location of cortado. Lets clients avoid the security warning for cross domain cortado
44 */
55 window.cortadoDomainLocations = {
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/loader.js
@@ -43,13 +43,16 @@
4444 // The default share embed mode ( can be "object" or "videojs" )
4545 //
4646 // "object" will provide a <object tag pointing to mwEmbedFrame.php
47 - // Object embeding should be much more compatilbe
 47+ // Object embedding should be much more compatible with sites that
 48+ // let users embed flash applets
4849 // "videojs" will include the source javascript and video tag to
4950 // rewrite the player on the remote page DOM
50 - // Video tag embeding is much more mash-up friendly but exposes
 51+ // Video tag embedding is much more mash-up friendly but exposes
5152 // the remote site to the mwEmbed js.
52 - 'shareEmbedMode' : 'object'
 53+ 'shareEmbedMode' : 'object',
5354
 55+ // Default player skin name
 56+ "playerSkinName" : "mvpcf"
5457 } );
5558
5659
@@ -63,16 +66,17 @@
6467 "javaEmbed" : "modules/EmbedPlayer/javaEmbed.js",
6568 "nativeEmbed" : "modules/EmbedPlayer/nativeEmbed.js",
6669 "quicktimeEmbed" : "modules/EmbedPlayer/quicktimeEmbed.js",
67 - "vlcEmbed" : "modules/EmbedPlayer/vlcEmbed.js"
 70+ "vlcEmbed" : "modules/EmbedPlayer/vlcEmbed.js",
 71+
 72+ "ctrlBuilder" : "modules/EmbedPlayer/skins/ctrlBuilder.js",
 73+
 74+ "kskinConfig" : "modules/EmbedPlayer/skins/kskin/kskinConfig.js",
 75+ "mw.style.kskin" : "modules/EmbedPlayer/skins/kskin/EmbedPlayer.css",
 76+
 77+ "mvpcfConfig" : "modules/EmbedPlayer/skins/mvpcf/mvpcfConfig.js",
 78+ "mw.style.mvpcf" : "modules/EmbedPlayer/skins/mvpcf/EmbedPlayer.css"
6879 } );
6980
70 -
71 -// Add style sheet dependencies
72 -mw.addClassStyleSheets( {
73 - "kskinConfig" : "skins/kskin/EmbedPlayer.css",
74 - "mvpcfConfig" : "skins/mvpcf/EmbedPlayer.css"
75 -} );
76 -
7781 /**
7882 * Check the current DOM for any tags in "rewritePlayerTags"
7983 *
@@ -146,38 +150,49 @@
147151 if( mw.getConfig( 'textInterface' ) == 'always' ) {
148152 addTimedTextReqFlag = true;
149153 }
150 -
 154+
 155+ var playerSkins = {};
151156 // Get the class of all embed video elements
152157 // to add the skin to the load request
153 - $j( mw.getConfig( 'rewritePlayerTags' ) ).each( function() {
 158+ $j( mw.getConfig( 'rewritePlayerTags' ) ).each( function() {
154159 var playerElement = this;
155 - var cName = $j( playerElement ).attr( 'class' );
 160+ var playerClassName = $j( playerElement ).attr( 'class' );
 161+ // Set playerClassName to default
 162+ if( ! playerClassName ){
 163+ playerClassName = mw.getConfig( 'playerSkinName' );
 164+ }
156165 for( var n=0; n < mw.valid_skins.length ; n++ ) {
157166 // Get any other skins that we need to load
158167 // That way skin js can be part of the single script-loader request:
159 - if( cName.indexOf( mw.valid_skins[ n ] ) !== -1) {
160 - dependencyRequest[0].push( mw.valid_skins[n] + 'Config' );
 168+ if( playerClassName.indexOf( mw.valid_skins[ n ] ) !== -1) {
 169+ // Add skin name to playerSkins
 170+ playerSkins[ mw.valid_skins[ n ] ] = true;
161171 }
162 - }
 172+ }
 173+
163174 // If add timed text flag not already set check for itext, and sources
164175 if( !addTimedTextReqFlag ) {
165176 if( $j( playerElement ).find( 'itext' ).length != 0 ) {
166177 // Has an itext child include timed text request
167178 addTimedTextReqFlag = true;
168 - // break out of the loop
169 - return false;
170179 }
171180 // Check for ROE pointer or apiTitleKey
172181 if ( $j( playerElement ).attr('roe')
173182 || $j( playerElement ).attr( 'apiTitleKey' ) )
174183 {
175184 addTimedTextReqFlag = true;
176 - // break out of the loop
177 - return false;
178185 }
179186 }
180 - } );
 187+ } );
181188
 189+ // Add the player skins css and js to the load request:
 190+ for( var pSkin in playerSkins ) {
 191+ // Add skin js
 192+ dependencyRequest[0].push( pSkin + 'Config' );
 193+ // Add the skin css
 194+ dependencyRequest[0].push( 'mw.style.' + pSkin );
 195+ }
 196+
182197 // Add timed text items if flag set.
183198 if( addTimedTextReqFlag ) {
184199 dependencyRequest[0].push( 'mw.TimedText' )
Index: branches/js2-work/phase3/js/mwEmbed/mwEmbed.js
@@ -38,13 +38,15 @@
3939 * The global mw object:
4040 */
4141 ( function( mw ) {
 42+ // The version of mwEmbed
 43+ mw.version = MW_EMBED_VERSION
4244
4345 // List valid skins here:
44 - mw.valid_skins = [ 'mvpcf', 'kskin' ];
 46+ mw.valid_skins = [ 'mvpcf', 'kskin' ];
 47+
 48+ // Storage variable for loaded style sheet keys
 49+ mw.style = { };
4550
46 - // The version of mwEmbed
47 - mw.version = MW_EMBED_VERSION
48 -
4951 /**
5052 * Configuration System:
5153 */
@@ -71,6 +73,7 @@
7274 for( var i in name ) {
7375 mw.setConfig( i, name[ i ] );
7476 }
 77+ return ;
7578 }
7679 mwConfig[ name ] = value;
7780 }
@@ -856,16 +859,9 @@
857860 * @key Name of class
858861 * @value Class file path
859862 */
860 - classPaths : { },
 863+ classPaths : { },
861864
862865 /**
863 - * Style sheet paths for associated classes
864 - * @key Name of the class
865 - * @value Style sheet path
866 - */
867 - stylePaths : { },
868 -
869 - /**
870866 * Core load function:
871867 *
872868 * @param {Mixed} loadRequest:
@@ -939,7 +935,7 @@
940936 return ;
941937 }
942938
943 - //possible error?
 939+ // Possible error?
944940 mw.log( "Error could not handle load request: " + loadRequest );
945941 },
946942
@@ -1040,12 +1036,7 @@
10411037 if ( !mw.isset( loadName ) ) {
10421038 groupClassKey += coma + loadName
10431039 coma = ',';
1044 - }
1045 - // Issue a request for any dependent style sheets ( won't load if already present )
1046 - if( typeof this.stylePaths[ loadName ] != 'undefined' ) {
1047 - mw.getStyleSheet( mw.getMwEmbedPath() + this.stylePaths[ loadName ] );
1048 - }
1049 -
 1040+ }
10501041 }else if( this.moduleLoaders[ loadName ] ) {
10511042 // Module loaders break up grouped script requests ( add the current groupClassKey )
10521043 if( groupClassKey != '' ) {
@@ -1123,7 +1114,7 @@
11241115 var baseClassPath = this.getClassPath( className );
11251116 // Add the mwEmbed path if not a root path or a full url
11261117 if( baseClassPath.indexOf( '/' ) !== 0 &&
1127 - baseClassPath.indexOf('://') === -1 ) {
 1118+ baseClassPath.indexOf( '://' ) === -1 ) {
11281119 scriptRequest = mw.getMwEmbedPath() + baseClassPath;
11291120 }else{
11301121 scriptRequest = baseClassPath;
@@ -1132,11 +1123,6 @@
11331124 mw.log( "Could not get url for class " + className );
11341125 return ;
11351126 }
1136 - }
1137 -
1138 - // Check for any associated style sheets that should be loaded
1139 - if( typeof this.stylePaths[ className ] != 'undefined' ) {
1140 - mw.getStyleSheet( mw.getMwEmbedPath() + this.stylePaths[ className ] );
11411127 }
11421128
11431129 // Include class defined check for older browsers
@@ -1211,20 +1197,6 @@
12121198 if( this.classPaths[ className ] )
12131199 return this.classPaths[ className ]
12141200 return false;
1215 - },
1216 -
1217 - /**
1218 - * Add a style sheet to be loaded the same time as the requested class
1219 - *
1220 - * NOTE: In general style sheets should be loaded via a module loader function.
1221 - * In some cases a single class has a single sheet dependency which can be set-up using this function
1222 - *
1223 - * @param {Object} sheetSet ClassKey : sheet location key value paris
1224 - */
1225 - addClassStyleSheets: function( sheetSet ) {
1226 - for(var i in sheetSet ) {
1227 - this.stylePaths[ i ] = sheetSet[ i ];
1228 - }
12291201 }
12301202 }
12311203 /**
@@ -1238,6 +1210,8 @@
12391211 return true;
12401212 }
12411213 while( mwLoadDoneCB[ requestName ].length ) {
 1214+ // check if mwLoadDoneCB is already "done"
 1215+ // the function list is not an object
12421216 if( typeof mwLoadDoneCB[ requestName ] != 'object' )
12431217 {
12441218 break;
@@ -1273,6 +1247,10 @@
12741248 /**
12751249 * Shortcut entry points / convenience functions:
12761250 * Lets you write mw.load() instead of mw.loader.load()
 1251+ * only these entry points should be used.
 1252+ *
 1253+ * future closure optimizations could minify internal
 1254+ * function names
12771255 */
12781256
12791257 /**
@@ -1282,7 +1260,6 @@
12831261 return mw.loader.load( loadRequest, callback );
12841262 }
12851263
1286 -
12871264 /**
12881265 * Add module entry point: Adds a module to the mwLoader object
12891266 */
@@ -1296,18 +1273,13 @@
12971274 mw.addClassFilePaths = function ( classSet ) {
12981275 return mw.loader.addClassFilePaths( classSet );
12991276 }
 1277+
13001278 /**
13011279 * Get Class File Path entry point:
13021280 */
13031281 mw.getClassPath = function( className ) {
13041282 return mw.loader.getClassPath( className );
13051283 }
1306 - /**
1307 - * Add Class Style Sheet entry point:
1308 - */
1309 - mw.addClassStyleSheets = function( sheetSet ) {
1310 - return mw.loader.addClassStyleSheets( sheetSet );
1311 - }
13121284
13131285
13141286 /**
@@ -1914,17 +1886,24 @@
19151887 * @param {Function} callback Function to call once script is loaded
19161888 */
19171889 mw.getScript = function( scriptRequest, callback ) {
1918 -
 1890+ // Setup the local callback
 1891+ var myCallback = function(){
 1892+ if( callback )
 1893+ callback( scriptRequest );
 1894+ }
19191895 // Set the base url based scriptLoader availability & type of scriptRequest
19201896 // ( presently script loader only handles "classes" not relative urls:
1921 - var slpath = mw.getScriptLoaderPath();
 1897+ var scriptLoaderPath = mw.getScriptLoaderPath();
19221898
19231899 // Check if its a class name, ( ie does not start with "/" and does not include ://
19241900 var isClassName = ( scriptRequest.indexOf('://') == -1 && scriptRequest.indexOf('/') !== 0 )? true : false;
19251901
1926 - if( slpath && isClassName ) {
1927 - url = slpath + '?class=' + scriptRequest;
1928 - }else{
 1902+ var ext = scriptRequest.substr( scriptRequest.lastIndexOf( '.' ), 4 ).toLowerCase();
 1903+ var isCssFile = ( ext == '.css') ? true : false ;
 1904+
 1905+ if( scriptLoaderPath && isClassName ) {
 1906+ url = scriptLoaderPath + '?class=' + scriptRequest;
 1907+ } else {
19291908 // Add the mwEmbed path if a relative path request
19301909 url = ( isClassName ) ? mw.getMwEmbedPath() : '';
19311910 url+= scriptRequest;
@@ -1936,21 +1915,33 @@
19371916
19381917
19391918 mw.log( 'mw.getScript: ' + url );
 1919+
19401920 // If jQuery is available and debug is off load the scirpt via jQuery
19411921 //( will use XHR if on same domain )
1942 - if( mw.isset( 'window.jQuery' ) && mw.getConfig( 'debug' ) === false ) {
1943 - $j.getScript( url, function() {
1944 - if( callback )
1945 - callback( scriptRequest );
1946 - });
 1922+ if( mw.isset( 'window.jQuery' )
 1923+ && mw.getConfig( 'debug' ) === false
 1924+ && !isCssFile )
 1925+ {
 1926+ $j.getScript( url, myCallback);
19471927 return ;
19481928 }
19491929
19501930 /**
19511931 * No jQuery
19521932 * OR
1953 - * In debug mode inject the script instead of doing an XHR eval
 1933+ * In debug mode
 1934+ * OR
 1935+ * Is css file
 1936+ *
 1937+ * :: inject the script instead of doing an XHR eval
19541938 */
 1939+
 1940+ // load sytle sheet directly if requested loading css
 1941+ if( isCssFile ){
 1942+ mw.getStyleSheet( url, myCallback);
 1943+ return ;
 1944+ }
 1945+
19551946 // Load and bind manually: ( copied from jQuery ajax function )
19561947 var head = document.getElementsByTagName("head")[ 0 ];
19571948 var script = document.createElement("script");
@@ -1959,32 +1950,46 @@
19601951 // Attach handlers ( if using script loader it issues onDone callback as well )
19611952 script.onload = script.onreadystatechange = function() {
19621953 if (!this.readyState || this.readyState == "loaded" || this.readyState == "complete") {
1963 - if( callback ) {
1964 - callback( scriptRequest );
1965 - }
 1954+ myCallback();
19661955 }
19671956 };
19681957 //mw.log(" append script: " + script.src );
19691958 // Append the script to the DOM:
19701959 head.appendChild( script );
1971 - }
 1960+ };
19721961
19731962 /**
 1963+ * Add a style sheet string to the document head
 1964+ *
 1965+ * @param {String} cssClassName Name of style sheet that has been defined
 1966+ * @param {String} cssString Css Payload to be added to head of document
 1967+ */
 1968+ mw.addStyleString = function( cssClassName, cssString ) {
 1969+ // Set the style to true ( to not request it again )
 1970+ mw.style[ cssClassName ] = true;
 1971+ // Wait for the DOM to be ready before adding in the css:
 1972+ mw.ready(function(){
 1973+ $j( 'head' ).append(
 1974+ $j( '<style/>' )
 1975+ .attr( {
 1976+ 'type' : 'text/css',
 1977+ 'media': 'all'
 1978+ })
 1979+ .text(
 1980+ cssString
 1981+ )
 1982+ );
 1983+ });
 1984+ };
 1985+
 1986+ /**
19741987 * Get a style sheet and append the style sheet to the DOM
19751988 *
19761989 * @param {Mixed}
1977 - * {Array} url List of urls to be loaded
19781990 * {String} url Url of the style sheet to be loaded
 1991+ * {Function} callback Function called once sheet is ready
19791992 */
1980 - mw.getStyleSheet = function( url ) {
1981 - // Load a set of style sheets:
1982 - if ( typeof url == 'object' ) {
1983 - for ( var i in url ) {
1984 - mw.getStyleSheet( url[i] );
1985 - }
1986 - return ;
1987 - }
1988 -
 1993+ mw.getStyleSheet = function( url , callback) {
19891994 // Add URL params ( if not already included )
19901995 if ( url.indexOf( '?' ) == -1 ) {
19911996 url += '?' + mw.getUrlParam();
@@ -2008,18 +2013,26 @@
20092014 } );
20102015 if( foundSheet ) {
20112016 mw.log( 'skiped sheet: ' + url);
 2017+ if( callback) {
 2018+ callback();
 2019+ }
20122020 return ;
20132021 }
20142022
20152023 mw.log( ' add css: ' + url );
20162024 $j( 'head' ).append(
2017 - $j('<link>').attr( {
 2025+ $j('<link />').attr( {
20182026 'rel' : 'stylesheet',
20192027 'type' : 'text/css',
20202028 'href' : url
20212029 } )
2022 - );
2023 - }
 2030+ );
 2031+ // Precently no easy way to check css "onLoad" attribute
 2032+ // In genneral sheets are loaded via script-loader.
 2033+ if( callback ) {
 2034+ callback();
 2035+ }
 2036+ };
20242037
20252038 /**
20262039 * Get the api url for a given content provider key
@@ -2032,7 +2045,7 @@
20332046 return mw.getConfig( providerId + '_apiurl');
20342047 }
20352048 return mw.getLocalApiUrl();
2036 - },
 2049+ };
20372050
20382051 /**
20392052 * Get Api URL from mediaWiki page defined variables
@@ -2045,7 +2058,7 @@
20462059 return wgServer + wgScriptPath + '/api.php';
20472060 }
20482061 return false;
2049 - }
 2062+ };
20502063
20512064 // Local mwEmbedPath variable ( for cache of mw.getMwEmbedPath )
20522065 var mwEmbedPath = null;
@@ -2458,24 +2471,16 @@
24592472 }
24602473 }
24612474
2462 - // Make sure we have jQuery:
 2475+ // Make sure we have jQuery and the common skin
 2476+ // NOTE mw.style.common should be factored out into
 2477+ // seperate module specifc classes
24632478 mw.load( 'window.jQuery', function() {
2464 - if ( ! window['$j'] ) {
2465 - window['$j'] = jQuery.noConflict();
2466 - }
2467 - mw.setConfig( 'jquery_skin_path', mw.getMwEmbedPath() + 'jquery/jquery.ui/themes/' + mw.getConfig( 'jQueryUISkin' ) + '/' );
 2479+ if ( ! window[ '$j' ] ) {
 2480+ window[ '$j' ] = jQuery.noConflict();
 2481+ }
24682482
2469 - // Ideally only load jquery ui theme sheet if ui-widget does not exist.
2470 - // NOTE: disabled as style sheets are cross domain and it behaves differently across browsers
2471 - //if( ! mw.styleRuleExists( 'ui-widget' ) ) {
2472 - mw.getStyleSheet( mw.getConfig( 'jquery_skin_path' ) + 'jquery-ui-1.7.1.custom.css' );
2473 - //}
 2483+ mw.setConfig( 'images_path', mw.getMwEmbedPath() + 'skins/common/images/' );
24742484
2475 - mw.setConfig( 'images_path', mw.getMwEmbedPath() + 'skins/common/images/' );
2476 -
2477 - // Get Core skin/style sheets are always available:
2478 - mw.getStyleSheet( mw.getMwEmbedPath() + 'skins/common/common.css' );
2479 -
24802485 // Set up AJAX to not send dynamic URLs for loading scripts
24812486 $j.ajaxSetup( {
24822487 cache: true
@@ -2487,18 +2492,24 @@
24882493 // Set up mvEmbed utility jQuery bindings
24892494 mw.dojQueryBindings();
24902495
2491 - // Run all the setup function hooks
2492 - // Once complete we can run .ready queued functions
2493 - function runSetupFunctions() {
2494 - if( mwSetupFunctions.length ) {
2495 - mwSetupFunctions.pop()( function() {
2496 - runSetupFunctions();
2497 - } );
2498 - }else{
2499 - mw.runReadyHooks();
 2496+ // Make sure style sheets are loaded:
 2497+ mw.load( [
 2498+ 'mw.style.common',
 2499+ 'mw.style.' + mw.getConfig( 'jQueryUISkin' )
 2500+ ], function(){
 2501+ // Run all the setup function hooks
 2502+ // Once complete we can run .ready queued functions
 2503+ function runSetupFunctions() {
 2504+ if( mwSetupFunctions.length ) {
 2505+ mwSetupFunctions.pop()( function() {
 2506+ runSetupFunctions();
 2507+ } );
 2508+ }else{
 2509+ mw.runReadyHooks();
 2510+ }
25002511 }
2501 - }
2502 - runSetupFunctions();
 2512+ runSetupFunctions();
 2513+ });
25032514 });
25042515 };
25052516
Index: branches/js2-work/phase3/js/mwEmbed/jsScriptLoader.php
@@ -103,7 +103,7 @@
104104
105105 // Special prepend js var to be added to the top of minification output.
106106 // useful for special comment tags in minification output
107 - $minificationTopJs = '';
 107+ $NotMinifiedTopJs = '';
108108
109109 // Build the output
110110 // Swap in the appropriate language per js_file
@@ -117,12 +117,21 @@
118118
119119 // If the core mwEmbed class entry point include all the loader js
120120 if( $classKey == 'mwEmbed' ){
 121+
121122 // Output the loaders:
122123 $this->jsout .= jsClassLoader::getCombinedLoaderJs();
 124+
123125 // Output the current language class js
124126 $this->jsout .= jsClassLoader::getLanguageJs( $this->langCode );
 127+
 128+ // Output the "common" css file
 129+ $filePath = self::getJsPathFromClass( 'mw.style.common' );
 130+ if( $filePath ) {
 131+ $this->jsout .= $this->getScriptText( 'mw.style.common', $filePath );
 132+ }
 133+
125134 // Output special IE comment tag to support special mwEmbed tags.
126 - $minificationTopJs.='/*@cc_on\'video source itext playlist\'.replace(/\w+/g,function(n){document.createElement(n)})@*/'."\n";
 135+ $NotMinifiedTopJs.='/*@cc_on\'video source itext playlist\'.replace(/\w+/g,function(n){document.createElement(n)})@*/'."\n";
127136 }
128137 }
129138
@@ -136,7 +145,7 @@
137146 // Check if we should minify the whole thing:
138147 if ( !$this->debug ) {
139148 $this->jsout = self::getMinifiedJs( $this->jsout , $this->requestKey );
140 - $this->jsout = $minificationTopJs . $this->jsout;
 149+ $this->jsout = $NotMinifiedTopJs . $this->jsout;
141150 }
142151
143152 // Save to the file cache
@@ -160,8 +169,10 @@
161170 /**
162171 * Get the loadDone javascript callback for a given class list
163172 *
164 - * Enables a done loading callback for browsers like safari
165 - * that don't consistently support the <script>.onload call
 173+ * Enables a done loading callback for browsers like older safari
 174+ * that did not consistently support the <script>.onload call
 175+ * or IE that sometimes gets undefined symbols at onload
 176+ * call time for associated script content
166177 *
167178 * @return String javascript to tell mwEmbed that the requested class set is loaded
168179 */
@@ -205,14 +216,16 @@
206217 if( !is_file( $wgJavaPath ) || ! is_file( $wgClosureCompilerPath ) ){
207218 return false;
208219 }
 220+
209221 // Update the requestKey with a random value if not provided
210222 // requestKey is used for the temporary file
211223 // ( There are problems with using standard output and Closure compile )
212 - if( $requestKey == '')
 224+ if( $requestKey == '') {
213225 $requestKey = rand() + microtime();
 226+ }
214227
215228 // Write the grouped javascript to a temporary file:
216 - // ( closure compiler does not support reading from standard in )
 229+ // ( closure compiler does not support reading from standard in pipe )
217230 $td = wfTempDir();
218231 $jsFileName = $td . '/' . md5( $requestKey ) . '.tmp.js';
219232 file_put_contents( $jsFileName, $js_string );
@@ -268,14 +281,16 @@
269282 $skinNames = array_keys( $skinNames );
270283 if ( in_array( strtolower( $skin ), $skinNames ) ) {
271284 // If in debug mode, add a comment with wiki title and rev:
272 - if ( $this->debug )
273 - $jsout .= "\n/**\n* GenerateUserJs: \n*/\n";
274 - return $jsout . $sk->generateUserJs( $skin ) . "\n";
 285+ if ( $this->debug ) {
 286+ $jsout .= "\n/**\n* GenerateUserJs: \n*/\n";
 287+ }
 288+ return $sk->generateUserJs( $skin ) . "\n";
275289 }
276290 } else {
277 - // Make sure the wiki title ends with .js
278 - if ( substr( $title_block, -3 ) != '.js' ) {
279 - $this->errorMsg .= 'WikiTitle includes should end with .js';
 291+ $ext = substr($title_block, strrpos($title_block, '.') + 1);
 292+ // Make sure the wiki title ends with .js or .css
 293+ if ( self::validFileExtension( $ext ) ) {
 294+ $this->errorMsg .= 'WikiTitle includes should end with .js or .css';
280295 return false;
281296 }
282297 // It's a wiki title, append the output of the wikitext:
@@ -286,21 +301,28 @@
287302 // If in debug mode, add a comment with wiki title and rev:
288303 if ( $this->debug )
289304 $jsout .= "\n/**\n* WikiJSPage: " . htmlspecialchars( $title_block ) . " rev: " . $a->getID() . " \n*/\n";
290 -
291 - return $jsout . $a->getContent() . "\n";
 305+ $fileStr = $a->getContent() . "\n";
 306+ $jsout.= ( $ext == 'css' ) ?
 307+ $this->transformCssOutput( $classKey, $fileStr ) :
 308+ $fileStr;
 309+ return $jsout;
292310 }
293311 }
294312 }else{
 313+ $ext = substr($file_name, strrpos($file_name, '.') + 1);
295314 // Dealing with files
296 -
297315 if ( trim( $file_name ) != '' ) {
298 - if ( $this->debug ){
299 - $jsout .= "\n/**\n* File: " . htmlspecialchars( $file_name ) . "\n*/\n";
300 - }
 316+ $fileStr = $this->getFileContents( $file_name ) . "\n";
 317+ if( $fileStr ){
 318+ // Add the file name if debug is enabled
 319+ if ( $this->debug ){
 320+ $jsout .= "\n/**\n* File: " . htmlspecialchars( $file_name ) . "\n*/\n";
 321+ }
 322+ $jsout.= ( $ext == 'css' ) ?
 323+ $this->transformCssOutput( $classKey, $fileStr, $file_name ) :
 324+ $fileStr;
301325
302 - $jsFileStr = $this->getFileContents( $file_name ) . "\n";
303 - if( $jsFileStr ){
304 - return $jsout . $jsFileStr;
 326+ return $jsout;
305327 }else{
306328 $this->errorMsg .= "\nError could not read file: ". htmlspecialchars( $file_name ) ."\n";
307329 return false;
@@ -311,7 +333,37 @@
312334 $this->errorMsg .= "\nUnknown error\n";
313335 return false;
314336 }
 337+
315338 /**
 339+ * Special function to transform css output and wrap in js call
 340+ */
 341+ private function transformCssOutput( $classKey, $cssString , $path ='') {
 342+ global $wgMwEmbedDirectory;
 343+
 344+ // Minify and update paths on cssString:
 345+ $cssOptions = array();
 346+ if( ! $this->debug ) {
 347+ $cssOptions[ 'preserveComments' ] = false;
 348+ }
 349+ $serverUri = $_SERVER['SCRIPT_URI'];
 350+
 351+ // Check for the two jsScriptLoader entry points:
 352+ if( strpos( $serverUri, 'mwScriptLoader.php') !== false ){
 353+ $cssOptions[ 'prependRelativePath' ] =
 354+ str_replace('mwScriptLoader.php', '', $serverUri)
 355+ . dirname( $path ) . '/';
 356+ } else if( strpos( $serverUri, 'jsScriptLoader.php') !== false ){
 357+ $cssOptions[ 'prependRelativePath' ] =
 358+ str_replace('jsScriptLoader.php', '', $serverUri)
 359+ . dirname( $path ) . '/';
 360+ }
 361+ $cssString = Minify_CSS::minify( $cssString, $cssOptions);
 362+
 363+ return 'mw.addStyleString("' . Xml::escapeJsString( $classKey )
 364+ . '", "' . Xml::escapeJsString( $cssString ) . '");' . "\n";
 365+ }
 366+
 367+ /**
316368 * Outputs the script headers
317369 */
318370 function outputJsHeaders() {
@@ -574,6 +626,11 @@
575627 }
576628 }
577629
 630+ // Check that the filename ends with .js or .css
 631+ function validFileExtension( $ext ){
 632+ return !( $ext == 'js' || $ext == 'css');
 633+ }
 634+
578635 /**
579636 * Retrieve the js file into a string, updates errorMsg if not retrivable.
580637 *
@@ -582,10 +639,9 @@
583640 */
584641 function getFileContents( $filePath ) {
585642 global $IP;
586 -
587 - // Check that the filename ends with .js
588 - if ( substr( $filePath, -3 ) != '.js' ) {
589 - $this->errorMsg .= "\nError file name must end with .js: " . htmlspecialchars( $filePath ) . " \n ";
 643+ $ext = substr($filePath, strrpos($filePath, '.') + 1);
 644+ if ( self::validFileExtension( $ext) ) {
 645+ $this->errorMsg .= "\nError file name must end with .js or .css " . htmlspecialchars( $filePath ) . " \n ";
590646 return false;
591647 }
592648
Index: branches/js2-work/phase3/js/mwEmbed/jquery/plugins/jquery.browserTest.js
@@ -45,6 +45,10 @@
4646 if (r.name === 'presto') {
4747 r.version = ($.browser.version > 9.27) ? 'futhark' : 'linear_b';
4848 }
 49+
 50+ if (r.name === 'opera' && $.browser.version >= 9.8) {
 51+ r.version = i.match( /version\/([0-9\.]*)/i )[1] || 10;
 52+ }
4953 r.versionNumber = parseFloat(r.version, 10) || 0;
5054 r.versionX = (r.version !== x) ? (r.version + '').substr(0, 1) : x;
5155 r.className = r.name + r.versionX;
@@ -60,7 +64,7 @@
6165 ['Navigator', 'Netscape']
6266 ]) : a).toLowerCase();
6367
64 - $.browser = $.extend((!z) ? $.browser : {}, c(a, /(camino|chrome|firefox|netscape|konqueror|lynx|msie|opera|safari)/, [], /(camino|chrome|firefox|netscape|netscape6|opera|version|konqueror|lynx|msie|safari)(\/|\s)([a-z0-9\.\+]*?)(\;|dev|rel|\s|$)/));
 68+ $.browser = $.extend((!z) ? $.browser : {}, c(a, /(camino|chrome|firefox|netscape|konqueror|lynx|msie|opera|safari|ipod|iphone|blackberry)/, [], /(camino|chrome|firefox|netscape|netscape6|opera|version|konqueror|lynx|msie|safari)(\/|\s)([a-z0-9\.\+]*?)(\;|dev|rel|\s|$)/));
6569
6670 $.layout = c(a, /(gecko|konqueror|msie|opera|webkit)/, [
6771 ['konqueror', 'khtml'],
Index: branches/js2-work/phase3/js/mwEmbed/jquery/plugins/jquery.textSelection.js
@@ -10,11 +10,6 @@
1111 getContents: function() {
1212 return this.val();
1313 },
14 -
15 -setContents: function( options ) {
16 - return this.val( options.contents );
17 -},
18 -
1914 /**
2015 * Get the currently selected text in this textarea. Will focus the textarea
2116 * in some browsers (IE/Opera)
@@ -249,7 +244,7 @@
250245 * is already visible. Defaults to false
251246 */
252247 scrollToCaretPosition: function( options ) {
253 - function getLineLength( e ) {
 248+ function getLineLength( e ) {
254249 return Math.floor( e.scrollWidth / ( $.os.name == 'linux' ? 7 : 8 ) );
255250 }
256251 function getCaretScrollPosition( e ) {
@@ -373,13 +368,22 @@
374369 }
375370 var context = $(this).data( 'wikiEditor-context' );
376371 if( ! context ){
377 - var hasIframe = false;
378 - } else{
 372+ var hasIframe= false;
 373+ } else {
379374 var hasIframe = context !== undefined && context.$iframe !== undefined;
380375 }
381 - // iframe functions have not been implemented yet, this is a temp hack
382 - //var hasIframe = false;
383 - return ( hasIframe ? context.fn : fn )[command].call( this, options );
 376+
 377+ // IE selection restore voodoo
 378+ var needSave = false;
 379+ if ( hasIframe && context.savedSelection !== null ) {
 380+ context.fn.restoreSelection();
 381+ needSave = true;
 382+ }
 383+ retval = ( hasIframe ? context.fn : fn )[command].call( this, options );
 384+ if ( hasIframe && needSave ) {
 385+ context.fn.saveSelection();
 386+ }
 387+ return retval;
384388 };
385389
386 -} )( jQuery );
\ No newline at end of file
 390+} )( jQuery );

Status & tagging log