Merging resourceloader branch into trunk. Full documentation is at http://www.mediawiki.org/wiki/ResourceLoader and a general overview has been posted on wikitech-li <http://lists.wikimedia.org/pipermail/wikitech-l/2010-September/049253.html>. One important change is that all JS is now loaded at the bottom, so any scripts assuming things from wikibits or whatever are present will fail.
This commit is contained in:
parent
ecf56c33fa
commit
32377424b9
275 changed files with 31365 additions and 6180 deletions
|
|
@ -52,6 +52,8 @@ $wgAutoloadLocalClasses = array(
|
|||
'ConstantDependency' => 'includes/CacheDependency.php',
|
||||
'CreativeCommonsRdf' => 'includes/Metadata.php',
|
||||
'Credits' => 'includes/Credits.php',
|
||||
'CSSJanus' => 'includes/CSSJanus.php',
|
||||
'CSSMin' => 'includes/CSSMin.php',
|
||||
'DBABagOStuff' => 'includes/BagOStuff.php',
|
||||
'DependencyWrapper' => 'includes/CacheDependency.php',
|
||||
'DiffHistoryBlob' => 'includes/HistoryBlob.php',
|
||||
|
|
@ -161,6 +163,7 @@ $wgAutoloadLocalClasses = array(
|
|||
'MediaWiki' => 'includes/Wiki.php',
|
||||
'MemCachedClientforWiki' => 'includes/memcached-client.php',
|
||||
'Message' => 'includes/Message.php',
|
||||
'MessageBlobStore' => 'includes/MessageBlobStore.php',
|
||||
'MessageCache' => 'includes/MessageCache.php',
|
||||
'MimeMagic' => 'includes/MimeMagic.php',
|
||||
'MWException' => 'includes/Exception.php',
|
||||
|
|
@ -194,6 +197,12 @@ $wgAutoloadLocalClasses = array(
|
|||
'RegexlikeReplacer' => 'includes/StringUtils.php',
|
||||
'ReplacementArray' => 'includes/StringUtils.php',
|
||||
'Replacer' => 'includes/StringUtils.php',
|
||||
'ResourceLoader' => 'includes/ResourceLoader.php',
|
||||
'ResourceLoaderContext' => 'includes/ResourceLoaderContext.php',
|
||||
'ResourceLoaderFileModule' => 'includes/ResourceLoaderModule.php',
|
||||
'ResourceLoaderModule' => 'includes/ResourceLoaderModule.php',
|
||||
'ResourceLoaderSiteModule' => 'includes/ResourceLoaderModule.php',
|
||||
'ResourceLoaderStartUpModule' => 'includes/ResourceLoaderModule.php',
|
||||
'ReverseChronologicalPager' => 'includes/Pager.php',
|
||||
'Revision' => 'includes/Revision.php',
|
||||
'RevisionDelete' => 'includes/RevisionDelete.php',
|
||||
|
|
|
|||
313
includes/CSSJanus.php
Normal file
313
includes/CSSJanus.php
Normal file
|
|
@ -0,0 +1,313 @@
|
|||
<?php
|
||||
/**
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* This is a PHP port of CSSJanus, a utility that transforms CSS style sheets
|
||||
* written for LTR to RTL.
|
||||
*
|
||||
* The original Python version of CSSJanus is Copyright 2008 by Google Inc. and
|
||||
* is distributed under the Apache license.
|
||||
*
|
||||
* Original code: http://code.google.com/p/cssjanus/source/browse/trunk/cssjanus.py
|
||||
* License of original code: http://code.google.com/p/cssjanus/source/browse/trunk/LICENSE
|
||||
* @author Roan Kattouw
|
||||
*
|
||||
*/
|
||||
class CSSJanus {
|
||||
// Patterns defined as null are built dynamically by buildPatterns()
|
||||
private static $patterns = array(
|
||||
'tmpToken' => '`TMP`',
|
||||
'nonAscii' => '[\200-\377]',
|
||||
'unicode' => '(?:(?:\\[0-9a-f]{1,6})(?:\r\n|\s)?)',
|
||||
'num' => '(?:[0-9]*\.[0-9]+|[0-9]+)',
|
||||
'unit' => '(?:em|ex|px|cm|mm|in|pt|pc|deg|rad|grad|ms|s|hz|khz|%)',
|
||||
'body_selector' => 'body\s*{\s*',
|
||||
'direction' => 'direction\s*:\s*',
|
||||
'escape' => null,
|
||||
'nmstart' => null,
|
||||
'nmchar' => null,
|
||||
'ident' => null,
|
||||
'quantity' => null,
|
||||
'possibly_negative_quantity' => null,
|
||||
'color' => null,
|
||||
'url_special_chars' => '[!#$%&*-~]',
|
||||
'valid_after_uri_chars' => '[\'\"]?\s*',
|
||||
'url_chars' => null,
|
||||
'lookahead_not_open_brace' => null,
|
||||
'lookahead_not_closing_paren' => null,
|
||||
'lookahead_for_closing_paren' => null,
|
||||
'lookbehind_not_letter' => '(?<![a-zA-Z])',
|
||||
'chars_within_selector' => '[^\}]*?',
|
||||
'noflip_annotation' => '\/\*\s*@noflip\s*\*\/',
|
||||
|
||||
'noflip_single' => null,
|
||||
'noflip_class' => null,
|
||||
'comment' => '/\/\*[^*]*\*+([^\/*][^*]*\*+)*\//',
|
||||
'body_direction_ltr' => null,
|
||||
'body_direction_rtl' => null,
|
||||
'left' => null,
|
||||
'right' => null,
|
||||
'left_in_url' => null,
|
||||
'right_in_url' => null,
|
||||
'ltr_in_url' => null,
|
||||
'rtl_in_url' => null,
|
||||
'cursor_east' => null,
|
||||
'cursor_west' => null,
|
||||
'four_notation_quantity' => null,
|
||||
'four_notation_color' => null,
|
||||
'bg_horizontal_percentage' => null,
|
||||
'bg_horizontal_percentage_x' => null,
|
||||
);
|
||||
|
||||
/**
|
||||
* Build patterns we can't define above because they depend on other patterns.
|
||||
*/
|
||||
private static function buildPatterns() {
|
||||
if ( !is_null( self::$patterns['escape'] ) ) {
|
||||
// Patterns have already been built
|
||||
return;
|
||||
}
|
||||
$patterns =& self::$patterns;
|
||||
$patterns['escape'] = "(?:{$patterns['unicode']}|\\[^\r\n\f0-9a-f])";
|
||||
$patterns['nmstart'] = "(?:[_a-z]|{$patterns['nonAscii']}|{$patterns['escape']})";
|
||||
$patterns['nmchar'] = "(?:[_a-z0-9-]|{$patterns['nonAscii']}|{$patterns['escape']})";
|
||||
$patterns['ident'] = "-?{$patterns['nmstart']}{$patterns['nmchar']}*";
|
||||
$patterns['quantity'] = "{$patterns['num']}(?:\s*{$patterns['unit']}|{$patterns['ident']})?";
|
||||
$patterns['possibly_negative_quantity'] = "((?:-?{$patterns['quantity']})|(?:inherit|auto))";
|
||||
$patterns['color'] = "(#?{$patterns['nmchar']}+)";
|
||||
$patterns['url_chars'] = "(?:{$patterns['url_special_chars']}|{$patterns['nonAscii']}|{$patterns['escape']})*";
|
||||
$patterns['lookahead_not_open_brace'] = "(?!({$patterns['nmchar']}|\r?\n|\s|#|\:|\.|\,|\+|>)*?{)";
|
||||
$patterns['lookahead_not_closing_paren'] = "(?!{$patterns['url_chars']}?{$patterns['valid_after_uri_chars']}\))";
|
||||
$patterns['lookahead_for_closing_paren'] = "(?={$patterns['url_chars']}?{$patterns['valid_after_uri_chars']}\))";
|
||||
|
||||
$patterns['noflip_single'] = "/({$patterns['noflip_annotation']}{$patterns['lookahead_not_open_brace']}[^;}]+;?)/i";
|
||||
$patterns['noflip_class'] = "/({$patterns['noflip_annotation']}{$patterns['chars_within_selector']}})/i";
|
||||
$patterns['body_direction_ltr'] = "/({$patterns['body_selector']}{$patterns['chars_within_selector']}{$patterns['direction']})ltr/i";
|
||||
$patterns['body_direction_rtl'] = "/({$patterns['body_selector']}{$patterns['chars_within_selector']}{$patterns['direction']})rtl/i";
|
||||
$patterns['left'] = "/{$patterns['lookbehind_not_letter']}(left){$patterns['lookahead_not_closing_paren']}{$patterns['lookahead_not_open_brace']}/i";
|
||||
$patterns['right'] = "/{$patterns['lookbehind_not_letter']}(right){$patterns['lookahead_not_closing_paren']}{$patterns['lookahead_not_open_brace']}/i";
|
||||
$patterns['left_in_url'] = "/{$patterns['lookbehind_not_letter']}(left){$patterns['lookahead_for_closing_paren']}/i";
|
||||
$patterns['right_in_url'] = "/{$patterns['lookbehind_not_letter']}(right){$patterns['lookahead_for_closing_paren']}/i";
|
||||
$patterns['ltr_in_url'] = "/{$patterns['lookbehind_not_letter']}(ltr){$patterns['lookahead_for_closing_paren']}/i";
|
||||
$patterns['rtl_in_url'] = "/{$patterns['lookbehind_not_letter']}(rtl){$patterns['lookahead_for_closing_paren']}/i";
|
||||
$patterns['cursor_east'] = "/{$patterns['lookbehind_not_letter']}([ns]?)e-resize/";
|
||||
$patterns['cursor_west'] = "/{$patterns['lookbehind_not_letter']}([ns]?)w-resize/";
|
||||
$patterns['four_notation_quantity'] = "/{$patterns['possibly_negative_quantity']}(\s+){$patterns['possibly_negative_quantity']}(\s+){$patterns['possibly_negative_quantity']}(\s+){$patterns['possibly_negative_quantity']}/i";
|
||||
$patterns['four_notation_color'] = "/(-color\s*:\s*){$patterns['color']}(\s+){$patterns['color']}(\s+){$patterns['color']}(\s+){$patterns['color']}/i";
|
||||
// The two regexes below are parenthesized differently then in the original implementation to make the
|
||||
// callback's job more straightforward
|
||||
$patterns['bg_horizontal_percentage'] = "/(background(?:-position)?\s*:\s*[^%]*?)({$patterns['num']})(%\s*(?:{$patterns['quantity']}|{$patterns['ident']}))/";
|
||||
$patterns['bg_horizontal_percentage_x'] = "/(background-position-x\s*:\s*)({$patterns['num']})(%)/";
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform an LTR stylesheet to RTL
|
||||
* @param string $css Stylesheet to transform
|
||||
* @param bool $swapLtrRtlInURL If true, swap 'ltr' and 'rtl' in URLs
|
||||
* @param bool $swapLeftRightInURL If true, swap 'left' and 'right' in URLs
|
||||
* @return Transformed stylesheet
|
||||
*/
|
||||
public static function transform( $css, $swapLtrRtlInURL = false, $swapLeftRightInURL = false ) {
|
||||
// We wrap tokens in ` , not ~ like the original implementation does.
|
||||
// This was done because ` is not a legal character in CSS and can only
|
||||
// occur in URLs, where we escape it to %60 before inserting our tokens.
|
||||
$css = str_replace( '`', '%60', $css );
|
||||
|
||||
self::buildPatterns();
|
||||
|
||||
// Tokenize single line rules with /* @noflip */
|
||||
$noFlipSingle = new CSSJanus_Tokenizer( self::$patterns['noflip_single'], '`NOFLIP_SINGLE`' );
|
||||
$css = $noFlipSingle->tokenize( $css );
|
||||
|
||||
// Tokenize class rules with /* @noflip */
|
||||
$noFlipClass = new CSSJanus_Tokenizer( self::$patterns['noflip_class'], '`NOFLIP_CLASS`' );
|
||||
$css = $noFlipClass->tokenize( $css );
|
||||
|
||||
// Tokenize comments
|
||||
$comments = new CSSJanus_Tokenizer( self::$patterns['comment'], '`C`' );
|
||||
$css = $comments->tokenize( $css );
|
||||
|
||||
// LTR->RTL fixes start here
|
||||
$css = self::fixBodyDirection( $css );
|
||||
if ( $swapLtrRtlInURL ) {
|
||||
$css = self::fixLtrRtlInURL( $css );
|
||||
}
|
||||
if ( $swapLeftRightInURL ) {
|
||||
$css = self::fixLeftRightInURL( $css );
|
||||
}
|
||||
$css = self::fixLeftAndRight( $css );
|
||||
$css = self::fixCursorProperties( $css );
|
||||
$css = self::fixFourPartNotation( $css );
|
||||
$css = self::fixBackgroundPosition( $css );
|
||||
|
||||
// Detokenize stuff we tokenized before
|
||||
$css = $comments->detokenize( $css );
|
||||
$css = $noFlipClass->detokenize( $css );
|
||||
$css = $noFlipSingle->detokenize( $css );
|
||||
return $css;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace direction: ltr; with direction: rtl; and vice versa, but *only*
|
||||
* those inside a body { .. } selector.
|
||||
*
|
||||
* Unlike the original implementation, this function doesn't suffer from
|
||||
* the bug causing "body\n{\ndirection: ltr;\n}" to be missed.
|
||||
* See http://code.google.com/p/cssjanus/issues/detail?id=15
|
||||
*/
|
||||
private static function fixBodyDirection( $css ) {
|
||||
$css = preg_replace( self::$patterns['body_direction_ltr'],
|
||||
'$1' . self::$patterns['tmpToken'], $css );
|
||||
$css = preg_replace( self::$patterns['body_direction_rtl'], '$1ltr', $css );
|
||||
$css = str_replace( self::$patterns['tmpToken'], 'rtl', $css );
|
||||
return $css;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace 'ltr' with 'rtl' and vice versa in background URLs
|
||||
*/
|
||||
private static function fixLtrRtlInURL( $css ) {
|
||||
$css = preg_replace( self::$patterns['ltr_in_url'], self::$patterns['tmpToken'], $css );
|
||||
$css = preg_replace( self::$patterns['rtl_in_url'], 'ltr', $css );
|
||||
$css = str_replace( self::$patterns['tmpToken'], 'rtl', $css );
|
||||
return $css;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace 'left' with 'right' and vice versa in background URLs
|
||||
*/
|
||||
private static function fixLeftRightInURL( $css ) {
|
||||
$css = preg_replace( self::$patterns['left_in_url'], self::$patterns['tmpToken'], $css );
|
||||
$css = preg_replace( self::$patterns['right_in_url'], 'left', $css );
|
||||
$css = str_replace( self::$patterns['tmpToken'], 'right', $css );
|
||||
return $css;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flip rules like left: , padding-right: , etc.
|
||||
*/
|
||||
private static function fixLeftAndRight( $css ) {
|
||||
$css = preg_replace( self::$patterns['left'], self::$patterns['tmpToken'], $css );
|
||||
$css = preg_replace( self::$patterns['right'], 'left', $css );
|
||||
$css = str_replace( self::$patterns['tmpToken'], 'right', $css );
|
||||
return $css;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flip East and West in rules like cursor: nw-resize;
|
||||
*/
|
||||
private static function fixCursorProperties( $css ) {
|
||||
$css = preg_replace( self::$patterns['cursor_east'],
|
||||
'$1' . self::$patterns['tmpToken'], $css );
|
||||
$css = preg_replace( self::$patterns['cursor_west'], '$1e-resize', $css );
|
||||
$css = str_replace( self::$patterns['tmpToken'], 'w-resize', $css );
|
||||
return $css;
|
||||
}
|
||||
|
||||
/**
|
||||
* Swap the second and fourth parts in four-part notation rules like
|
||||
* padding: 1px 2px 3px 4px;
|
||||
*
|
||||
* Unlike the original implementation, this function doesn't suffer from
|
||||
* the bug where whitespace is not preserved when flipping four-part rules
|
||||
* and four-part color rules with multiple whitespace characters between
|
||||
* colors are not recognized.
|
||||
* See http://code.google.com/p/cssjanus/issues/detail?id=16
|
||||
*/
|
||||
private static function fixFourPartNotation( $css ) {
|
||||
$css = preg_replace( self::$patterns['four_notation_quantity'], '$1$2$7$4$5$6$3', $css );
|
||||
$css = preg_replace( self::$patterns['four_notation_color'], '$1$2$3$8$5$6$7$4', $css );
|
||||
return $css;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flip horizontal background percentages.
|
||||
*/
|
||||
private static function fixBackgroundPosition( $css ) {
|
||||
$css = preg_replace_callback( self::$patterns['bg_horizontal_percentage'],
|
||||
array( 'self', 'calculateNewBackgroundPosition' ), $css );
|
||||
$css = preg_replace_callback( self::$patterns['bg_horizontal_percentage_x'],
|
||||
array( 'self', 'calculateNewBackgroundPosition' ), $css );
|
||||
return $css;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for calculateNewBackgroundPosition()
|
||||
*/
|
||||
private static function calculateNewBackgroundPosition( $matches ) {
|
||||
return $matches[1] . ( 100 - $matches[2] ) . $matches[3];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility class used by CSSJanus that tokenizes and untokenizes things we want
|
||||
* to protect from being janused.
|
||||
* @author Roan Kattouw
|
||||
*/
|
||||
class CSSJanus_Tokenizer {
|
||||
private $regex, $token;
|
||||
private $originals;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param $regex string Regular expression whose matches to replace by a token.
|
||||
* @param $token string Token
|
||||
*/
|
||||
public function __construct( $regex, $token ) {
|
||||
$this->regex = $regex;
|
||||
$this->token = $token;
|
||||
$this->originals = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace all occurrences of $regex in $str with a token and remember
|
||||
* the original strings.
|
||||
* @param $str string String to tokenize
|
||||
* @return string Tokenized string
|
||||
*/
|
||||
public function tokenize( $str ) {
|
||||
return preg_replace_callback( $this->regex, array( $this, 'tokenizeCallback' ), $str );
|
||||
}
|
||||
|
||||
private function tokenizeCallback( $matches ) {
|
||||
$this->originals[] = $matches[0];
|
||||
return $this->token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace tokens with their originals. If multiple strings were tokenized, it's important they be
|
||||
* detokenized in exactly the SAME ORDER.
|
||||
* @param string $str String previously run through tokenize()
|
||||
* @return string Original string
|
||||
*/
|
||||
public function detokenize( $str ) {
|
||||
// PHP has no function to replace only the first occurrence or to
|
||||
// replace occurrences of the same string with different values,
|
||||
// so we use preg_replace_callback() even though we don't really need a regex
|
||||
return preg_replace_callback( '/' . preg_quote( $this->token, '/' ) . '/',
|
||||
array( $this, 'detokenizeCallback' ), $str );
|
||||
}
|
||||
|
||||
private function detokenizeCallback( $matches ) {
|
||||
$retval = current( $this->originals );
|
||||
next( $this->originals );
|
||||
return $retval;
|
||||
}
|
||||
|
||||
}
|
||||
100
includes/CSSMin.php
Normal file
100
includes/CSSMin.php
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
<?php
|
||||
|
||||
class CSSMin {
|
||||
|
||||
/* Constants */
|
||||
|
||||
/**
|
||||
* Maximum file size to still qualify for in-line embedding as a data-URI
|
||||
*
|
||||
* 24,576 is used because Internet Explorer has a 32,768 byte limit for data URIs, which when base64 encoded will
|
||||
* result in a 1/3 increase in size.
|
||||
*/
|
||||
const EMBED_SIZE_LIMIT = 24576;
|
||||
|
||||
/* Static Methods */
|
||||
|
||||
/**
|
||||
* Gets a list of local file paths which are referenced in a CSS style sheet
|
||||
*
|
||||
* @param $source string CSS data to remap
|
||||
* @param $path string File path where the source was read from (optional)
|
||||
* @return array List of local file references
|
||||
*/
|
||||
public static function getLocalFileReferences( $source, $path = null ) {
|
||||
$pattern = '/url\([\'"]?(?<file>[^\?\)\:]*)\??[^\)]*[\'"]?\)/';
|
||||
$files = array();
|
||||
if ( preg_match_all( $pattern, $source, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER ) ) {
|
||||
foreach ( $matches as $match ) {
|
||||
$file = ( isset( $path ) ? rtrim( $path, '/' ) . '/' : '' ) . "{$match['file'][0]}";
|
||||
// Only proceed if we can access the file
|
||||
if ( file_exists( $file ) ) {
|
||||
$files[] = $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remaps CSS URL paths and automatically embeds data URIs for URL rules preceded by an /* @embed * / comment
|
||||
*
|
||||
* @param $source string CSS data to remap
|
||||
* @param $path string File path where the source was read from
|
||||
* @return string Remapped CSS data
|
||||
*/
|
||||
public static function remap( $source, $path ) {
|
||||
$pattern = '/((?<embed>\s*\/\*\s*\@embed\s*\*\/)(?<rule>[^\;\}]*))?url\([\'"]?(?<file>[^\?\)\:]*)\??[^\)]*[\'"]?\)(?<extra>[^;]*)[\;]?/';
|
||||
$offset = 0;
|
||||
while ( preg_match( $pattern, $source, $match, PREG_OFFSET_CAPTURE, $offset ) ) {
|
||||
// Shortcuts
|
||||
$embed = $match['embed'][0];
|
||||
$rule = $match['rule'][0];
|
||||
$extra = $match['extra'][0];
|
||||
$file = "{$path}/{$match['file'][0]}";
|
||||
// Only proceed if we can access the file
|
||||
if ( file_exists( $file ) ) {
|
||||
// Add version parameter as a time-stamp in ISO 8601 format, using Z for the timezone, meaning GMT
|
||||
$url = "{$file}?" . gmdate( 'Y-m-d\TH:i:s\Z', round( filemtime( $file ), -2 ) );
|
||||
// Detect when URLs were preceeded with embed tags, and also verify file size is below the limit
|
||||
if ( $match['embed'][1] > 0 && filesize( $file ) < self::EMBED_SIZE_LIMIT ) {
|
||||
// If we ever get to PHP 5.3, we should use the Fileinfo extension instead of mime_content_type
|
||||
$type = mime_content_type( $file );
|
||||
// Strip off any trailing = symbols (makes browsers freak out)
|
||||
$data = rtrim( base64_encode( file_get_contents( $file ) ), '=' );
|
||||
// Build 2 CSS properties; one which uses a base64 encoded data URI in place of the @embed
|
||||
// comment to try and retain line-number integrity , and the other with a remapped an versioned
|
||||
// URL and an Internet Explorer hack making it ignored in all browsers that support data URIs
|
||||
$replacement = "{$rule}url(data:{$type};base64,{$data}){$extra};{$rule}url({$url}){$extra}!ie;";
|
||||
} else {
|
||||
// Build a CSS property with a remapped and versioned URL
|
||||
$replacement = "{$embed}{$rule}url({$url}){$extra};";
|
||||
}
|
||||
// Perform replacement on the source
|
||||
$source = substr_replace( $source, $replacement, $match[0][1], strlen( $match[0][0] ) );
|
||||
// Move the offset to the end of the replacement in the source
|
||||
$offset = $match[0][1] + strlen( $replacement );
|
||||
continue;
|
||||
}
|
||||
// Move the offset to the end of the match, leaving it alone
|
||||
$offset = $match[0][1] + strlen( $match[0][0] );
|
||||
}
|
||||
return $source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes whitespace from CSS data
|
||||
*
|
||||
* @param $source string CSS data to minify
|
||||
* @return string Minified CSS data
|
||||
*/
|
||||
public static function minify( $css ) {
|
||||
return trim(
|
||||
str_replace(
|
||||
array( '; ', ': ', ' {', '{ ', ', ', '} ', ';}' ),
|
||||
array( ';', ':', '{', '{', ',', '}', '}' ),
|
||||
preg_replace( array( '/\s+/', '/\/\*.*?\*\//s' ), array( ' ', '' ), $css )
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -601,13 +601,13 @@ class EnhancedChangesList extends ChangesList {
|
|||
* @return String
|
||||
*/
|
||||
public function beginRecentChangesList() {
|
||||
global $wgStylePath, $wgStyleVersion;
|
||||
global $wgStylePath, $wgStyleVersion, $wgOut;
|
||||
$this->rc_cache = array();
|
||||
$this->rcMoveIndex = 0;
|
||||
$this->rcCacheIndex = 0;
|
||||
$this->lastdate = '';
|
||||
$this->rclistOpen = false;
|
||||
$script = Html::linkedScript( $wgStylePath . "/common/enhancedchanges.js?$wgStyleVersion" );
|
||||
$wgOut->addModules( 'mediawiki.legacy.enhancedchanges' );
|
||||
return $script;
|
||||
}
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1628,6 +1628,19 @@ $wgUseETag = false;
|
|||
*/
|
||||
$wgClockSkewFudge = 5;
|
||||
|
||||
/**
|
||||
* Maximum time in seconds to cache resources served by the resource loader on
|
||||
* the client side (e.g. in the browser cache).
|
||||
*/
|
||||
$wgResourceLoaderClientMaxage = 30*24*60*60; // 30 days
|
||||
|
||||
/**
|
||||
* Maximum time in seconds to cache resources served by the resource loader on
|
||||
* the server side. This means Squid/Varnish but also any other public proxy
|
||||
* cache between the client and MediaWiki.
|
||||
*/
|
||||
$wgResourceLoaderServerMaxage = 30*24*60*60; // 30 days
|
||||
|
||||
/** @} */ # end of cache settings
|
||||
|
||||
/************************************************************************//**
|
||||
|
|
@ -2190,26 +2203,6 @@ $wgUseSiteJs = true;
|
|||
/** Use the site's Cascading Style Sheets (CSS)? */
|
||||
$wgUseSiteCss = true;
|
||||
|
||||
/**
|
||||
* Version of jQuery to use. Currently available versions are 1.3.2 and 1.4.2 .
|
||||
* Other versions can be installed by hand at your own risk, see
|
||||
* http://www.mediawiki.org/wiki/Manual:$wgJQueryVersion
|
||||
*/
|
||||
$wgJQueryVersion = '1.4.2';
|
||||
|
||||
/**
|
||||
* Use a minified version of jQuery. If enabled, jquery-versionnumber.min.js
|
||||
* will be used instead of jquery-versionnumber.js . It is recommended you only
|
||||
* disable this for debugging purposes.
|
||||
*/
|
||||
$wgJQueryMinified = true;
|
||||
|
||||
/**
|
||||
* Include jQuery on every page served by MediaWiki. You can disable this if
|
||||
* your user/site-wide JS doesn't need it and you want to save bandwidth.
|
||||
*/
|
||||
$wgJQueryOnEveryPage = true;
|
||||
|
||||
/**
|
||||
* Set to false to disable application of access keys and tooltips,
|
||||
* eg to avoid keyboard conflicts with system keys or as a low-level
|
||||
|
|
|
|||
|
|
@ -318,11 +318,11 @@ class EditPage {
|
|||
$this->preview = true;
|
||||
}
|
||||
|
||||
$wgOut->addScriptFile( 'edit.js' );
|
||||
$wgOut->addModules( 'mediawiki.legacy.edit' );
|
||||
|
||||
if ( $wgUser->getOption( 'uselivepreview', false ) ) {
|
||||
$wgOut->includeJQuery();
|
||||
$wgOut->addScriptFile( 'preview.js' );
|
||||
$wgOut->addModules( 'mediawiki.legacy.preview' );
|
||||
}
|
||||
// Bug #19334: textarea jumps when editing articles in IE8
|
||||
$wgOut->addStyle( 'common/IE80Fixes.css', 'screen', 'IE 8' );
|
||||
|
|
@ -2108,7 +2108,7 @@ HTML
|
|||
* @return string
|
||||
*/
|
||||
static function getEditToolbar() {
|
||||
global $wgStylePath, $wgContLang, $wgLang;
|
||||
global $wgStylePath, $wgContLang, $wgLang, $wgOut;
|
||||
|
||||
/**
|
||||
|
||||
|
|
@ -2244,8 +2244,11 @@ HTML
|
|||
array_map( array( 'Xml', 'encodeJsVar' ), $params ) );
|
||||
$script .= "addButton($paramList);\n";
|
||||
}
|
||||
$toolbar .= Html::inlineScript( "\n$script\n" );
|
||||
|
||||
|
||||
$wgOut->addScript( Html::inlineScript(
|
||||
"if ( mediaWiki !== undefined ) { mediaWiki.loader.using( 'mediawiki.legacy.edit', function() { $script } ); }"
|
||||
) );
|
||||
|
||||
$toolbar .= "\n</div>";
|
||||
|
||||
wfRunHooks( 'EditPageBeforeEditToolbar', array( &$toolbar ) );
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ class HTMLForm {
|
|||
|
||||
global $wgOut, $wgStylePath;
|
||||
|
||||
$wgOut->addScriptFile( "$wgStylePath/common/htmlform.js" );
|
||||
$wgOut->addModules( 'mediawiki.legacy.htmlform' );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ class HistoryPage {
|
|||
$wgOut->setRobotPolicy( 'noindex,nofollow' );
|
||||
$wgOut->setSyndicated( true );
|
||||
$wgOut->setFeedAppendQuery( 'action=history' );
|
||||
$wgOut->addScriptFile( 'history.js' );
|
||||
$wgOut->addModules( array( 'mediawiki.legacy.history' ) );
|
||||
|
||||
$logPage = SpecialPage::getTitleFor( 'Log' );
|
||||
$logLink = $this->skin->link(
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ class ImagePage extends Article {
|
|||
$collapse = htmlspecialchars( Xml::escapeJsString( wfMsg( 'metadata-collapse' ) ) );
|
||||
$wgOut->addHTML( Xml::element( 'h2', array( 'id' => 'metadata' ), wfMsg( 'metadata' ) ) . "\n" );
|
||||
$wgOut->addWikiText( $this->makeMetadataTable( $formattedMetadata ) );
|
||||
$wgOut->addScriptFile( 'metadata.js' );
|
||||
$wgOut->addModules( array( 'mediawiki.legacy.metadata' ) );
|
||||
$wgOut->addHTML(
|
||||
"<script type=\"text/javascript\">attachMetadataToggle('mw_metadata', '$expand', '$collapse');</script>\n" );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,8 +60,11 @@ class JSMin {
|
|||
// -- Public Static Methods --------------------------------------------------
|
||||
|
||||
public static function minify( $js ) {
|
||||
wfProfileIn( __METHOD__ );
|
||||
$jsmin = new JSMin( $js );
|
||||
return $jsmin->min();
|
||||
$ret = $jsmin->min();
|
||||
wfProfileOut( __METHOD__ );
|
||||
return $ret;
|
||||
}
|
||||
|
||||
// -- Public Instance Methods ------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -1328,16 +1328,7 @@ class Linker {
|
|||
'<table id="toc" class="toc"><tr><td>'
|
||||
. '<div id="toctitle"><h2>' . $title . "</h2></div>\n"
|
||||
. $toc
|
||||
# no trailing newline, script should not be wrapped in a
|
||||
# paragraph
|
||||
. "</ul>\n</td></tr></table>"
|
||||
. Html::inlineScript(
|
||||
'if (window.showTocToggle) {'
|
||||
. ' var tocShowText = "' . Xml::escapeJsString( wfMsg( 'showtoc' ) ) . '";'
|
||||
. ' var tocHideText = "' . Xml::escapeJsString( wfMsg( 'hidetoc' ) ) . '";'
|
||||
. ' showTocToggle();'
|
||||
. ' } ' )
|
||||
. "\n";
|
||||
. "</ul>\n</td></tr></table>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -621,6 +621,9 @@ class LocalisationCache {
|
|||
}
|
||||
}
|
||||
$this->store->finishWrite();
|
||||
|
||||
# Clear out the MessageBlobStore
|
||||
MessageBlobStore::clear();
|
||||
|
||||
wfProfileOut( __METHOD__ );
|
||||
}
|
||||
|
|
|
|||
329
includes/MessageBlobStore.php
Normal file
329
includes/MessageBlobStore.php
Normal file
|
|
@ -0,0 +1,329 @@
|
|||
<?php
|
||||
/**
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
* @author Roan Kattouw
|
||||
* @author Trevor Parscal
|
||||
*/
|
||||
|
||||
/**
|
||||
* This class provides access to the resource message blobs storage used by
|
||||
* the ResourceLoader.
|
||||
*
|
||||
* A message blob is a JSON object containing the interface messages for a
|
||||
* certain resource in a certain language. These message blobs are cached
|
||||
* in the msg_resource table and automatically invalidated when one of their
|
||||
* consistuent messages or the resource itself is changed.
|
||||
*/
|
||||
class MessageBlobStore {
|
||||
/**
|
||||
* Get the message blobs for a set of modules
|
||||
* @param $modules array Array of module names
|
||||
* @param $lang string Language code
|
||||
* @return array An array mapping module names to message blobs
|
||||
*/
|
||||
public static function get( $modules, $lang ) {
|
||||
// TODO: Invalidate blob when module touched
|
||||
if ( !count( $modules ) ) {
|
||||
return array();
|
||||
}
|
||||
// Try getting from the DB first
|
||||
$blobs = self::getFromDB( $modules, $lang );
|
||||
|
||||
// Generate blobs for any missing modules and store them in the DB
|
||||
$missing = array_diff( $modules, array_keys( $blobs ) );
|
||||
foreach ( $missing as $module ) {
|
||||
$blob = self::insertMessageBlob( $module, $lang );
|
||||
if ( $blob ) {
|
||||
$blobs[$module] = $blob;
|
||||
}
|
||||
}
|
||||
return $blobs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate and insert a new message blob. If the blob was already
|
||||
* present, it is not regenerated; instead, the preexisting blob
|
||||
* is fetched and returned.
|
||||
* @param $module string Module name
|
||||
* @param $lang string Language code
|
||||
* @return mixed Message blob or false if the module has no messages
|
||||
*/
|
||||
public static function insertMessageBlob( $module, $lang ) {
|
||||
$blob = self::generateMessageBlob( $module, $lang );
|
||||
if ( !$blob ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$dbw = wfGetDb( DB_MASTER );
|
||||
$success = $dbw->insert( 'msg_resource', array(
|
||||
'mr_lang' => $lang,
|
||||
'mr_resource' => $module,
|
||||
'mr_blob' => $blob,
|
||||
'mr_timestamp' => $dbw->timestamp()
|
||||
),
|
||||
__METHOD__,
|
||||
array( 'IGNORE' )
|
||||
);
|
||||
if ( $success ) {
|
||||
if ( $dbw->affectedRows() == 0 ) {
|
||||
// Blob was already present, fetch it
|
||||
$blob = $dbr->selectField( 'msg_resource', 'mr_blob', array(
|
||||
'mr_resource' => $module,
|
||||
'mr_lang' => $lang,
|
||||
),
|
||||
__METHOD__
|
||||
);
|
||||
} else {
|
||||
// Update msg_resource_links
|
||||
$rows = array();
|
||||
$mod = ResourceLoader::getModule( $module );
|
||||
foreach ( $mod->getMessages() as $key ) {
|
||||
$rows[] = array(
|
||||
'mrl_resource' => $module,
|
||||
'mrl_message' => $key
|
||||
);
|
||||
}
|
||||
$dbw->insert( 'msg_resource_links', $rows,
|
||||
__METHOD__, array( 'IGNORE' )
|
||||
);
|
||||
}
|
||||
}
|
||||
return $blob;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update all message blobs for a given module.
|
||||
* @param $module string Module name
|
||||
* @param $lang string Language code (optional)
|
||||
* @return mixed If $lang is set, the new message blob for that language is returned if present. Otherwise, null is returned.
|
||||
*/
|
||||
public static function updateModule( $module, $lang = null ) {
|
||||
$retval = null;
|
||||
|
||||
// Find all existing blobs for this module
|
||||
$dbw = wfGetDb( DB_MASTER );
|
||||
$res = $dbw->select( 'msg_resource', array( 'mr_lang', 'mr_blob' ),
|
||||
array( 'mr_resource' => $module ),
|
||||
__METHOD__
|
||||
);
|
||||
|
||||
// Build the new msg_resource rows
|
||||
$newRows = array();
|
||||
$now = $dbw->timestamp();
|
||||
// Save the last-processed old and new blobs for later
|
||||
$oldBlob = $newBlob = null;
|
||||
foreach ( $res as $row ) {
|
||||
$oldBlob = $row->mr_blob;
|
||||
$newBlob = self::generateMessageBlob( $module, $row->mr_lang );
|
||||
if ( $row->mr_lang === $lang ) {
|
||||
$retval = $newBlob;
|
||||
}
|
||||
$newRows[] = array(
|
||||
'mr_resource' => $module,
|
||||
'mr_lang' => $row->mr_lang,
|
||||
'mr_blob' => $newBlob,
|
||||
'mr_timestamp' => $now
|
||||
);
|
||||
}
|
||||
|
||||
$dbw->replace( 'msg_resource',
|
||||
array( array( 'mr_resource', 'mr_lang' ) ),
|
||||
$newRows, __METHOD__
|
||||
);
|
||||
|
||||
// Figure out which messages were added and removed
|
||||
$oldMessages = array_keys( FormatJson::decode( $oldBlob, true ) );
|
||||
$newMessages = array_keys( FormatJson::decode( $newBlob, true ) );
|
||||
$added = array_diff( $newMessages, $oldMessages );
|
||||
$removed = array_diff( $oldMessages, $newMessages );
|
||||
|
||||
// Delete removed messages, insert added ones
|
||||
if ( $removed ) {
|
||||
$dbw->delete( 'msg_resource_links', array(
|
||||
'mrl_resource' => $module,
|
||||
'mrl_message' => $removed
|
||||
), __METHOD__
|
||||
);
|
||||
}
|
||||
$newLinksRows = array();
|
||||
foreach ( $added as $message ) {
|
||||
$newLinksRows[] = array(
|
||||
'mrl_resource' => $module,
|
||||
'mrl_message' => $message
|
||||
);
|
||||
}
|
||||
if ( $newLinksRows ) {
|
||||
$dbw->insert( 'msg_resource_links', $newLinksRows, __METHOD__,
|
||||
array( 'IGNORE' ) // just in case
|
||||
);
|
||||
}
|
||||
|
||||
return $retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a single message in all message blobs it occurs in.
|
||||
* @param $key string Message key
|
||||
*/
|
||||
public static function updateMessage( $key ) {
|
||||
$dbw = wfGetDb( DB_MASTER );
|
||||
|
||||
// Keep running until the updates queue is empty.
|
||||
// Due to update conflicts, the queue might not be emptied
|
||||
// in one iteration.
|
||||
$updates = null;
|
||||
do {
|
||||
$updates = self::getUpdatesForMessage( $key, $updates );
|
||||
foreach ( $updates as $key => $update ) {
|
||||
// Update the row on the condition that it
|
||||
// didn't change since we fetched it by putting
|
||||
// the timestamp in the WHERE clause.
|
||||
$success = $dbw->update( 'msg_resource',
|
||||
array( 'mr_blob' => $update['newBlob'],
|
||||
'mr_timestamp' => $dbw->timestamp() ),
|
||||
array( 'mr_resource' => $update['resource'],
|
||||
'mr_lang' => $update['lang'],
|
||||
'mr_timestamp' => $update['timestamp'] ),
|
||||
__METHOD__
|
||||
);
|
||||
|
||||
// Only requeue conflicted updates.
|
||||
// If update() returned false, don't retry, for
|
||||
// fear of getting into an infinite loop
|
||||
if ( !( $success && $dbw->affectedRows() == 0 ) ) {
|
||||
// Not conflicted
|
||||
unset( $updates[$key] );
|
||||
}
|
||||
}
|
||||
} while ( count( $updates ) );
|
||||
|
||||
// No need to update msg_resource_links because we didn't add
|
||||
// or remove any messages, we just changed their contents.
|
||||
}
|
||||
|
||||
public static function clear() {
|
||||
// TODO: Give this some more thought
|
||||
// TODO: Is TRUNCATE better?
|
||||
$dbw = wfGetDb( DB_MASTER );
|
||||
$dbw->delete( 'msg_resource', '*', __METHOD__ );
|
||||
$dbw->delete( 'msg_resource_links', '*', __METHOD__ );
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an update queue for updateMessage()
|
||||
* @param $key string Message key
|
||||
* @param $prevUpdates array Updates queue to refresh or null to build a fresh update queue
|
||||
* @return array Updates queue
|
||||
*/
|
||||
private static function getUpdatesForMessage( $key, $prevUpdates = null ) {
|
||||
$dbw = wfGetDb( DB_MASTER );
|
||||
if ( is_null( $prevUpdates ) ) {
|
||||
// Fetch all blobs referencing $key
|
||||
$res = $dbw->select(
|
||||
array( 'msg_resource', 'msg_resource_links' ),
|
||||
array( 'mr_resource', 'mr_lang', 'mr_blob', 'mr_timestamp' ),
|
||||
array( 'mrl_message' => $key, 'mr_resource=mrl_resource' ),
|
||||
__METHOD__
|
||||
);
|
||||
} else {
|
||||
// Refetch the blobs referenced by $prevUpdates
|
||||
|
||||
// Reorganize the (resource, lang) pairs in the format
|
||||
// expected by makeWhereFrom2d()
|
||||
$twoD = array();
|
||||
foreach ( $prevUpdates as $update ) {
|
||||
$twoD[$update['resource']][$update['lang']] = true;
|
||||
}
|
||||
|
||||
$res = $dbw->select( 'msg_resource',
|
||||
array( 'mr_resource', 'mr_lang', 'mr_blob', 'mr_timestamp' ),
|
||||
$dbw->makeWhereFrom2d( $twoD, 'mr_resource', 'mr_lang' ),
|
||||
__METHOD__
|
||||
);
|
||||
}
|
||||
|
||||
// Build the new updates queue
|
||||
$updates = array();
|
||||
foreach ( $res as $row ) {
|
||||
$updates[] = array(
|
||||
'resource' => $row->mr_resource,
|
||||
'lang' => $row->mr_lang,
|
||||
'timestamp' => $row->mr_timestamp,
|
||||
'newBlob' => self::reencodeBlob( $row->mr_blob,
|
||||
$key, $row->mr_lang )
|
||||
);
|
||||
}
|
||||
return $updates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reencode a message blob with the updated value for a message
|
||||
* @param $blob string Message blob (JSON object)
|
||||
* @param $key string Message key
|
||||
* @param $lang string Language code
|
||||
* @return Message blob with $key replaced with its new value
|
||||
*/
|
||||
private static function reencodeBlob( $blob, $key, $lang ) {
|
||||
$decoded = FormatJson::decode( $blob, true );
|
||||
$decoded[$key] = wfMsgExt( $key, array( 'language' => $lang ) );
|
||||
return FormatJson::encode( $decoded );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the message blobs for a set of modules from the database.
|
||||
* Modules whose blobs are not in the database are silently dropped.
|
||||
* @param $modules array Array of module names
|
||||
* @param $lang string Language code
|
||||
* @return array Array mapping module names to blobs
|
||||
*/
|
||||
private static function getFromDB( $modules, $lang ) {
|
||||
$retval = array();
|
||||
$dbr = wfGetDB( DB_SLAVE );
|
||||
$res = $dbr->select( 'msg_resource', array( 'mr_blob', 'mr_resource', 'mr_timestamp' ),
|
||||
array( 'mr_resource' => $modules, 'mr_lang' => $lang ),
|
||||
__METHOD__
|
||||
);
|
||||
foreach ( $res as $row ) {
|
||||
$module = ResourceLoader::getModule( $row->mr_resource );
|
||||
if ( !$module ) {
|
||||
// This shouldn't be possible
|
||||
throw new MWException( __METHOD__ . ' passed an invalid module name' );
|
||||
}
|
||||
if ( array_keys( FormatJson::decode( $row->mr_blob, true ) ) !== $module->getMessages() ) {
|
||||
$retval[$row->mr_resource] = self::updateModule( $row->mr_resource, $lang );
|
||||
} else {
|
||||
$retval[$row->mr_resource] = $row->mr_blob;
|
||||
}
|
||||
}
|
||||
return $retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the message blob for a given module in a given language.
|
||||
* @param $module string Module name
|
||||
* @param $lang string Language code
|
||||
* @return string JSON object
|
||||
*/
|
||||
private static function generateMessageBlob( $module, $lang ) {
|
||||
$mod = ResourceLoader::getModule( $module );
|
||||
$messages = array();
|
||||
foreach ( $mod->getMessages() as $key ) {
|
||||
$messages[$key] = wfMsgExt( $key, array( 'language' => $lang ) );
|
||||
}
|
||||
return FormatJson::encode( $messages );
|
||||
}
|
||||
}
|
||||
|
|
@ -411,7 +411,7 @@ class MessageCache {
|
|||
return;
|
||||
}
|
||||
|
||||
list( , $code ) = $this->figureMessage( $title );
|
||||
list( $msg, $code ) = $this->figureMessage( $title );
|
||||
|
||||
$cacheKey = wfMemcKey( 'messages', $code );
|
||||
$this->load( $code );
|
||||
|
|
@ -451,6 +451,10 @@ class MessageCache {
|
|||
$sidebarKey = wfMemcKey( 'sidebar', $code );
|
||||
$parserMemc->delete( $sidebarKey );
|
||||
}
|
||||
|
||||
// Update the message in the message blob store
|
||||
global $wgContLang;
|
||||
MessageBlobStore::updateMessage( $wgContLang->lcfirst( $msg ) );
|
||||
|
||||
wfRunHooks( "MessageCacheReplace", array( $title, $text ) );
|
||||
|
||||
|
|
@ -807,7 +811,7 @@ class MessageCache {
|
|||
}
|
||||
|
||||
public function figureMessage( $key ) {
|
||||
global $wgContLanguageCode;
|
||||
global $wgContLanguageCode, $wgContLang;
|
||||
$pieces = explode( '/', $key );
|
||||
if( count( $pieces ) < 2 )
|
||||
return array( $key, $wgContLanguageCode );
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ class OutputPage {
|
|||
var $mCategoryLinks = array(), $mCategories = array(), $mLanguageLinks = array();
|
||||
|
||||
var $mScripts = '', $mLinkColours, $mPageLinkTitle = '', $mHeadItems = array();
|
||||
var $mModules = array(), $mModuleScripts = array(), $mModuleStyles = array(), $mModuleMessages = array();
|
||||
var $mInlineMsg = array();
|
||||
|
||||
var $mTemplateIds = array();
|
||||
|
|
@ -224,6 +225,78 @@ class OutputPage {
|
|||
return $this->mScripts . $this->getHeadItems();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of modules to include on this page
|
||||
* @return array of module names
|
||||
*/
|
||||
public function getModules() {
|
||||
return $this->mModules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add one or more modules recognized by the resource loader. Modules added
|
||||
* through this function will be loaded by the resource loader when the
|
||||
* page loads.
|
||||
* @param $module mixed Module name (string) or array of module names
|
||||
*/
|
||||
public function addModules( $modules ) {
|
||||
$this->mModules = array_merge( $this->mModules, (array)$modules );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of module JS to include on this page
|
||||
* @return array of module names
|
||||
*/
|
||||
public function getModuleScripts() {
|
||||
return $this->mModuleScripts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add only JS of one or more modules recognized by the resource loader. Module
|
||||
* scripts added through this function will be loaded by the resource loader when
|
||||
* the page loads.
|
||||
* @param $module mixed Module name (string) or array of module names
|
||||
*/
|
||||
public function addModuleScripts( $modules ) {
|
||||
$this->mModuleScripts = array_merge( $this->mModuleScripts, (array)$modules );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of module CSS to include on this page
|
||||
* @return array of module names
|
||||
*/
|
||||
public function getModuleStyles() {
|
||||
return $this->mModuleStyles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add only CSS of one or more modules recognized by the resource loader. Module
|
||||
* styles added through this function will be loaded by the resource loader when
|
||||
* the page loads.
|
||||
* @param $module mixed Module name (string) or array of module names
|
||||
*/
|
||||
public function addModuleStyles( $modules ) {
|
||||
$this->mModuleStyles = array_merge( $this->mModuleStyles, (array)$modules );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of module messages to include on this page
|
||||
* @return array of module names
|
||||
*/
|
||||
public function getModuleMessages() {
|
||||
return $this->mModuleMessages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add only messages of one or more modules recognized by the resource loader.
|
||||
* Module messages added through this function will be loaded by the resource
|
||||
* loader when the page loads.
|
||||
* @param $module mixed Module name (string) or array of module names
|
||||
*/
|
||||
public function addModuleMessages( $modules ) {
|
||||
$this->mModuleMessages = array_merge( $this->mModuleMessages, (array)$modules );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all header items in a string
|
||||
*
|
||||
|
|
@ -1095,6 +1168,7 @@ class OutputPage {
|
|||
}
|
||||
$this->mNoGallery = $parserOutput->getNoGallery();
|
||||
$this->mHeadItems = array_merge( $this->mHeadItems, $parserOutput->getHeadItems() );
|
||||
$this->addModules( $parserOutput->getModules() );
|
||||
// Versioning...
|
||||
foreach ( (array)$parserOutput->mTemplateIds as $ns => $dbks ) {
|
||||
if ( isset( $this->mTemplateIds[$ns] ) ) {
|
||||
|
|
@ -1528,24 +1602,27 @@ class OutputPage {
|
|||
}
|
||||
|
||||
$sk = $wgUser->getSkin();
|
||||
|
||||
|
||||
// Add base resources
|
||||
$this->addModules( array( 'mediawiki.legacy.wikibits' ) );
|
||||
|
||||
// Add various resources if required
|
||||
if ( $wgUseAjax ) {
|
||||
$this->addScriptFile( 'ajax.js' );
|
||||
$this->addModules( 'mediawiki.legacy.ajax' );
|
||||
|
||||
wfRunHooks( 'AjaxAddScript', array( &$this ) );
|
||||
|
||||
if( $wgAjaxWatch && $wgUser->isLoggedIn() ) {
|
||||
$this->includeJQuery();
|
||||
$this->addScriptFile( 'ajaxwatch.js' );
|
||||
$this->addModules( 'mediawiki.legacy.ajaxwatch' );
|
||||
}
|
||||
|
||||
if ( $wgEnableMWSuggest && !$wgUser->getOption( 'disablesuggest', false ) ) {
|
||||
$this->addScriptFile( 'mwsuggest.js' );
|
||||
$this->addModules( 'mediawiki.legacy.mwsuggest' );
|
||||
}
|
||||
}
|
||||
|
||||
if( $wgUser->getBoolOption( 'editsectiononrightclick' ) ) {
|
||||
$this->addScriptFile( 'rightclickedit.js' );
|
||||
$this->addModules( 'mediawiki.legacy.rightclickedit' );
|
||||
}
|
||||
|
||||
if( $wgUniversalEditButton ) {
|
||||
|
|
@ -1568,9 +1645,6 @@ class OutputPage {
|
|||
}
|
||||
}
|
||||
|
||||
if ( $wgJQueryOnEveryPage ) {
|
||||
$this->includeJQuery();
|
||||
}
|
||||
|
||||
# Buffer output; final headers may depend on later processing
|
||||
ob_start();
|
||||
|
|
@ -1975,8 +2049,7 @@ class OutputPage {
|
|||
$data['messages'][$message] = wfMsg( $message );
|
||||
}
|
||||
$this->addScript( Html::inlineScript( 'var passwordSecurity=' . FormatJson::encode( $data ) ) );
|
||||
$this->addScriptFile( 'password.js' );
|
||||
$this->addStyle( 'common/password.css' );
|
||||
$this->addModules( 'mediawiki.legacy.password' );
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
|
|
@ -2145,9 +2218,9 @@ class OutputPage {
|
|||
$ret .= Html::element( 'title', null, $this->getHTMLTitle() ) . "\n";
|
||||
|
||||
$ret .= implode( "\n", array(
|
||||
$this->getHeadLinks(),
|
||||
$this->getHeadLinks( $sk ),
|
||||
$this->buildCssLinks(),
|
||||
$this->getHeadScripts( $sk ) . $this->getHeadItems(),
|
||||
$this->getHeadItems(),
|
||||
) );
|
||||
if ( $sk->usercss ) {
|
||||
$ret .= Html::inlineStyle( $sk->usercss );
|
||||
|
|
@ -2199,34 +2272,70 @@ class OutputPage {
|
|||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
static function makeResourceLoaderLink( $skin, $modules, $only ) {
|
||||
global $wgUser, $wgLang, $wgRequest, $wgScriptPath;
|
||||
// TODO: Should this be a static function of ResourceLoader instead?
|
||||
$query = array(
|
||||
'modules' => implode( '|', array_unique( (array) $modules ) ),
|
||||
'lang' => $wgLang->getCode(),
|
||||
'debug' => $wgRequest->getBool( 'debug' ) && $wgRequest->getVal( 'debug' ) !== 'false',
|
||||
'skin' => $wgUser->getSkin()->getSkinName(),
|
||||
'only' => $only,
|
||||
);
|
||||
// Automatically select style/script elements
|
||||
if ( $only === 'styles' ) {
|
||||
return Html::linkedStyle( wfAppendQuery( $wgScriptPath . '/load.php', $query ) );
|
||||
} else {
|
||||
return Html::linkedScript( wfAppendQuery( $wgScriptPath . '/load.php', $query ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the global variables and mScripts; also adds userjs to the end if
|
||||
* enabled
|
||||
* enabled. Despite the name, these scripts are no longer put in the
|
||||
* <head> but at the bottom of the <body>
|
||||
*
|
||||
* @param $sk Skin object to use
|
||||
* @return String: HTML fragment
|
||||
*/
|
||||
function getHeadScripts( Skin $sk ) {
|
||||
global $wgUser, $wgRequest, $wgJsMimeType, $wgUseSiteJs;
|
||||
global $wgStylePath, $wgStyleVersion;
|
||||
|
||||
$scripts = Skin::makeGlobalVariablesScript( $sk->getSkinName() ) . "\n";
|
||||
$scripts .= Html::linkedScript( "{$wgStylePath}/common/wikibits.js?$wgStyleVersion" );
|
||||
|
||||
// add site JS if enabled
|
||||
if( $wgUseSiteJs ) {
|
||||
$jsCache = $wgUser->isLoggedIn() ? '&smaxage=0' : '';
|
||||
$this->addScriptFile(
|
||||
Skin::makeUrl(
|
||||
'-',
|
||||
"action=raw$jsCache&gen=js&useskin=" .
|
||||
urlencode( $sk->getSkinName() )
|
||||
)
|
||||
global $wgUser, $wgRequest, $wgJsMimeType;
|
||||
global $wgStylePath, $wgStyleVersion, $wgUseSiteJs;
|
||||
|
||||
// Statup - this will immediately load jquery and mediawiki modules
|
||||
$scripts = self::makeResourceLoaderLink( $sk, 'startup', 'scripts' );
|
||||
// Configuration
|
||||
$scripts .= Skin::makeGlobalVariablesScript( $sk->getSkinName() ) . "\n";
|
||||
// Support individual script requests in debug mode
|
||||
if ( $wgRequest->getBool( 'debug' ) && $wgRequest->getVal( 'debug' ) !== 'false' ) {
|
||||
// Scripts
|
||||
foreach ( $this->getModuleScripts() as $name ) {
|
||||
$scripts .= self::makeResourceLoaderLink( $sk, $name, 'scripts' );
|
||||
}
|
||||
// Messages
|
||||
foreach ( $this->getModuleMessages() as $name ) {
|
||||
$scripts .= self::makeResourceLoaderLink( $sk, $name, 'messages' );
|
||||
}
|
||||
} else {
|
||||
// Scripts
|
||||
if ( count( $this->getModuleScripts() ) ) {
|
||||
$scripts .= self::makeResourceLoaderLink( $sk, $this->getModuleScripts(), 'scripts' );
|
||||
}
|
||||
// Messages
|
||||
if ( count( $this->getModuleMessages() ) ) {
|
||||
$scripts .= self::makeResourceLoaderLink( $sk, $this->getModuleMessages(), 'messages' );
|
||||
}
|
||||
}
|
||||
if ( $this->getModules() ) {
|
||||
// Modules - let the client calculate dependencies and batch requests as it likes
|
||||
$modules = FormatJson::encode( $this->getModules() );
|
||||
$scripts .= Html::inlineScript(
|
||||
"if ( mediaWiki !== undefined ) { mediaWiki.loader.load( {$modules} ); }"
|
||||
);
|
||||
}
|
||||
|
||||
// add user JS if enabled
|
||||
// TODO: User Scripts should be included using the resource loader
|
||||
// Add user JS if enabled
|
||||
if( $this->isUserJsAllowed() && $wgUser->isLoggedIn() ) {
|
||||
$action = $wgRequest->getVal( 'action', 'view' );
|
||||
if( $this->mTitle && $this->mTitle->isJsSubpage() && $sk->userCanPreview( $action ) ) {
|
||||
|
|
@ -2234,12 +2343,8 @@ class OutputPage {
|
|||
$this->addInlineScript( $wgRequest->getText( 'wpTextbox1' ) );
|
||||
} else {
|
||||
$userpage = $wgUser->getUserPage();
|
||||
$names = array( 'common', $sk->getSkinName() );
|
||||
foreach( $names as $name ) {
|
||||
$scriptpage = Title::makeTitleSafe(
|
||||
NS_USER,
|
||||
$userpage->getDBkey() . '/' . $name . '.js'
|
||||
);
|
||||
foreach( array( 'common', $sk->getSkinName() ) as $name ) {
|
||||
$scriptpage = Title::makeTitleSafe( NS_USER, $userpage->getDBkey() . '/' . $name . '.js' );
|
||||
if ( $scriptpage && $scriptpage->exists() && ( $scriptpage->getLength() > 0 ) ) {
|
||||
$userjs = $scriptpage->getLocalURL( 'action=raw&ctype=' . $wgJsMimeType );
|
||||
$this->addScriptFile( $userjs, $scriptpage->getLatestRevID() );
|
||||
|
|
@ -2247,8 +2352,14 @@ class OutputPage {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
$scripts .= "\n" . $this->mScripts;
|
||||
// This should be at the bottom of the body - below ALL other scripts
|
||||
$scripts .= Html::inlineScript( "if ( mediaWiki !== undefined ) { mediaWiki.loader.go(); }" );
|
||||
// Add site JS if enabled
|
||||
if ( $wgUseSiteJs ) {
|
||||
$scripts .= self::makeResourceLoaderLink( $sk, 'sitejs', 'scripts' );
|
||||
}
|
||||
|
||||
return $scripts;
|
||||
}
|
||||
|
||||
|
|
@ -2296,8 +2407,8 @@ class OutputPage {
|
|||
/**
|
||||
* @return string HTML tag links to be put in the header.
|
||||
*/
|
||||
public function getHeadLinks() {
|
||||
global $wgFeed;
|
||||
public function getHeadLinks( $sk ) {
|
||||
global $wgFeed, $wgRequest;
|
||||
|
||||
// Ideally this should happen earlier, somewhere. :P
|
||||
$this->addDefaultMeta();
|
||||
|
|
@ -2367,6 +2478,17 @@ class OutputPage {
|
|||
}
|
||||
}
|
||||
|
||||
// Support individual script requests in debug mode
|
||||
if ( $wgRequest->getBool( 'debug' ) && $wgRequest->getVal( 'debug' ) !== 'false' ) {
|
||||
foreach ( $this->getModuleStyles() as $name ) {
|
||||
$tags[] = self::makeResourceLoaderLink( $sk, $name, 'styles' );
|
||||
}
|
||||
} else {
|
||||
if ( count( $this->getModuleStyles() ) ) {
|
||||
$tags[] = self::makeResourceLoaderLink( $sk, $this->getModuleStyles(), 'styles' );
|
||||
}
|
||||
}
|
||||
|
||||
return implode( "\n", $tags );
|
||||
}
|
||||
|
||||
|
|
@ -2637,20 +2759,10 @@ class OutputPage {
|
|||
* @param $modules Array: list of jQuery modules which should be loaded
|
||||
* @return Array: the list of modules which were not loaded.
|
||||
* @since 1.16
|
||||
* @deprecated No longer needed as of 1.17
|
||||
*/
|
||||
public function includeJQuery( $modules = array() ) {
|
||||
global $wgStylePath, $wgStyleVersion, $wgJQueryVersion, $wgJQueryMinified;
|
||||
|
||||
$supportedModules = array( /** TODO: add things here */ );
|
||||
$unsupported = array_diff( $modules, $supportedModules );
|
||||
|
||||
$min = $wgJQueryMinified ? '.min' : '';
|
||||
$url = "$wgStylePath/common/jquery-$wgJQueryVersion$min.js?$wgStyleVersion";
|
||||
if ( !$this->mJQueryDone ) {
|
||||
$this->mJQueryDone = true;
|
||||
$this->mScripts = Html::linkedScript( $url ) . "\n" . $this->mScripts;
|
||||
}
|
||||
return $unsupported;
|
||||
return array();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -330,14 +330,14 @@ class ProtectionForm {
|
|||
* @return String: HTML form
|
||||
*/
|
||||
function buildForm() {
|
||||
global $wgUser, $wgLang;
|
||||
global $wgUser, $wgLang, $wgOut;
|
||||
|
||||
$mProtectreasonother = Xml::label( wfMsg( 'protectcomment' ), 'wpProtectReasonSelection' );
|
||||
$mProtectreason = Xml::label( wfMsg( 'protect-otherreason' ), 'mwProtect-reason' );
|
||||
|
||||
$out = '';
|
||||
if( !$this->disabled ) {
|
||||
$out .= $this->buildScript();
|
||||
$wgOut->addModules( 'mediawiki.legacy.protect' );
|
||||
$out .= Xml::openElement( 'form', array( 'method' => 'post',
|
||||
'action' => $this->mTitle->getLocalUrl( 'action=protect' ),
|
||||
'id' => 'mw-Protect-Form', 'onsubmit' => 'ProtectionForm.enableUnchainedInputs(true)' ) );
|
||||
|
|
@ -508,8 +508,8 @@ class ProtectionForm {
|
|||
}
|
||||
|
||||
if ( !$this->disabled ) {
|
||||
$out .= Xml::closeElement( 'form' ) .
|
||||
$this->buildCleanupScript();
|
||||
$out .= Xml::closeElement( 'form' );
|
||||
$wgOut->addScript( $this->buildCleanupScript() );
|
||||
}
|
||||
|
||||
return $out;
|
||||
|
|
@ -572,12 +572,7 @@ class ProtectionForm {
|
|||
return $msg;
|
||||
}
|
||||
}
|
||||
|
||||
function buildScript() {
|
||||
global $wgStylePath, $wgStyleVersion;
|
||||
return Html::linkedScript( "$wgStylePath/common/protect.js?$wgStyleVersion.1" );
|
||||
}
|
||||
|
||||
|
||||
function buildCleanupScript() {
|
||||
global $wgRestrictionLevels, $wgGroupPermissions;
|
||||
$script = 'var wgCascadeableLevels=';
|
||||
|
|
@ -597,7 +592,7 @@ class ProtectionForm {
|
|||
$encOptions = Xml::encodeJsVar( $options );
|
||||
|
||||
$script .= "ProtectionForm.init($encOptions)";
|
||||
return Html::inlineScript( $script );
|
||||
return Html::inlineScript( "if ( mediaWiki !== undefined ) { mediaWiki.loader.using( 'mediawiki.legacy.protect', function() { {$script} } ); }" );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -78,10 +78,6 @@ class RawPage {
|
|||
$this->mGen = $gen;
|
||||
if( is_null( $smaxage ) ) $smaxage = $wgSquidMaxage;
|
||||
if($ctype == '') $ctype = 'text/css';
|
||||
} elseif( $gen == 'js' ) {
|
||||
$this->mGen = $gen;
|
||||
if( is_null( $smaxage ) ) $smaxage = $wgSquidMaxage;
|
||||
if($ctype == '') $ctype = $wgJsMimeType;
|
||||
} else {
|
||||
$this->mGen = false;
|
||||
}
|
||||
|
|
@ -169,8 +165,6 @@ class RawPage {
|
|||
$sk->initPage( $wgOut );
|
||||
if( $this->mGen == 'css' ) {
|
||||
return $sk->generateUserStylesheet();
|
||||
} else if( $this->mGen == 'js' ) {
|
||||
return $sk->generateUserJs();
|
||||
}
|
||||
} else {
|
||||
return $this->getArticleText();
|
||||
|
|
|
|||
339
includes/ResourceLoader.php
Normal file
339
includes/ResourceLoader.php
Normal file
|
|
@ -0,0 +1,339 @@
|
|||
<?php
|
||||
/**
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
* @author Roan Kattouw
|
||||
* @author Trevor Parscal
|
||||
*/
|
||||
|
||||
/*
|
||||
* Dynamic JavaScript and CSS resource loading system
|
||||
*
|
||||
* @example
|
||||
* // Registers a module with the resource loading system
|
||||
* ResourceLoader::register( 'foo', array(
|
||||
* // Script or list of scripts to include when implementating the module (required)
|
||||
* 'script' => 'resources/foo/foo.js',
|
||||
* // List of scripts or lists of scripts to include based on the current language
|
||||
* 'locales' => array(
|
||||
* 'en-gb' => 'resources/foo/locales/en-gb.js',
|
||||
* ),
|
||||
* // Script or list of scripts to include only when in debug mode
|
||||
* 'debug' => 'resources/foo/debug.js',
|
||||
* // If this module is going to be loaded before the mediawiki module is ready such as jquery or the mediawiki
|
||||
* // module itself, it can be included without special loader wrapping - this will also limit the module to not be
|
||||
* // able to specify needs, custom loaders, styles, themes or messages (any of the options below) - raw scripts
|
||||
* // get registered as 'ready' after the mediawiki module is ready, so they can be named as dependencies
|
||||
* 'raw' => false,
|
||||
* // Modules or list of modules which are needed and should be used when generating loader code
|
||||
* 'needs' => 'resources/foo/foo.js',
|
||||
* // Script or list of scripts which will cause loader code to not be generated - if you are doing something fancy
|
||||
* // with your dependencies this gives you a way to use custom registration code
|
||||
* 'loader' => 'resources/foo/loader.js',
|
||||
* // Style-sheets or list of style-sheets to include
|
||||
* 'style' => 'resources/foo/foo.css',
|
||||
* // List of style-sheets or lists of style-sheets to include based on the skin - if no match is found for current
|
||||
* // skin, 'default' is used - if default doesn't exist nothing is added
|
||||
* 'themes' => array(
|
||||
* 'default' => 'resources/foo/themes/default/foo.css',
|
||||
* 'vector' => 'resources/foo/themes/vector.foo.css',
|
||||
* ),
|
||||
* // List of keys of messages to include
|
||||
* 'messages' => array( 'foo-hello', 'foo-goodbye' ),
|
||||
* // Subclass of ResourceLoaderModule to use for custom modules
|
||||
* 'class' => 'ResourceLoaderSiteJSModule',
|
||||
* ) );
|
||||
* @example
|
||||
* // Responds to a resource loading request
|
||||
* ResourceLoader::respond( $wgRequest, $wgServer . $wgScriptPath . '/load.php' );
|
||||
*/
|
||||
class ResourceLoader {
|
||||
|
||||
/* Protected Static Members */
|
||||
|
||||
// @var array list of module name/ResourceLoaderModule object pairs
|
||||
protected static $modules = array();
|
||||
|
||||
/* Protected Static Methods */
|
||||
|
||||
/**
|
||||
* Runs text through a filter, caching the filtered result for future calls
|
||||
*
|
||||
* @param {string} $filter name of filter to run
|
||||
* @param {string} $data text to filter, such as JavaScript or CSS text
|
||||
* @param {string} $file path to file being filtered, (optional: only required for CSS to resolve paths)
|
||||
* @return {string} filtered data
|
||||
*/
|
||||
protected static function filter( $filter, $data ) {
|
||||
global $wgMemc;
|
||||
// For empty or whitespace-only things, don't do any processing
|
||||
if ( trim( $data ) === '' ) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
// Try memcached
|
||||
$key = wfMemcKey( 'resourceloader', 'filter', $filter, md5( $data ) );
|
||||
$cached = $wgMemc->get( $key );
|
||||
if ( $cached !== false && $cached !== null ) {
|
||||
return $cached;
|
||||
}
|
||||
|
||||
// Run the filter
|
||||
try {
|
||||
switch ( $filter ) {
|
||||
case 'minify-js':
|
||||
$result = JSMin::minify( $data );
|
||||
break;
|
||||
case 'minify-css':
|
||||
$result = CSSMin::minify( $data );
|
||||
break;
|
||||
case 'flip-css':
|
||||
$result = CSSJanus::transform( $data, true, false );
|
||||
break;
|
||||
default:
|
||||
// Don't cache anything, just pass right through
|
||||
return $data;
|
||||
}
|
||||
} catch ( Exception $exception ) {
|
||||
throw new MWException( 'Filter threw an exception: ' . $exception->getMessage() );
|
||||
}
|
||||
|
||||
// Save to memcached
|
||||
$wgMemc->set( $key, $result );
|
||||
return $result;
|
||||
}
|
||||
|
||||
/* Static Methods */
|
||||
|
||||
/**
|
||||
* Registers a module with the ResourceLoader system.
|
||||
*
|
||||
* Note that registering the same object under multiple names is not supported and may silently fail in all
|
||||
* kinds of interesting ways.
|
||||
*
|
||||
* @param {mixed} $name string of name of module or array of name/object pairs
|
||||
* @param {ResourceLoaderModule} $object module object (optional when using multiple-registration calling style)
|
||||
* @return {boolean} false if there were any errors, in which case one or more modules were not registered
|
||||
*
|
||||
* @todo We need much more clever error reporting, not just in detailing what happened, but in bringing errors to
|
||||
* the client in a way that they can easily see them if they want to, such as by using FireBug
|
||||
*/
|
||||
public static function register( $name, ResourceLoaderModule $object = null ) {
|
||||
// Allow multiple modules to be registered in one call
|
||||
if ( is_array( $name ) && !isset( $object ) ) {
|
||||
foreach ( $name as $key => $value ) {
|
||||
self::register( $key, $value );
|
||||
}
|
||||
return;
|
||||
}
|
||||
// Disallow duplicate registrations
|
||||
if ( isset( self::$modules[$name] ) ) {
|
||||
// A module has already been registered by this name
|
||||
throw new MWException( 'Another module has already been registered as ' . $name );
|
||||
}
|
||||
// Attach module
|
||||
self::$modules[$name] = $object;
|
||||
$object->setName( $name );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a map of all modules and their options
|
||||
*
|
||||
* @return {array} array( modulename => ResourceLoaderModule )
|
||||
*/
|
||||
public static function getModules() {
|
||||
return self::$modules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ResourceLoaderModule object for a given module name
|
||||
* @param $name string Module name
|
||||
* @return mixed ResourceLoaderModule or null if not registered
|
||||
*/
|
||||
public static function getModule( $name ) {
|
||||
return isset( self::$modules[$name] ) ? self::$modules[$name] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets registration code for all modules, except pre-registered ones listed in self::$preRegisteredModules
|
||||
*
|
||||
* The $lang, $skin and $debug parameters are used to calculate the last modified timestamps for each
|
||||
* module.
|
||||
* @param $lang string Language code
|
||||
* @param $skin string Skin name
|
||||
* @param $debug bool Debug mode flag
|
||||
* @return {string} JavaScript code for registering all modules with the client loader
|
||||
*/
|
||||
public static function getModuleRegistrations( ResourceLoaderContext $context ) {
|
||||
$scripts = '';
|
||||
$registrations = array();
|
||||
foreach ( self::$modules as $name => $module ) {
|
||||
// Support module loader scripts
|
||||
if ( ( $loader = $module->getLoaderScript() ) !== false ) {
|
||||
$scripts .= $loader;
|
||||
}
|
||||
// Automatically register module
|
||||
else {
|
||||
// Modules without dependencies pass two arguments (name, timestamp) to mediaWiki.loader.register()
|
||||
if ( !count( $module->getDependencies() ) ) {
|
||||
$registrations[] = array( $name, $module->getModifiedTime( $context ) );
|
||||
}
|
||||
// Modules with dependencies pass three arguments (name, timestamp, dependencies) to mediaWiki.loader.register()
|
||||
else {
|
||||
$registrations[] = array( $name, $module->getModifiedTime( $context ), $module->getDependencies() );
|
||||
}
|
||||
}
|
||||
}
|
||||
return $scripts . "mediaWiki.loader.register( " . FormatJson::encode( $registrations ) . " );";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the highest modification time of all modules, based on a given combination of language code,
|
||||
* skin name and debug mode flag.
|
||||
* @param $lang string Language code
|
||||
* @param $skin string Skin name
|
||||
* @param $debug bool Debug mode flag
|
||||
* @return int UNIX timestamp
|
||||
*/
|
||||
public static function getHighestModifiedTime( ResourceLoaderContext $context ) {
|
||||
$time = 1; // wfTimestamp() treats 0 as 'now', so that's not a suitable choice
|
||||
foreach ( self::$modules as $module ) {
|
||||
$time = max( $time, $module->getModifiedTime( $context ) );
|
||||
}
|
||||
return $time;
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
|
||||
/*
|
||||
* Outputs a response to a resource load-request, including a content-type header
|
||||
*
|
||||
* @param {WebRequest} $request web request object to respond to
|
||||
* @param {string} $server web-accessible path to script server
|
||||
*
|
||||
* $options format:
|
||||
* array(
|
||||
* 'lang' => [string: language code, optional, code of default language by default],
|
||||
* 'skin' => [string: name of skin, optional, name of default skin by default],
|
||||
* 'dir' => [string: 'ltr' or 'rtl', optional, direction of lang by default],
|
||||
* 'debug' => [boolean: true to include debug-only scripts, optional, false by default],
|
||||
* 'only' => [string: 'scripts', 'styles' or 'messages', optional, if set only get part of the requested module]
|
||||
* )
|
||||
*/
|
||||
public static function respond( ResourceLoaderContext $context ) {
|
||||
// Split requested modules into two groups, modules and missing
|
||||
$modules = array();
|
||||
$missing = array();
|
||||
foreach ( $context->getModules() as $name ) {
|
||||
if ( isset( self::$modules[$name] ) ) {
|
||||
$modules[] = $name;
|
||||
} else {
|
||||
$missing[] = $name;
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate the mtime and caching maxages for this request. We need this, 304 or no 304
|
||||
$mtime = 1;
|
||||
$maxage = PHP_INT_MAX;
|
||||
$smaxage = PHP_INT_MAX;
|
||||
foreach ( $modules as $name ) {
|
||||
$mtime = max( $mtime, self::$modules[$name]->getModifiedTime( $context ) );
|
||||
$maxage = min( $maxage, self::$modules[$name]->getClientMaxage() );
|
||||
$smaxage = min( $smaxage, self::$modules[$name]->getServerMaxage() );
|
||||
}
|
||||
header( 'Last-Modified: ' . wfTimestamp( TS_RFC2822, $mtime ) );
|
||||
$expires = wfTimestamp( TS_RFC2822, min( $maxage, $smaxage ) + time() );
|
||||
header( "Cache-Control: public, maxage=$maxage, s-maxage=$smaxage" );
|
||||
header( "Expires: $expires" );
|
||||
|
||||
// Check if there's an If-Modified-Since header and respond with a 304 Not Modified if possible
|
||||
$ims = $context->getRequest()->getHeader( 'If-Modified-Since' );
|
||||
if ( $ims !== false && wfTimestamp( TS_UNIX, $ims ) == $mtime ) {
|
||||
header( 'HTTP/1.0 304 Not Modified' );
|
||||
header( 'Status: 304 Not Modified' );
|
||||
return;
|
||||
}
|
||||
|
||||
// Use output buffering
|
||||
ob_start();
|
||||
|
||||
// Pre-fetch blobs
|
||||
$blobs = $context->shouldIncludeMessages() ?
|
||||
MessageBlobStore::get( $modules, $context->getLanguage() ) : array();
|
||||
|
||||
// Generate output
|
||||
foreach ( $modules as $name ) {
|
||||
// Scripts
|
||||
$scripts = '';
|
||||
if ( $context->shouldIncludeScripts() ) {
|
||||
$scripts .= self::$modules[$name]->getScript( $context );
|
||||
}
|
||||
// Styles
|
||||
$styles = '';
|
||||
if (
|
||||
$context->shouldIncludeStyles() &&
|
||||
( $styles .= self::$modules[$name]->getStyle( $context ) ) !== ''
|
||||
) {
|
||||
if ( $context->getDirection() == 'rtl' ) {
|
||||
$styles = self::filter( 'flip-css', $styles );
|
||||
}
|
||||
$styles = $context->getDebug() ? $styles : self::filter( 'minify-css', $styles );
|
||||
}
|
||||
// Messages
|
||||
$messages = isset( $blobs[$name] ) ? $blobs[$name] : '{}';
|
||||
// Output
|
||||
if ( $context->getOnly() === 'styles' ) {
|
||||
echo $styles;
|
||||
} else if ( $context->getOnly() === 'scripts' ) {
|
||||
echo $scripts;
|
||||
} else if ( $context->getOnly() === 'messages' ) {
|
||||
echo "mediaWiki.msg.set( $messages );\n";
|
||||
} else {
|
||||
$styles = Xml::escapeJsString( $styles );
|
||||
echo "mediaWiki.loader.implement( '$name', function() {{$scripts}},\n'$styles',\n$messages );\n";
|
||||
}
|
||||
}
|
||||
// Update the status of script-only modules
|
||||
if ( $context->getOnly() === 'scripts' && !in_array( 'startup', $modules ) ) {
|
||||
$statuses = array();
|
||||
foreach ( $modules as $name ) {
|
||||
$statuses[$name] = 'ready';
|
||||
}
|
||||
$statuses = FormatJson::encode( $statuses );
|
||||
echo "mediaWiki.loader.state( $statuses );";
|
||||
}
|
||||
// Register missing modules
|
||||
if ( $context->shouldIncludeScripts() ) {
|
||||
foreach ( $missing as $name ) {
|
||||
echo "mediaWiki.loader.register( '$name', null, 'missing' );\n";
|
||||
}
|
||||
}
|
||||
// Output the appropriate header
|
||||
if ( $context->getOnly() === 'styles' ) {
|
||||
header( 'Content-Type: text/css' );
|
||||
} else {
|
||||
header( 'Content-Type: text/javascript' );
|
||||
if ( $context->getDebug() ) {
|
||||
ob_end_flush();
|
||||
} else {
|
||||
echo self::filter( 'minify-js', ob_get_clean() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Temp hack
|
||||
require_once "$IP/resources/Resources.php";
|
||||
113
includes/ResourceLoaderContext.php
Normal file
113
includes/ResourceLoaderContext.php
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
<?php
|
||||
/**
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
* @author Trevor Parscal
|
||||
* @author Roan Kattouw
|
||||
*/
|
||||
|
||||
/**
|
||||
* Object passed around to modules which contains information about the state of a specific loader request
|
||||
*/
|
||||
class ResourceLoaderContext {
|
||||
|
||||
/* Protected Members */
|
||||
|
||||
protected $request;
|
||||
protected $server;
|
||||
protected $modules;
|
||||
protected $language;
|
||||
protected $direction;
|
||||
protected $skin;
|
||||
protected $debug;
|
||||
protected $only;
|
||||
protected $hash;
|
||||
|
||||
/* Methods */
|
||||
|
||||
public function __construct( WebRequest $request, $server ) {
|
||||
global $wgUser, $wgLang, $wgDefaultSkin;
|
||||
|
||||
$this->request = $request;
|
||||
$this->server = $server;
|
||||
// Interperet request
|
||||
$this->modules = explode( '|', $request->getVal( 'modules' ) );
|
||||
$this->language = $request->getVal( 'lang' );
|
||||
$this->direction = $request->getVal( 'dir' );
|
||||
$this->skin = $request->getVal( 'skin' );
|
||||
$this->debug = $request->getVal( 'debug' ) === 'true' || $request->getBool( 'debug' );
|
||||
$this->only = $request->getVal( 'only' );
|
||||
// Fallback on system defaults
|
||||
if ( !$this->language ) {
|
||||
$this->language = $wgLang->getCode();
|
||||
}
|
||||
if ( !$this->direction ) {
|
||||
$this->direction = Language::factory( $this->language )->getDir();
|
||||
}
|
||||
if ( !$this->skin ) {
|
||||
$this->skin = $wgDefaultSkin;
|
||||
}
|
||||
}
|
||||
|
||||
public function getRequest() {
|
||||
return $this->request;
|
||||
}
|
||||
|
||||
public function getServer() {
|
||||
return $this->server;
|
||||
}
|
||||
|
||||
public function getModules() {
|
||||
return $this->modules;
|
||||
}
|
||||
|
||||
public function getLanguage() {
|
||||
return $this->language;
|
||||
}
|
||||
|
||||
public function getDirection() {
|
||||
return $this->direction;
|
||||
}
|
||||
|
||||
public function getSkin() {
|
||||
return $this->skin;
|
||||
}
|
||||
|
||||
public function getDebug() {
|
||||
return $this->debug;
|
||||
}
|
||||
|
||||
public function getOnly() {
|
||||
return $this->only;
|
||||
}
|
||||
|
||||
public function shouldIncludeScripts() {
|
||||
return is_null( $this->only ) || $this->only === 'scripts';
|
||||
}
|
||||
|
||||
public function shouldIncludeStyles() {
|
||||
return is_null( $this->only ) || $this->only === 'styles';
|
||||
}
|
||||
|
||||
public function shouldIncludeMessages() {
|
||||
return is_null( $this->only ) || $this->only === 'messages';
|
||||
}
|
||||
|
||||
public function getHash() {
|
||||
return isset( $this->hash ) ?
|
||||
$this->hash : $this->hash = implode( '|', array( $this->language, $this->skin, $this->debug ) );
|
||||
}
|
||||
}
|
||||
695
includes/ResourceLoaderModule.php
Normal file
695
includes/ResourceLoaderModule.php
Normal file
|
|
@ -0,0 +1,695 @@
|
|||
<?php
|
||||
/**
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
* @author Trevor Parscal
|
||||
* @author Roan Kattouw
|
||||
*/
|
||||
|
||||
/**
|
||||
* Interface for resource loader modules, with name registration and maxage functionality.
|
||||
*/
|
||||
abstract class ResourceLoaderModule {
|
||||
|
||||
/* Protected Members */
|
||||
|
||||
protected $name = null;
|
||||
|
||||
/* Methods */
|
||||
|
||||
/**
|
||||
* Get this module's name. This is set when the module is registered
|
||||
* with ResourceLoader::register()
|
||||
* @return mixed Name (string) or null if no name was set
|
||||
*/
|
||||
public function getName() {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this module's name. This is called by ResourceLodaer::register()
|
||||
* when registering the module. Other code should not call this.
|
||||
* @param $name string Name
|
||||
*/
|
||||
public function setName( $name ) {
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* The maximum number of seconds to cache this module for in the
|
||||
* client-side (browser) cache. Override this only if you have a good
|
||||
* reason not to use $wgResourceLoaderClientMaxage.
|
||||
* @return int Cache maxage in seconds
|
||||
*/
|
||||
public function getClientMaxage() {
|
||||
global $wgResourceLoaderClientMaxage;
|
||||
return $wgResourceLoaderClientMaxage;
|
||||
}
|
||||
|
||||
/**
|
||||
* The maximum number of seconds to cache this module for in the
|
||||
* server-side (Squid / proxy) cache. Override this only if you have a
|
||||
* good reason not to use $wgResourceLoaderServerMaxage.
|
||||
* @return int Cache maxage in seconds
|
||||
*/
|
||||
public function getServerMaxage() {
|
||||
global $wgResourceLoaderServerMaxage;
|
||||
return $wgResourceLoaderServerMaxage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all JS for this module for a given language and skin.
|
||||
* Includes all relevant JS except loader scripts.
|
||||
* @param $lang string Language code
|
||||
* @param $skin string Skin name
|
||||
* @param $debug bool Whether to include debug scripts
|
||||
* @return string JS
|
||||
*/
|
||||
public abstract function getScript( ResourceLoaderContext $context );
|
||||
|
||||
/**
|
||||
* Get all CSS for this module for a given skin.
|
||||
* @param $skin string Skin name
|
||||
* @return string CSS
|
||||
*/
|
||||
public abstract function getStyle( ResourceLoaderContext $context );
|
||||
|
||||
/**
|
||||
* Get the messages needed for this module.
|
||||
*
|
||||
* To get a JSON blob with messages, use MessageBlobStore::get()
|
||||
* @return array of message keys. Keys may occur more than once
|
||||
*/
|
||||
public abstract function getMessages();
|
||||
|
||||
/**
|
||||
* Get the loader JS for this module, if set.
|
||||
* @return mixed Loader JS (string) or false if no custom loader set
|
||||
*/
|
||||
public abstract function getLoaderScript();
|
||||
|
||||
/**
|
||||
* Get a list of modules this module depends on.
|
||||
*
|
||||
* Dependency information is taken into account when loading a module
|
||||
* on the client side. When adding a module on the server side,
|
||||
* dependency information is NOT taken into account and YOU are
|
||||
* responsible for adding dependent modules as well. If you don't do
|
||||
* this, the client side loader will send a second request back to the
|
||||
* server to fetch the missing modules, which kind of defeats the
|
||||
* purpose of the resource loader.
|
||||
*
|
||||
* To add dependencies dynamically on the client side, use a custom
|
||||
* loader script, see getLoaderScript()
|
||||
* @return array Array of module names (strings)
|
||||
*/
|
||||
public abstract function getDependencies();
|
||||
|
||||
/**
|
||||
* Get this module's last modification timestamp for a given
|
||||
* combination of language, skin and debug mode flag. This is typically
|
||||
* the highest of each of the relevant components' modification
|
||||
* timestamps. Whenever anything happens that changes the module's
|
||||
* contents for these parameters, the mtime should increase.
|
||||
* @param $lang string Language code
|
||||
* @param $skin string Skin name
|
||||
* @param $debug bool Debug mode flag
|
||||
* @return int UNIX timestamp
|
||||
*/
|
||||
public abstract function getModifiedTime( ResourceLoaderContext $context );
|
||||
}
|
||||
|
||||
/**
|
||||
* Module based on local JS/CSS files. This is the most common type of module.
|
||||
*/
|
||||
class ResourceLoaderFileModule extends ResourceLoaderModule {
|
||||
|
||||
/* Protected Members */
|
||||
|
||||
protected $scripts = array();
|
||||
protected $styles = array();
|
||||
protected $messages = array();
|
||||
protected $dependencies = array();
|
||||
protected $debugScripts = array();
|
||||
protected $languageScripts = array();
|
||||
protected $skinScripts = array();
|
||||
protected $skinStyles = array();
|
||||
protected $loaders = array();
|
||||
protected $parameters = array();
|
||||
|
||||
// In-object cache for file dependencies
|
||||
protected $fileDeps = array();
|
||||
// In-object cache for mtime
|
||||
protected $modifiedTime = array();
|
||||
|
||||
/* Methods */
|
||||
|
||||
/**
|
||||
* Construct a new module from an options array.
|
||||
*
|
||||
* @param $options array Options array. If empty, an empty module will be constructed
|
||||
*
|
||||
* $options format:
|
||||
* array(
|
||||
* // Required module options (mutually exclusive)
|
||||
* 'scripts' => 'dir/script.js' | array( 'dir/script1.js', 'dir/script2.js' ... ),
|
||||
*
|
||||
* // Optional module options
|
||||
* 'languageScripts' => array(
|
||||
* '[lang name]' => 'dir/lang.js' | '[lang name]' => array( 'dir/lang1.js', 'dir/lang2.js' ... )
|
||||
* ...
|
||||
* ),
|
||||
* 'skinScripts' => 'dir/skin.js' | array( 'dir/skin1.js', 'dir/skin2.js' ... ),
|
||||
* 'debugScripts' => 'dir/debug.js' | array( 'dir/debug1.js', 'dir/debug2.js' ... ),
|
||||
*
|
||||
* // Non-raw module options
|
||||
* 'dependencies' => 'module' | array( 'module1', 'module2' ... )
|
||||
* 'loaderScripts' => 'dir/loader.js' | array( 'dir/loader1.js', 'dir/loader2.js' ... ),
|
||||
* 'styles' => 'dir/file.css' | array( 'dir/file1.css', 'dir/file2.css' ... ),
|
||||
* 'skinStyles' => array(
|
||||
* '[skin name]' => 'dir/skin.css' | '[skin name]' => array( 'dir/skin1.css', 'dir/skin2.css' ... )
|
||||
* ...
|
||||
* ),
|
||||
* 'messages' => array( 'message1', 'message2' ... ),
|
||||
* )
|
||||
*/
|
||||
public function __construct( $options = array() ) {
|
||||
foreach ( $options as $option => $value ) {
|
||||
switch ( $option ) {
|
||||
case 'scripts':
|
||||
$this->scripts = (array)$value;
|
||||
break;
|
||||
case 'styles':
|
||||
$this->styles = (array)$value;
|
||||
break;
|
||||
case 'messages':
|
||||
$this->messages = (array)$value;
|
||||
break;
|
||||
case 'dependencies':
|
||||
$this->dependencies = (array)$value;
|
||||
break;
|
||||
case 'debugScripts':
|
||||
$this->debugScripts = (array)$value;
|
||||
break;
|
||||
case 'languageScripts':
|
||||
$this->languageScripts = (array)$value;
|
||||
break;
|
||||
case 'skinScripts':
|
||||
$this->skinScripts = (array)$value;
|
||||
break;
|
||||
case 'skinStyles':
|
||||
$this->skinStyles = (array)$value;
|
||||
break;
|
||||
case 'loaders':
|
||||
$this->loaders = (array)$value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add script files to this module. In order to be valid, a module
|
||||
* must contain at least one script file.
|
||||
* @param $scripts mixed Path to script file (string) or array of paths
|
||||
*/
|
||||
public function addScripts( $scripts ) {
|
||||
$this->scripts = array_merge( $this->scripts, (array)$scripts );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add style (CSS) files to this module.
|
||||
* @param $styles mixed Path to CSS file (string) or array of paths
|
||||
*/
|
||||
public function addStyles( $styles ) {
|
||||
$this->styles = array_merge( $this->styles, (array)$styles );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add messages to this module.
|
||||
* @param $messages mixed Message key (string) or array of message keys
|
||||
*/
|
||||
public function addMessages( $messages ) {
|
||||
$this->messages = array_merge( $this->messages, (array)$messages );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add dependencies. Dependency information is taken into account when
|
||||
* loading a module on the client side. When adding a module on the
|
||||
* server side, dependency information is NOT taken into account and
|
||||
* YOU are responsible for adding dependent modules as well. If you
|
||||
* don't do this, the client side loader will send a second request
|
||||
* back to the server to fetch the missing modules, which kind of
|
||||
* defeats the point of using the resource loader in the first place.
|
||||
*
|
||||
* To add dependencies dynamically on the client side, use a custom
|
||||
* loader (see addLoaders())
|
||||
*
|
||||
* @param $dependencies mixed Module name (string) or array of module names
|
||||
*/
|
||||
public function addDependencies( $dependencies ) {
|
||||
$this->dependencies = array_merge( $this->dependencies, (array)$dependencies );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add debug scripts to the module. These scripts are only included
|
||||
* in debug mode.
|
||||
* @param $scripts mixed Path to script file (string) or array of paths
|
||||
*/
|
||||
public function addDebugScripts( $scripts ) {
|
||||
$this->debugScripts = array_merge( $this->debugScripts, (array)$scripts );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add language-specific scripts. These scripts are only included for
|
||||
* a given language.
|
||||
* @param $lang string Language code
|
||||
* @param $scripts mixed Path to script file (string) or array of paths
|
||||
*/
|
||||
public function addLanguageScripts( $lang, $scripts ) {
|
||||
$this->languageScripts = array_merge_recursive(
|
||||
$this->languageScripts,
|
||||
array( $lang => $scripts )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add skin-specific scripts. These scripts are only included for
|
||||
* a given skin.
|
||||
* @param $skin string Skin name, or 'default'
|
||||
* @param $scripts mixed Path to script file (string) or array of paths
|
||||
*/
|
||||
public function addSkinScripts( $skin, $scripts ) {
|
||||
$this->skinScripts = array_merge_recursive(
|
||||
$this->skinScripts,
|
||||
array( $skin => $scripts )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add skin-specific CSS. These CSS files are only included for a
|
||||
* given skin. If there are no skin-specific CSS files for a skin,
|
||||
* the files defined for 'default' will be used, if any.
|
||||
* @param $skin string Skin name, or 'default'
|
||||
* @param $scripts mixed Path to CSS file (string) or array of paths
|
||||
*/
|
||||
public function addSkinStyles( $skin, $scripts ) {
|
||||
$this->skinStyles = array_merge_recursive(
|
||||
$this->skinStyles,
|
||||
array( $skin => $scripts )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add loader scripts. These scripts are loaded on every page and are
|
||||
* responsible for registering this module using
|
||||
* mediaWiki.loader.register(). If there are no loader scripts defined,
|
||||
* the resource loader will register the module itself.
|
||||
*
|
||||
* Loader scripts are used to determine a module's dependencies
|
||||
* dynamically on the client side (e.g. based on browser type/version).
|
||||
* Note that loader scripts are included on every page, so they should
|
||||
* be lightweight and use mediaWiki.loader.register()'s callback
|
||||
* feature to defer dependency calculation.
|
||||
* @param $scripts mixed Path to script file (string) or array of paths
|
||||
*/
|
||||
public function addLoaders( $scripts ) {
|
||||
$this->loaders = array_merge( $this->loaders, (array)$scripts );
|
||||
}
|
||||
|
||||
public function getScript( ResourceLoaderContext $context ) {
|
||||
$retval = $this->getPrimaryScript() . "\n" .
|
||||
$this->getLanguageScript( $context->getLanguage() ) . "\n" .
|
||||
$this->getSkinScript( $context->getSkin() );
|
||||
if ( $context->getDebug() ) {
|
||||
$retval .= $this->getDebugScript();
|
||||
}
|
||||
return $retval;
|
||||
}
|
||||
|
||||
public function getStyle( ResourceLoaderContext $context ) {
|
||||
$style = $this->getPrimaryStyle() . "\n" . $this->getSkinStyle( $context->getSkin() );
|
||||
|
||||
// Extract and store the list of referenced files
|
||||
$files = CSSMin::getLocalFileReferences( $style );
|
||||
|
||||
// Only store if modified
|
||||
if ( $files !== $this->getFileDependencies( $context->getSkin() ) ) {
|
||||
$encFiles = FormatJson::encode( $files );
|
||||
$dbw = wfGetDb( DB_MASTER );
|
||||
$dbw->replace( 'module_deps',
|
||||
array( array( 'md_module', 'md_skin' ) ), array(
|
||||
'md_module' => $this->getName(),
|
||||
'md_skin' => $context->getSkin(),
|
||||
'md_deps' => $encFiles,
|
||||
)
|
||||
);
|
||||
|
||||
// Save into memcached
|
||||
global $wgMemc;
|
||||
$key = wfMemcKey( 'resourceloader', 'module_deps', $this->getName(), $context->getSkin() );
|
||||
$wgMemc->set( $key, $encFiles );
|
||||
}
|
||||
return $style;
|
||||
}
|
||||
|
||||
public function getMessages() {
|
||||
return $this->messages;
|
||||
}
|
||||
|
||||
public function getDependencies() {
|
||||
return $this->dependencies;
|
||||
}
|
||||
|
||||
public function getLoaderScript() {
|
||||
if ( count( $this->loaders ) == 0 ) {
|
||||
return false;
|
||||
}
|
||||
return self::concatScripts( $this->loaders );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the last modified timestamp of this module, which is calculated
|
||||
* as the highest last modified timestamp of its constituent files and
|
||||
* the files it depends on (see getFileDependencies()). Only files
|
||||
* relevant to the given language and skin are taken into account, and
|
||||
* files only relevant in debug mode are not taken into account when
|
||||
* debug mode is off.
|
||||
* @param $lang string Language code
|
||||
* @param $skin string Skin name
|
||||
* @param $debug bool Debug mode flag
|
||||
* @return int UNIX timestamp
|
||||
*/
|
||||
public function getModifiedTime( ResourceLoaderContext $context ) {
|
||||
if ( isset( $this->modifiedTime[$context->getHash()] ) ) {
|
||||
return $this->modifiedTime[$context->getHash()];
|
||||
}
|
||||
|
||||
$files = array_merge(
|
||||
$this->scripts,
|
||||
$this->styles,
|
||||
$context->getDebug() ? $this->debugScripts : array(),
|
||||
isset( $this->languageScripts[$context->getLanguage()] ) ?
|
||||
(array) $this->languageScripts[$context->getLanguage()] : array(),
|
||||
(array) self::getSkinFiles( $context->getSkin(), $this->skinScripts ),
|
||||
(array) self::getSkinFiles( $context->getSkin(), $this->skinStyles ),
|
||||
$this->loaders,
|
||||
$this->getFileDependencies( $context->getSkin() )
|
||||
);
|
||||
$filesMtime = max( array_map( 'filemtime', array_map( array( __CLASS__, 'remapFilename' ), $files ) ) );
|
||||
|
||||
// Get the mtime of the message blob
|
||||
// TODO: This timestamp is queried a lot and queried separately for each module. Maybe it should be put in memcached?
|
||||
$dbr = wfGetDb( DB_SLAVE );
|
||||
$msgBlobMtime = $dbr->selectField( 'msg_resource', 'mr_timestamp', array(
|
||||
'mr_resource' => $this->getName(),
|
||||
'mr_lang' => $context->getLanguage()
|
||||
), __METHOD__
|
||||
);
|
||||
$msgBlobMtime = $msgBlobMtime ? wfTimestamp( TS_UNIX, $msgBlobMtime ) : 0;
|
||||
|
||||
$this->modifiedTime[$context->getHash()] = max( $filesMtime, $msgBlobMtime );
|
||||
return $this->modifiedTime[$context->getHash()];
|
||||
}
|
||||
|
||||
/* Protected Members */
|
||||
|
||||
/**
|
||||
* Get the primary JS for this module. This is pulled from the
|
||||
* script files added through addScripts()
|
||||
* @return string JS
|
||||
*/
|
||||
protected function getPrimaryScript() {
|
||||
return self::concatScripts( $this->scripts );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the primary CSS for this module. This is pulled from the CSS
|
||||
* files added through addStyles()
|
||||
* @return string JS
|
||||
*/
|
||||
protected function getPrimaryStyle() {
|
||||
return self::concatStyles( $this->styles );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the debug JS for this module. This is pulled from the script
|
||||
* files added through addDebugScripts()
|
||||
* @return string JS
|
||||
*/
|
||||
protected function getDebugScript() {
|
||||
return self::concatScripts( $this->debugScripts );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the language-specific JS for a given language. This is pulled
|
||||
* from the language-specific script files added through addLanguageScripts()
|
||||
* @return string JS
|
||||
*/
|
||||
protected function getLanguageScript( $lang ) {
|
||||
if ( !isset( $this->languageScripts[$lang] ) ) {
|
||||
return '';
|
||||
}
|
||||
return self::concatScripts( $this->languageScripts[$lang] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the skin-specific JS for a given skin. This is pulled from the
|
||||
* skin-specific JS files added through addSkinScripts()
|
||||
* @return string JS
|
||||
*/
|
||||
protected function getSkinScript( $skin ) {
|
||||
return self::concatScripts( self::getSkinFiles( $skin, $this->skinScripts ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the skin-specific CSS for a given skin. This is pulled from the
|
||||
* skin-specific CSS files added through addSkinStyles()
|
||||
* @return string CSS
|
||||
*/
|
||||
protected function getSkinStyle( $skin ) {
|
||||
return self::concatStyles( self::getSkinFiles( $skin, $this->skinStyles ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to get skin-specific data from an array.
|
||||
* @param $skin string Skin name
|
||||
* @param $map array Map of skin names to arrays
|
||||
* @return $map[$skin] if set and non-empty, or $map['default'] if set, or an empty array
|
||||
*/
|
||||
protected static function getSkinFiles( $skin, $map ) {
|
||||
$retval = array();
|
||||
if ( isset( $map[$skin] ) && $map[$skin] ) {
|
||||
$retval = $map[$skin];
|
||||
} else if ( isset( $map['default'] ) ) {
|
||||
$retval = $map['default'];
|
||||
}
|
||||
return $retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the files this module depends on indirectly for a given skin.
|
||||
* Currently these are only image files referenced by the module's CSS.
|
||||
* @param $skin string Skin name
|
||||
* @return array of files
|
||||
*/
|
||||
protected function getFileDependencies( $skin ) {
|
||||
// Try in-object cache first
|
||||
if ( isset( $this->fileDeps[$skin] ) ) {
|
||||
return $this->fileDeps[$skin];
|
||||
}
|
||||
|
||||
// Now try memcached
|
||||
global $wgMemc;
|
||||
$key = wfMemcKey( 'resourceloader', 'module_deps', $this->getName(), $skin );
|
||||
$deps = $wgMemc->get( $key );
|
||||
|
||||
if ( !$deps ) {
|
||||
$dbr = wfGetDb( DB_SLAVE );
|
||||
$deps = $dbr->selectField( 'module_deps', 'md_deps', array(
|
||||
'md_module' => $this->getName(),
|
||||
'md_skin' => $skin,
|
||||
), __METHOD__
|
||||
);
|
||||
if ( !$deps ) {
|
||||
$deps = '[]'; // Empty array so we can do negative caching
|
||||
}
|
||||
$wgMemc->set( $key, $deps );
|
||||
}
|
||||
$this->fileDeps = FormatJson::decode( $deps, true );
|
||||
return $this->fileDeps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the contents of a set of files and concatenate them, with
|
||||
* newlines in between. Each file is used only once.
|
||||
* @param $files array Array of file names
|
||||
* @return string Concatenated contents of $files
|
||||
*/
|
||||
protected static function concatScripts( $files ) {
|
||||
return implode( "\n", array_map( 'file_get_contents', array_map( array( __CLASS__, 'remapFilename' ), array_unique( (array) $files ) ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the contents of a set of CSS files, remap then and concatenate
|
||||
* them, with newlines in between. Each file is used only once.
|
||||
* @param $files array Array of file names
|
||||
* @return string Concatenated and remapped contents of $files
|
||||
*/
|
||||
protected static function concatStyles( $files ) {
|
||||
return implode( "\n", array_map( array( __CLASS__, 'remapStyle' ), array_unique( (array) $files ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Remap a relative to $IP. Used as a callback for array_map()
|
||||
* @param $file string File name
|
||||
* @return string $IP/$file
|
||||
*/
|
||||
protected static function remapFilename( $file ) {
|
||||
global $IP;
|
||||
return "$IP/$file";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the contents of a CSS file and run it through CSSMin::remap().
|
||||
* This wrapper is needed so we can use array_map() in concatStyles()
|
||||
* @param $file string File name
|
||||
* @return string Remapped CSS
|
||||
*/
|
||||
protected static function remapStyle( $file ) {
|
||||
return CSSMin::remap( file_get_contents( self::remapFilename( $file ) ), dirname( $file ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom module for MediaWiki:Common.js and MediaWiki:Skinname.js
|
||||
* TODO: Add Site CSS functionality too
|
||||
*/
|
||||
class ResourceLoaderSiteModule extends ResourceLoaderModule {
|
||||
|
||||
/* Protected Members */
|
||||
|
||||
// In-object cache for modified time
|
||||
protected $modifiedTime = null;
|
||||
|
||||
/* Methods */
|
||||
|
||||
public function getScript( ResourceLoaderContext $context ) {
|
||||
return Skin::newFromKey( $context->getSkin() )->generateUserJs();
|
||||
}
|
||||
|
||||
public function getModifiedTime( ResourceLoaderContext $context ) {
|
||||
if ( isset( $this->modifiedTime[$context->getHash()] ) ) {
|
||||
return $this->modifiedTime[$context->getHash()];
|
||||
}
|
||||
|
||||
// HACK: We duplicate the message names from generateUserJs()
|
||||
// here and weird things (i.e. mtime moving backwards) can happen
|
||||
// when a MediaWiki:Something.js page is deleted
|
||||
$jsPages = array( Title::makeTitle( NS_MEDIAWIKI, 'Common.js' ),
|
||||
Title::makeTitle( NS_MEDIAWIKI, ucfirst( $context->getSkin() ) . '.js' )
|
||||
);
|
||||
|
||||
// Do batch existence check
|
||||
// TODO: This would work better if page_touched were loaded by this as well
|
||||
$lb = new LinkBatch( $jsPages );
|
||||
$lb->execute();
|
||||
|
||||
$this->modifiedTime = 1; // wfTimestamp() interprets 0 as "now"
|
||||
foreach ( $jsPages as $jsPage ) {
|
||||
if ( $jsPage->exists() ) {
|
||||
$this->modifiedTime = max( $this->modifiedTime, wfTimestamp( TS_UNIX, $jsPage->getTouched() ) );
|
||||
}
|
||||
}
|
||||
return $this->modifiedTime;
|
||||
}
|
||||
|
||||
public function getStyle( ResourceLoaderContext $context ) { return ''; }
|
||||
public function getMessages() { return array(); }
|
||||
public function getLoaderScript() { return ''; }
|
||||
public function getDependencies() { return array(); }
|
||||
}
|
||||
|
||||
|
||||
class ResourceLoaderStartUpModule extends ResourceLoaderModule {
|
||||
|
||||
/* Protected Members */
|
||||
|
||||
protected $modifiedTime = null;
|
||||
|
||||
/* Methods */
|
||||
|
||||
public function getScript( ResourceLoaderContext $context ) {
|
||||
global $IP;
|
||||
|
||||
$scripts = file_get_contents( "$IP/resources/startup.js" );
|
||||
if ( $context->getOnly() === 'scripts' ) {
|
||||
// Get all module registrations
|
||||
$registration = ResourceLoader::getModuleRegistrations( $context );
|
||||
// Build configuration
|
||||
$config = FormatJson::encode(
|
||||
array( 'server' => $context->getServer(), 'debug' => $context->getDebug() )
|
||||
);
|
||||
// Add a well-known start-up function
|
||||
$scripts .= "window.startUp = function() { $registration mediaWiki.config.set( $config ); };";
|
||||
// Build load query for jquery and mediawiki modules
|
||||
$query = wfArrayToCGI(
|
||||
array(
|
||||
'modules' => implode( '|', array( 'jquery', 'mediawiki' ) ),
|
||||
'only' => 'scripts',
|
||||
'lang' => $context->getLanguage(),
|
||||
'dir' => $context->getDirection(),
|
||||
'skin' => $context->getSkin(),
|
||||
'debug' => $context->getDebug(),
|
||||
'version' => wfTimestamp( TS_ISO_8601, round( max(
|
||||
ResourceLoader::getModule( 'jquery' )->getModifiedTime( $context ),
|
||||
ResourceLoader::getModule( 'mediawiki' )->getModifiedTime( $context )
|
||||
), -2 ) )
|
||||
)
|
||||
);
|
||||
// Build HTML code for loading jquery and mediawiki modules
|
||||
$loadScript = Html::linkedScript( $context->getServer() . "?$query" );
|
||||
// Add code to add jquery and mediawiki loading code; only if the current client is compatible
|
||||
$scripts .= "if ( isCompatible() ) { document.write( '$loadScript' ); }";
|
||||
// Delete the compatible function - it's not needed anymore
|
||||
$scripts .= "delete window['isCompatible'];";
|
||||
}
|
||||
return $scripts;
|
||||
}
|
||||
|
||||
public function getModifiedTime( ResourceLoaderContext $context ) {
|
||||
global $IP;
|
||||
if ( !is_null( $this->modifiedTime ) ) {
|
||||
return $this->modifiedTime;
|
||||
}
|
||||
// HACK getHighestModifiedTime() calls this function, so protect against infinite recursion
|
||||
$this->modifiedTime = filemtime( "$IP/resources/startup.js" );
|
||||
$this->modifiedTime = ResourceLoader::getHighestModifiedTime( $context );
|
||||
return $this->modifiedTime;
|
||||
}
|
||||
|
||||
public function getClientMaxage() {
|
||||
return 300; // 5 minutes
|
||||
}
|
||||
|
||||
public function getServerMaxage() {
|
||||
return 300; // 5 minutes
|
||||
}
|
||||
|
||||
public function getStyle( ResourceLoaderContext $context ) { return ''; }
|
||||
public function getMessages() { return array(); }
|
||||
public function getLoaderScript() { return ''; }
|
||||
public function getDependencies() { return array(); }
|
||||
}
|
||||
|
|
@ -332,23 +332,17 @@ class Skin extends Linker {
|
|||
|
||||
$out->out( $afterContent );
|
||||
|
||||
$out->out( $this->bottomScripts() );
|
||||
$out->out( $this->bottomScripts( $out ) );
|
||||
|
||||
$out->out( wfReportTime() );
|
||||
|
||||
$out->out( "\n</body></html>" );
|
||||
wfProfileOut( __METHOD__ );
|
||||
}
|
||||
|
||||
|
||||
static function makeVariablesScript( $data ) {
|
||||
if( $data ) {
|
||||
$r = array();
|
||||
foreach ( $data as $name => $value ) {
|
||||
$encValue = Xml::encodeJsVar( $value );
|
||||
$r[] = "$name=$encValue";
|
||||
}
|
||||
$js = 'var ' . implode( ",\n", $r ) . ';';
|
||||
return Html::inlineScript( "\n$js\n" );
|
||||
return Html::inlineScript( 'mediaWiki.config.set(' . json_encode( $data ) . ');' );
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
|
|
@ -686,8 +680,9 @@ CSS;
|
|||
* @param $out OutputPage
|
||||
*/
|
||||
function setupSkinUserCss( OutputPage $out ) {
|
||||
$out->addStyle( 'common/shared.css' );
|
||||
$out->addStyle( 'common/oldshared.css' );
|
||||
// This includes the shared.js and oldshared.js files from skins/common/
|
||||
$out->addModuleStyles( 'mediawiki.legacy.shared' );
|
||||
// TODO: Figure out how to best integrate this stuff into ResourceLoader
|
||||
$out->addStyle( $this->getStylesheet() );
|
||||
$out->addStyle( 'common/common_rtl.css', '', '', 'rtl' );
|
||||
}
|
||||
|
|
@ -992,10 +987,11 @@ CSS;
|
|||
|
||||
/**
|
||||
* This gets called shortly before the </body> tag.
|
||||
* @param $out OutputPage object
|
||||
* @return String HTML-wrapped JS code to be put before </body>
|
||||
*/
|
||||
function bottomScripts() {
|
||||
$bottomScriptText = "\n" . Html::inlineScript( 'if (window.runOnloadHook) runOnloadHook();' ) . "\n";
|
||||
function bottomScripts( $out ) {
|
||||
$bottomScriptText = "\n" . $out->getHeadScripts( $this );
|
||||
wfRunHooks( 'SkinAfterBottomScripts', array( $this, &$bottomScriptText ) );
|
||||
return $bottomScriptText;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,8 +107,8 @@ class SkinTemplate extends Skin {
|
|||
* @param $out OutputPage
|
||||
*/
|
||||
function setupSkinUserCss( OutputPage $out ){
|
||||
$out->addStyle( 'common/shared.css', 'screen' );
|
||||
$out->addStyle( 'common/commonPrint.css', 'print' );
|
||||
$out->addModuleStyles( 'mediawiki.legacy.shared' );
|
||||
$out->addModuleStyles( 'mediawiki.legacy.commonPrint' );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -421,7 +421,7 @@ class SkinTemplate extends Skin {
|
|||
|
||||
$tpl->set( 'reporttime', wfReportTime() );
|
||||
$tpl->set( 'sitenotice', wfGetSiteNotice() );
|
||||
$tpl->set( 'bottomscripts', $this->bottomScripts() );
|
||||
$tpl->set( 'bottomscripts', $this->bottomScripts( $out ) );
|
||||
|
||||
$printfooter = "<div class=\"printfooter\">\n" . $this->printSource() . "</div>\n";
|
||||
global $wgBetterDirectionality;
|
||||
|
|
|
|||
|
|
@ -128,10 +128,15 @@ wfProfileOut( 'WebStart.php-conf' );
|
|||
|
||||
wfProfileIn( 'WebStart.php-ob_start' );
|
||||
# Initialise output buffering
|
||||
if ( ob_get_level() ) {
|
||||
# Someone's been mixing configuration data with code!
|
||||
# How annoying.
|
||||
} elseif ( !defined( 'MW_NO_OUTPUT_BUFFER' ) ) {
|
||||
|
||||
# Check that there is no previous output or previously set up buffers, because
|
||||
# that would cause us to potentially mix gzip and non-gzip output, creating a
|
||||
# big mess.
|
||||
# In older versions of PHP ob_get_level() returns 0 if there is no buffering or
|
||||
# previous output, in newer versions the default output buffer is always set up
|
||||
# and ob_get_level() returns 1. In this case we check that the buffer is empty.
|
||||
# FIXME: Check that this is the right way to handle this
|
||||
if ( !defined( 'MW_NO_OUTPUT_BUFFER' ) && ( ob_get_level() == 0 || ( ob_get_level() == 1 && ob_get_contents() === '' ) ) ) {
|
||||
require_once( "$IP/includes/OutputHandler.php" );
|
||||
ob_start( 'wfOutputHandler' );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -580,10 +580,7 @@ CONTROL;
|
|||
*/
|
||||
function showDiffStyle() {
|
||||
global $wgStylePath, $wgStyleVersion, $wgOut;
|
||||
$wgOut->addStyle( 'common/diff.css' );
|
||||
|
||||
// JS is needed to detect old versions of Mozilla to work around an annoyance bug.
|
||||
$wgOut->addScript( "<script type=\"text/javascript\" src=\"$wgStylePath/common/diff.js?$wgStyleVersion\"></script>" );
|
||||
$wgOut->addModules( 'mediawiki.legacy.diff' );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -167,6 +167,8 @@ class MysqlUpdater extends DatabaseUpdater {
|
|||
array( 'addField', 'categorylinks', 'cl_collation', 'patch-categorylinks-better-collation.sql' ),
|
||||
array( 'do_cl_fields_update' ),
|
||||
array( 'do_collation_update' ),
|
||||
array( 'addTable', 'msg_resource', 'patch-msg_resource.sql' ),
|
||||
array( 'addTable', 'module_deps', 'patch-module_deps.sql' ),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ class SqliteUpdater extends DatabaseUpdater {
|
|||
array( 'addField', 'interwiki', 'iw_api', 'patch-iw_api_and_wikiid.sql' ),
|
||||
array( 'drop_index_if_exists', 'iwlinks', 'iwl_prefix', 'patch-kill-iwl_prefix.sql' ),
|
||||
array( 'drop_index_if_exists', 'iwlinks', 'iwl_prefix_from_title', 'patch-kill-iwl_pft.sql' ),
|
||||
array( 'addTable', 'msg_resource', 'patch-msg_resource.sql' ),
|
||||
array( 'addTable', 'module_deps', 'patch-module_deps.sql' ),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -116,6 +116,7 @@ class ParserOutput extends CacheTime
|
|||
$mHideNewSection = false, # Hide the new section link?
|
||||
$mNoGallery = false, # No gallery on category page? (__NOGALLERY__)
|
||||
$mHeadItems = array(), # Items to put in the <head> section
|
||||
$mModules = array(), # Modules to be loaded by the resource loader
|
||||
$mOutputHooks = array(), # Hook tags as per $wgParserOutputHooks
|
||||
$mWarnings = array(), # Warning text to be returned to the user. Wikitext formatted, in the key only
|
||||
$mSections = array(), # Table of contents
|
||||
|
|
@ -146,6 +147,7 @@ class ParserOutput extends CacheTime
|
|||
function &getExternalLinks() { return $this->mExternalLinks; }
|
||||
function getNoGallery() { return $this->mNoGallery; }
|
||||
function getHeadItems() { return $this->mHeadItems; }
|
||||
function getModules() { return $this->mModules; }
|
||||
function getSubtitle() { return $this->mSubtitle; }
|
||||
function getOutputHooks() { return (array)$this->mOutputHooks; }
|
||||
function getWarnings() { return array_keys( $this->mWarnings ); }
|
||||
|
|
@ -267,6 +269,10 @@ class ParserOutput extends CacheTime
|
|||
$this->mHeadItems[] = $section;
|
||||
}
|
||||
}
|
||||
|
||||
function addModules( $modules ) {
|
||||
$this->mModules = array_merge( $this->mModules, (array) $modules );
|
||||
}
|
||||
|
||||
/**
|
||||
* Override the title to be used for display
|
||||
|
|
|
|||
|
|
@ -196,8 +196,8 @@ class IPBlockForm extends SpecialPage {
|
|||
wfMsgForContent( 'ipbreasonotherlist' ), $this->BlockReasonList, 'wpBlockDropDown', 4 );
|
||||
|
||||
global $wgStylePath, $wgStyleVersion;
|
||||
$wgOut->addModules( 'mediawiki.legacy.block' );
|
||||
$wgOut->addHTML(
|
||||
Xml::tags( 'script', array( 'type' => 'text/javascript', 'src' => "$wgStylePath/common/block.js?$wgStyleVersion" ), '' ) .
|
||||
Xml::openElement( 'form', array( 'method' => 'post', 'action' => $titleObj->getLocalURL( 'action=submit' ), 'id' => 'blockip' ) ) .
|
||||
Xml::openElement( 'fieldset' ) .
|
||||
Xml::element( 'legend', null, wfMsg( 'blockip-legend' ) ) .
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ class SpecialPreferences extends SpecialPage {
|
|||
return;
|
||||
}
|
||||
|
||||
$wgOut->addScriptFile( 'prefs.js' );
|
||||
$wgOut->addModules( 'mediawiki.legacy.prefs' );
|
||||
|
||||
if ( $wgRequest->getCheck( 'success' ) ) {
|
||||
$wgOut->wrapWikiMsg(
|
||||
|
|
|
|||
|
|
@ -366,7 +366,7 @@ class SpecialSearch {
|
|||
$wgOut->setArticleRelated( false );
|
||||
$wgOut->setRobotPolicy( 'noindex,nofollow' );
|
||||
// add javascript specific to special:search
|
||||
$wgOut->addScriptFile( 'search.js' );
|
||||
$wgOut->addModules( 'mediawiki.legacy.search' );
|
||||
|
||||
// Bug #16886: Sister projects box moves down the first extract on IE7
|
||||
$wgOut->addStyle( 'common/IE70Fixes.css', 'screen', 'IE 7' );
|
||||
|
|
|
|||
|
|
@ -1065,8 +1065,7 @@ class UploadForm extends HTMLForm {
|
|||
$wgOut->addScript( Skin::makeVariablesScript( $scriptVars ) );
|
||||
|
||||
// For <charinsert> support
|
||||
$wgOut->addScriptFile( 'edit.js' );
|
||||
$wgOut->addScriptFile( 'upload.js' );
|
||||
$wgOut->addModules( array( 'mediawiki.legacy.edit', 'mediawiki.legacy.upload' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
56
load.php
Normal file
56
load.php
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
/**
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
* @author Roan Kattouw
|
||||
* @author Trevor Parscal
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file is the entry point for the resource loader.
|
||||
*/
|
||||
|
||||
require ( dirname( __FILE__ ) . '/includes/WebStart.php' );
|
||||
wfProfileIn( 'load.php' );
|
||||
|
||||
// URL safety checks
|
||||
//
|
||||
// See RawPage.php for details; summary is that MSIE can override the
|
||||
// Content-Type if it sees a recognized extension on the URL, such as
|
||||
// might be appended via PATH_INFO after 'load.php'.
|
||||
//
|
||||
// Some resources can contain HTML-like strings (e.g. in messages)
|
||||
// which will end up triggering HTML detection and execution.
|
||||
//
|
||||
if ( $wgRequest->isPathInfoBad() ) {
|
||||
wfHttpError( 403, 'Forbidden',
|
||||
'Invalid file extension found in PATH_INFO. ' .
|
||||
'The resource loader must be accessed through the primary script entry point.' );
|
||||
return;
|
||||
// FIXME: Doesn't this execute the rest of the request anyway?
|
||||
// Was taken from api.php so I guess it's maybe OK but it doesn't look good.
|
||||
}
|
||||
|
||||
// Respond to resource loading request
|
||||
ResourceLoader::respond( new ResourceLoaderContext( $wgRequest, $wgServer . $wgScriptPath . '/load.php' ) );
|
||||
|
||||
wfProfileOut( 'load.php' );
|
||||
wfLogProfilingData();
|
||||
|
||||
// Shut down the database
|
||||
wfGetLBFactory()->shutdown();
|
||||
12
maintenance/archives/patch-module_deps.sql
Normal file
12
maintenance/archives/patch-module_deps.sql
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
-- Table for tracking which local files a module depends on that aren't
|
||||
-- registered directly.
|
||||
-- Currently only used for tracking images that CSS depends on
|
||||
CREATE TABLE /*_*/module_deps (
|
||||
-- Module name
|
||||
md_module varchar(255) NOT NULL,
|
||||
-- Skin name
|
||||
md_skin varchar(32) NOT NULL,
|
||||
-- JSON blob with file dependencies
|
||||
md_deps mediumblob NOT NULL
|
||||
) /*$wgDBTableOptions*/;
|
||||
CREATE UNIQUE INDEX /*i*/md_module_skin ON /*_*/module_deps (md_module, md_skin);
|
||||
20
maintenance/archives/patch-msg_resource.sql
Normal file
20
maintenance/archives/patch-msg_resource.sql
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
-- Table for storing JSON message blobs for the resource loader
|
||||
CREATE TABLE /*_*/msg_resource (
|
||||
-- Resource name
|
||||
mr_resource varchar(255) NOT NULL,
|
||||
-- Language code
|
||||
mr_lang varbinary(32) NOT NULL,
|
||||
-- JSON blob. This is an incomplete JSON object, i.e. without the wrapping {}
|
||||
mr_blob mediumblob NOT NULL,
|
||||
-- Timestamp of last update
|
||||
mr_timestamp binary(14) NOT NULL
|
||||
) /*$wgDBTableOptions*/;
|
||||
CREATE UNIQUE INDEX /*i*/mr_resource_lang ON /*_*/msg_resource(mr_resource, mr_lang);
|
||||
|
||||
-- Table for administering which message is contained in which resource
|
||||
CREATE TABLE /*_*/msg_resource_links (
|
||||
mrl_resource varchar(255) NOT NULL,
|
||||
-- Message key
|
||||
mrl_message varchar(255) NOT NULL
|
||||
) /*$wgDBTableOptions*/;
|
||||
CREATE UNIQUE INDEX /*i*/mrl_message_resource ON /*_*/msg_resource_links (mrl_message, mrl_resource);
|
||||
|
|
@ -1395,4 +1395,38 @@ CREATE TABLE /*_*/l10n_cache (
|
|||
) /*$wgDBTableOptions*/;
|
||||
CREATE INDEX /*i*/lc_lang_key ON /*_*/l10n_cache (lc_lang, lc_key);
|
||||
|
||||
-- Table for storing JSON message blobs for the resource loader
|
||||
CREATE TABLE /*_*/msg_resource (
|
||||
-- Resource name
|
||||
mr_resource varchar(255) NOT NULL,
|
||||
-- Language code
|
||||
mr_lang varbinary(32) NOT NULL,
|
||||
-- JSON blob
|
||||
mr_blob mediumblob NOT NULL,
|
||||
-- Timestamp of last update
|
||||
mr_timestamp binary(14) NOT NULL
|
||||
) /*$wgDBTableOptions*/;
|
||||
CREATE UNIQUE INDEX /*i*/mr_resource_lang ON /*_*/msg_resource (mr_resource, mr_lang);
|
||||
|
||||
-- Table for administering which message is contained in which resource
|
||||
CREATE TABLE /*_*/msg_resource_links (
|
||||
mrl_resource varchar(255) NOT NULL,
|
||||
-- Message key
|
||||
mrl_message varchar(255) NOT NULL
|
||||
) /*$wgDBTableOptions*/;
|
||||
CREATE UNIQUE INDEX /*i*/mrl_message_resource ON /*_*/msg_resource_links (mrl_message, mrl_resource);
|
||||
|
||||
-- Table for tracking which local files a module depends on that aren't
|
||||
-- registered directly.
|
||||
-- Currently only used for tracking images that CSS depends on
|
||||
CREATE TABLE /*_*/module_deps (
|
||||
-- Module name
|
||||
md_module varchar(255) NOT NULL,
|
||||
-- Skin name
|
||||
md_skin varchar(32) NOT NULL,
|
||||
-- JSON blob with file dependencies
|
||||
md_deps mediumblob NOT NULL
|
||||
) /*$wgDBTableOptions*/;
|
||||
CREATE UNIQUE INDEX /*i*/md_module_skin ON /*_*/module_deps (md_module, md_skin);
|
||||
|
||||
-- vim: sw=2 sts=2 et
|
||||
|
|
|
|||
16
maintenance/tests/ResourceLoaderFileModuleTest.php
Normal file
16
maintenance/tests/ResourceLoaderFileModuleTest.php
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
class ResourceLoaderFileModuleTest extends PHPUnit_Framework_TestCase {
|
||||
|
||||
/* Provider Methods */
|
||||
|
||||
public function provide() {
|
||||
|
||||
}
|
||||
|
||||
/* Test Methods */
|
||||
|
||||
public function test() {
|
||||
|
||||
}
|
||||
}
|
||||
16
maintenance/tests/ResourceLoaderTest.php
Normal file
16
maintenance/tests/ResourceLoaderTest.php
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
class ResourceLoaderTest extends PHPUnit_Framework_TestCase {
|
||||
|
||||
/* Provider Methods */
|
||||
|
||||
public function provide() {
|
||||
|
||||
}
|
||||
|
||||
/* Test Methods */
|
||||
|
||||
public function test() {
|
||||
|
||||
}
|
||||
}
|
||||
363
resources/Resources.php
Normal file
363
resources/Resources.php
Normal file
|
|
@ -0,0 +1,363 @@
|
|||
<?php
|
||||
|
||||
ResourceLoader::register( array(
|
||||
|
||||
/* Special resources who have their own classes */
|
||||
|
||||
'site' => new ResourceLoaderSiteModule,
|
||||
'startup' => new ResourceLoaderStartUpModule,
|
||||
|
||||
/* Skins */
|
||||
|
||||
'vector' => new ResourceLoaderFileModule( array( 'styles' => 'skins/vector/main-ltr.css' ) ),
|
||||
|
||||
/* jQuery */
|
||||
|
||||
'jquery' => new ResourceLoaderFileModule( array( 'scripts' => 'resources/jquery/jquery.js' ) ),
|
||||
|
||||
/* jQuery Plugins */
|
||||
|
||||
'jquery.tabIndex' => new ResourceLoaderFileModule( array( 'scripts' => 'resources/jquery/jquery.tabIndex.js' ) ),
|
||||
'jquery.cookie' => new ResourceLoaderFileModule( array( 'scripts' => 'resources/jquery/jquery.cookie.js' ) ),
|
||||
|
||||
/* jQuery UI */
|
||||
|
||||
// Core
|
||||
'jquery.ui.core' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'resources/jquery.ui/jquery.ui.core.js',
|
||||
'skinStyles' => array(
|
||||
'default' => array(
|
||||
'resources/jquery.ui/themes/default/jquery.ui.core.css',
|
||||
'resources/jquery.ui/themes/default/jquery.ui.theme.css',
|
||||
),
|
||||
'vector' => array(
|
||||
'resources/jquery.ui/themes/vector/jquery.ui.core.css',
|
||||
'resources/jquery.ui/themes/vector/jquery.ui.theme.css',
|
||||
),
|
||||
),
|
||||
'dependencies' => 'jquery',
|
||||
) ),
|
||||
'jquery.ui.widget' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'resources/jquery.ui/jquery.ui.widget.js',
|
||||
'dependencies' => 'jquery.ui.core',
|
||||
) ),
|
||||
'jquery.ui.mouse' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'resources/jquery.ui/jquery.ui.mouse.js',
|
||||
'dependencies' => 'jquery',
|
||||
) ),
|
||||
'jquery.ui.position' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'resources/jquery.ui/jquery.ui.position.js',
|
||||
'dependencies' => 'jquery',
|
||||
) ),
|
||||
// Interactions
|
||||
'jquery.ui.draggable' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'resources/jquery.ui/jquery.ui.draggable.js',
|
||||
'dependencies' => 'jquery.ui.core',
|
||||
) ),
|
||||
'jquery.ui.droppable' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'resources/jquery.ui/jquery.ui.droppable.js',
|
||||
'dependencies' => array( 'jquery.ui.core', 'jquery.ui.draggable' ),
|
||||
) ),
|
||||
'jquery.ui.resizable' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'resources/jquery.ui/jquery.ui.resizable.js',
|
||||
'skinStyles' => array(
|
||||
'default' => 'resources/jquery.ui/themes/default/jquery.ui.resizable.css',
|
||||
'vector' => 'resources/jquery.ui/themes/vector/jquery.ui.resizable.css',
|
||||
),
|
||||
'dependencies' => 'jquery.ui.core',
|
||||
) ),
|
||||
'jquery.ui.selectable' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'resources/jquery.ui/jquery.ui.selectable.js',
|
||||
'skinStyles' => array(
|
||||
'default' => 'resources/jquery.ui/themes/default/jquery.ui.selectable.css',
|
||||
'vector' => 'resources/jquery.ui/themes/vector/jquery.ui.selectable.css',
|
||||
),
|
||||
'dependencies' => 'jquery.ui.core',
|
||||
) ),
|
||||
'jquery.ui.sortable' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'resources/jquery.ui/jquery.ui.sortable.js',
|
||||
'dependencies' => 'jquery.ui.core',
|
||||
) ),
|
||||
// Widgets
|
||||
'jquery.ui.accordion' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'resources/jquery.ui/jquery.ui.accordion.js',
|
||||
'dependencies' => 'jquery.ui.core',
|
||||
'skinStyles' => array(
|
||||
'default' => 'resources/jquery.ui/themes/default/jquery.ui.accordion.css',
|
||||
'vector' => 'resources/jquery.ui/themes/vector/jquery.ui.accordion.css',
|
||||
),
|
||||
) ),
|
||||
'jquery.ui.autocomplete' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'resources/jquery.ui/jquery.ui.autocomplete.js',
|
||||
'dependencies' => array( 'jquery.ui.core', 'jquery.ui.widget', 'jquery.ui.position' ),
|
||||
'skinStyles' => array(
|
||||
'default' => 'resources/jquery.ui/themes/default/jquery.ui.autocomplete.css',
|
||||
'vector' => 'resources/jquery.ui/themes/vector/jquery.ui.autocomplete.css',
|
||||
),
|
||||
) ),
|
||||
'jquery.ui.button' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'resources/jquery.ui/jquery.ui.button.js',
|
||||
'dependencies' => array( 'jquery.ui.core', 'jquery.ui.widget' ),
|
||||
'skinStyles' => array(
|
||||
'default' => 'resources/jquery.ui/themes/default/jquery.ui.button.css',
|
||||
'vector' => 'resources/jquery.ui/themes/vector/jquery.ui.button.css',
|
||||
),
|
||||
) ),
|
||||
'jquery.ui.datepicker' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'resources/jquery.ui/jquery.ui.datepicker.js',
|
||||
'dependencies' => 'jquery.ui.core',
|
||||
'skinStyles' => array(
|
||||
'default' => 'resources/jquery.ui/themes/default/jquery.ui.datepicker.css',
|
||||
'vector' => 'resources/jquery.ui/themes/vector/jquery.ui.datepicker.css',
|
||||
),
|
||||
'languageScripts' => array(
|
||||
'af' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-af.js',
|
||||
'ar' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-ar.js',
|
||||
'az' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-az.js',
|
||||
'bg' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-bg.js',
|
||||
'bs' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-bs.js',
|
||||
'ca' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-ca.js',
|
||||
'cs' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-cs.js',
|
||||
'da' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-da.js',
|
||||
'de' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-de.js',
|
||||
'el' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-el.js',
|
||||
'en-gb' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-en-GB.js',
|
||||
'eo' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-eo.js',
|
||||
'es' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-es.js',
|
||||
'et' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-et.js',
|
||||
'eu' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-eu.js',
|
||||
'fa' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-fa.js',
|
||||
'fi' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-fi.js',
|
||||
'fo' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-fo.js',
|
||||
'fr-ch' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-fr-CH.js',
|
||||
'fr' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-fr.js',
|
||||
'he' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-he.js',
|
||||
'hr' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-hr.js',
|
||||
'hu' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-hu.js',
|
||||
'hy' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-hy.js',
|
||||
'id' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-id.js',
|
||||
'is' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-is.js',
|
||||
'it' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-it.js',
|
||||
'ja' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-ja.js',
|
||||
'ko' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-ko.js',
|
||||
'lt' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-lt.js',
|
||||
'lv' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-lv.js',
|
||||
'ms' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-ms.js',
|
||||
'nl' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-nl.js',
|
||||
'no' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-no.js',
|
||||
'pl' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-pl.js',
|
||||
'pt-br' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-pt-BR.js',
|
||||
'ro' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-ro.js',
|
||||
'ru' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-ru.js',
|
||||
'sk' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-sk.js',
|
||||
'sl' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-sl.js',
|
||||
'sq' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-sq.js',
|
||||
'sr-sr' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-sr-SR.js',
|
||||
'sr' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-sr.js',
|
||||
'sv' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-sv.js',
|
||||
'ta' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-ta.js',
|
||||
'th' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-th.js',
|
||||
'tr' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-tr.js',
|
||||
'uk' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-uk.js',
|
||||
'vi' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-vi.js',
|
||||
'zh-cn' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-zh-CN.js',
|
||||
'zh-hk' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-zh-HK.js',
|
||||
'zh-tw' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-zh-TW.js'
|
||||
),
|
||||
) ),
|
||||
'jquery.ui.dialog' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'resources/jquery.ui/jquery.ui.dialog.js',
|
||||
'dependencies' => 'jquery.ui.core',
|
||||
'skinStyles' => array(
|
||||
'default' => 'resources/jquery.ui/themes/default/jquery.ui.dialog.css',
|
||||
'vector' => 'resources/jquery.ui/themes/vector/jquery.ui.dialog.css',
|
||||
),
|
||||
) ),
|
||||
'jquery.ui.progressbar' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'resources/jquery.ui/jquery.ui.progressbar.js',
|
||||
'dependencies' => 'jquery.ui.core',
|
||||
'skinStyles' => array(
|
||||
'default' => 'resources/jquery.ui/themes/default/jquery.ui.progressbar.css',
|
||||
'vector' => 'resources/jquery.ui/themes/vector/jquery.ui.progressbar.css',
|
||||
),
|
||||
) ),
|
||||
'jquery.ui.slider' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'resources/jquery.ui/jquery.ui.slider.js',
|
||||
'dependencies' => array( 'jquery.ui.core', 'jquery.ui.widget', 'jquery.ui.mouse' ),
|
||||
'skinStyles' => array(
|
||||
'default' => 'resources/jquery.ui/themes/default/jquery.ui.slider.css',
|
||||
'vector' => 'resources/jquery.ui/themes/vector/jquery.ui.slider.css',
|
||||
),
|
||||
) ),
|
||||
'jquery.ui.tabs' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'resources/jquery.ui/jquery.ui.tabs.js',
|
||||
'dependencies' => 'jquery.ui.core',
|
||||
'skinStyles' => array(
|
||||
'default' => 'resources/jquery.ui/themes/default/jquery.ui.tabs.css',
|
||||
'vector' => 'resources/jquery.ui/themes/vector/jquery.ui.tabs.css',
|
||||
),
|
||||
) ),
|
||||
// Effects
|
||||
'jquery.effects.core' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'resources/jquery.effects/jquery.effects.core.js',
|
||||
'dependencies' => 'jquery',
|
||||
) ),
|
||||
'jquery.effects.blind' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'resources/jquery.effects/jquery.effects.blind.js',
|
||||
'dependencies' => 'jquery.effects.core',
|
||||
) ),
|
||||
'jquery.effects.bounce' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'resources/jquery.effects/jquery.effects.bounce.js',
|
||||
'dependencies' => 'jquery.effects.core',
|
||||
) ),
|
||||
'jquery.effects.clip' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'resources/jquery.effects/jquery.effects.clip.js',
|
||||
'dependencies' => 'jquery.effects.core',
|
||||
) ),
|
||||
'jquery.effects.drop' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'resources/jquery.effects/jquery.effects.drop.js',
|
||||
'dependencies' => 'jquery.effects.core',
|
||||
) ),
|
||||
'jquery.effects.explode' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'resources/jquery.effects/jquery.effects.explode.js',
|
||||
'dependencies' => 'jquery.effects.core',
|
||||
) ),
|
||||
'jquery.effects.fold' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'resources/jquery.effects/jquery.effects.fold.js',
|
||||
'dependencies' => 'jquery.effects.core',
|
||||
) ),
|
||||
'jquery.effects.highlight' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'resources/jquery.effects/jquery.effects.highlight.js',
|
||||
'dependencies' => 'jquery.effects.core',
|
||||
) ),
|
||||
'jquery.effects.pulsate' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'resources/jquery.effects/jquery.effects.pulsate.js',
|
||||
'dependencies' => 'jquery.effects.core',
|
||||
) ),
|
||||
'jquery.effects.scale' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'resources/jquery.effects/jquery.effects.scale.js',
|
||||
'dependencies' => 'jquery.effects.core',
|
||||
) ),
|
||||
'jquery.effects.shake' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'resources/jquery.effects/jquery.effects.shake.js',
|
||||
'dependencies' => 'jquery.effects.core',
|
||||
) ),
|
||||
'jquery.effects.slide' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'resources/jquery.effects/jquery.effects.slide.js',
|
||||
'dependencies' => 'jquery.effects.core',
|
||||
) ),
|
||||
'jquery.effects.transfer' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'resources/jquery.effects/jquery.effects.transfer.js',
|
||||
'dependencies' => 'jquery.effects.core',
|
||||
) ),
|
||||
|
||||
/* MediaWiki */
|
||||
|
||||
'mediawiki' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'resources/mediawiki/mediawiki.js',
|
||||
'debugScripts' => 'resources/mediawiki/mediawiki.log.js',
|
||||
) ),
|
||||
|
||||
/* MediaWiki Utilities */
|
||||
|
||||
'mediawiki.util.client' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'resources/mediawiki.util/mediawiki.util.client.js',
|
||||
) ),
|
||||
|
||||
/* MediaWiki Legacy */
|
||||
|
||||
'mediawiki.legacy.ajax' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'skins/common/ajax.js',
|
||||
'messages' => array( 'watch', 'unwatch', 'watching', 'unwatching', 'tooltip-ca-watch', 'tooltip-ca-unwatch' ),
|
||||
'dependencies' => 'mediawiki.legacy.wikibits',
|
||||
) ),
|
||||
'mediawiki.legacy.ajaxwatch' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'skins/common/ajaxwatch.js',
|
||||
'dependencies' => 'mediawiki.legacy.wikibits',
|
||||
) ),
|
||||
'mediawiki.legacy.block' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'skins/common/block.js',
|
||||
'dependencies' => 'mediawiki.legacy.wikibits',
|
||||
) ),
|
||||
'mediawiki.legacy.changepassword' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'skins/common/changepassword.js',
|
||||
'dependencies' => 'mediawiki.legacy.wikibits',
|
||||
) ),
|
||||
'mediawiki.legacy.commonPrint' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'skins/common/commonPrint.css',
|
||||
) ),
|
||||
'mediawiki.legacy.config' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'skins/common/config.js',
|
||||
'styles' => array( 'skins/common/config.css', 'skins/common/config-cc.css' ),
|
||||
'dependencies' => 'mediawiki.legacy.wikibits',
|
||||
) ),
|
||||
'mediawiki.legacy.diff' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'skins/common/diff.js',
|
||||
'styles' => 'skins/common/diff.css',
|
||||
'dependencies' => 'mediawiki.legacy.wikibits',
|
||||
) ),
|
||||
'mediawiki.legacy.edit' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'skins/common/edit.js',
|
||||
'dependencies' => 'mediawiki.legacy.wikibits',
|
||||
) ),
|
||||
'mediawiki.legacy.enhancedchanges' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'skins/common/enhancedchanges.js',
|
||||
'dependencies' => 'mediawiki.legacy.wikibits',
|
||||
) ),
|
||||
'mediawiki.legacy.history' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'skins/common/history.js',
|
||||
'dependencies' => 'mediawiki.legacy.wikibits',
|
||||
) ),
|
||||
'mediawiki.legacy.htmlform' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'skins/common/htmlform.js',
|
||||
'dependencies' => 'mediawiki.legacy.wikibits',
|
||||
) ),
|
||||
'mediawiki.legacy.IEFixes' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'skins/common/IEFixes.js',
|
||||
'dependencies' => 'mediawiki.legacy.wikibits',
|
||||
) ),
|
||||
'mediawiki.legacy.metadata' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'skins/common/metadata.js',
|
||||
'dependencies' => 'mediawiki.legacy.wikibits',
|
||||
) ),
|
||||
'mediawiki.legacy.mwsuggest' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'skins/common/mwsuggest.js',
|
||||
'dependencies' => 'mediawiki.legacy.wikibits',
|
||||
) ),
|
||||
'mediawiki.legacy.password' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'skins/common/password.js',
|
||||
'styles' => 'skins/common/password.css',
|
||||
'dependencies' => 'mediawiki.legacy.wikibits',
|
||||
) ),
|
||||
'mediawiki.legacy.prefs' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'skins/common/prefs.js',
|
||||
'dependencies' => array( 'mediawiki.legacy.wikibits', 'mediawiki.legacy.htmlform' ),
|
||||
) ),
|
||||
'mediawiki.legacy.preview' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'skins/common/preview.js',
|
||||
'dependencies' => 'mediawiki.legacy.wikibits',
|
||||
) ),
|
||||
'mediawiki.legacy.protect' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'skins/common/protect.js',
|
||||
'dependencies' => 'mediawiki.legacy.wikibits',
|
||||
) ),
|
||||
'mediawiki.legacy.rightclickedit' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'skins/common/rightclickedit.js',
|
||||
'dependencies' => 'mediawiki.legacy.wikibits',
|
||||
) ),
|
||||
'mediawiki.legacy.search' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'skins/common/search.js',
|
||||
'dependencies' => 'mediawiki.legacy.wikibits',
|
||||
) ),
|
||||
'mediawiki.legacy.shared' => new ResourceLoaderFileModule( array(
|
||||
'styles' => array( 'skins/common/shared.css', 'skins/common/oldshared.css' ),
|
||||
) ),
|
||||
'mediawiki.legacy.upload' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'skins/common/upload.js',
|
||||
'dependencies' => 'mediawiki.legacy.wikibits',
|
||||
) ),
|
||||
'mediawiki.legacy.wikibits' => new ResourceLoaderFileModule( array(
|
||||
'scripts' => 'skins/common/wikibits.js',
|
||||
'messages' => array( 'showtoc', 'hidetoc' ),
|
||||
) ),
|
||||
) );
|
||||
49
resources/jquery.effects/jquery.effects.blind.js
vendored
Normal file
49
resources/jquery.effects/jquery.effects.blind.js
vendored
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* jQuery UI Effects Blind 1.8.2
|
||||
*
|
||||
* Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT (MIT-LICENSE.txt)
|
||||
* and GPL (GPL-LICENSE.txt) licenses.
|
||||
*
|
||||
* http://docs.jquery.com/UI/Effects/Blind
|
||||
*
|
||||
* Depends:
|
||||
* jquery.effects.core.js
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
$.effects.blind = function(o) {
|
||||
|
||||
return this.queue(function() {
|
||||
|
||||
// Create element
|
||||
var el = $(this), props = ['position','top','left'];
|
||||
|
||||
// Set options
|
||||
var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
|
||||
var direction = o.options.direction || 'vertical'; // Default direction
|
||||
|
||||
// Adjust
|
||||
$.effects.save(el, props); el.show(); // Save & Show
|
||||
var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
|
||||
var ref = (direction == 'vertical') ? 'height' : 'width';
|
||||
var distance = (direction == 'vertical') ? wrapper.height() : wrapper.width();
|
||||
if(mode == 'show') wrapper.css(ref, 0); // Shift
|
||||
|
||||
// Animation
|
||||
var animation = {};
|
||||
animation[ref] = mode == 'show' ? distance : 0;
|
||||
|
||||
// Animate
|
||||
wrapper.animate(animation, o.duration, o.options.easing, function() {
|
||||
if(mode == 'hide') el.hide(); // Hide
|
||||
$.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
|
||||
if(o.callback) o.callback.apply(el[0], arguments); // Callback
|
||||
el.dequeue();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
78
resources/jquery.effects/jquery.effects.bounce.js
vendored
Normal file
78
resources/jquery.effects/jquery.effects.bounce.js
vendored
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* jQuery UI Effects Bounce 1.8.2
|
||||
*
|
||||
* Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT (MIT-LICENSE.txt)
|
||||
* and GPL (GPL-LICENSE.txt) licenses.
|
||||
*
|
||||
* http://docs.jquery.com/UI/Effects/Bounce
|
||||
*
|
||||
* Depends:
|
||||
* jquery.effects.core.js
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
$.effects.bounce = function(o) {
|
||||
|
||||
return this.queue(function() {
|
||||
|
||||
// Create element
|
||||
var el = $(this), props = ['position','top','left'];
|
||||
|
||||
// Set options
|
||||
var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
|
||||
var direction = o.options.direction || 'up'; // Default direction
|
||||
var distance = o.options.distance || 20; // Default distance
|
||||
var times = o.options.times || 5; // Default # of times
|
||||
var speed = o.duration || 250; // Default speed per bounce
|
||||
if (/show|hide/.test(mode)) props.push('opacity'); // Avoid touching opacity to prevent clearType and PNG issues in IE
|
||||
|
||||
// Adjust
|
||||
$.effects.save(el, props); el.show(); // Save & Show
|
||||
$.effects.createWrapper(el); // Create Wrapper
|
||||
var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
|
||||
var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
|
||||
var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) / 3 : el.outerWidth({margin:true}) / 3);
|
||||
if (mode == 'show') el.css('opacity', 0).css(ref, motion == 'pos' ? -distance : distance); // Shift
|
||||
if (mode == 'hide') distance = distance / (times * 2);
|
||||
if (mode != 'hide') times--;
|
||||
|
||||
// Animate
|
||||
if (mode == 'show') { // Show Bounce
|
||||
var animation = {opacity: 1};
|
||||
animation[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
|
||||
el.animate(animation, speed / 2, o.options.easing);
|
||||
distance = distance / 2;
|
||||
times--;
|
||||
};
|
||||
for (var i = 0; i < times; i++) { // Bounces
|
||||
var animation1 = {}, animation2 = {};
|
||||
animation1[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
|
||||
animation2[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
|
||||
el.animate(animation1, speed / 2, o.options.easing).animate(animation2, speed / 2, o.options.easing);
|
||||
distance = (mode == 'hide') ? distance * 2 : distance / 2;
|
||||
};
|
||||
if (mode == 'hide') { // Last Bounce
|
||||
var animation = {opacity: 0};
|
||||
animation[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
|
||||
el.animate(animation, speed / 2, o.options.easing, function(){
|
||||
el.hide(); // Hide
|
||||
$.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
|
||||
if(o.callback) o.callback.apply(this, arguments); // Callback
|
||||
});
|
||||
} else {
|
||||
var animation1 = {}, animation2 = {};
|
||||
animation1[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
|
||||
animation2[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
|
||||
el.animate(animation1, speed / 2, o.options.easing).animate(animation2, speed / 2, o.options.easing, function(){
|
||||
$.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
|
||||
if(o.callback) o.callback.apply(this, arguments); // Callback
|
||||
});
|
||||
};
|
||||
el.queue('fx', function() { el.dequeue(); });
|
||||
el.dequeue();
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
54
resources/jquery.effects/jquery.effects.clip.js
vendored
Normal file
54
resources/jquery.effects/jquery.effects.clip.js
vendored
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* jQuery UI Effects Clip 1.8.2
|
||||
*
|
||||
* Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT (MIT-LICENSE.txt)
|
||||
* and GPL (GPL-LICENSE.txt) licenses.
|
||||
*
|
||||
* http://docs.jquery.com/UI/Effects/Clip
|
||||
*
|
||||
* Depends:
|
||||
* jquery.effects.core.js
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
$.effects.clip = function(o) {
|
||||
|
||||
return this.queue(function() {
|
||||
|
||||
// Create element
|
||||
var el = $(this), props = ['position','top','left','height','width'];
|
||||
|
||||
// Set options
|
||||
var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
|
||||
var direction = o.options.direction || 'vertical'; // Default direction
|
||||
|
||||
// Adjust
|
||||
$.effects.save(el, props); el.show(); // Save & Show
|
||||
var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
|
||||
var animate = el[0].tagName == 'IMG' ? wrapper : el;
|
||||
var ref = {
|
||||
size: (direction == 'vertical') ? 'height' : 'width',
|
||||
position: (direction == 'vertical') ? 'top' : 'left'
|
||||
};
|
||||
var distance = (direction == 'vertical') ? animate.height() : animate.width();
|
||||
if(mode == 'show') { animate.css(ref.size, 0); animate.css(ref.position, distance / 2); } // Shift
|
||||
|
||||
// Animation
|
||||
var animation = {};
|
||||
animation[ref.size] = mode == 'show' ? distance : 0;
|
||||
animation[ref.position] = mode == 'show' ? 0 : distance / 2;
|
||||
|
||||
// Animate
|
||||
animate.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
|
||||
if(mode == 'hide') el.hide(); // Hide
|
||||
$.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
|
||||
if(o.callback) o.callback.apply(el[0], arguments); // Callback
|
||||
el.dequeue();
|
||||
}});
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
714
resources/jquery.effects/jquery.effects.core.js
vendored
Normal file
714
resources/jquery.effects/jquery.effects.core.js
vendored
Normal file
|
|
@ -0,0 +1,714 @@
|
|||
/*
|
||||
* jQuery UI Effects 1.8.2
|
||||
*
|
||||
* Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT (MIT-LICENSE.txt)
|
||||
* and GPL (GPL-LICENSE.txt) licenses.
|
||||
*
|
||||
* http://docs.jquery.com/UI/Effects/
|
||||
*/
|
||||
;jQuery.effects || (function($) {
|
||||
|
||||
$.effects = {};
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/****************************** COLOR ANIMATIONS ******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
// override the animation for color styles
|
||||
$.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor',
|
||||
'borderRightColor', 'borderTopColor', 'color', 'outlineColor'],
|
||||
function(i, attr) {
|
||||
$.fx.step[attr] = function(fx) {
|
||||
if (!fx.colorInit) {
|
||||
fx.start = getColor(fx.elem, attr);
|
||||
fx.end = getRGB(fx.end);
|
||||
fx.colorInit = true;
|
||||
}
|
||||
|
||||
fx.elem.style[attr] = 'rgb(' +
|
||||
Math.max(Math.min(parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0], 10), 255), 0) + ',' +
|
||||
Math.max(Math.min(parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1], 10), 255), 0) + ',' +
|
||||
Math.max(Math.min(parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2], 10), 255), 0) + ')';
|
||||
};
|
||||
});
|
||||
|
||||
// Color Conversion functions from highlightFade
|
||||
// By Blair Mitchelmore
|
||||
// http://jquery.offput.ca/highlightFade/
|
||||
|
||||
// Parse strings looking for color tuples [255,255,255]
|
||||
function getRGB(color) {
|
||||
var result;
|
||||
|
||||
// Check if we're already dealing with an array of colors
|
||||
if ( color && color.constructor == Array && color.length == 3 )
|
||||
return color;
|
||||
|
||||
// Look for rgb(num,num,num)
|
||||
if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color))
|
||||
return [parseInt(result[1],10), parseInt(result[2],10), parseInt(result[3],10)];
|
||||
|
||||
// Look for rgb(num%,num%,num%)
|
||||
if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color))
|
||||
return [parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55];
|
||||
|
||||
// Look for #a0b1c2
|
||||
if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color))
|
||||
return [parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16)];
|
||||
|
||||
// Look for #fff
|
||||
if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color))
|
||||
return [parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)];
|
||||
|
||||
// Look for rgba(0, 0, 0, 0) == transparent in Safari 3
|
||||
if (result = /rgba\(0, 0, 0, 0\)/.exec(color))
|
||||
return colors['transparent'];
|
||||
|
||||
// Otherwise, we're most likely dealing with a named color
|
||||
return colors[$.trim(color).toLowerCase()];
|
||||
}
|
||||
|
||||
function getColor(elem, attr) {
|
||||
var color;
|
||||
|
||||
do {
|
||||
color = $.curCSS(elem, attr);
|
||||
|
||||
// Keep going until we find an element that has color, or we hit the body
|
||||
if ( color != '' && color != 'transparent' || $.nodeName(elem, "body") )
|
||||
break;
|
||||
|
||||
attr = "backgroundColor";
|
||||
} while ( elem = elem.parentNode );
|
||||
|
||||
return getRGB(color);
|
||||
};
|
||||
|
||||
// Some named colors to work with
|
||||
// From Interface by Stefan Petre
|
||||
// http://interface.eyecon.ro/
|
||||
|
||||
var colors = {
|
||||
aqua:[0,255,255],
|
||||
azure:[240,255,255],
|
||||
beige:[245,245,220],
|
||||
black:[0,0,0],
|
||||
blue:[0,0,255],
|
||||
brown:[165,42,42],
|
||||
cyan:[0,255,255],
|
||||
darkblue:[0,0,139],
|
||||
darkcyan:[0,139,139],
|
||||
darkgrey:[169,169,169],
|
||||
darkgreen:[0,100,0],
|
||||
darkkhaki:[189,183,107],
|
||||
darkmagenta:[139,0,139],
|
||||
darkolivegreen:[85,107,47],
|
||||
darkorange:[255,140,0],
|
||||
darkorchid:[153,50,204],
|
||||
darkred:[139,0,0],
|
||||
darksalmon:[233,150,122],
|
||||
darkviolet:[148,0,211],
|
||||
fuchsia:[255,0,255],
|
||||
gold:[255,215,0],
|
||||
green:[0,128,0],
|
||||
indigo:[75,0,130],
|
||||
khaki:[240,230,140],
|
||||
lightblue:[173,216,230],
|
||||
lightcyan:[224,255,255],
|
||||
lightgreen:[144,238,144],
|
||||
lightgrey:[211,211,211],
|
||||
lightpink:[255,182,193],
|
||||
lightyellow:[255,255,224],
|
||||
lime:[0,255,0],
|
||||
magenta:[255,0,255],
|
||||
maroon:[128,0,0],
|
||||
navy:[0,0,128],
|
||||
olive:[128,128,0],
|
||||
orange:[255,165,0],
|
||||
pink:[255,192,203],
|
||||
purple:[128,0,128],
|
||||
violet:[128,0,128],
|
||||
red:[255,0,0],
|
||||
silver:[192,192,192],
|
||||
white:[255,255,255],
|
||||
yellow:[255,255,0],
|
||||
transparent: [255,255,255]
|
||||
};
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/****************************** CLASS ANIMATIONS ******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
var classAnimationActions = ['add', 'remove', 'toggle'],
|
||||
shorthandStyles = {
|
||||
border: 1,
|
||||
borderBottom: 1,
|
||||
borderColor: 1,
|
||||
borderLeft: 1,
|
||||
borderRight: 1,
|
||||
borderTop: 1,
|
||||
borderWidth: 1,
|
||||
margin: 1,
|
||||
padding: 1
|
||||
};
|
||||
|
||||
function getElementStyles() {
|
||||
var style = document.defaultView
|
||||
? document.defaultView.getComputedStyle(this, null)
|
||||
: this.currentStyle,
|
||||
newStyle = {},
|
||||
key,
|
||||
camelCase;
|
||||
|
||||
// webkit enumerates style porperties
|
||||
if (style && style.length && style[0] && style[style[0]]) {
|
||||
var len = style.length;
|
||||
while (len--) {
|
||||
key = style[len];
|
||||
if (typeof style[key] == 'string') {
|
||||
camelCase = key.replace(/\-(\w)/g, function(all, letter){
|
||||
return letter.toUpperCase();
|
||||
});
|
||||
newStyle[camelCase] = style[key];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (key in style) {
|
||||
if (typeof style[key] === 'string') {
|
||||
newStyle[key] = style[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return newStyle;
|
||||
}
|
||||
|
||||
function filterStyles(styles) {
|
||||
var name, value;
|
||||
for (name in styles) {
|
||||
value = styles[name];
|
||||
if (
|
||||
// ignore null and undefined values
|
||||
value == null ||
|
||||
// ignore functions (when does this occur?)
|
||||
$.isFunction(value) ||
|
||||
// shorthand styles that need to be expanded
|
||||
name in shorthandStyles ||
|
||||
// ignore scrollbars (break in IE)
|
||||
(/scrollbar/).test(name) ||
|
||||
|
||||
// only colors or values that can be converted to numbers
|
||||
(!(/color/i).test(name) && isNaN(parseFloat(value)))
|
||||
) {
|
||||
delete styles[name];
|
||||
}
|
||||
}
|
||||
|
||||
return styles;
|
||||
}
|
||||
|
||||
function styleDifference(oldStyle, newStyle) {
|
||||
var diff = { _: 0 }, // http://dev.jquery.com/ticket/5459
|
||||
name;
|
||||
|
||||
for (name in newStyle) {
|
||||
if (oldStyle[name] != newStyle[name]) {
|
||||
diff[name] = newStyle[name];
|
||||
}
|
||||
}
|
||||
|
||||
return diff;
|
||||
}
|
||||
|
||||
$.effects.animateClass = function(value, duration, easing, callback) {
|
||||
if ($.isFunction(easing)) {
|
||||
callback = easing;
|
||||
easing = null;
|
||||
}
|
||||
|
||||
return this.each(function() {
|
||||
|
||||
var that = $(this),
|
||||
originalStyleAttr = that.attr('style') || ' ',
|
||||
originalStyle = filterStyles(getElementStyles.call(this)),
|
||||
newStyle,
|
||||
className = that.attr('className');
|
||||
|
||||
$.each(classAnimationActions, function(i, action) {
|
||||
if (value[action]) {
|
||||
that[action + 'Class'](value[action]);
|
||||
}
|
||||
});
|
||||
newStyle = filterStyles(getElementStyles.call(this));
|
||||
that.attr('className', className);
|
||||
|
||||
that.animate(styleDifference(originalStyle, newStyle), duration, easing, function() {
|
||||
$.each(classAnimationActions, function(i, action) {
|
||||
if (value[action]) { that[action + 'Class'](value[action]); }
|
||||
});
|
||||
// work around bug in IE by clearing the cssText before setting it
|
||||
if (typeof that.attr('style') == 'object') {
|
||||
that.attr('style').cssText = '';
|
||||
that.attr('style').cssText = originalStyleAttr;
|
||||
} else {
|
||||
that.attr('style', originalStyleAttr);
|
||||
}
|
||||
if (callback) { callback.apply(this, arguments); }
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
$.fn.extend({
|
||||
_addClass: $.fn.addClass,
|
||||
addClass: function(classNames, speed, easing, callback) {
|
||||
return speed ? $.effects.animateClass.apply(this, [{ add: classNames },speed,easing,callback]) : this._addClass(classNames);
|
||||
},
|
||||
|
||||
_removeClass: $.fn.removeClass,
|
||||
removeClass: function(classNames,speed,easing,callback) {
|
||||
return speed ? $.effects.animateClass.apply(this, [{ remove: classNames },speed,easing,callback]) : this._removeClass(classNames);
|
||||
},
|
||||
|
||||
_toggleClass: $.fn.toggleClass,
|
||||
toggleClass: function(classNames, force, speed, easing, callback) {
|
||||
if ( typeof force == "boolean" || force === undefined ) {
|
||||
if ( !speed ) {
|
||||
// without speed parameter;
|
||||
return this._toggleClass(classNames, force);
|
||||
} else {
|
||||
return $.effects.animateClass.apply(this, [(force?{add:classNames}:{remove:classNames}),speed,easing,callback]);
|
||||
}
|
||||
} else {
|
||||
// without switch parameter;
|
||||
return $.effects.animateClass.apply(this, [{ toggle: classNames },force,speed,easing]);
|
||||
}
|
||||
},
|
||||
|
||||
switchClass: function(remove,add,speed,easing,callback) {
|
||||
return $.effects.animateClass.apply(this, [{ add: add, remove: remove },speed,easing,callback]);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/*********************************** EFFECTS **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
$.extend($.effects, {
|
||||
version: "1.8.2",
|
||||
|
||||
// Saves a set of properties in a data storage
|
||||
save: function(element, set) {
|
||||
for(var i=0; i < set.length; i++) {
|
||||
if(set[i] !== null) element.data("ec.storage."+set[i], element[0].style[set[i]]);
|
||||
}
|
||||
},
|
||||
|
||||
// Restores a set of previously saved properties from a data storage
|
||||
restore: function(element, set) {
|
||||
for(var i=0; i < set.length; i++) {
|
||||
if(set[i] !== null) element.css(set[i], element.data("ec.storage."+set[i]));
|
||||
}
|
||||
},
|
||||
|
||||
setMode: function(el, mode) {
|
||||
if (mode == 'toggle') mode = el.is(':hidden') ? 'show' : 'hide'; // Set for toggle
|
||||
return mode;
|
||||
},
|
||||
|
||||
getBaseline: function(origin, original) { // Translates a [top,left] array into a baseline value
|
||||
// this should be a little more flexible in the future to handle a string & hash
|
||||
var y, x;
|
||||
switch (origin[0]) {
|
||||
case 'top': y = 0; break;
|
||||
case 'middle': y = 0.5; break;
|
||||
case 'bottom': y = 1; break;
|
||||
default: y = origin[0] / original.height;
|
||||
};
|
||||
switch (origin[1]) {
|
||||
case 'left': x = 0; break;
|
||||
case 'center': x = 0.5; break;
|
||||
case 'right': x = 1; break;
|
||||
default: x = origin[1] / original.width;
|
||||
};
|
||||
return {x: x, y: y};
|
||||
},
|
||||
|
||||
// Wraps the element around a wrapper that copies position properties
|
||||
createWrapper: function(element) {
|
||||
|
||||
// if the element is already wrapped, return it
|
||||
if (element.parent().is('.ui-effects-wrapper')) {
|
||||
return element.parent();
|
||||
}
|
||||
|
||||
// wrap the element
|
||||
var props = {
|
||||
width: element.outerWidth(true),
|
||||
height: element.outerHeight(true),
|
||||
'float': element.css('float')
|
||||
},
|
||||
wrapper = $('<div></div>')
|
||||
.addClass('ui-effects-wrapper')
|
||||
.css({
|
||||
fontSize: '100%',
|
||||
background: 'transparent',
|
||||
border: 'none',
|
||||
margin: 0,
|
||||
padding: 0
|
||||
});
|
||||
|
||||
element.wrap(wrapper);
|
||||
wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually loose the reference to the wrapped element
|
||||
|
||||
// transfer positioning properties to the wrapper
|
||||
if (element.css('position') == 'static') {
|
||||
wrapper.css({ position: 'relative' });
|
||||
element.css({ position: 'relative' });
|
||||
} else {
|
||||
$.extend(props, {
|
||||
position: element.css('position'),
|
||||
zIndex: element.css('z-index')
|
||||
});
|
||||
$.each(['top', 'left', 'bottom', 'right'], function(i, pos) {
|
||||
props[pos] = element.css(pos);
|
||||
if (isNaN(parseInt(props[pos], 10))) {
|
||||
props[pos] = 'auto';
|
||||
}
|
||||
});
|
||||
element.css({position: 'relative', top: 0, left: 0 });
|
||||
}
|
||||
|
||||
return wrapper.css(props).show();
|
||||
},
|
||||
|
||||
removeWrapper: function(element) {
|
||||
if (element.parent().is('.ui-effects-wrapper'))
|
||||
return element.parent().replaceWith(element);
|
||||
return element;
|
||||
},
|
||||
|
||||
setTransition: function(element, list, factor, value) {
|
||||
value = value || {};
|
||||
$.each(list, function(i, x){
|
||||
unit = element.cssUnit(x);
|
||||
if (unit[0] > 0) value[x] = unit[0] * factor + unit[1];
|
||||
});
|
||||
return value;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
function _normalizeArguments(effect, options, speed, callback) {
|
||||
// shift params for method overloading
|
||||
if (typeof effect == 'object') {
|
||||
callback = options;
|
||||
speed = null;
|
||||
options = effect;
|
||||
effect = options.effect;
|
||||
}
|
||||
if ($.isFunction(options)) {
|
||||
callback = options;
|
||||
speed = null;
|
||||
options = {};
|
||||
}
|
||||
if ($.isFunction(speed)) {
|
||||
callback = speed;
|
||||
speed = null;
|
||||
}
|
||||
if (typeof options == 'number' || $.fx.speeds[options]) {
|
||||
callback = speed;
|
||||
speed = options;
|
||||
options = {};
|
||||
}
|
||||
|
||||
options = options || {};
|
||||
|
||||
speed = speed || options.duration;
|
||||
speed = $.fx.off ? 0 : typeof speed == 'number'
|
||||
? speed : $.fx.speeds[speed] || $.fx.speeds._default;
|
||||
|
||||
callback = callback || options.complete;
|
||||
|
||||
return [effect, options, speed, callback];
|
||||
}
|
||||
|
||||
$.fn.extend({
|
||||
effect: function(effect, options, speed, callback) {
|
||||
var args = _normalizeArguments.apply(this, arguments),
|
||||
// TODO: make effects takes actual parameters instead of a hash
|
||||
args2 = {
|
||||
options: args[1],
|
||||
duration: args[2],
|
||||
callback: args[3]
|
||||
},
|
||||
effectMethod = $.effects[effect];
|
||||
|
||||
return effectMethod && !$.fx.off ? effectMethod.call(this, args2) : this;
|
||||
},
|
||||
|
||||
_show: $.fn.show,
|
||||
show: function(speed) {
|
||||
if (!speed || typeof speed == 'number' || $.fx.speeds[speed]) {
|
||||
return this._show.apply(this, arguments);
|
||||
} else {
|
||||
var args = _normalizeArguments.apply(this, arguments);
|
||||
args[1].mode = 'show';
|
||||
return this.effect.apply(this, args);
|
||||
}
|
||||
},
|
||||
|
||||
_hide: $.fn.hide,
|
||||
hide: function(speed) {
|
||||
if (!speed || typeof speed == 'number' || $.fx.speeds[speed]) {
|
||||
return this._hide.apply(this, arguments);
|
||||
} else {
|
||||
var args = _normalizeArguments.apply(this, arguments);
|
||||
args[1].mode = 'hide';
|
||||
return this.effect.apply(this, args);
|
||||
}
|
||||
},
|
||||
|
||||
// jQuery core overloads toggle and create _toggle
|
||||
__toggle: $.fn.toggle,
|
||||
toggle: function(speed) {
|
||||
if (!speed || typeof speed == 'number' || $.fx.speeds[speed] ||
|
||||
typeof speed == 'boolean' || $.isFunction(speed)) {
|
||||
return this.__toggle.apply(this, arguments);
|
||||
} else {
|
||||
var args = _normalizeArguments.apply(this, arguments);
|
||||
args[1].mode = 'toggle';
|
||||
return this.effect.apply(this, args);
|
||||
}
|
||||
},
|
||||
|
||||
// helper functions
|
||||
cssUnit: function(key) {
|
||||
var style = this.css(key), val = [];
|
||||
$.each( ['em','px','%','pt'], function(i, unit){
|
||||
if(style.indexOf(unit) > 0)
|
||||
val = [parseFloat(style), unit];
|
||||
});
|
||||
return val;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/*********************************** EASING ***********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/*
|
||||
* jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
|
||||
*
|
||||
* Uses the built in easing capabilities added In jQuery 1.1
|
||||
* to offer multiple easing options
|
||||
*
|
||||
* TERMS OF USE - jQuery Easing
|
||||
*
|
||||
* Open source under the BSD License.
|
||||
*
|
||||
* Copyright 2008 George McGinley Smith
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the author nor the names of contributors may be used to endorse
|
||||
* or promote products derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
// t: current time, b: begInnIng value, c: change In value, d: duration
|
||||
$.easing.jswing = $.easing.swing;
|
||||
|
||||
$.extend($.easing,
|
||||
{
|
||||
def: 'easeOutQuad',
|
||||
swing: function (x, t, b, c, d) {
|
||||
//alert($.easing.default);
|
||||
return $.easing[$.easing.def](x, t, b, c, d);
|
||||
},
|
||||
easeInQuad: function (x, t, b, c, d) {
|
||||
return c*(t/=d)*t + b;
|
||||
},
|
||||
easeOutQuad: function (x, t, b, c, d) {
|
||||
return -c *(t/=d)*(t-2) + b;
|
||||
},
|
||||
easeInOutQuad: function (x, t, b, c, d) {
|
||||
if ((t/=d/2) < 1) return c/2*t*t + b;
|
||||
return -c/2 * ((--t)*(t-2) - 1) + b;
|
||||
},
|
||||
easeInCubic: function (x, t, b, c, d) {
|
||||
return c*(t/=d)*t*t + b;
|
||||
},
|
||||
easeOutCubic: function (x, t, b, c, d) {
|
||||
return c*((t=t/d-1)*t*t + 1) + b;
|
||||
},
|
||||
easeInOutCubic: function (x, t, b, c, d) {
|
||||
if ((t/=d/2) < 1) return c/2*t*t*t + b;
|
||||
return c/2*((t-=2)*t*t + 2) + b;
|
||||
},
|
||||
easeInQuart: function (x, t, b, c, d) {
|
||||
return c*(t/=d)*t*t*t + b;
|
||||
},
|
||||
easeOutQuart: function (x, t, b, c, d) {
|
||||
return -c * ((t=t/d-1)*t*t*t - 1) + b;
|
||||
},
|
||||
easeInOutQuart: function (x, t, b, c, d) {
|
||||
if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
|
||||
return -c/2 * ((t-=2)*t*t*t - 2) + b;
|
||||
},
|
||||
easeInQuint: function (x, t, b, c, d) {
|
||||
return c*(t/=d)*t*t*t*t + b;
|
||||
},
|
||||
easeOutQuint: function (x, t, b, c, d) {
|
||||
return c*((t=t/d-1)*t*t*t*t + 1) + b;
|
||||
},
|
||||
easeInOutQuint: function (x, t, b, c, d) {
|
||||
if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
|
||||
return c/2*((t-=2)*t*t*t*t + 2) + b;
|
||||
},
|
||||
easeInSine: function (x, t, b, c, d) {
|
||||
return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
|
||||
},
|
||||
easeOutSine: function (x, t, b, c, d) {
|
||||
return c * Math.sin(t/d * (Math.PI/2)) + b;
|
||||
},
|
||||
easeInOutSine: function (x, t, b, c, d) {
|
||||
return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
|
||||
},
|
||||
easeInExpo: function (x, t, b, c, d) {
|
||||
return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
|
||||
},
|
||||
easeOutExpo: function (x, t, b, c, d) {
|
||||
return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
|
||||
},
|
||||
easeInOutExpo: function (x, t, b, c, d) {
|
||||
if (t==0) return b;
|
||||
if (t==d) return b+c;
|
||||
if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
|
||||
return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
|
||||
},
|
||||
easeInCirc: function (x, t, b, c, d) {
|
||||
return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
|
||||
},
|
||||
easeOutCirc: function (x, t, b, c, d) {
|
||||
return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
|
||||
},
|
||||
easeInOutCirc: function (x, t, b, c, d) {
|
||||
if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
|
||||
return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
|
||||
},
|
||||
easeInElastic: function (x, t, b, c, d) {
|
||||
var s=1.70158;var p=0;var a=c;
|
||||
if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
|
||||
if (a < Math.abs(c)) { a=c; var s=p/4; }
|
||||
else var s = p/(2*Math.PI) * Math.asin (c/a);
|
||||
return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
|
||||
},
|
||||
easeOutElastic: function (x, t, b, c, d) {
|
||||
var s=1.70158;var p=0;var a=c;
|
||||
if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
|
||||
if (a < Math.abs(c)) { a=c; var s=p/4; }
|
||||
else var s = p/(2*Math.PI) * Math.asin (c/a);
|
||||
return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
|
||||
},
|
||||
easeInOutElastic: function (x, t, b, c, d) {
|
||||
var s=1.70158;var p=0;var a=c;
|
||||
if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5);
|
||||
if (a < Math.abs(c)) { a=c; var s=p/4; }
|
||||
else var s = p/(2*Math.PI) * Math.asin (c/a);
|
||||
if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
|
||||
return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
|
||||
},
|
||||
easeInBack: function (x, t, b, c, d, s) {
|
||||
if (s == undefined) s = 1.70158;
|
||||
return c*(t/=d)*t*((s+1)*t - s) + b;
|
||||
},
|
||||
easeOutBack: function (x, t, b, c, d, s) {
|
||||
if (s == undefined) s = 1.70158;
|
||||
return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
|
||||
},
|
||||
easeInOutBack: function (x, t, b, c, d, s) {
|
||||
if (s == undefined) s = 1.70158;
|
||||
if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
|
||||
return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
|
||||
},
|
||||
easeInBounce: function (x, t, b, c, d) {
|
||||
return c - $.easing.easeOutBounce (x, d-t, 0, c, d) + b;
|
||||
},
|
||||
easeOutBounce: function (x, t, b, c, d) {
|
||||
if ((t/=d) < (1/2.75)) {
|
||||
return c*(7.5625*t*t) + b;
|
||||
} else if (t < (2/2.75)) {
|
||||
return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
|
||||
} else if (t < (2.5/2.75)) {
|
||||
return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
|
||||
} else {
|
||||
return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
|
||||
}
|
||||
},
|
||||
easeInOutBounce: function (x, t, b, c, d) {
|
||||
if (t < d/2) return $.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
|
||||
return $.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
*
|
||||
* TERMS OF USE - EASING EQUATIONS
|
||||
*
|
||||
* Open source under the BSD License.
|
||||
*
|
||||
* Copyright 2001 Robert Penner
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the author nor the names of contributors may be used to endorse
|
||||
* or promote products derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
})(jQuery);
|
||||
50
resources/jquery.effects/jquery.effects.drop.js
vendored
Normal file
50
resources/jquery.effects/jquery.effects.drop.js
vendored
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* jQuery UI Effects Drop 1.8.2
|
||||
*
|
||||
* Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT (MIT-LICENSE.txt)
|
||||
* and GPL (GPL-LICENSE.txt) licenses.
|
||||
*
|
||||
* http://docs.jquery.com/UI/Effects/Drop
|
||||
*
|
||||
* Depends:
|
||||
* jquery.effects.core.js
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
$.effects.drop = function(o) {
|
||||
|
||||
return this.queue(function() {
|
||||
|
||||
// Create element
|
||||
var el = $(this), props = ['position','top','left','opacity'];
|
||||
|
||||
// Set options
|
||||
var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
|
||||
var direction = o.options.direction || 'left'; // Default Direction
|
||||
|
||||
// Adjust
|
||||
$.effects.save(el, props); el.show(); // Save & Show
|
||||
$.effects.createWrapper(el); // Create Wrapper
|
||||
var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
|
||||
var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
|
||||
var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) / 2 : el.outerWidth({margin:true}) / 2);
|
||||
if (mode == 'show') el.css('opacity', 0).css(ref, motion == 'pos' ? -distance : distance); // Shift
|
||||
|
||||
// Animation
|
||||
var animation = {opacity: mode == 'show' ? 1 : 0};
|
||||
animation[ref] = (mode == 'show' ? (motion == 'pos' ? '+=' : '-=') : (motion == 'pos' ? '-=' : '+=')) + distance;
|
||||
|
||||
// Animate
|
||||
el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
|
||||
if(mode == 'hide') el.hide(); // Hide
|
||||
$.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
|
||||
if(o.callback) o.callback.apply(this, arguments); // Callback
|
||||
el.dequeue();
|
||||
}});
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
79
resources/jquery.effects/jquery.effects.explode.js
vendored
Normal file
79
resources/jquery.effects/jquery.effects.explode.js
vendored
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* jQuery UI Effects Explode 1.8.2
|
||||
*
|
||||
* Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT (MIT-LICENSE.txt)
|
||||
* and GPL (GPL-LICENSE.txt) licenses.
|
||||
*
|
||||
* http://docs.jquery.com/UI/Effects/Explode
|
||||
*
|
||||
* Depends:
|
||||
* jquery.effects.core.js
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
$.effects.explode = function(o) {
|
||||
|
||||
return this.queue(function() {
|
||||
|
||||
var rows = o.options.pieces ? Math.round(Math.sqrt(o.options.pieces)) : 3;
|
||||
var cells = o.options.pieces ? Math.round(Math.sqrt(o.options.pieces)) : 3;
|
||||
|
||||
o.options.mode = o.options.mode == 'toggle' ? ($(this).is(':visible') ? 'hide' : 'show') : o.options.mode;
|
||||
var el = $(this).show().css('visibility', 'hidden');
|
||||
var offset = el.offset();
|
||||
|
||||
//Substract the margins - not fixing the problem yet.
|
||||
offset.top -= parseInt(el.css("marginTop"),10) || 0;
|
||||
offset.left -= parseInt(el.css("marginLeft"),10) || 0;
|
||||
|
||||
var width = el.outerWidth(true);
|
||||
var height = el.outerHeight(true);
|
||||
|
||||
for(var i=0;i<rows;i++) { // =
|
||||
for(var j=0;j<cells;j++) { // ||
|
||||
el
|
||||
.clone()
|
||||
.appendTo('body')
|
||||
.wrap('<div></div>')
|
||||
.css({
|
||||
position: 'absolute',
|
||||
visibility: 'visible',
|
||||
left: -j*(width/cells),
|
||||
top: -i*(height/rows)
|
||||
})
|
||||
.parent()
|
||||
.addClass('ui-effects-explode')
|
||||
.css({
|
||||
position: 'absolute',
|
||||
overflow: 'hidden',
|
||||
width: width/cells,
|
||||
height: height/rows,
|
||||
left: offset.left + j*(width/cells) + (o.options.mode == 'show' ? (j-Math.floor(cells/2))*(width/cells) : 0),
|
||||
top: offset.top + i*(height/rows) + (o.options.mode == 'show' ? (i-Math.floor(rows/2))*(height/rows) : 0),
|
||||
opacity: o.options.mode == 'show' ? 0 : 1
|
||||
}).animate({
|
||||
left: offset.left + j*(width/cells) + (o.options.mode == 'show' ? 0 : (j-Math.floor(cells/2))*(width/cells)),
|
||||
top: offset.top + i*(height/rows) + (o.options.mode == 'show' ? 0 : (i-Math.floor(rows/2))*(height/rows)),
|
||||
opacity: o.options.mode == 'show' ? 1 : 0
|
||||
}, o.duration || 500);
|
||||
}
|
||||
}
|
||||
|
||||
// Set a timeout, to call the callback approx. when the other animations have finished
|
||||
setTimeout(function() {
|
||||
|
||||
o.options.mode == 'show' ? el.css({ visibility: 'visible' }) : el.css({ visibility: 'visible' }).hide();
|
||||
if(o.callback) o.callback.apply(el[0]); // Callback
|
||||
el.dequeue();
|
||||
|
||||
$('div.ui-effects-explode').remove();
|
||||
|
||||
}, o.duration || 500);
|
||||
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
56
resources/jquery.effects/jquery.effects.fold.js
vendored
Normal file
56
resources/jquery.effects/jquery.effects.fold.js
vendored
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* jQuery UI Effects Fold 1.8.2
|
||||
*
|
||||
* Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT (MIT-LICENSE.txt)
|
||||
* and GPL (GPL-LICENSE.txt) licenses.
|
||||
*
|
||||
* http://docs.jquery.com/UI/Effects/Fold
|
||||
*
|
||||
* Depends:
|
||||
* jquery.effects.core.js
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
$.effects.fold = function(o) {
|
||||
|
||||
return this.queue(function() {
|
||||
|
||||
// Create element
|
||||
var el = $(this), props = ['position','top','left'];
|
||||
|
||||
// Set options
|
||||
var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
|
||||
var size = o.options.size || 15; // Default fold size
|
||||
var horizFirst = !(!o.options.horizFirst); // Ensure a boolean value
|
||||
var duration = o.duration ? o.duration / 2 : $.fx.speeds._default / 2;
|
||||
|
||||
// Adjust
|
||||
$.effects.save(el, props); el.show(); // Save & Show
|
||||
var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
|
||||
var widthFirst = ((mode == 'show') != horizFirst);
|
||||
var ref = widthFirst ? ['width', 'height'] : ['height', 'width'];
|
||||
var distance = widthFirst ? [wrapper.width(), wrapper.height()] : [wrapper.height(), wrapper.width()];
|
||||
var percent = /([0-9]+)%/.exec(size);
|
||||
if(percent) size = parseInt(percent[1],10) / 100 * distance[mode == 'hide' ? 0 : 1];
|
||||
if(mode == 'show') wrapper.css(horizFirst ? {height: 0, width: size} : {height: size, width: 0}); // Shift
|
||||
|
||||
// Animation
|
||||
var animation1 = {}, animation2 = {};
|
||||
animation1[ref[0]] = mode == 'show' ? distance[0] : size;
|
||||
animation2[ref[1]] = mode == 'show' ? distance[1] : 0;
|
||||
|
||||
// Animate
|
||||
wrapper.animate(animation1, duration, o.options.easing)
|
||||
.animate(animation2, duration, o.options.easing, function() {
|
||||
if(mode == 'hide') el.hide(); // Hide
|
||||
$.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
|
||||
if(o.callback) o.callback.apply(el[0], arguments); // Callback
|
||||
el.dequeue();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
50
resources/jquery.effects/jquery.effects.highlight.js
vendored
Normal file
50
resources/jquery.effects/jquery.effects.highlight.js
vendored
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* jQuery UI Effects Highlight 1.8.2
|
||||
*
|
||||
* Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT (MIT-LICENSE.txt)
|
||||
* and GPL (GPL-LICENSE.txt) licenses.
|
||||
*
|
||||
* http://docs.jquery.com/UI/Effects/Highlight
|
||||
*
|
||||
* Depends:
|
||||
* jquery.effects.core.js
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
$.effects.highlight = function(o) {
|
||||
return this.queue(function() {
|
||||
var elem = $(this),
|
||||
props = ['backgroundImage', 'backgroundColor', 'opacity'],
|
||||
mode = $.effects.setMode(elem, o.options.mode || 'show'),
|
||||
animation = {
|
||||
backgroundColor: elem.css('backgroundColor')
|
||||
};
|
||||
|
||||
if (mode == 'hide') {
|
||||
animation.opacity = 0;
|
||||
}
|
||||
|
||||
$.effects.save(elem, props);
|
||||
elem
|
||||
.show()
|
||||
.css({
|
||||
backgroundImage: 'none',
|
||||
backgroundColor: o.options.color || '#ffff99'
|
||||
})
|
||||
.animate(animation, {
|
||||
queue: false,
|
||||
duration: o.duration,
|
||||
easing: o.options.easing,
|
||||
complete: function() {
|
||||
(mode == 'hide' && elem.hide());
|
||||
$.effects.restore(elem, props);
|
||||
(mode == 'show' && !$.support.opacity && this.style.removeAttribute('filter'));
|
||||
(o.callback && o.callback.apply(this, arguments));
|
||||
elem.dequeue();
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
51
resources/jquery.effects/jquery.effects.pulsate.js
vendored
Normal file
51
resources/jquery.effects/jquery.effects.pulsate.js
vendored
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* jQuery UI Effects Pulsate 1.8.2
|
||||
*
|
||||
* Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT (MIT-LICENSE.txt)
|
||||
* and GPL (GPL-LICENSE.txt) licenses.
|
||||
*
|
||||
* http://docs.jquery.com/UI/Effects/Pulsate
|
||||
*
|
||||
* Depends:
|
||||
* jquery.effects.core.js
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
$.effects.pulsate = function(o) {
|
||||
return this.queue(function() {
|
||||
var elem = $(this),
|
||||
mode = $.effects.setMode(elem, o.options.mode || 'show');
|
||||
times = ((o.options.times || 5) * 2) - 1;
|
||||
duration = o.duration ? o.duration / 2 : $.fx.speeds._default / 2,
|
||||
isVisible = elem.is(':visible'),
|
||||
animateTo = 0;
|
||||
|
||||
if (!isVisible) {
|
||||
elem.css('opacity', 0).show();
|
||||
animateTo = 1;
|
||||
}
|
||||
|
||||
if ((mode == 'hide' && isVisible) || (mode == 'show' && !isVisible)) {
|
||||
times--;
|
||||
}
|
||||
|
||||
for (var i = 0; i < times; i++) {
|
||||
elem.animate({ opacity: animateTo }, duration, o.options.easing);
|
||||
animateTo = (animateTo + 1) % 2;
|
||||
}
|
||||
|
||||
elem.animate({ opacity: animateTo }, duration, o.options.easing, function() {
|
||||
if (animateTo == 0) {
|
||||
elem.hide();
|
||||
}
|
||||
(o.callback && o.callback.apply(this, arguments));
|
||||
});
|
||||
|
||||
elem
|
||||
.queue('fx', function() { elem.dequeue(); })
|
||||
.dequeue();
|
||||
});
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
178
resources/jquery.effects/jquery.effects.scale.js
vendored
Normal file
178
resources/jquery.effects/jquery.effects.scale.js
vendored
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
/*
|
||||
* jQuery UI Effects Scale 1.8.2
|
||||
*
|
||||
* Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT (MIT-LICENSE.txt)
|
||||
* and GPL (GPL-LICENSE.txt) licenses.
|
||||
*
|
||||
* http://docs.jquery.com/UI/Effects/Scale
|
||||
*
|
||||
* Depends:
|
||||
* jquery.effects.core.js
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
$.effects.puff = function(o) {
|
||||
return this.queue(function() {
|
||||
var elem = $(this),
|
||||
mode = $.effects.setMode(elem, o.options.mode || 'hide'),
|
||||
percent = parseInt(o.options.percent, 10) || 150,
|
||||
factor = percent / 100,
|
||||
original = { height: elem.height(), width: elem.width() };
|
||||
|
||||
$.extend(o.options, {
|
||||
fade: true,
|
||||
mode: mode,
|
||||
percent: mode == 'hide' ? percent : 100,
|
||||
from: mode == 'hide'
|
||||
? original
|
||||
: {
|
||||
height: original.height * factor,
|
||||
width: original.width * factor
|
||||
}
|
||||
});
|
||||
|
||||
elem.effect('scale', o.options, o.duration, o.callback);
|
||||
elem.dequeue();
|
||||
});
|
||||
};
|
||||
|
||||
$.effects.scale = function(o) {
|
||||
|
||||
return this.queue(function() {
|
||||
|
||||
// Create element
|
||||
var el = $(this);
|
||||
|
||||
// Set options
|
||||
var options = $.extend(true, {}, o.options);
|
||||
var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
|
||||
var percent = parseInt(o.options.percent,10) || (parseInt(o.options.percent,10) == 0 ? 0 : (mode == 'hide' ? 0 : 100)); // Set default scaling percent
|
||||
var direction = o.options.direction || 'both'; // Set default axis
|
||||
var origin = o.options.origin; // The origin of the scaling
|
||||
if (mode != 'effect') { // Set default origin and restore for show/hide
|
||||
options.origin = origin || ['middle','center'];
|
||||
options.restore = true;
|
||||
}
|
||||
var original = {height: el.height(), width: el.width()}; // Save original
|
||||
el.from = o.options.from || (mode == 'show' ? {height: 0, width: 0} : original); // Default from state
|
||||
|
||||
// Adjust
|
||||
var factor = { // Set scaling factor
|
||||
y: direction != 'horizontal' ? (percent / 100) : 1,
|
||||
x: direction != 'vertical' ? (percent / 100) : 1
|
||||
};
|
||||
el.to = {height: original.height * factor.y, width: original.width * factor.x}; // Set to state
|
||||
|
||||
if (o.options.fade) { // Fade option to support puff
|
||||
if (mode == 'show') {el.from.opacity = 0; el.to.opacity = 1;};
|
||||
if (mode == 'hide') {el.from.opacity = 1; el.to.opacity = 0;};
|
||||
};
|
||||
|
||||
// Animation
|
||||
options.from = el.from; options.to = el.to; options.mode = mode;
|
||||
|
||||
// Animate
|
||||
el.effect('size', options, o.duration, o.callback);
|
||||
el.dequeue();
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
$.effects.size = function(o) {
|
||||
|
||||
return this.queue(function() {
|
||||
|
||||
// Create element
|
||||
var el = $(this), props = ['position','top','left','width','height','overflow','opacity'];
|
||||
var props1 = ['position','top','left','overflow','opacity']; // Always restore
|
||||
var props2 = ['width','height','overflow']; // Copy for children
|
||||
var cProps = ['fontSize'];
|
||||
var vProps = ['borderTopWidth', 'borderBottomWidth', 'paddingTop', 'paddingBottom'];
|
||||
var hProps = ['borderLeftWidth', 'borderRightWidth', 'paddingLeft', 'paddingRight'];
|
||||
|
||||
// Set options
|
||||
var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
|
||||
var restore = o.options.restore || false; // Default restore
|
||||
var scale = o.options.scale || 'both'; // Default scale mode
|
||||
var origin = o.options.origin; // The origin of the sizing
|
||||
var original = {height: el.height(), width: el.width()}; // Save original
|
||||
el.from = o.options.from || original; // Default from state
|
||||
el.to = o.options.to || original; // Default to state
|
||||
// Adjust
|
||||
if (origin) { // Calculate baseline shifts
|
||||
var baseline = $.effects.getBaseline(origin, original);
|
||||
el.from.top = (original.height - el.from.height) * baseline.y;
|
||||
el.from.left = (original.width - el.from.width) * baseline.x;
|
||||
el.to.top = (original.height - el.to.height) * baseline.y;
|
||||
el.to.left = (original.width - el.to.width) * baseline.x;
|
||||
};
|
||||
var factor = { // Set scaling factor
|
||||
from: {y: el.from.height / original.height, x: el.from.width / original.width},
|
||||
to: {y: el.to.height / original.height, x: el.to.width / original.width}
|
||||
};
|
||||
if (scale == 'box' || scale == 'both') { // Scale the css box
|
||||
if (factor.from.y != factor.to.y) { // Vertical props scaling
|
||||
props = props.concat(vProps);
|
||||
el.from = $.effects.setTransition(el, vProps, factor.from.y, el.from);
|
||||
el.to = $.effects.setTransition(el, vProps, factor.to.y, el.to);
|
||||
};
|
||||
if (factor.from.x != factor.to.x) { // Horizontal props scaling
|
||||
props = props.concat(hProps);
|
||||
el.from = $.effects.setTransition(el, hProps, factor.from.x, el.from);
|
||||
el.to = $.effects.setTransition(el, hProps, factor.to.x, el.to);
|
||||
};
|
||||
};
|
||||
if (scale == 'content' || scale == 'both') { // Scale the content
|
||||
if (factor.from.y != factor.to.y) { // Vertical props scaling
|
||||
props = props.concat(cProps);
|
||||
el.from = $.effects.setTransition(el, cProps, factor.from.y, el.from);
|
||||
el.to = $.effects.setTransition(el, cProps, factor.to.y, el.to);
|
||||
};
|
||||
};
|
||||
$.effects.save(el, restore ? props : props1); el.show(); // Save & Show
|
||||
$.effects.createWrapper(el); // Create Wrapper
|
||||
el.css('overflow','hidden').css(el.from); // Shift
|
||||
|
||||
// Animate
|
||||
if (scale == 'content' || scale == 'both') { // Scale the children
|
||||
vProps = vProps.concat(['marginTop','marginBottom']).concat(cProps); // Add margins/font-size
|
||||
hProps = hProps.concat(['marginLeft','marginRight']); // Add margins
|
||||
props2 = props.concat(vProps).concat(hProps); // Concat
|
||||
el.find("*[width]").each(function(){
|
||||
child = $(this);
|
||||
if (restore) $.effects.save(child, props2);
|
||||
var c_original = {height: child.height(), width: child.width()}; // Save original
|
||||
child.from = {height: c_original.height * factor.from.y, width: c_original.width * factor.from.x};
|
||||
child.to = {height: c_original.height * factor.to.y, width: c_original.width * factor.to.x};
|
||||
if (factor.from.y != factor.to.y) { // Vertical props scaling
|
||||
child.from = $.effects.setTransition(child, vProps, factor.from.y, child.from);
|
||||
child.to = $.effects.setTransition(child, vProps, factor.to.y, child.to);
|
||||
};
|
||||
if (factor.from.x != factor.to.x) { // Horizontal props scaling
|
||||
child.from = $.effects.setTransition(child, hProps, factor.from.x, child.from);
|
||||
child.to = $.effects.setTransition(child, hProps, factor.to.x, child.to);
|
||||
};
|
||||
child.css(child.from); // Shift children
|
||||
child.animate(child.to, o.duration, o.options.easing, function(){
|
||||
if (restore) $.effects.restore(child, props2); // Restore children
|
||||
}); // Animate children
|
||||
});
|
||||
};
|
||||
|
||||
// Animate
|
||||
el.animate(el.to, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
|
||||
if (el.to.opacity === 0) {
|
||||
el.css('opacity', el.from.opacity);
|
||||
}
|
||||
if(mode == 'hide') el.hide(); // Hide
|
||||
$.effects.restore(el, restore ? props : props1); $.effects.removeWrapper(el); // Restore
|
||||
if(o.callback) o.callback.apply(this, arguments); // Callback
|
||||
el.dequeue();
|
||||
}});
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
57
resources/jquery.effects/jquery.effects.shake.js
vendored
Normal file
57
resources/jquery.effects/jquery.effects.shake.js
vendored
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* jQuery UI Effects Shake 1.8.2
|
||||
*
|
||||
* Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT (MIT-LICENSE.txt)
|
||||
* and GPL (GPL-LICENSE.txt) licenses.
|
||||
*
|
||||
* http://docs.jquery.com/UI/Effects/Shake
|
||||
*
|
||||
* Depends:
|
||||
* jquery.effects.core.js
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
$.effects.shake = function(o) {
|
||||
|
||||
return this.queue(function() {
|
||||
|
||||
// Create element
|
||||
var el = $(this), props = ['position','top','left'];
|
||||
|
||||
// Set options
|
||||
var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
|
||||
var direction = o.options.direction || 'left'; // Default direction
|
||||
var distance = o.options.distance || 20; // Default distance
|
||||
var times = o.options.times || 3; // Default # of times
|
||||
var speed = o.duration || o.options.duration || 140; // Default speed per shake
|
||||
|
||||
// Adjust
|
||||
$.effects.save(el, props); el.show(); // Save & Show
|
||||
$.effects.createWrapper(el); // Create Wrapper
|
||||
var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
|
||||
var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
|
||||
|
||||
// Animation
|
||||
var animation = {}, animation1 = {}, animation2 = {};
|
||||
animation[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
|
||||
animation1[ref] = (motion == 'pos' ? '+=' : '-=') + distance * 2;
|
||||
animation2[ref] = (motion == 'pos' ? '-=' : '+=') + distance * 2;
|
||||
|
||||
// Animate
|
||||
el.animate(animation, speed, o.options.easing);
|
||||
for (var i = 1; i < times; i++) { // Shakes
|
||||
el.animate(animation1, speed, o.options.easing).animate(animation2, speed, o.options.easing);
|
||||
};
|
||||
el.animate(animation1, speed, o.options.easing).
|
||||
animate(animation, speed / 2, o.options.easing, function(){ // Last shake
|
||||
$.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
|
||||
if(o.callback) o.callback.apply(this, arguments); // Callback
|
||||
});
|
||||
el.queue('fx', function() { el.dequeue(); });
|
||||
el.dequeue();
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
50
resources/jquery.effects/jquery.effects.slide.js
vendored
Normal file
50
resources/jquery.effects/jquery.effects.slide.js
vendored
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* jQuery UI Effects Slide 1.8.2
|
||||
*
|
||||
* Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT (MIT-LICENSE.txt)
|
||||
* and GPL (GPL-LICENSE.txt) licenses.
|
||||
*
|
||||
* http://docs.jquery.com/UI/Effects/Slide
|
||||
*
|
||||
* Depends:
|
||||
* jquery.effects.core.js
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
$.effects.slide = function(o) {
|
||||
|
||||
return this.queue(function() {
|
||||
|
||||
// Create element
|
||||
var el = $(this), props = ['position','top','left'];
|
||||
|
||||
// Set options
|
||||
var mode = $.effects.setMode(el, o.options.mode || 'show'); // Set Mode
|
||||
var direction = o.options.direction || 'left'; // Default Direction
|
||||
|
||||
// Adjust
|
||||
$.effects.save(el, props); el.show(); // Save & Show
|
||||
$.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
|
||||
var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
|
||||
var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
|
||||
var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) : el.outerWidth({margin:true}));
|
||||
if (mode == 'show') el.css(ref, motion == 'pos' ? -distance : distance); // Shift
|
||||
|
||||
// Animation
|
||||
var animation = {};
|
||||
animation[ref] = (mode == 'show' ? (motion == 'pos' ? '+=' : '-=') : (motion == 'pos' ? '-=' : '+=')) + distance;
|
||||
|
||||
// Animate
|
||||
el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
|
||||
if(mode == 'hide') el.hide(); // Hide
|
||||
$.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
|
||||
if(o.callback) o.callback.apply(this, arguments); // Callback
|
||||
el.dequeue();
|
||||
}});
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
45
resources/jquery.effects/jquery.effects.transfer.js
vendored
Normal file
45
resources/jquery.effects/jquery.effects.transfer.js
vendored
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* jQuery UI Effects Transfer 1.8.2
|
||||
*
|
||||
* Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT (MIT-LICENSE.txt)
|
||||
* and GPL (GPL-LICENSE.txt) licenses.
|
||||
*
|
||||
* http://docs.jquery.com/UI/Effects/Transfer
|
||||
*
|
||||
* Depends:
|
||||
* jquery.effects.core.js
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
$.effects.transfer = function(o) {
|
||||
return this.queue(function() {
|
||||
var elem = $(this),
|
||||
target = $(o.options.to),
|
||||
endPosition = target.offset(),
|
||||
animation = {
|
||||
top: endPosition.top,
|
||||
left: endPosition.left,
|
||||
height: target.innerHeight(),
|
||||
width: target.innerWidth()
|
||||
},
|
||||
startPosition = elem.offset(),
|
||||
transfer = $('<div class="ui-effects-transfer"></div>')
|
||||
.appendTo(document.body)
|
||||
.addClass(o.options.className)
|
||||
.css({
|
||||
top: startPosition.top,
|
||||
left: startPosition.left,
|
||||
height: elem.innerHeight(),
|
||||
width: elem.innerWidth(),
|
||||
position: 'absolute'
|
||||
})
|
||||
.animate(animation, o.duration, o.options.easing, function() {
|
||||
transfer.remove();
|
||||
(o.callback && o.callback.apply(elem[0], arguments));
|
||||
elem.dequeue();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
23
resources/jquery.ui/i18n/jquery.ui.datepicker-af.js
vendored
Normal file
23
resources/jquery.ui/i18n/jquery.ui.datepicker-af.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* Afrikaans initialisation for the jQuery UI date picker plugin. */
|
||||
/* Written by Renier Pretorius. */
|
||||
jQuery(function($){
|
||||
$.datepicker.regional['af'] = {
|
||||
closeText: 'Selekteer',
|
||||
prevText: 'Vorige',
|
||||
nextText: 'Volgende',
|
||||
currentText: 'Vandag',
|
||||
monthNames: ['Januarie','Februarie','Maart','April','Mei','Junie',
|
||||
'Julie','Augustus','September','Oktober','November','Desember'],
|
||||
monthNamesShort: ['Jan', 'Feb', 'Mrt', 'Apr', 'Mei', 'Jun',
|
||||
'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Des'],
|
||||
dayNames: ['Sondag', 'Maandag', 'Dinsdag', 'Woensdag', 'Donderdag', 'Vrydag', 'Saterdag'],
|
||||
dayNamesShort: ['Son', 'Maa', 'Din', 'Woe', 'Don', 'Vry', 'Sat'],
|
||||
dayNamesMin: ['So','Ma','Di','Wo','Do','Vr','Sa'],
|
||||
weekHeader: 'Wk',
|
||||
dateFormat: 'dd/mm/yy',
|
||||
firstDay: 1,
|
||||
isRTL: false,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional['af']);
|
||||
});
|
||||
24
resources/jquery.ui/i18n/jquery.ui.datepicker-ar.js
vendored
Normal file
24
resources/jquery.ui/i18n/jquery.ui.datepicker-ar.js
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/* Arabic Translation for jQuery UI date picker plugin. */
|
||||
/* Khaled Al Horani -- koko.dw@gmail.com */
|
||||
/* خالد الحوراني -- koko.dw@gmail.com */
|
||||
/* NOTE: monthNames are the original months names and they are the Arabic names, not the new months name فبراير - يناير and there isn't any Arabic roots for these months */
|
||||
jQuery(function($){
|
||||
$.datepicker.regional['ar'] = {
|
||||
closeText: 'إغلاق',
|
||||
prevText: '<السابق',
|
||||
nextText: 'التالي>',
|
||||
currentText: 'اليوم',
|
||||
monthNames: ['كانون الثاني', 'شباط', 'آذار', 'نيسان', 'آذار', 'حزيران',
|
||||
'تموز', 'آب', 'أيلول', 'تشرين الأول', 'تشرين الثاني', 'كانون الأول'],
|
||||
monthNamesShort: ['1','2','3','4','5','6','7','8','9','10','11','12'],
|
||||
dayNames: ['السبت', 'الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة'],
|
||||
dayNamesShort: ['سبت', 'أحد', 'اثنين', 'ثلاثاء', 'أربعاء', 'خميس', 'جمعة'],
|
||||
dayNamesMin: ['سبت', 'أحد', 'اثنين', 'ثلاثاء', 'أربعاء', 'خميس', 'جمعة'],
|
||||
weekHeader: 'أسبوع',
|
||||
dateFormat: 'dd/mm/yy',
|
||||
firstDay: 0,
|
||||
isRTL: true,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional['ar']);
|
||||
});
|
||||
23
resources/jquery.ui/i18n/jquery.ui.datepicker-az.js
vendored
Normal file
23
resources/jquery.ui/i18n/jquery.ui.datepicker-az.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* Azerbaijani (UTF-8) initialisation for the jQuery UI date picker plugin. */
|
||||
/* Written by Jamil Najafov (necefov33@gmail.com). */
|
||||
jQuery(function($) {
|
||||
$.datepicker.regional['az'] = {
|
||||
closeText: 'Bağla',
|
||||
prevText: '<Geri',
|
||||
nextText: 'İrəli>',
|
||||
currentText: 'Bugün',
|
||||
monthNames: ['Yanvar','Fevral','Mart','Aprel','May','İyun',
|
||||
'İyul','Avqust','Sentyabr','Oktyabr','Noyabr','Dekabr'],
|
||||
monthNamesShort: ['Yan','Fev','Mar','Apr','May','İyun',
|
||||
'İyul','Avq','Sen','Okt','Noy','Dek'],
|
||||
dayNames: ['Bazar','Bazar ertəsi','Çərşənbə axşamı','Çərşənbə','Cümə axşamı','Cümə','Şənbə'],
|
||||
dayNamesShort: ['B','Be','Ça','Ç','Ca','C','Ş'],
|
||||
dayNamesMin: ['B','B','Ç','С','Ç','C','Ş'],
|
||||
weekHeader: 'Hf',
|
||||
dateFormat: 'dd.mm.yy',
|
||||
firstDay: 1,
|
||||
isRTL: false,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional['az']);
|
||||
});
|
||||
24
resources/jquery.ui/i18n/jquery.ui.datepicker-bg.js
vendored
Normal file
24
resources/jquery.ui/i18n/jquery.ui.datepicker-bg.js
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/* Bulgarian initialisation for the jQuery UI date picker plugin. */
|
||||
/* Written by Stoyan Kyosev (http://svest.org). */
|
||||
jQuery(function($){
|
||||
$.datepicker.regional['bg'] = {
|
||||
closeText: 'затвори',
|
||||
prevText: '<назад',
|
||||
nextText: 'напред>',
|
||||
nextBigText: '>>',
|
||||
currentText: 'днес',
|
||||
monthNames: ['Януари','Февруари','Март','Април','Май','Юни',
|
||||
'Юли','Август','Септември','Октомври','Ноември','Декември'],
|
||||
monthNamesShort: ['Яну','Фев','Мар','Апр','Май','Юни',
|
||||
'Юли','Авг','Сеп','Окт','Нов','Дек'],
|
||||
dayNames: ['Неделя','Понеделник','Вторник','Сряда','Четвъртък','Петък','Събота'],
|
||||
dayNamesShort: ['Нед','Пон','Вто','Сря','Чет','Пет','Съб'],
|
||||
dayNamesMin: ['Не','По','Вт','Ср','Че','Пе','Съ'],
|
||||
weekHeader: 'Wk',
|
||||
dateFormat: 'dd.mm.yy',
|
||||
firstDay: 1,
|
||||
isRTL: false,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional['bg']);
|
||||
});
|
||||
23
resources/jquery.ui/i18n/jquery.ui.datepicker-bs.js
vendored
Normal file
23
resources/jquery.ui/i18n/jquery.ui.datepicker-bs.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* Bosnian i18n for the jQuery UI date picker plugin. */
|
||||
/* Written by Kenan Konjo. */
|
||||
jQuery(function($){
|
||||
$.datepicker.regional['bs'] = {
|
||||
closeText: 'Zatvori',
|
||||
prevText: '<',
|
||||
nextText: '>',
|
||||
currentText: 'Danas',
|
||||
monthNames: ['Januar','Februar','Mart','April','Maj','Juni',
|
||||
'Juli','August','Septembar','Oktobar','Novembar','Decembar'],
|
||||
monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun',
|
||||
'Jul','Aug','Sep','Okt','Nov','Dec'],
|
||||
dayNames: ['Nedelja','Ponedeljak','Utorak','Srijeda','Četvrtak','Petak','Subota'],
|
||||
dayNamesShort: ['Ned','Pon','Uto','Sri','Čet','Pet','Sub'],
|
||||
dayNamesMin: ['Ne','Po','Ut','Sr','Če','Pe','Su'],
|
||||
weekHeader: 'Wk',
|
||||
dateFormat: 'dd.mm.yy',
|
||||
firstDay: 1,
|
||||
isRTL: false,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional['bs']);
|
||||
});
|
||||
23
resources/jquery.ui/i18n/jquery.ui.datepicker-ca.js
vendored
Normal file
23
resources/jquery.ui/i18n/jquery.ui.datepicker-ca.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* Inicialització en català per a l'extenció 'calendar' per jQuery. */
|
||||
/* Writers: (joan.leon@gmail.com). */
|
||||
jQuery(function($){
|
||||
$.datepicker.regional['ca'] = {
|
||||
closeText: 'Tancar',
|
||||
prevText: '<Ant',
|
||||
nextText: 'Seg>',
|
||||
currentText: 'Avui',
|
||||
monthNames: ['Gener','Febrer','Març','Abril','Maig','Juny',
|
||||
'Juliol','Agost','Setembre','Octubre','Novembre','Desembre'],
|
||||
monthNamesShort: ['Gen','Feb','Mar','Abr','Mai','Jun',
|
||||
'Jul','Ago','Set','Oct','Nov','Des'],
|
||||
dayNames: ['Diumenge','Dilluns','Dimarts','Dimecres','Dijous','Divendres','Dissabte'],
|
||||
dayNamesShort: ['Dug','Dln','Dmt','Dmc','Djs','Dvn','Dsb'],
|
||||
dayNamesMin: ['Dg','Dl','Dt','Dc','Dj','Dv','Ds'],
|
||||
weekHeader: 'Sm',
|
||||
dateFormat: 'dd/mm/yy',
|
||||
firstDay: 1,
|
||||
isRTL: false,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional['ca']);
|
||||
});
|
||||
23
resources/jquery.ui/i18n/jquery.ui.datepicker-cs.js
vendored
Normal file
23
resources/jquery.ui/i18n/jquery.ui.datepicker-cs.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* Czech initialisation for the jQuery UI date picker plugin. */
|
||||
/* Written by Tomas Muller (tomas@tomas-muller.net). */
|
||||
jQuery(function($){
|
||||
$.datepicker.regional['cs'] = {
|
||||
closeText: 'Zavřít',
|
||||
prevText: '<Dříve',
|
||||
nextText: 'Později>',
|
||||
currentText: 'Nyní',
|
||||
monthNames: ['leden','únor','březen','duben','květen','červen',
|
||||
'červenec','srpen','září','říjen','listopad','prosinec'],
|
||||
monthNamesShort: ['led','úno','bře','dub','kvě','čer',
|
||||
'čvc','srp','zář','říj','lis','pro'],
|
||||
dayNames: ['neděle', 'pondělí', 'úterý', 'středa', 'čtvrtek', 'pátek', 'sobota'],
|
||||
dayNamesShort: ['ne', 'po', 'út', 'st', 'čt', 'pá', 'so'],
|
||||
dayNamesMin: ['ne','po','út','st','čt','pá','so'],
|
||||
weekHeader: 'Týd',
|
||||
dateFormat: 'dd.mm.yy',
|
||||
firstDay: 1,
|
||||
isRTL: false,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional['cs']);
|
||||
});
|
||||
23
resources/jquery.ui/i18n/jquery.ui.datepicker-da.js
vendored
Normal file
23
resources/jquery.ui/i18n/jquery.ui.datepicker-da.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* Danish initialisation for the jQuery UI date picker plugin. */
|
||||
/* Written by Jan Christensen ( deletestuff@gmail.com). */
|
||||
jQuery(function($){
|
||||
$.datepicker.regional['da'] = {
|
||||
closeText: 'Luk',
|
||||
prevText: '<Forrige',
|
||||
nextText: 'Næste>',
|
||||
currentText: 'Idag',
|
||||
monthNames: ['Januar','Februar','Marts','April','Maj','Juni',
|
||||
'Juli','August','September','Oktober','November','December'],
|
||||
monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun',
|
||||
'Jul','Aug','Sep','Okt','Nov','Dec'],
|
||||
dayNames: ['Søndag','Mandag','Tirsdag','Onsdag','Torsdag','Fredag','Lørdag'],
|
||||
dayNamesShort: ['Søn','Man','Tir','Ons','Tor','Fre','Lør'],
|
||||
dayNamesMin: ['Sø','Ma','Ti','On','To','Fr','Lø'],
|
||||
weekHeader: 'Uge',
|
||||
dateFormat: 'dd-mm-yy',
|
||||
firstDay: 1,
|
||||
isRTL: false,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional['da']);
|
||||
});
|
||||
23
resources/jquery.ui/i18n/jquery.ui.datepicker-de.js
vendored
Normal file
23
resources/jquery.ui/i18n/jquery.ui.datepicker-de.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* German initialisation for the jQuery UI date picker plugin. */
|
||||
/* Written by Milian Wolff (mail@milianw.de). */
|
||||
jQuery(function($){
|
||||
$.datepicker.regional['de'] = {
|
||||
closeText: 'schließen',
|
||||
prevText: '<zurück',
|
||||
nextText: 'Vor>',
|
||||
currentText: 'heute',
|
||||
monthNames: ['Januar','Februar','März','April','Mai','Juni',
|
||||
'Juli','August','September','Oktober','November','Dezember'],
|
||||
monthNamesShort: ['Jan','Feb','Mär','Apr','Mai','Jun',
|
||||
'Jul','Aug','Sep','Okt','Nov','Dez'],
|
||||
dayNames: ['Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'],
|
||||
dayNamesShort: ['So','Mo','Di','Mi','Do','Fr','Sa'],
|
||||
dayNamesMin: ['So','Mo','Di','Mi','Do','Fr','Sa'],
|
||||
weekHeader: 'Wo',
|
||||
dateFormat: 'dd.mm.yy',
|
||||
firstDay: 1,
|
||||
isRTL: false,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional['de']);
|
||||
});
|
||||
23
resources/jquery.ui/i18n/jquery.ui.datepicker-el.js
vendored
Normal file
23
resources/jquery.ui/i18n/jquery.ui.datepicker-el.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* Greek (el) initialisation for the jQuery UI date picker plugin. */
|
||||
/* Written by Alex Cicovic (http://www.alexcicovic.com) */
|
||||
jQuery(function($){
|
||||
$.datepicker.regional['el'] = {
|
||||
closeText: 'Κλείσιμο',
|
||||
prevText: 'Προηγούμενος',
|
||||
nextText: 'Επόμενος',
|
||||
currentText: 'Τρέχων Μήνας',
|
||||
monthNames: ['Ιανουάριος','Φεβρουάριος','Μάρτιος','Απρίλιος','Μάιος','Ιούνιος',
|
||||
'Ιούλιος','Αύγουστος','Σεπτέμβριος','Οκτώβριος','Νοέμβριος','Δεκέμβριος'],
|
||||
monthNamesShort: ['Ιαν','Φεβ','Μαρ','Απρ','Μαι','Ιουν',
|
||||
'Ιουλ','Αυγ','Σεπ','Οκτ','Νοε','Δεκ'],
|
||||
dayNames: ['Κυριακή','Δευτέρα','Τρίτη','Τετάρτη','Πέμπτη','Παρασκευή','Σάββατο'],
|
||||
dayNamesShort: ['Κυρ','Δευ','Τρι','Τετ','Πεμ','Παρ','Σαβ'],
|
||||
dayNamesMin: ['Κυ','Δε','Τρ','Τε','Πε','Πα','Σα'],
|
||||
weekHeader: 'Εβδ',
|
||||
dateFormat: 'dd/mm/yy',
|
||||
firstDay: 1,
|
||||
isRTL: false,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional['el']);
|
||||
});
|
||||
23
resources/jquery.ui/i18n/jquery.ui.datepicker-en-GB.js
vendored
Normal file
23
resources/jquery.ui/i18n/jquery.ui.datepicker-en-GB.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* English/UK initialisation for the jQuery UI date picker plugin. */
|
||||
/* Written by Stuart. */
|
||||
jQuery(function($){
|
||||
$.datepicker.regional['en-GB'] = {
|
||||
closeText: 'Done',
|
||||
prevText: 'Prev',
|
||||
nextText: 'Next',
|
||||
currentText: 'Today',
|
||||
monthNames: ['January','February','March','April','May','June',
|
||||
'July','August','September','October','November','December'],
|
||||
monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
|
||||
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
|
||||
dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
|
||||
dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
|
||||
dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'],
|
||||
weekHeader: 'Wk',
|
||||
dateFormat: 'dd/mm/yy',
|
||||
firstDay: 1,
|
||||
isRTL: false,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional['en-GB']);
|
||||
});
|
||||
23
resources/jquery.ui/i18n/jquery.ui.datepicker-eo.js
vendored
Normal file
23
resources/jquery.ui/i18n/jquery.ui.datepicker-eo.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* Esperanto initialisation for the jQuery UI date picker plugin. */
|
||||
/* Written by Olivier M. (olivierweb@ifrance.com). */
|
||||
jQuery(function($){
|
||||
$.datepicker.regional['eo'] = {
|
||||
closeText: 'Fermi',
|
||||
prevText: '<Anta',
|
||||
nextText: 'Sekv>',
|
||||
currentText: 'Nuna',
|
||||
monthNames: ['Januaro','Februaro','Marto','Aprilo','Majo','Junio',
|
||||
'Julio','Aŭgusto','Septembro','Oktobro','Novembro','Decembro'],
|
||||
monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun',
|
||||
'Jul','Aŭg','Sep','Okt','Nov','Dec'],
|
||||
dayNames: ['Dimanĉo','Lundo','Mardo','Merkredo','Ĵaŭdo','Vendredo','Sabato'],
|
||||
dayNamesShort: ['Dim','Lun','Mar','Mer','Ĵaŭ','Ven','Sab'],
|
||||
dayNamesMin: ['Di','Lu','Ma','Me','Ĵa','Ve','Sa'],
|
||||
weekHeader: 'Sb',
|
||||
dateFormat: 'dd/mm/yy',
|
||||
firstDay: 0,
|
||||
isRTL: false,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional['eo']);
|
||||
});
|
||||
23
resources/jquery.ui/i18n/jquery.ui.datepicker-es.js
vendored
Normal file
23
resources/jquery.ui/i18n/jquery.ui.datepicker-es.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* Inicialización en español para la extensión 'UI date picker' para jQuery. */
|
||||
/* Traducido por Vester (xvester@gmail.com). */
|
||||
jQuery(function($){
|
||||
$.datepicker.regional['es'] = {
|
||||
closeText: 'Cerrar',
|
||||
prevText: '<Ant',
|
||||
nextText: 'Sig>',
|
||||
currentText: 'Hoy',
|
||||
monthNames: ['Enero','Febrero','Marzo','Abril','Mayo','Junio',
|
||||
'Julio','Agosto','Septiembre','Octubre','Noviembre','Diciembre'],
|
||||
monthNamesShort: ['Ene','Feb','Mar','Abr','May','Jun',
|
||||
'Jul','Ago','Sep','Oct','Nov','Dic'],
|
||||
dayNames: ['Domingo','Lunes','Martes','Miércoles','Jueves','Viernes','Sábado'],
|
||||
dayNamesShort: ['Dom','Lun','Mar','Mié','Juv','Vie','Sáb'],
|
||||
dayNamesMin: ['Do','Lu','Ma','Mi','Ju','Vi','Sá'],
|
||||
weekHeader: 'Sm',
|
||||
dateFormat: 'dd/mm/yy',
|
||||
firstDay: 1,
|
||||
isRTL: false,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional['es']);
|
||||
});
|
||||
23
resources/jquery.ui/i18n/jquery.ui.datepicker-et.js
vendored
Normal file
23
resources/jquery.ui/i18n/jquery.ui.datepicker-et.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* Estonian initialisation for the jQuery UI date picker plugin. */
|
||||
/* Written by Mart Sõmermaa (mrts.pydev at gmail com). */
|
||||
jQuery(function($){
|
||||
$.datepicker.regional['et'] = {
|
||||
closeText: 'Sulge',
|
||||
prevText: 'Eelnev',
|
||||
nextText: 'Järgnev',
|
||||
currentText: 'Täna',
|
||||
monthNames: ['Jaanuar','Veebruar','Märts','Aprill','Mai','Juuni',
|
||||
'Juuli','August','September','Oktoober','November','Detsember'],
|
||||
monthNamesShort: ['Jaan', 'Veebr', 'Märts', 'Apr', 'Mai', 'Juuni',
|
||||
'Juuli', 'Aug', 'Sept', 'Okt', 'Nov', 'Dets'],
|
||||
dayNames: ['Pühapäev', 'Esmaspäev', 'Teisipäev', 'Kolmapäev', 'Neljapäev', 'Reede', 'Laupäev'],
|
||||
dayNamesShort: ['Pühap', 'Esmasp', 'Teisip', 'Kolmap', 'Neljap', 'Reede', 'Laup'],
|
||||
dayNamesMin: ['P','E','T','K','N','R','L'],
|
||||
weekHeader: 'Sm',
|
||||
dateFormat: 'dd.mm.yy',
|
||||
firstDay: 1,
|
||||
isRTL: false,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional['et']);
|
||||
});
|
||||
23
resources/jquery.ui/i18n/jquery.ui.datepicker-eu.js
vendored
Normal file
23
resources/jquery.ui/i18n/jquery.ui.datepicker-eu.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* Euskarako oinarria 'UI date picker' jquery-ko extentsioarentzat */
|
||||
/* Karrikas-ek itzulia (karrikas@karrikas.com) */
|
||||
jQuery(function($){
|
||||
$.datepicker.regional['eu'] = {
|
||||
closeText: 'Egina',
|
||||
prevText: '<Aur',
|
||||
nextText: 'Hur>',
|
||||
currentText: 'Gaur',
|
||||
monthNames: ['Urtarrila','Otsaila','Martxoa','Apirila','Maiatza','Ekaina',
|
||||
'Uztaila','Abuztua','Iraila','Urria','Azaroa','Abendua'],
|
||||
monthNamesShort: ['Urt','Ots','Mar','Api','Mai','Eka',
|
||||
'Uzt','Abu','Ira','Urr','Aza','Abe'],
|
||||
dayNames: ['Igandea','Astelehena','Asteartea','Asteazkena','Osteguna','Ostirala','Larunbata'],
|
||||
dayNamesShort: ['Iga','Ast','Ast','Ast','Ost','Ost','Lar'],
|
||||
dayNamesMin: ['Ig','As','As','As','Os','Os','La'],
|
||||
weekHeader: 'Wk',
|
||||
dateFormat: 'yy/mm/dd',
|
||||
firstDay: 1,
|
||||
isRTL: false,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional['eu']);
|
||||
});
|
||||
23
resources/jquery.ui/i18n/jquery.ui.datepicker-fa.js
vendored
Normal file
23
resources/jquery.ui/i18n/jquery.ui.datepicker-fa.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* Persian (Farsi) Translation for the jQuery UI date picker plugin. */
|
||||
/* Javad Mowlanezhad -- jmowla@gmail.com */
|
||||
/* Jalali calendar should supported soon! (Its implemented but I have to test it) */
|
||||
jQuery(function($) {
|
||||
$.datepicker.regional['fa'] = {
|
||||
closeText: 'بستن',
|
||||
prevText: '<قبلي',
|
||||
nextText: 'بعدي>',
|
||||
currentText: 'امروز',
|
||||
monthNames: ['فروردين','ارديبهشت','خرداد','تير','مرداد','شهريور',
|
||||
'مهر','آبان','آذر','دي','بهمن','اسفند'],
|
||||
monthNamesShort: ['1','2','3','4','5','6','7','8','9','10','11','12'],
|
||||
dayNames: ['يکشنبه','دوشنبه','سهشنبه','چهارشنبه','پنجشنبه','جمعه','شنبه'],
|
||||
dayNamesShort: ['ي','د','س','چ','پ','ج', 'ش'],
|
||||
dayNamesMin: ['ي','د','س','چ','پ','ج', 'ش'],
|
||||
weekHeader: 'هف',
|
||||
dateFormat: 'yy/mm/dd',
|
||||
firstDay: 6,
|
||||
isRTL: true,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional['fa']);
|
||||
});
|
||||
23
resources/jquery.ui/i18n/jquery.ui.datepicker-fi.js
vendored
Normal file
23
resources/jquery.ui/i18n/jquery.ui.datepicker-fi.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* Finnish initialisation for the jQuery UI date picker plugin. */
|
||||
/* Written by Harri Kilpi<70> (harrikilpio@gmail.com). */
|
||||
jQuery(function($){
|
||||
$.datepicker.regional['fi'] = {
|
||||
closeText: 'Sulje',
|
||||
prevText: '«Edellinen',
|
||||
nextText: 'Seuraava»',
|
||||
currentText: 'Tänään',
|
||||
monthNames: ['Tammikuu','Helmikuu','Maaliskuu','Huhtikuu','Toukokuu','Kesäkuu',
|
||||
'Heinäkuu','Elokuu','Syyskuu','Lokakuu','Marraskuu','Joulukuu'],
|
||||
monthNamesShort: ['Tammi','Helmi','Maalis','Huhti','Touko','Kesä',
|
||||
'Heinä','Elo','Syys','Loka','Marras','Joulu'],
|
||||
dayNamesShort: ['Su','Ma','Ti','Ke','To','Pe','Su'],
|
||||
dayNames: ['Sunnuntai','Maanantai','Tiistai','Keskiviikko','Torstai','Perjantai','Lauantai'],
|
||||
dayNamesMin: ['Su','Ma','Ti','Ke','To','Pe','La'],
|
||||
weekHeader: 'Vk',
|
||||
dateFormat: 'dd.mm.yy',
|
||||
firstDay: 1,
|
||||
isRTL: false,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional['fi']);
|
||||
});
|
||||
23
resources/jquery.ui/i18n/jquery.ui.datepicker-fo.js
vendored
Normal file
23
resources/jquery.ui/i18n/jquery.ui.datepicker-fo.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* Faroese initialisation for the jQuery UI date picker plugin */
|
||||
/* Written by Sverri Mohr Olsen, sverrimo@gmail.com */
|
||||
jQuery(function($){
|
||||
$.datepicker.regional['fo'] = {
|
||||
closeText: 'Lat aftur',
|
||||
prevText: '<Fyrra',
|
||||
nextText: 'Næsta>',
|
||||
currentText: 'Í dag',
|
||||
monthNames: ['Januar','Februar','Mars','Apríl','Mei','Juni',
|
||||
'Juli','August','September','Oktober','November','Desember'],
|
||||
monthNamesShort: ['Jan','Feb','Mar','Apr','Mei','Jun',
|
||||
'Jul','Aug','Sep','Okt','Nov','Des'],
|
||||
dayNames: ['Sunnudagur','Mánadagur','Týsdagur','Mikudagur','Hósdagur','Fríggjadagur','Leyardagur'],
|
||||
dayNamesShort: ['Sun','Mán','Týs','Mik','Hós','Frí','Ley'],
|
||||
dayNamesMin: ['Su','Má','Tý','Mi','Hó','Fr','Le'],
|
||||
weekHeader: 'Vk',
|
||||
dateFormat: 'dd-mm-yy',
|
||||
firstDay: 0,
|
||||
isRTL: false,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional['fo']);
|
||||
});
|
||||
23
resources/jquery.ui/i18n/jquery.ui.datepicker-fr-CH.js
vendored
Normal file
23
resources/jquery.ui/i18n/jquery.ui.datepicker-fr-CH.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* Swiss-French initialisation for the jQuery UI date picker plugin. */
|
||||
/* Written Martin Voelkle (martin.voelkle@e-tc.ch). */
|
||||
jQuery(function($){
|
||||
$.datepicker.regional['fr-CH'] = {
|
||||
closeText: 'Fermer',
|
||||
prevText: '<Préc',
|
||||
nextText: 'Suiv>',
|
||||
currentText: 'Courant',
|
||||
monthNames: ['Janvier','Février','Mars','Avril','Mai','Juin',
|
||||
'Juillet','Août','Septembre','Octobre','Novembre','Décembre'],
|
||||
monthNamesShort: ['Jan','Fév','Mar','Avr','Mai','Jun',
|
||||
'Jul','Aoû','Sep','Oct','Nov','Déc'],
|
||||
dayNames: ['Dimanche','Lundi','Mardi','Mercredi','Jeudi','Vendredi','Samedi'],
|
||||
dayNamesShort: ['Dim','Lun','Mar','Mer','Jeu','Ven','Sam'],
|
||||
dayNamesMin: ['Di','Lu','Ma','Me','Je','Ve','Sa'],
|
||||
weekHeader: 'Sm',
|
||||
dateFormat: 'dd.mm.yy',
|
||||
firstDay: 1,
|
||||
isRTL: false,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional['fr-CH']);
|
||||
});
|
||||
23
resources/jquery.ui/i18n/jquery.ui.datepicker-fr.js
vendored
Normal file
23
resources/jquery.ui/i18n/jquery.ui.datepicker-fr.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* French initialisation for the jQuery UI date picker plugin. */
|
||||
/* Written by Keith Wood (kbwood{at}iinet.com.au) and Stéphane Nahmani (sholby@sholby.net). */
|
||||
jQuery(function($){
|
||||
$.datepicker.regional['fr'] = {
|
||||
closeText: 'Fermer',
|
||||
prevText: '<Préc',
|
||||
nextText: 'Suiv>',
|
||||
currentText: 'Courant',
|
||||
monthNames: ['Janvier','Février','Mars','Avril','Mai','Juin',
|
||||
'Juillet','Août','Septembre','Octobre','Novembre','Décembre'],
|
||||
monthNamesShort: ['Jan','Fév','Mar','Avr','Mai','Jun',
|
||||
'Jul','Aoû','Sep','Oct','Nov','Déc'],
|
||||
dayNames: ['Dimanche','Lundi','Mardi','Mercredi','Jeudi','Vendredi','Samedi'],
|
||||
dayNamesShort: ['Dim','Lun','Mar','Mer','Jeu','Ven','Sam'],
|
||||
dayNamesMin: ['Di','Lu','Ma','Me','Je','Ve','Sa'],
|
||||
weekHeader: 'Sm',
|
||||
dateFormat: 'dd/mm/yy',
|
||||
firstDay: 1,
|
||||
isRTL: false,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional['fr']);
|
||||
});
|
||||
23
resources/jquery.ui/i18n/jquery.ui.datepicker-he.js
vendored
Normal file
23
resources/jquery.ui/i18n/jquery.ui.datepicker-he.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* Hebrew initialisation for the UI Datepicker extension. */
|
||||
/* Written by Amir Hardon (ahardon at gmail dot com). */
|
||||
jQuery(function($){
|
||||
$.datepicker.regional['he'] = {
|
||||
closeText: 'סגור',
|
||||
prevText: '<הקודם',
|
||||
nextText: 'הבא>',
|
||||
currentText: 'היום',
|
||||
monthNames: ['ינואר','פברואר','מרץ','אפריל','מאי','יוני',
|
||||
'יולי','אוגוסט','ספטמבר','אוקטובר','נובמבר','דצמבר'],
|
||||
monthNamesShort: ['1','2','3','4','5','6',
|
||||
'7','8','9','10','11','12'],
|
||||
dayNames: ['ראשון','שני','שלישי','רביעי','חמישי','שישי','שבת'],
|
||||
dayNamesShort: ['א\'','ב\'','ג\'','ד\'','ה\'','ו\'','שבת'],
|
||||
dayNamesMin: ['א\'','ב\'','ג\'','ד\'','ה\'','ו\'','שבת'],
|
||||
weekHeader: 'Wk',
|
||||
dateFormat: 'dd/mm/yy',
|
||||
firstDay: 0,
|
||||
isRTL: true,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional['he']);
|
||||
});
|
||||
23
resources/jquery.ui/i18n/jquery.ui.datepicker-hr.js
vendored
Normal file
23
resources/jquery.ui/i18n/jquery.ui.datepicker-hr.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* Croatian i18n for the jQuery UI date picker plugin. */
|
||||
/* Written by Vjekoslav Nesek. */
|
||||
jQuery(function($){
|
||||
$.datepicker.regional['hr'] = {
|
||||
closeText: 'Zatvori',
|
||||
prevText: '<',
|
||||
nextText: '>',
|
||||
currentText: 'Danas',
|
||||
monthNames: ['Siječanj','Veljača','Ožujak','Travanj','Svibanj','Lipanj',
|
||||
'Srpanj','Kolovoz','Rujan','Listopad','Studeni','Prosinac'],
|
||||
monthNamesShort: ['Sij','Velj','Ožu','Tra','Svi','Lip',
|
||||
'Srp','Kol','Ruj','Lis','Stu','Pro'],
|
||||
dayNames: ['Nedjelja','Ponedjeljak','Utorak','Srijeda','Četvrtak','Petak','Subota'],
|
||||
dayNamesShort: ['Ned','Pon','Uto','Sri','Čet','Pet','Sub'],
|
||||
dayNamesMin: ['Ne','Po','Ut','Sr','Če','Pe','Su'],
|
||||
weekHeader: 'Tje',
|
||||
dateFormat: 'dd.mm.yy.',
|
||||
firstDay: 1,
|
||||
isRTL: false,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional['hr']);
|
||||
});
|
||||
23
resources/jquery.ui/i18n/jquery.ui.datepicker-hu.js
vendored
Normal file
23
resources/jquery.ui/i18n/jquery.ui.datepicker-hu.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* Hungarian initialisation for the jQuery UI date picker plugin. */
|
||||
/* Written by Istvan Karaszi (jquery@spam.raszi.hu). */
|
||||
jQuery(function($){
|
||||
$.datepicker.regional['hu'] = {
|
||||
closeText: 'bezárás',
|
||||
prevText: '« vissza',
|
||||
nextText: 'előre »',
|
||||
currentText: 'ma',
|
||||
monthNames: ['Január', 'Február', 'Március', 'Április', 'Május', 'Június',
|
||||
'Július', 'Augusztus', 'Szeptember', 'Október', 'November', 'December'],
|
||||
monthNamesShort: ['Jan', 'Feb', 'Már', 'Ápr', 'Máj', 'Jún',
|
||||
'Júl', 'Aug', 'Szep', 'Okt', 'Nov', 'Dec'],
|
||||
dayNames: ['Vasárnap', 'Hétfö', 'Kedd', 'Szerda', 'Csütörtök', 'Péntek', 'Szombat'],
|
||||
dayNamesShort: ['Vas', 'Hét', 'Ked', 'Sze', 'Csü', 'Pén', 'Szo'],
|
||||
dayNamesMin: ['V', 'H', 'K', 'Sze', 'Cs', 'P', 'Szo'],
|
||||
weekHeader: 'Hé',
|
||||
dateFormat: 'yy-mm-dd',
|
||||
firstDay: 1,
|
||||
isRTL: false,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional['hu']);
|
||||
});
|
||||
23
resources/jquery.ui/i18n/jquery.ui.datepicker-hy.js
vendored
Normal file
23
resources/jquery.ui/i18n/jquery.ui.datepicker-hy.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* Armenian(UTF-8) initialisation for the jQuery UI date picker plugin. */
|
||||
/* Written by Levon Zakaryan (levon.zakaryan@gmail.com)*/
|
||||
jQuery(function($){
|
||||
$.datepicker.regional['hy'] = {
|
||||
closeText: 'Փակել',
|
||||
prevText: '<Նախ.',
|
||||
nextText: 'Հաջ.>',
|
||||
currentText: 'Այսօր',
|
||||
monthNames: ['Հունվար','Փետրվար','Մարտ','Ապրիլ','Մայիս','Հունիս',
|
||||
'Հուլիս','Օգոստոս','Սեպտեմբեր','Հոկտեմբեր','Նոյեմբեր','Դեկտեմբեր'],
|
||||
monthNamesShort: ['Հունվ','Փետր','Մարտ','Ապր','Մայիս','Հունիս',
|
||||
'Հուլ','Օգս','Սեպ','Հոկ','Նոյ','Դեկ'],
|
||||
dayNames: ['կիրակի','եկուշաբթի','երեքշաբթի','չորեքշաբթի','հինգշաբթի','ուրբաթ','շաբաթ'],
|
||||
dayNamesShort: ['կիր','երկ','երք','չրք','հնգ','ուրբ','շբթ'],
|
||||
dayNamesMin: ['կիր','երկ','երք','չրք','հնգ','ուրբ','շբթ'],
|
||||
weekHeader: 'ՇԲՏ',
|
||||
dateFormat: 'dd.mm.yy',
|
||||
firstDay: 1,
|
||||
isRTL: false,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional['hy']);
|
||||
});
|
||||
23
resources/jquery.ui/i18n/jquery.ui.datepicker-id.js
vendored
Normal file
23
resources/jquery.ui/i18n/jquery.ui.datepicker-id.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* Indonesian initialisation for the jQuery UI date picker plugin. */
|
||||
/* Written by Deden Fathurahman (dedenf@gmail.com). */
|
||||
jQuery(function($){
|
||||
$.datepicker.regional['id'] = {
|
||||
closeText: 'Tutup',
|
||||
prevText: '<mundur',
|
||||
nextText: 'maju>',
|
||||
currentText: 'hari ini',
|
||||
monthNames: ['Januari','Februari','Maret','April','Mei','Juni',
|
||||
'Juli','Agustus','September','Oktober','Nopember','Desember'],
|
||||
monthNamesShort: ['Jan','Feb','Mar','Apr','Mei','Jun',
|
||||
'Jul','Agus','Sep','Okt','Nop','Des'],
|
||||
dayNames: ['Minggu','Senin','Selasa','Rabu','Kamis','Jumat','Sabtu'],
|
||||
dayNamesShort: ['Min','Sen','Sel','Rab','kam','Jum','Sab'],
|
||||
dayNamesMin: ['Mg','Sn','Sl','Rb','Km','jm','Sb'],
|
||||
weekHeader: 'Mg',
|
||||
dateFormat: 'dd/mm/yy',
|
||||
firstDay: 0,
|
||||
isRTL: false,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional['id']);
|
||||
});
|
||||
23
resources/jquery.ui/i18n/jquery.ui.datepicker-is.js
vendored
Normal file
23
resources/jquery.ui/i18n/jquery.ui.datepicker-is.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* Icelandic initialisation for the jQuery UI date picker plugin. */
|
||||
/* Written by Haukur H. Thorsson (haukur@eskill.is). */
|
||||
jQuery(function($){
|
||||
$.datepicker.regional['is'] = {
|
||||
closeText: 'Loka',
|
||||
prevText: '< Fyrri',
|
||||
nextText: 'Næsti >',
|
||||
currentText: 'Í dag',
|
||||
monthNames: ['Janúar','Febrúar','Mars','Apríl','Maí','Júní',
|
||||
'Júlí','Ágúst','September','Október','Nóvember','Desember'],
|
||||
monthNamesShort: ['Jan','Feb','Mar','Apr','Maí','Jún',
|
||||
'Júl','Ágú','Sep','Okt','Nóv','Des'],
|
||||
dayNames: ['Sunnudagur','Mánudagur','Þriðjudagur','Miðvikudagur','Fimmtudagur','Föstudagur','Laugardagur'],
|
||||
dayNamesShort: ['Sun','Mán','Þri','Mið','Fim','Fös','Lau'],
|
||||
dayNamesMin: ['Su','Má','Þr','Mi','Fi','Fö','La'],
|
||||
weekHeader: 'Vika',
|
||||
dateFormat: 'dd/mm/yy',
|
||||
firstDay: 0,
|
||||
isRTL: false,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional['is']);
|
||||
});
|
||||
23
resources/jquery.ui/i18n/jquery.ui.datepicker-it.js
vendored
Normal file
23
resources/jquery.ui/i18n/jquery.ui.datepicker-it.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* Italian initialisation for the jQuery UI date picker plugin. */
|
||||
/* Written by Antonello Pasella (antonello.pasella@gmail.com). */
|
||||
jQuery(function($){
|
||||
$.datepicker.regional['it'] = {
|
||||
closeText: 'Chiudi',
|
||||
prevText: '<Prec',
|
||||
nextText: 'Succ>',
|
||||
currentText: 'Oggi',
|
||||
monthNames: ['Gennaio','Febbraio','Marzo','Aprile','Maggio','Giugno',
|
||||
'Luglio','Agosto','Settembre','Ottobre','Novembre','Dicembre'],
|
||||
monthNamesShort: ['Gen','Feb','Mar','Apr','Mag','Giu',
|
||||
'Lug','Ago','Set','Ott','Nov','Dic'],
|
||||
dayNames: ['Domenica','Lunedì','Martedì','Mercoledì','Giovedì','Venerdì','Sabato'],
|
||||
dayNamesShort: ['Dom','Lun','Mar','Mer','Gio','Ven','Sab'],
|
||||
dayNamesMin: ['Do','Lu','Ma','Me','Gi','Ve','Sa'],
|
||||
weekHeader: 'Sm',
|
||||
dateFormat: 'dd/mm/yy',
|
||||
firstDay: 1,
|
||||
isRTL: false,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional['it']);
|
||||
});
|
||||
23
resources/jquery.ui/i18n/jquery.ui.datepicker-ja.js
vendored
Normal file
23
resources/jquery.ui/i18n/jquery.ui.datepicker-ja.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* Japanese initialisation for the jQuery UI date picker plugin. */
|
||||
/* Written by Kentaro SATO (kentaro@ranvis.com). */
|
||||
jQuery(function($){
|
||||
$.datepicker.regional['ja'] = {
|
||||
closeText: '閉じる',
|
||||
prevText: '<前',
|
||||
nextText: '次>',
|
||||
currentText: '今日',
|
||||
monthNames: ['1月','2月','3月','4月','5月','6月',
|
||||
'7月','8月','9月','10月','11月','12月'],
|
||||
monthNamesShort: ['1月','2月','3月','4月','5月','6月',
|
||||
'7月','8月','9月','10月','11月','12月'],
|
||||
dayNames: ['日曜日','月曜日','火曜日','水曜日','木曜日','金曜日','土曜日'],
|
||||
dayNamesShort: ['日','月','火','水','木','金','土'],
|
||||
dayNamesMin: ['日','月','火','水','木','金','土'],
|
||||
weekHeader: '週',
|
||||
dateFormat: 'yy/mm/dd',
|
||||
firstDay: 0,
|
||||
isRTL: false,
|
||||
showMonthAfterYear: true,
|
||||
yearSuffix: '年'};
|
||||
$.datepicker.setDefaults($.datepicker.regional['ja']);
|
||||
});
|
||||
23
resources/jquery.ui/i18n/jquery.ui.datepicker-ko.js
vendored
Normal file
23
resources/jquery.ui/i18n/jquery.ui.datepicker-ko.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* Korean initialisation for the jQuery calendar extension. */
|
||||
/* Written by DaeKwon Kang (ncrash.dk@gmail.com). */
|
||||
jQuery(function($){
|
||||
$.datepicker.regional['ko'] = {
|
||||
closeText: '닫기',
|
||||
prevText: '이전달',
|
||||
nextText: '다음달',
|
||||
currentText: '오늘',
|
||||
monthNames: ['1월(JAN)','2월(FEB)','3월(MAR)','4월(APR)','5월(MAY)','6월(JUN)',
|
||||
'7월(JUL)','8월(AUG)','9월(SEP)','10월(OCT)','11월(NOV)','12월(DEC)'],
|
||||
monthNamesShort: ['1월(JAN)','2월(FEB)','3월(MAR)','4월(APR)','5월(MAY)','6월(JUN)',
|
||||
'7월(JUL)','8월(AUG)','9월(SEP)','10월(OCT)','11월(NOV)','12월(DEC)'],
|
||||
dayNames: ['일','월','화','수','목','금','토'],
|
||||
dayNamesShort: ['일','월','화','수','목','금','토'],
|
||||
dayNamesMin: ['일','월','화','수','목','금','토'],
|
||||
weekHeader: 'Wk',
|
||||
dateFormat: 'yy-mm-dd',
|
||||
firstDay: 0,
|
||||
isRTL: false,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: '년'};
|
||||
$.datepicker.setDefaults($.datepicker.regional['ko']);
|
||||
});
|
||||
23
resources/jquery.ui/i18n/jquery.ui.datepicker-lt.js
vendored
Normal file
23
resources/jquery.ui/i18n/jquery.ui.datepicker-lt.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* Lithuanian (UTF-8) initialisation for the jQuery UI date picker plugin. */
|
||||
/* @author Arturas Paleicikas <arturas@avalon.lt> */
|
||||
jQuery(function($){
|
||||
$.datepicker.regional['lt'] = {
|
||||
closeText: 'Uždaryti',
|
||||
prevText: '<Atgal',
|
||||
nextText: 'Pirmyn>',
|
||||
currentText: 'Šiandien',
|
||||
monthNames: ['Sausis','Vasaris','Kovas','Balandis','Gegužė','Birželis',
|
||||
'Liepa','Rugpjūtis','Rugsėjis','Spalis','Lapkritis','Gruodis'],
|
||||
monthNamesShort: ['Sau','Vas','Kov','Bal','Geg','Bir',
|
||||
'Lie','Rugp','Rugs','Spa','Lap','Gru'],
|
||||
dayNames: ['sekmadienis','pirmadienis','antradienis','trečiadienis','ketvirtadienis','penktadienis','šeštadienis'],
|
||||
dayNamesShort: ['sek','pir','ant','tre','ket','pen','šeš'],
|
||||
dayNamesMin: ['Se','Pr','An','Tr','Ke','Pe','Še'],
|
||||
weekHeader: 'Wk',
|
||||
dateFormat: 'yy-mm-dd',
|
||||
firstDay: 1,
|
||||
isRTL: false,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional['lt']);
|
||||
});
|
||||
23
resources/jquery.ui/i18n/jquery.ui.datepicker-lv.js
vendored
Normal file
23
resources/jquery.ui/i18n/jquery.ui.datepicker-lv.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* Latvian (UTF-8) initialisation for the jQuery UI date picker plugin. */
|
||||
/* @author Arturas Paleicikas <arturas.paleicikas@metasite.net> */
|
||||
jQuery(function($){
|
||||
$.datepicker.regional['lv'] = {
|
||||
closeText: 'Aizvērt',
|
||||
prevText: 'Iepr',
|
||||
nextText: 'Nāka',
|
||||
currentText: 'Šodien',
|
||||
monthNames: ['Janvāris','Februāris','Marts','Aprīlis','Maijs','Jūnijs',
|
||||
'Jūlijs','Augusts','Septembris','Oktobris','Novembris','Decembris'],
|
||||
monthNamesShort: ['Jan','Feb','Mar','Apr','Mai','Jūn',
|
||||
'Jūl','Aug','Sep','Okt','Nov','Dec'],
|
||||
dayNames: ['svētdiena','pirmdiena','otrdiena','trešdiena','ceturtdiena','piektdiena','sestdiena'],
|
||||
dayNamesShort: ['svt','prm','otr','tre','ctr','pkt','sst'],
|
||||
dayNamesMin: ['Sv','Pr','Ot','Tr','Ct','Pk','Ss'],
|
||||
weekHeader: 'Nav',
|
||||
dateFormat: 'dd-mm-yy',
|
||||
firstDay: 1,
|
||||
isRTL: false,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional['lv']);
|
||||
});
|
||||
23
resources/jquery.ui/i18n/jquery.ui.datepicker-ms.js
vendored
Normal file
23
resources/jquery.ui/i18n/jquery.ui.datepicker-ms.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* Malaysian initialisation for the jQuery UI date picker plugin. */
|
||||
/* Written by Mohd Nawawi Mohamad Jamili (nawawi@ronggeng.net). */
|
||||
jQuery(function($){
|
||||
$.datepicker.regional['ms'] = {
|
||||
closeText: 'Tutup',
|
||||
prevText: '<Sebelum',
|
||||
nextText: 'Selepas>',
|
||||
currentText: 'hari ini',
|
||||
monthNames: ['Januari','Februari','Mac','April','Mei','Jun',
|
||||
'Julai','Ogos','September','Oktober','November','Disember'],
|
||||
monthNamesShort: ['Jan','Feb','Mac','Apr','Mei','Jun',
|
||||
'Jul','Ogo','Sep','Okt','Nov','Dis'],
|
||||
dayNames: ['Ahad','Isnin','Selasa','Rabu','Khamis','Jumaat','Sabtu'],
|
||||
dayNamesShort: ['Aha','Isn','Sel','Rab','kha','Jum','Sab'],
|
||||
dayNamesMin: ['Ah','Is','Se','Ra','Kh','Ju','Sa'],
|
||||
weekHeader: 'Mg',
|
||||
dateFormat: 'dd/mm/yy',
|
||||
firstDay: 0,
|
||||
isRTL: false,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional['ms']);
|
||||
});
|
||||
23
resources/jquery.ui/i18n/jquery.ui.datepicker-nl.js
vendored
Normal file
23
resources/jquery.ui/i18n/jquery.ui.datepicker-nl.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* Dutch (UTF-8) initialisation for the jQuery UI date picker plugin. */
|
||||
/* Written by Mathias Bynens <http://mathiasbynens.be/> */
|
||||
jQuery(function($){
|
||||
$.datepicker.regional.nl = {
|
||||
closeText: 'Sluiten',
|
||||
prevText: '←',
|
||||
nextText: '→',
|
||||
currentText: 'Vandaag',
|
||||
monthNames: ['januari', 'februari', 'maart', 'april', 'mei', 'juni',
|
||||
'juli', 'augustus', 'september', 'oktober', 'november', 'december'],
|
||||
monthNamesShort: ['jan', 'feb', 'maa', 'apr', 'mei', 'jun',
|
||||
'jul', 'aug', 'sep', 'okt', 'nov', 'dec'],
|
||||
dayNames: ['zondag', 'maandag', 'dinsdag', 'woensdag', 'donderdag', 'vrijdag', 'zaterdag'],
|
||||
dayNamesShort: ['zon', 'maa', 'din', 'woe', 'don', 'vri', 'zat'],
|
||||
dayNamesMin: ['zo', 'ma', 'di', 'wo', 'do', 'vr', 'za'],
|
||||
weekHeader: 'Wk',
|
||||
dateFormat: 'dd/mm/yy',
|
||||
firstDay: 1,
|
||||
isRTL: false,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional.nl);
|
||||
});
|
||||
23
resources/jquery.ui/i18n/jquery.ui.datepicker-no.js
vendored
Normal file
23
resources/jquery.ui/i18n/jquery.ui.datepicker-no.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* Norwegian initialisation for the jQuery UI date picker plugin. */
|
||||
/* Written by Naimdjon Takhirov (naimdjon@gmail.com). */
|
||||
jQuery(function($){
|
||||
$.datepicker.regional['no'] = {
|
||||
closeText: 'Lukk',
|
||||
prevText: '«Forrige',
|
||||
nextText: 'Neste»',
|
||||
currentText: 'I dag',
|
||||
monthNames: ['Januar','Februar','Mars','April','Mai','Juni',
|
||||
'Juli','August','September','Oktober','November','Desember'],
|
||||
monthNamesShort: ['Jan','Feb','Mar','Apr','Mai','Jun',
|
||||
'Jul','Aug','Sep','Okt','Nov','Des'],
|
||||
dayNamesShort: ['Søn','Man','Tir','Ons','Tor','Fre','Lør'],
|
||||
dayNames: ['Søndag','Mandag','Tirsdag','Onsdag','Torsdag','Fredag','Lørdag'],
|
||||
dayNamesMin: ['Sø','Ma','Ti','On','To','Fr','Lø'],
|
||||
weekHeader: 'Uke',
|
||||
dateFormat: 'yy-mm-dd',
|
||||
firstDay: 0,
|
||||
isRTL: false,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional['no']);
|
||||
});
|
||||
23
resources/jquery.ui/i18n/jquery.ui.datepicker-pl.js
vendored
Normal file
23
resources/jquery.ui/i18n/jquery.ui.datepicker-pl.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* Polish initialisation for the jQuery UI date picker plugin. */
|
||||
/* Written by Jacek Wysocki (jacek.wysocki@gmail.com). */
|
||||
jQuery(function($){
|
||||
$.datepicker.regional['pl'] = {
|
||||
closeText: 'Zamknij',
|
||||
prevText: '<Poprzedni',
|
||||
nextText: 'Następny>',
|
||||
currentText: 'Dziś',
|
||||
monthNames: ['Styczeń','Luty','Marzec','Kwiecień','Maj','Czerwiec',
|
||||
'Lipiec','Sierpień','Wrzesień','Październik','Listopad','Grudzień'],
|
||||
monthNamesShort: ['Sty','Lu','Mar','Kw','Maj','Cze',
|
||||
'Lip','Sie','Wrz','Pa','Lis','Gru'],
|
||||
dayNames: ['Niedziela','Poniedziałek','Wtorek','Środa','Czwartek','Piątek','Sobota'],
|
||||
dayNamesShort: ['Nie','Pn','Wt','Śr','Czw','Pt','So'],
|
||||
dayNamesMin: ['N','Pn','Wt','Śr','Cz','Pt','So'],
|
||||
weekHeader: 'Tydz',
|
||||
dateFormat: 'dd.mm.yy',
|
||||
firstDay: 1,
|
||||
isRTL: false,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional['pl']);
|
||||
});
|
||||
23
resources/jquery.ui/i18n/jquery.ui.datepicker-pt-BR.js
vendored
Normal file
23
resources/jquery.ui/i18n/jquery.ui.datepicker-pt-BR.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* Brazilian initialisation for the jQuery UI date picker plugin. */
|
||||
/* Written by Leonildo Costa Silva (leocsilva@gmail.com). */
|
||||
jQuery(function($){
|
||||
$.datepicker.regional['pt-BR'] = {
|
||||
closeText: 'Fechar',
|
||||
prevText: '<Anterior',
|
||||
nextText: 'Próximo>',
|
||||
currentText: 'Hoje',
|
||||
monthNames: ['Janeiro','Fevereiro','Março','Abril','Maio','Junho',
|
||||
'Julho','Agosto','Setembro','Outubro','Novembro','Dezembro'],
|
||||
monthNamesShort: ['Jan','Fev','Mar','Abr','Mai','Jun',
|
||||
'Jul','Ago','Set','Out','Nov','Dez'],
|
||||
dayNames: ['Domingo','Segunda-feira','Terça-feira','Quarta-feira','Quinta-feira','Sexta-feira','Sabado'],
|
||||
dayNamesShort: ['Dom','Seg','Ter','Qua','Qui','Sex','Sab'],
|
||||
dayNamesMin: ['Dom','Seg','Ter','Qua','Qui','Sex','Sab'],
|
||||
weekHeader: 'Sm',
|
||||
dateFormat: 'dd/mm/yy',
|
||||
firstDay: 0,
|
||||
isRTL: false,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional['pt-BR']);
|
||||
});
|
||||
26
resources/jquery.ui/i18n/jquery.ui.datepicker-ro.js
vendored
Normal file
26
resources/jquery.ui/i18n/jquery.ui.datepicker-ro.js
vendored
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/* Romanian initialisation for the jQuery UI date picker plugin.
|
||||
*
|
||||
* Written by Edmond L. (ll_edmond@walla.com)
|
||||
* and Ionut G. Stan (ionut.g.stan@gmail.com)
|
||||
*/
|
||||
jQuery(function($){
|
||||
$.datepicker.regional['ro'] = {
|
||||
closeText: 'Închide',
|
||||
prevText: '« Luna precedentă',
|
||||
nextText: 'Luna următoare »',
|
||||
currentText: 'Azi',
|
||||
monthNames: ['Ianuarie','Februarie','Martie','Aprilie','Mai','Iunie',
|
||||
'Iulie','August','Septembrie','Octombrie','Noiembrie','Decembrie'],
|
||||
monthNamesShort: ['Ian', 'Feb', 'Mar', 'Apr', 'Mai', 'Iun',
|
||||
'Iul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
|
||||
dayNames: ['Duminică', 'Luni', 'Marţi', 'Miercuri', 'Joi', 'Vineri', 'Sâmbătă'],
|
||||
dayNamesShort: ['Dum', 'Lun', 'Mar', 'Mie', 'Joi', 'Vin', 'Sâm'],
|
||||
dayNamesMin: ['Du','Lu','Ma','Mi','Jo','Vi','Sâ'],
|
||||
weekHeader: 'Săpt',
|
||||
dateFormat: 'dd.mm.yy',
|
||||
firstDay: 1,
|
||||
isRTL: false,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional['ro']);
|
||||
});
|
||||
23
resources/jquery.ui/i18n/jquery.ui.datepicker-ru.js
vendored
Normal file
23
resources/jquery.ui/i18n/jquery.ui.datepicker-ru.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* Russian (UTF-8) initialisation for the jQuery UI date picker plugin. */
|
||||
/* Written by Andrew Stromnov (stromnov@gmail.com). */
|
||||
jQuery(function($){
|
||||
$.datepicker.regional['ru'] = {
|
||||
closeText: 'Закрыть',
|
||||
prevText: '<Пред',
|
||||
nextText: 'След>',
|
||||
currentText: 'Сегодня',
|
||||
monthNames: ['Январь','Февраль','Март','Апрель','Май','Июнь',
|
||||
'Июль','Август','Сентябрь','Октябрь','Ноябрь','Декабрь'],
|
||||
monthNamesShort: ['Янв','Фев','Мар','Апр','Май','Июн',
|
||||
'Июл','Авг','Сен','Окт','Ноя','Дек'],
|
||||
dayNames: ['воскресенье','понедельник','вторник','среда','четверг','пятница','суббота'],
|
||||
dayNamesShort: ['вск','пнд','втр','срд','чтв','птн','сбт'],
|
||||
dayNamesMin: ['Вс','Пн','Вт','Ср','Чт','Пт','Сб'],
|
||||
weekHeader: 'Не',
|
||||
dateFormat: 'dd.mm.yy',
|
||||
firstDay: 1,
|
||||
isRTL: false,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional['ru']);
|
||||
});
|
||||
23
resources/jquery.ui/i18n/jquery.ui.datepicker-sk.js
vendored
Normal file
23
resources/jquery.ui/i18n/jquery.ui.datepicker-sk.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* Slovak initialisation for the jQuery UI date picker plugin. */
|
||||
/* Written by Vojtech Rinik (vojto@hmm.sk). */
|
||||
jQuery(function($){
|
||||
$.datepicker.regional['sk'] = {
|
||||
closeText: 'Zavrieť',
|
||||
prevText: '<Predchádzajúci',
|
||||
nextText: 'Nasledujúci>',
|
||||
currentText: 'Dnes',
|
||||
monthNames: ['Január','Február','Marec','Apríl','Máj','Jún',
|
||||
'Júl','August','September','Október','November','December'],
|
||||
monthNamesShort: ['Jan','Feb','Mar','Apr','Máj','Jún',
|
||||
'Júl','Aug','Sep','Okt','Nov','Dec'],
|
||||
dayNames: ['Nedel\'a','Pondelok','Utorok','Streda','Štvrtok','Piatok','Sobota'],
|
||||
dayNamesShort: ['Ned','Pon','Uto','Str','Štv','Pia','Sob'],
|
||||
dayNamesMin: ['Ne','Po','Ut','St','Št','Pia','So'],
|
||||
weekHeader: 'Ty',
|
||||
dateFormat: 'dd.mm.yy',
|
||||
firstDay: 1,
|
||||
isRTL: false,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional['sk']);
|
||||
});
|
||||
24
resources/jquery.ui/i18n/jquery.ui.datepicker-sl.js
vendored
Normal file
24
resources/jquery.ui/i18n/jquery.ui.datepicker-sl.js
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/* Slovenian initialisation for the jQuery UI date picker plugin. */
|
||||
/* Written by Jaka Jancar (jaka@kubje.org). */
|
||||
/* c = č, s = š z = ž C = Č S = Š Z = Ž */
|
||||
jQuery(function($){
|
||||
$.datepicker.regional['sl'] = {
|
||||
closeText: 'Zapri',
|
||||
prevText: '<Prejšnji',
|
||||
nextText: 'Naslednji>',
|
||||
currentText: 'Trenutni',
|
||||
monthNames: ['Januar','Februar','Marec','April','Maj','Junij',
|
||||
'Julij','Avgust','September','Oktober','November','December'],
|
||||
monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun',
|
||||
'Jul','Avg','Sep','Okt','Nov','Dec'],
|
||||
dayNames: ['Nedelja','Ponedeljek','Torek','Sreda','Četrtek','Petek','Sobota'],
|
||||
dayNamesShort: ['Ned','Pon','Tor','Sre','Čet','Pet','Sob'],
|
||||
dayNamesMin: ['Ne','Po','To','Sr','Če','Pe','So'],
|
||||
weekHeader: 'Teden',
|
||||
dateFormat: 'dd.mm.yy',
|
||||
firstDay: 1,
|
||||
isRTL: false,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional['sl']);
|
||||
});
|
||||
23
resources/jquery.ui/i18n/jquery.ui.datepicker-sq.js
vendored
Normal file
23
resources/jquery.ui/i18n/jquery.ui.datepicker-sq.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* Albanian initialisation for the jQuery UI date picker plugin. */
|
||||
/* Written by Flakron Bytyqi (flakron@gmail.com). */
|
||||
jQuery(function($){
|
||||
$.datepicker.regional['sq'] = {
|
||||
closeText: 'mbylle',
|
||||
prevText: '<mbrapa',
|
||||
nextText: 'Përpara>',
|
||||
currentText: 'sot',
|
||||
monthNames: ['Janar','Shkurt','Mars','Prill','Maj','Qershor',
|
||||
'Korrik','Gusht','Shtator','Tetor','Nëntor','Dhjetor'],
|
||||
monthNamesShort: ['Jan','Shk','Mar','Pri','Maj','Qer',
|
||||
'Kor','Gus','Sht','Tet','Nën','Dhj'],
|
||||
dayNames: ['E Diel','E Hënë','E Martë','E Mërkurë','E Enjte','E Premte','E Shtune'],
|
||||
dayNamesShort: ['Di','Hë','Ma','Më','En','Pr','Sh'],
|
||||
dayNamesMin: ['Di','Hë','Ma','Më','En','Pr','Sh'],
|
||||
weekHeader: 'Ja',
|
||||
dateFormat: 'dd.mm.yy',
|
||||
firstDay: 1,
|
||||
isRTL: false,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional['sq']);
|
||||
});
|
||||
23
resources/jquery.ui/i18n/jquery.ui.datepicker-sr-SR.js
vendored
Normal file
23
resources/jquery.ui/i18n/jquery.ui.datepicker-sr-SR.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* Serbian i18n for the jQuery UI date picker plugin. */
|
||||
/* Written by Dejan Dimić. */
|
||||
jQuery(function($){
|
||||
$.datepicker.regional['sr-SR'] = {
|
||||
closeText: 'Zatvori',
|
||||
prevText: '<',
|
||||
nextText: '>',
|
||||
currentText: 'Danas',
|
||||
monthNames: ['Januar','Februar','Mart','April','Maj','Jun',
|
||||
'Jul','Avgust','Septembar','Oktobar','Novembar','Decembar'],
|
||||
monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun',
|
||||
'Jul','Avg','Sep','Okt','Nov','Dec'],
|
||||
dayNames: ['Nedelja','Ponedeljak','Utorak','Sreda','Četvrtak','Petak','Subota'],
|
||||
dayNamesShort: ['Ned','Pon','Uto','Sre','Čet','Pet','Sub'],
|
||||
dayNamesMin: ['Ne','Po','Ut','Sr','Če','Pe','Su'],
|
||||
weekHeader: 'Sed',
|
||||
dateFormat: 'dd/mm/yy',
|
||||
firstDay: 1,
|
||||
isRTL: false,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional['sr-SR']);
|
||||
});
|
||||
23
resources/jquery.ui/i18n/jquery.ui.datepicker-sr.js
vendored
Normal file
23
resources/jquery.ui/i18n/jquery.ui.datepicker-sr.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* Serbian i18n for the jQuery UI date picker plugin. */
|
||||
/* Written by Dejan Dimić. */
|
||||
jQuery(function($){
|
||||
$.datepicker.regional['sr'] = {
|
||||
closeText: 'Затвори',
|
||||
prevText: '<',
|
||||
nextText: '>',
|
||||
currentText: 'Данас',
|
||||
monthNames: ['Јануар','Фебруар','Март','Април','Мај','Јун',
|
||||
'Јул','Август','Септембар','Октобар','Новембар','Децембар'],
|
||||
monthNamesShort: ['Јан','Феб','Мар','Апр','Мај','Јун',
|
||||
'Јул','Авг','Сеп','Окт','Нов','Дец'],
|
||||
dayNames: ['Недеља','Понедељак','Уторак','Среда','Четвртак','Петак','Субота'],
|
||||
dayNamesShort: ['Нед','Пон','Уто','Сре','Чет','Пет','Суб'],
|
||||
dayNamesMin: ['Не','По','Ут','Ср','Че','Пе','Су'],
|
||||
weekHeader: 'Сед',
|
||||
dateFormat: 'dd/mm/yy',
|
||||
firstDay: 1,
|
||||
isRTL: false,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional['sr']);
|
||||
});
|
||||
23
resources/jquery.ui/i18n/jquery.ui.datepicker-sv.js
vendored
Normal file
23
resources/jquery.ui/i18n/jquery.ui.datepicker-sv.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* Swedish initialisation for the jQuery UI date picker plugin. */
|
||||
/* Written by Anders Ekdahl ( anders@nomadiz.se). */
|
||||
jQuery(function($){
|
||||
$.datepicker.regional['sv'] = {
|
||||
closeText: 'Stäng',
|
||||
prevText: '«Förra',
|
||||
nextText: 'Nästa»',
|
||||
currentText: 'Idag',
|
||||
monthNames: ['Januari','Februari','Mars','April','Maj','Juni',
|
||||
'Juli','Augusti','September','Oktober','November','December'],
|
||||
monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun',
|
||||
'Jul','Aug','Sep','Okt','Nov','Dec'],
|
||||
dayNamesShort: ['Sön','Mån','Tis','Ons','Tor','Fre','Lör'],
|
||||
dayNames: ['Söndag','Måndag','Tisdag','Onsdag','Torsdag','Fredag','Lördag'],
|
||||
dayNamesMin: ['Sö','Må','Ti','On','To','Fr','Lö'],
|
||||
weekHeader: 'Ve',
|
||||
dateFormat: 'yy-mm-dd',
|
||||
firstDay: 1,
|
||||
isRTL: false,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional['sv']);
|
||||
});
|
||||
23
resources/jquery.ui/i18n/jquery.ui.datepicker-ta.js
vendored
Normal file
23
resources/jquery.ui/i18n/jquery.ui.datepicker-ta.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* Tamil (UTF-8) initialisation for the jQuery UI date picker plugin. */
|
||||
/* Written by S A Sureshkumar (saskumar@live.com). */
|
||||
jQuery(function($){
|
||||
$.datepicker.regional['ta'] = {
|
||||
closeText: 'மூடு',
|
||||
prevText: 'முன்னையது',
|
||||
nextText: 'அடுத்தது',
|
||||
currentText: 'இன்று',
|
||||
monthNames: ['தை','மாசி','பங்குனி','சித்திரை','வைகாசி','ஆனி',
|
||||
'ஆடி','ஆவணி','புரட்டாசி','ஐப்பசி','கார்த்திகை','மார்கழி'],
|
||||
monthNamesShort: ['தை','மாசி','பங்','சித்','வைகா','ஆனி',
|
||||
'ஆடி','ஆவ','புர','ஐப்','கார்','மார்'],
|
||||
dayNames: ['ஞாயிற்றுக்கிழமை','திங்கட்கிழமை','செவ்வாய்க்கிழமை','புதன்கிழமை','வியாழக்கிழமை','வெள்ளிக்கிழமை','சனிக்கிழமை'],
|
||||
dayNamesShort: ['ஞாயிறு','திங்கள்','செவ்வாய்','புதன்','வியாழன்','வெள்ளி','சனி'],
|
||||
dayNamesMin: ['ஞா','தி','செ','பு','வி','வெ','ச'],
|
||||
weekHeader: 'Не',
|
||||
dateFormat: 'dd/mm/yy',
|
||||
firstDay: 1,
|
||||
isRTL: false,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional['ta']);
|
||||
});
|
||||
23
resources/jquery.ui/i18n/jquery.ui.datepicker-th.js
vendored
Normal file
23
resources/jquery.ui/i18n/jquery.ui.datepicker-th.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* Thai initialisation for the jQuery UI date picker plugin. */
|
||||
/* Written by pipo (pipo@sixhead.com). */
|
||||
jQuery(function($){
|
||||
$.datepicker.regional['th'] = {
|
||||
closeText: 'ปิด',
|
||||
prevText: '« ย้อน',
|
||||
nextText: 'ถัดไป »',
|
||||
currentText: 'วันนี้',
|
||||
monthNames: ['มกราคม','กุมภาพันธ์','มีนาคม','เมษายน','พฤษภาคม','มิถุนายน',
|
||||
'กรกฏาคม','สิงหาคม','กันยายน','ตุลาคม','พฤศจิกายน','ธันวาคม'],
|
||||
monthNamesShort: ['ม.ค.','ก.พ.','มี.ค.','เม.ย.','พ.ค.','มิ.ย.',
|
||||
'ก.ค.','ส.ค.','ก.ย.','ต.ค.','พ.ย.','ธ.ค.'],
|
||||
dayNames: ['อาทิตย์','จันทร์','อังคาร','พุธ','พฤหัสบดี','ศุกร์','เสาร์'],
|
||||
dayNamesShort: ['อา.','จ.','อ.','พ.','พฤ.','ศ.','ส.'],
|
||||
dayNamesMin: ['อา.','จ.','อ.','พ.','พฤ.','ศ.','ส.'],
|
||||
weekHeader: 'Wk',
|
||||
dateFormat: 'dd/mm/yy',
|
||||
firstDay: 0,
|
||||
isRTL: false,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional['th']);
|
||||
});
|
||||
23
resources/jquery.ui/i18n/jquery.ui.datepicker-tr.js
vendored
Normal file
23
resources/jquery.ui/i18n/jquery.ui.datepicker-tr.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* Turkish initialisation for the jQuery UI date picker plugin. */
|
||||
/* Written by Izzet Emre Erkan (kara@karalamalar.net). */
|
||||
jQuery(function($){
|
||||
$.datepicker.regional['tr'] = {
|
||||
closeText: 'kapat',
|
||||
prevText: '<geri',
|
||||
nextText: 'ileri>',
|
||||
currentText: 'bugün',
|
||||
monthNames: ['Ocak','Şubat','Mart','Nisan','Mayıs','Haziran',
|
||||
'Temmuz','Ağustos','Eylül','Ekim','Kasım','Aralık'],
|
||||
monthNamesShort: ['Oca','Şub','Mar','Nis','May','Haz',
|
||||
'Tem','Ağu','Eyl','Eki','Kas','Ara'],
|
||||
dayNames: ['Pazar','Pazartesi','Salı','Çarşamba','Perşembe','Cuma','Cumartesi'],
|
||||
dayNamesShort: ['Pz','Pt','Sa','Ça','Pe','Cu','Ct'],
|
||||
dayNamesMin: ['Pz','Pt','Sa','Ça','Pe','Cu','Ct'],
|
||||
weekHeader: 'Hf',
|
||||
dateFormat: 'dd.mm.yy',
|
||||
firstDay: 1,
|
||||
isRTL: false,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional['tr']);
|
||||
});
|
||||
23
resources/jquery.ui/i18n/jquery.ui.datepicker-uk.js
vendored
Normal file
23
resources/jquery.ui/i18n/jquery.ui.datepicker-uk.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* Ukrainian (UTF-8) initialisation for the jQuery UI date picker plugin. */
|
||||
/* Written by Maxim Drogobitskiy (maxdao@gmail.com). */
|
||||
jQuery(function($){
|
||||
$.datepicker.regional['uk'] = {
|
||||
closeText: 'Закрити',
|
||||
prevText: '<',
|
||||
nextText: '>',
|
||||
currentText: 'Сьогодні',
|
||||
monthNames: ['Січень','Лютий','Березень','Квітень','Травень','Червень',
|
||||
'Липень','Серпень','Вересень','Жовтень','Листопад','Грудень'],
|
||||
monthNamesShort: ['Січ','Лют','Бер','Кві','Тра','Чер',
|
||||
'Лип','Сер','Вер','Жов','Лис','Гру'],
|
||||
dayNames: ['неділя','понеділок','вівторок','середа','четвер','п’ятниця','субота'],
|
||||
dayNamesShort: ['нед','пнд','вів','срд','чтв','птн','сбт'],
|
||||
dayNamesMin: ['Нд','Пн','Вт','Ср','Чт','Пт','Сб'],
|
||||
weekHeader: 'Не',
|
||||
dateFormat: 'dd/mm/yy',
|
||||
firstDay: 1,
|
||||
isRTL: false,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional['uk']);
|
||||
});
|
||||
23
resources/jquery.ui/i18n/jquery.ui.datepicker-vi.js
vendored
Normal file
23
resources/jquery.ui/i18n/jquery.ui.datepicker-vi.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* Vietnamese initialisation for the jQuery UI date picker plugin. */
|
||||
/* Translated by Le Thanh Huy (lthanhhuy@cit.ctu.edu.vn). */
|
||||
jQuery(function($){
|
||||
$.datepicker.regional['vi'] = {
|
||||
closeText: 'Đóng',
|
||||
prevText: '<Trước',
|
||||
nextText: 'Tiếp>',
|
||||
currentText: 'Hôm nay',
|
||||
monthNames: ['Tháng Một', 'Tháng Hai', 'Tháng Ba', 'Tháng Tư', 'Tháng Năm', 'Tháng Sáu',
|
||||
'Tháng Bảy', 'Tháng Tám', 'Tháng Chín', 'Tháng Mười', 'Tháng Mười Một', 'Tháng Mười Hai'],
|
||||
monthNamesShort: ['Tháng 1', 'Tháng 2', 'Tháng 3', 'Tháng 4', 'Tháng 5', 'Tháng 6',
|
||||
'Tháng 7', 'Tháng 8', 'Tháng 9', 'Tháng 10', 'Tháng 11', 'Tháng 12'],
|
||||
dayNames: ['Chủ Nhật', 'Thứ Hai', 'Thứ Ba', 'Thứ Tư', 'Thứ Năm', 'Thứ Sáu', 'Thứ Bảy'],
|
||||
dayNamesShort: ['CN', 'T2', 'T3', 'T4', 'T5', 'T6', 'T7'],
|
||||
dayNamesMin: ['CN', 'T2', 'T3', 'T4', 'T5', 'T6', 'T7'],
|
||||
weekHeader: 'Tu',
|
||||
dateFormat: 'dd/mm/yy',
|
||||
firstDay: 0,
|
||||
isRTL: false,
|
||||
showMonthAfterYear: false,
|
||||
yearSuffix: ''};
|
||||
$.datepicker.setDefaults($.datepicker.regional['vi']);
|
||||
});
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue