diff --git a/.dir-locals.el b/.dir-locals.el new file mode 100644 index 00000000000..a8a4cb6a815 --- /dev/null +++ b/.dir-locals.el @@ -0,0 +1,4 @@ +((nil . ((buffer-file-coding-system . utf-8-dos))) + (js-mode . ((js-indent-level . 4))) + (css-mode . ((css-indent-offset . 4))) + (less-css-mode . ((css-indent-offset . 4)))) diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000000..4be1c918527 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Disable LF normalization for all files +* -text \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000000..77d98bfa233 --- /dev/null +++ b/.gitignore @@ -0,0 +1,27 @@ +*.tmp +*.gpState +*.pdb +*.suo +*.swp +*.user +*.mdb +obj/ +bin/ +dist/ +.DS_Store +.JustCode +.bundle/ +.livereload +!src/jquery.min.js +styles/web/*.css +styles/mobile/*.css +styles/dataviz/*.min.css +styles/*.css +!styles/web/kendo.rtl.css +node_modules +./tags +*-test-results.xml +.listen_test +.tern-port +kendo-cdn +src/.tern-port diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000000..3844f7fdb54 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "build/less-js"] + path = build/less-js + url = git@github.com:telerik/less.js.git diff --git a/Gruntfile.js b/Gruntfile.js new file mode 100644 index 00000000000..1263f56e88e --- /dev/null +++ b/Gruntfile.js @@ -0,0 +1,227 @@ +var META = require("./build/kendo-meta.js"); +var TESTS = require("./build/grunt/tests.js"); +var PATH = require("path"); + +module.exports = function(grunt) { + grunt.loadNpmTasks('grunt-karma'); + grunt.loadNpmTasks('grunt-debug-task'); + grunt.loadNpmTasks('grunt-contrib-jshint'); + grunt.loadNpmTasks('grunt-contrib-copy'); + grunt.loadTasks('build/grunt/tasks'); + + function addSrc(f) { + return PATH.join("src", f); + } + + var browsers = ['Chrome']; + + var tests = [ "tests/**/*.js" ]; + + var browserOption = grunt.option('browser'); + var testsOption = grunt.option('tests'); + var jqueryOption = grunt.option('jquery'); + var jquery = 'src/jquery.js'; + + if (testsOption) { + tests = [ testsOption ]; + } + + if (jqueryOption) { + jquery = "http://code.jquery.com/jquery-" + jqueryOption + ".min.js"; + } + + TESTS.beforeTestFiles.push(jquery); + TESTS.beforeTestFiles.push('tests/jquery.mockjax.js'); + + if (browserOption) { + browsers = [ browserOption ]; + } + + var reporters = [ 'progress' ]; + + if (grunt.option('junit-results')) { + reporters.push('junit'); + } + + var jshint = grunt.file.readJSON('build/grunt/jshint.json'); + + var files = grunt.option('files'); + + jshint.files = files ? files.split(",") : jshint.files; + + // all files (including subfiles like editor/main.js etc.) + var allKendoFiles = META.loadAll().map(addSrc); + + // files directly in src/ + var mainKendoFiles = META.listKendoFiles().map(addSrc); + + // Project configuration. + grunt.initConfig({ + + pkg: grunt.file.readJSON('package.json'), + jshint: jshint, + karma: { + options: { + browserStack: { + username: 'petyoivanov', + accessKey: 'QBgixFUrxrEQyY2nKVqb' + }, + sauceLabs: { + username: 'petyosi', + accessKey: '2e136bfe-8507-4ac2-b201-1c2f53003669', + startConnect: true, + testName: 'zergling' + }, + customLaunchers: { + bs_chrome: { + base: 'BrowserStack', + browser: 'chrome', + browser_version: 'latest', + os: 'OS X', + os_version: 'Mavericks' + }, + sl_chrome: { + base: 'SauceLabs', + browserName: 'chrome', + version: '31' + } + }, + reportSlowerThan: 500, + basePath: '', + frameworks: ['qunit'], + preprocessors: { + 'tests/**/.html': [], + 'tests/**/*-fixture.html': ['html2js'], + }, + reporters: ['progress'], + colors: true, + autoWatch: true, + browsers: browsers, + captureTimeout: 60000, + browserNoActivityTimeout: 30000, + singleRun: grunt.option('single-run') + }, + ci: { + options: { + reporters: ['progress', 'junit'], + + junitReporter: { + outputFile: grunt.option('junit-results') + }, + + singleRun: true, + + files: [].concat( + TESTS.compiledStyleSheets, + TESTS.beforeTestFiles, + [ 'dist/js/kendo.all.min.js', 'dist/js/kendo.aspnetmvc.min.js' ], + TESTS.afterTestFiles, + tests + ) + } + }, + unit: { + options: { + files: [].concat( + TESTS.beforeTestFiles, + allKendoFiles, + TESTS.afterTestFiles, + tests + ) + } + } + }, + + copy: { + jquery: { + files: [{ + expand: true, + cwd: "src/", + src: [ "jquery.*" ], + dest: '<%= kendo.options.jsDestDir %>/', + }] + }, + timezones: { + files: [{ + expand: true, + cwd: "src/", + src: "kendo.timezones.js" , + dest: '<%= kendo.options.jsDestDir %>/', + }] + }, + css_assets: { + files: [{ + expand: true, + cwd: "styles", + src: ["**/*.less", "**/*.woff", "**/*.ttf", "**/*.png", "**/*.gif", "**/*.css" ], + dest: '<%= kendo.options.stylesDestDir %>/', + }] + } + }, + + kendo: { + options: { + destDir: "dist", + jsDestDir: PATH.join("dist", "js"), + stylesDestDir: PATH.join("dist", "styles") + }, + min: { + src: mainKendoFiles, + dest: "<%= kendo.options.jsDestDir %>", + ext: ".min.js", + }, + full: { + src: mainKendoFiles, + dest: "<%= kendo.options.jsDestDir %>", + ext: ".js", + }, + download_builder: { + src: mainKendoFiles, + ext: ".min.js", + dest: PATH.join("dist", "download-builder", "content", "js"), + }, + config: { + src: mainKendoFiles, + dest: "download-builder/config/kendo-config.json" + }, + cultures: { + src: [ "src/cultures/kendo.culture.*.js", + "!src/cultures/kendo.culture.*.min.js" ], + dest: "<%= kendo.options.jsDestDir %>/cultures", + }, + }, + + custom: { + options: { + destDir: "<%= kendo.options.jsDestDir %>", + }, + }, + + less: { + options: { + destDir: "<%= kendo.options.destDir %>", + }, + compile: { + src: [ "styles/**/kendo*.less" ], + } + }, + + license: { + apply: { + src: [ "<%= kendo.options.destDir %>/**/*" ], + filter: function(src) { + return PATH.basename(src).match(/^kendo(.+)(js|css|less)$/); + } + } + } + + }); + + // Default task(s). + grunt.registerTask('default', ['karma:unit']); + grunt.registerTask("ci", [ 'kendo:min', 'styles', 'copy:jquery', 'copy:timezones', 'karma:ci' ]); + grunt.registerTask('tests', [ 'karma:unit' ]); + grunt.registerTask('styles', [ 'copy:css_assets', 'less' ]); + grunt.registerTask('all', [ 'kendo', 'copy:jquery', 'copy:timezones' ]); + grunt.registerTask('build', ['copy:jquery', 'copy:timezones', 'kendo:min', 'kendo:full', 'kendo:cultures', 'styles', 'license']); +}; diff --git a/README b/README new file mode 100644 index 00000000000..004f63ab18c --- /dev/null +++ b/README @@ -0,0 +1,6 @@ +Contents of Kendo UI zip file distribution: + +/examples - Kendo UI quick start demos +/js - Kendo UI minified javascript files +/source - Kendo UI complete source code +/styles - Kendo UI minified css styles diff --git a/VERSION b/VERSION new file mode 100644 index 00000000000..c7bb9758a9b --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +{ "year": 2014, "release": 1 } diff --git a/build/grunt/jshint.json b/build/grunt/jshint.json new file mode 100644 index 00000000000..38ec0fadf4e --- /dev/null +++ b/build/grunt/jshint.json @@ -0,0 +1,17 @@ +{ + "files": [ + "src/kendo*.js", + "src/editor/*.js", + "src/dataviz/**/*.js", + "tests/map/layers/helpers.js", + "tests/**/test-helper.js", + "demos/mvc/content/shared/js/examples.js", + "demos/mvc/content/shared/js/console.js", + "themebuilder/bootstrap.js", + "themebuilder/scripts/themebuilder.js", + "themebuilder/scripts/constants.js" + ], + "options": { + "ignores": ["**/*.min.js", "src/kendo.web.js", "src/kendo.aspnetmvc.js", "src/kendo.all.js", "src/kendo.mobile.js", "src/kendo.dataviz.js", "src/kendo.timezones.js", "src/kendo.icenium.js", "src/kendo.model.js", "src/kendo.winjs.js", "src/kendo.editor.js" ] + } +} diff --git a/build/grunt/tasks/kendo.js b/build/grunt/tasks/kendo.js new file mode 100644 index 00000000000..635f78a14a1 --- /dev/null +++ b/build/grunt/tasks/kendo.js @@ -0,0 +1,168 @@ +var FS = require("fs"); +var PATH = require("path"); +var META = require("../../kendo-meta.js"); + +function outdated(source, dest) { + if (Array.isArray(source)) { + for (var i = 0; i < source.length; ++i) { + if (outdated(source[i], dest)) + return true; + } + return false; + } + try { + var sstat = FS.statSync(source); + var dstat = FS.statSync(dest); + return sstat.mtime.getTime() > dstat.mtime.getTime(); + } catch(ex) { + return true; + } +} + +module.exports = function(grunt) { + + function makeSources(task) { + task.files.forEach(function(f){ + var destDir = f.dest; + var ext = f.ext; + f.src.forEach(function(f){ + var basename = PATH.basename(f, PATH.extname(f)); + var dest = PATH.join(destDir, basename + ext); + var comp = META.getKendoFile(f.replace(/^src\//, "")), code; + var srcFiles = comp.getBuildDeps().map(function(f){ + return "src/" + f; + }); + if (outdated(srcFiles, dest)) { + if (comp.isBundle() && task.target == "download_builder") { + return; // bundles not needed here + } + grunt.log.writeln("Making " + dest); + if (task.target == "min") { + code = comp.buildMinSource(); + var map = comp.buildMinSourceMap(); + grunt.file.write(dest + ".map", map); + } else if (task.target == "full") { + code = comp.buildFullSource(); + } else if (task.target == "download_builder") { + code = comp.buildMinSource_noAMD(); + } + grunt.file.write(dest, code); + } + }); + }); + } + + function makeBundle(task, bundle, components, force) { + bundle = "kendo." + bundle + ".js"; + var bundleMin = bundle.replace(/\.js$/, ".min.js"); + var dest = PATH.join(task.options().destDir, bundle); + var destMin = PATH.join(task.options().destDir, bundleMin); + var files = components.map(function(f){ return PATH.join("src", f) }); + + if (grunt.option("show")) { + META.loadComponents(components).forEach(function(f){ + var comp = META.getKendoFile(f); + if (!comp.isSubfile()) { + console.log(comp.filename()); + } + }); + return; + } + + if (force || outdated(files, dest)) { + grunt.log.writeln("Making bundle " + dest); + var data = META.bundleFiles(components, bundle); + grunt.file.write(dest, data.code); + } + + if (force || outdated(files, destMin)) { + grunt.log.writeln("Making bundle " + destMin); + var data = META.bundleFiles(components, bundleMin, true); + grunt.file.write(destMin, data.code); + grunt.file.write(destMin + ".map", data.map); + } + } + + function makeKendoConfig(task) { + var files = getSrc(task); + var dest = task.files[0].dest; + if (outdated(files, dest)) { + grunt.log.writeln("Building kendo-config.json"); + var data = META.buildKendoConfig(); + grunt.file.write(dest, JSON.stringify(data, null, 2)); + } + } + + function makeCultures(task) { + var destDir = task.files[0].dest; + var files = getSrc(task); + files.forEach(function(f){ + var basename = PATH.basename(f); + var dest = PATH.join(destDir, basename); + var destMin = dest.replace(/\.js$/, ".min.js"); + if (outdated(f, dest)) { + var code = grunt.file.read(f, { encoding: "utf8" }); + + // cultures depend on kendo.core but we can't declare that in the AMD wrapper because people would + // frequently load cultures along with kendo.all.js which already includes kendo.core. Therefore we + // initialize window.kendo here if it's not present. + code = code.replace(/^(\s*)kendo\.cultures\[.*?\]\s*=/m, function(s, indent){ + return indent + "var kendo = window.kendo || (window.kendo = { cultures: {} });\n" + s; + }); + + code = META.wrapAMD([], code); + grunt.log.writeln("Writing " + dest); + grunt.file.write(dest, code); + + var ast = META.minify(code); + code = ast.print_to_string(); + grunt.log.writeln("Writing " + destMin); + grunt.file.write(destMin, code); + } + }); + } + + function getSrc(task) { + return task.files.reduce(function(a, f){ + f.src.forEach(function(f){ + a.push(f); + }); + return a; + }, []); + } + + grunt.registerMultiTask("kendo", "Kendo UI build task", function(){ + var task = this; + switch (task.target) { + case "min": + case "full": + case "download_builder": + makeSources(task); + break; + + case "config": + makeKendoConfig(task); + break; + + case "cultures": + makeCultures(task); + break; + } + }); + + grunt.registerTask("custom", "Custom Kendo build", function(){ + var task = this; + var files = task.args[0].trim().split(/\s*,\s*/); + files = files.map(function(c){ + var name = "kendo." + c + ".js"; + var comp = META.getKendoFile(name); + try { + comp.getOrigCode(); + } catch(ex) { + throw new Error("Can't find Kendo file: " + name); + } + return name; + }); + makeBundle(task, "custom", files, true); + }); +}; diff --git a/build/grunt/tasks/less.js b/build/grunt/tasks/less.js new file mode 100644 index 00000000000..e158dc41ec2 --- /dev/null +++ b/build/grunt/tasks/less.js @@ -0,0 +1,32 @@ +var PATH = require("path"); +var LESS = require("../../less-js"); +var CSSMIN = require("cssmin").cssmin; + +module.exports = function(grunt) { + grunt.registerMultiTask("less", "Build CSS styles", function(){ + var task = this; + var destDir = task.options().destDir; + task.files.forEach(function(f){ + f.src.forEach(function(f){ + var base = PATH.dirname(f); + var p = new LESS.Parser({ + paths : [ base ], + filename : PATH.basename(f), + syncImport: true + }); + grunt.log.writeln("Compiling stylesheet: " + f); + p.parse(grunt.file.read(f), function(err, tree){ + try { + var css = tree.toCSS(); + grunt.file.write(PATH.join(destDir, f.replace(/\.less$/, ".css")), css); + var cssmin = CSSMIN(css); + grunt.file.write(PATH.join(destDir, f.replace(/\.less$/, ".min.css")), cssmin); + } catch(ex) { + grunt.log.error("Can't LESS-compile " + f); + console.log(ex); + } + }); + }); + }); + }); +} diff --git a/build/grunt/tasks/license.js b/build/grunt/tasks/license.js new file mode 100644 index 00000000000..df169f3a3d0 --- /dev/null +++ b/build/grunt/tasks/license.js @@ -0,0 +1,17 @@ +var PATH = require("path"); +var LESS = require("../../less-js"); +var CSSMIN = require("cssmin").cssmin; +var licensePath = PATH.join("resources", "legal", "public-license.txt"); + +module.exports = function(grunt) { + grunt.registerMultiTask("license", "Apply license to built files", function() { + var licenseContents = grunt.template.process(grunt.file.read(licensePath), { data: { year: grunt.template.today('yyyy') }}); + + this.files.forEach(function(f) { + f.src.forEach(function(file) { + var contents = licenseContents + "\n" + grunt.file.read(file); + grunt.file.write(file, contents); + }); + }); + }); +} diff --git a/build/grunt/tests.js b/build/grunt/tests.js new file mode 100644 index 00000000000..88679a86a6e --- /dev/null +++ b/build/grunt/tests.js @@ -0,0 +1,24 @@ +exports.beforeTestFiles = [ + { pattern: 'styles/**/*.*', watched: true, included: false }, + { pattern: 'tests/router/sandbox.html', watched: true, included: false }, + { pattern: 'tests/window/blank.html', watched: true, included: false }, + { pattern: 'tests/**/*-fixture.html' } +]; + +exports.afterTestFiles = [ + 'src/kendo.timezones.js', + 'src/cultures/kendo.culture.de-DE.js', + 'src/cultures/kendo.culture.bg-BG.js', + 'src/cultures/kendo.culture.en-ZA.js', + "src/cultures/kendo.culture.es-ES.js", + 'tests/kendo-test-helpers.js', + 'tests/**/test-helper.js', + 'build/less-js/dist/less-1.6.0.min.js' +]; + +exports.compiledStyleSheets = [ + 'dist/styles/web/kendo.common.core.css', + 'dist/styles/web/kendo.rtl.css' +]; + + diff --git a/build/kendo-meta.js b/build/kendo-meta.js new file mode 100644 index 00000000000..92dd8fb5b1b --- /dev/null +++ b/build/kendo-meta.js @@ -0,0 +1,822 @@ +var PATH = require("path"); +var FS = require("fs"); +var SYS = require("util"); +var U2 = require("uglify-js"); + +var SRCDIR = PATH.join(__dirname, "..", "src"); + +var AMD_WRAPPER = "(function(f, define){\n\ + define($DEPS, f);\n\ +})(function(){\n\ +\n\ +$CODE\n\ +\n\ +return window.kendo;\n\ +\n\ +}, typeof define == 'function' && define.amd ? define : function(_, f){ f(); });"; + +var getKendoFile = (function() { + + function KendoFile(filename) { + this._filename = filename; + } + + KendoFile.prototype = { + + filename: function() { + return this._filename; + }, + + dirname: cachedProperty("dirname", function(){ + return PATH.dirname(this.getFullFileName()); + }), + + getFullFileName: cachedProperty("getFullFileName", function() { + return PATH.join(SRCDIR, this.filename()); + }), + + getOrigCode: cachedProperty("getOrigCode", function(){ + var code = FS.readFileSync(this.getFullFileName(), "utf8"); + code = code.replace(/\r/g, ""); // + return code; + }), + + getOrigAST: cachedProperty("getOrigAST", function(){ + return U2_parse(this.getOrigCode(), { + filename: this.filename() + }); + }), + + isBundle: cachedProperty("isBundle", function(){ + var ast = this.getAMDFactory().factory; + return walkAST(ast, function(node){ + if (node instanceof U2.AST_Directive && node.value == "bundle all") + this.exit(true); + if (node !== ast) + return true; // don't go inside + }) || false; + }), + + getMeta: cachedProperty("getMeta", function(){ + var self = this; + var meta = walkAST(self.getOrigAST(), function(node){ + if (isMetaNode(node)) { + var meta = (1,eval)("(" + node.definitions[0].value.print_to_string() + ")"); + meta.source = self.filename().replace(/\.js$/i, ".min.js"); + meta.widgets = extract_widget_info(self.getFullAST()); + this.exit(meta); + } + }); + return meta; + }), + + // get the direct AMD dependencies, as extracted from the + // code. They will be relative to this component and without + // .js extension. + getAMDDeps: cachedProperty("getAMDDeps", function(){ + var deps = []; + function define(d, factory) { + if (Array.isArray(d)) deps = d; + } + define.amd = true; + try { + new Function("define", this.getOrigCode())(define); + } catch(ex) { + SYS.error("*** Can't determine AMD deps for " + this.filename() + ". Failed to evaluate."); + console.log(" [", ex, "]"); + } + return deps; + }), + + getAMDFactory: cachedProperty("getAMDFactory", function(){ + return walkAST(this.getOrigAST(), findDefine); + }), + + _makeAllDeps: function(maxLevel) { + return loadComponent(this.filename(), this.dirname(), [], maxLevel); + }, + + // returns an array of file names -- *all* files required to + // load this component, including internal files (for split + // components). + getAllFileDeps: cachedProperty("getAllFileDeps", function(){ + return this._makeAllDeps(); + }), + + // returns an array of file names -- only the files that this + // component is built from, such as editor/main.js etc. + // Currently we assume these files are files not directly in + // src/ dir, but in some subdirectory -- hence we get all + // names and filter out those directly in src/. + getCompFiles: cachedProperty("getCompFiles", function(){ + return this._makeAllDeps(2).filter(function(f){ + var dir = PATH.dirname(f); + return dir != "." && dir != ""; + }); + }), + + getDirectCompDeps: cachedProperty("getDirectCompDeps", function(){ + var self = this, a = self._makeAllDeps(2); // level 2 means load upto directly required components. + return a.filter(function(f){ + comp = getKendoFile(f); + return comp !== self && !comp.isSubfile(); + }); + }), + + // Generates the complete (readable) source of this component. + // Merge any subfiles, and remove them from the `define` list, + // leaving there only other toplevel components. Drops + // __meta__ too. Drops `define` wrapper from the subfiles. + buildFullSource: cachedProperty("buildFullSource", function(){ + if (this.isBundle()) { + return bundleFiles(this.getDirectCompDeps(), this.filename()).code; + } else { + return wrapAMD( + fileNamesToAMDDeps(this.getDirectCompDeps()), + this.getFullCode() + ); + } + }), + + buildMinAST: cachedProperty("buildMinAST", function(){ + if (this.isBundle()) { + return bundleFiles_getMinAST(this.getDirectCompDeps()); + } else { + var ast = cloneAST(this.getFullAST()); + var deps = fileNamesToAMDDeps(this.getDirectCompDeps(), true); + ast = get_wrapper().wrap(deps, ast); + return minify(ast); + } + }), + + getBuildDeps: cachedProperty("getBuildDeps", function(){ + return loadComponents([ this.filename() ], this.isBundle() ? null : 2); + }), + + buildMinAST_noAMD: cachedProperty("buildMinAST_noAMD", function(){ + var ast = this.buildMinAST(); + var f = walkAST(ast, findDefine).factory; + var stats = []; + walkAST(f, function(node){ + if (node !== f) { + if (node instanceof U2.AST_Return) { + var p = node.value; + while (p instanceof U2.AST_Seq) { + stats.push(new U2.AST_SimpleStatement({ body: p.car })); + p = p.cdr; + } + if (p && p.has_side_effects(U2.Compressor({ unsafe: true, pure_getters: true }))) { + stats.push(new U2.AST_SimpleStatement({ body: p })); + } + this.exit(); + } + else if (node instanceof U2.AST_Statement) { + stats.push(node); + return true; + } + } + }); + if (stats.length == 0) { + throw new Error("Can't find main code for " + this.filename()); + } + return new U2.AST_Toplevel({ body: stats }); + }), + + buildMinSource_noAMD: cachedProperty("buildMinSource_noAMD", function(){ + return this.buildMinAST_noAMD().print_to_string(); + }), + + buildMinSource: cachedProperty("buildMinSource", function(){ + var source_map = this._source_map = U2.SourceMap({ + file: this.filename().replace(/\.js$/i, ".min.js"), + // orig_line_diff: 8, + // dest_line_diff: 8, + root: "../../src/" // XXX: what's the source map root? + }); + return this.buildMinAST().print_to_string({ + source_map: source_map + }); + }), + + buildMinSourceMap: cachedProperty("buildMinSourceMap", function(){ + this.buildMinSource(); + return this._source_map.toString(); + }), + + getFullAST: cachedProperty("getFullAST", function(){ + var self = this; + if (self.isSubfile()) { + throw new Error("getFullAST doesn't make sense for subfiles: " + self.filename()); + } + var deps = this.getCompFiles(); + var ast = this.getAMDFactory().factory; + if (deps.length == 0) return ast; + ast = cloneAST(ast); + ast.transform(new U2.TreeTransformer(function(node, descend){ + if (node === ast) { + descend(node, this); + var stats = []; + deps.forEach(function(f){ + var comp = getKendoFile(f); + var f = comp.getAMDFactory().factory; + stats.push.apply(stats, f.body); + }); + node.body.unshift.apply(node.body, stats); + return node; + } + if (isMetaNode(node)) + return U2.MAP.skip; + if (node instanceof U2.AST_Return && (/^return (window\.)?kendo/.test(node.print_to_string()))) + return U2.MAP.skip; + if (node instanceof U2.AST_Statement) + return node; + })); + return ast; + }), + + getFullCode: cachedProperty("getFullCode", function() { + var self = this; + if (self.isSubfile()) { + throw new Error("getFullCode doesn't make sense for subfiles: " + self.filename()); + } + + var my_code = ""; + var ast = this.getAMDFactory().factory; + if (ast.body.length > 0) { + my_code = this.getOrigCode(); + + var replacements = []; + replacements.push( + { begin : 0, + end : ast.body[0].start.pos, + text : "" + }, + { begin : ast.body[ast.body.length - 1].end.endpos, + end : my_code.length, + text : "" } + ); + + walkAST(ast, function(node){ + if (isMetaNode(node)) { + replacements.push({ + begin : node.start.pos, + end : node.end.endpos, + text : "" + }); + return true; + } + if (node instanceof U2.AST_Return && + (/^return (window\.)?kendo/.test(node.print_to_string()))) { + replacements.push({ + begin : node.start.pos, + end : node.end.endpos, + text : "" + }); + return true; + } + if (node instanceof U2.AST_Statement && node !== ast) + return true; // don't dive + }); + + my_code = replaceInString(my_code, replacements); + } + + var files = this.getCompFiles().map(function(f){ + var comp = getKendoFile(f); + return comp.getMainCode(); + }); + files.push(my_code); + + return files.join("\n\n").trim(); + }), + + getMainCode: cachedProperty("getMainCode", function(){ + var ast = this.getAMDFactory().factory; + if (ast.body.length == 0) return ""; + return this.getOrigCode().substring(ast.body[0].start.pos, ast.body[ast.body.length - 1].end.endpos); + }), + + // return true if this is a "subfile", i.e. editor/main.js + isSubfile: function() { + var dir = PATH.dirname(this.filename()); + return !(dir == "." || dir == ""); + } + }; + + function unwrapFunction(code) { + return code.replace(/^[^\{]*?{|}[^\}]*?$/g, "").trim(); + } + + var FILES = {}; + function getKendoFile(filename) { + return FILES[filename] || ( + FILES[filename] = new KendoFile(filename) + ); + } + + return getKendoFile; +})(); + +function U2_parse(code, options) { + // if (options) { + // SYS.error("--- parsing " + options.filename); + // } + try { + code = code.replace(/\r/g, ""); // + return U2.parse(code, options); + } catch(ex) { + if (ex instanceof U2.JS_Parse_Error) { + console.log(options.filename); + console.log(ex); + } + } +} + +var get_wrapper = (function(wrapper){ + return function() { + if (wrapper) return wrapper; + wrapper = U2_parse(AMD_WRAPPER); + wrapper.wrap = function(deps, cont) { + return wrapper.transform(new U2.TreeTransformer( + null, // need no 'before' + function after(node){ + if (node instanceof U2.AST_SymbolRef && node.name == "$DEPS") { + return new U2.AST_Array({ + elements: deps.map(function(x){ + return new U2.AST_String({ value: x }); + }) + }); + } + if (node instanceof U2.AST_SimpleStatement + && node.body instanceof U2.AST_SymbolRef + && node.body.name == "$CODE") { + return U2.MAP.splice(cont.body); + } + } + )); + }; + return wrapper; + }; +})(); + +function wrapAMD(deps, code) { + var v = { + CODE: code, + DEPS: beautify(deps), + }; + return AMD_WRAPPER.replace(/\$(CODE|DEPS)/g, function(s, p){ + return v[p]; + }); +}; + +function isMetaNode(node) { + return node instanceof U2.AST_Var + && node.definitions.length == 1 + && node.definitions[0].name.name == "__meta__"; +}; + +function fileNamesToAMDDeps(files, min) { + return files.map(function(filename){ + filename = filename.replace(/^(\.\/)?/, "./"); // make sure it starts with ./ + filename = filename.replace(/\.js$/i, ""); // drop the extension + if (min) filename += ".min"; // minified? + return filename; + }); +}; + +function replaceInString(str, replacements) { + replacements = U2.mergeSort(replacements, function(a, b){ + return a.begin - b.begin; + }); + for (var i = replacements.length; --i >= 0;) { + var r = replacements[i]; + str = str.substr(0, r.begin) + r.text + str.substr(r.end); + } + return str; +}; + +function cachedProperty(name, fetcher) { + name = "_" + name; + return function() { + var self = this; + if (self[name] != null) + return self[name]; + return self[name] = fetcher.apply(self, arguments); + }; +} + +function cloneAST(ast) { + return ast.transform(new U2.TreeTransformer(null, function(){})); +} + +function walkAST(ast, walker) { + var returnValue, exit = { + exit: function(ret) { + returnValue = ret; + throw exit; + } + }; + try { + ast.walk(new U2.TreeWalker(function(node, descend){ + return walker.call(exit, node, descend); + })); + } catch(ex) { + if (ex === exit) return returnValue; + throw ex; + } +} + +function findDefine(node) { + // (function(f, define){ define([ deps... ], f) })(FACTORY); + if (node instanceof U2.AST_Call + && node.args[0] instanceof U2.AST_Function + && node.expression instanceof U2.AST_Function + && node.expression.argnames.length == 2 + && node.expression.argnames[1].name == "define" + && node.expression.body[0] instanceof U2.AST_SimpleStatement + && node.expression.body[0].body instanceof U2.AST_Call + && node.expression.body[0].body.expression instanceof U2.AST_SymbolRef + && node.expression.body[0].body.expression.name == "define" + && node.expression.body[0].body.args[1] instanceof U2.AST_SymbolRef + && node.expression.body[0].body.args[1].name == node.expression.argnames[0].name) + { + this.exit({ + factory : node.args[0], + requires : node.expression.body[0].body.args[0], + }); + } + + // define([ deps... ], FACTORY) + if (node instanceof U2.AST_Call + && node.expression instanceof U2.AST_SymbolRef + && node.expression.name == "define" + && node.args.length == 2 + && node.args[0] instanceof U2.AST_Array + && node.args[1] instanceof U2.AST_Function) + { + this.exit({ + factory : node.args[1], + requires : node.args[0], + }); + } + + // define(FACTORY) + if (node instanceof U2.AST_Call + && node.expression instanceof U2.AST_SymbolRef + && node.expression.name == "define" + && node.args.length == 1 + && node.args[0] instanceof U2.AST_Function) + { + this.exit({ + factory : node.args[0], + }); + } +} + +function contains(a, x) { + return a.indexOf(x) >= 0; +} + +function pushUniq(a, x) { + if (!contains(a, x)) + a.push(x); +} + +function removeDuplicates(a) { + var ret = []; + for (var i = 0; i < a.length; ++i) + pushUniq(ret, a[i]); + return ret; +} + +function beautify(obj) { + return U2_parse("(" + JSON.stringify(obj) + ")").body[0].body.print_to_string({ + beautify: true, indent_level: 4 + }); +} + +function minify(code, filename) { + var ast; + if (code instanceof U2.AST_Node) { + ast = code; + } else { + ast = U2_parse(code, { filename: filename }); + } + var compressor = U2.Compressor({ + unsafe : true, + hoist_vars : true, + warnings : false, + pure_getters : true, + }); + ast.figure_out_scope(); + ast = ast.transform(compressor); + ast.figure_out_scope(); + ast.compute_char_frequency(); + ast.mangle_names({ + except: [ "define" ] + }); + return ast; +} + +function loadComponent(filename, basedir, files, maxLevel) { + var loading = []; + function load(filename, basedir, level) { + if (maxLevel != null && level == maxLevel) + return; + // normalize the filename relative to the kendo src directory + filename = filename.replace(/(\.js)?$/, ".js"); + filename = PATH.resolve(basedir, filename); + filename = PATH.relative(SRCDIR, filename); + if (!contains(loading, filename) && !contains(files, filename)) { + loading.push(filename); + var comp = getKendoFile(filename); + comp.getAMDDeps().forEach(function(f){ + // level is increased only if we don't load a subfile. + // otherwise we assume we're on the same level as the current component. + load(f, comp.dirname(), level + (comp.isSubfile() ? 0 : 1)); + }); + files.push(filename); + } + } + load(filename, basedir, 0); + return files; +} + +function listKendoFiles() { + var js_files = FS.readdirSync(SRCDIR) + .filter(function(filename){ + return /^kendo\..*\.js$/i.test(filename) && !/\.min\.js$/i.test(filename); + }) + .filter(function(filename){ + var code = FS.readFileSync(PATH.join(SRCDIR, filename), "utf8"); + var has_define = ( /define[\s\n\t]*\(/.test(code) ); + if (!has_define) { + SYS.error("*** Skipping file " + filename + " (no RequireJS wrapper)"); + } + return has_define; // XXX: this sucks but it'll do until we cleanup + }) + .sort(); + return js_files; +} + +function extract_widget_info(ast) { + ast = new U2.AST_Toplevel(ast); + ast.figure_out_scope(); + var widgets = []; + var scope = null; + + // Quick-n-dirty heuristic that should cover the use cases in Kendo. + function dumb_eval(node) { + if (node instanceof U2.AST_Constant) { + return node.getValue(); + } + if (node instanceof U2.AST_SymbolRef) { + var init = node.definition().init; + if (init) { + return dumb_eval(init); + } + return node.name; + } + if (node instanceof U2.AST_Dot) { + return dumb_eval(node.expression) + "." + node.property; + } + if (node instanceof U2.AST_Call && is_widget(node)) { + return "kendo.ui.Widget.extend"; + } + return null; // dunno how to handle + } + + // determine if node points to [window.]kendo.ui.SOMETHING + function is_widget(node) { + if (node instanceof U2.AST_Call && + node.expression instanceof U2.AST_Dot && + node.expression.property == "extend") { + var x = dumb_eval(node.expression); + if (!x) return false; + return /^(window\.)?(kendo|kendo\.dataviz|kendo\.mobile)\.ui\..+?\.extend/.test(x); + } + } + + var tw = new U2.TreeWalker(function(node, descend){ + if (node instanceof U2.AST_Scope) { + var save_scope = scope; + scope = node; + descend(); + scope = save_scope; + return true; + } + if (is_widget(node)) { + var def = node.args[0]; + var options = def.properties.filter(function(prop){ + return prop.key == "options"; + })[0]; + var events = def.properties.filter(function(prop){ + return prop.key == "events"; + })[0]; + if (events && events.value instanceof U2.AST_Array) { + events = events.value.elements.map(function(el){ + return dumb_eval(el); + }); + } + if (options) { + var name = options.value.properties.filter(function(prop){ + return prop.key == "name"; + })[0]; + if (name && name.value) { + name = name.value.value; + widgets.push({ + name : name, + options : options.value.properties.map(function(prop){ return prop.key }), + events : events, + inherits : node.expression.expression.print_to_string({ beautify: true }), + file : node.start.file, + line : node.start.line, + col : node.start.col + }); + } + } + } + }); + ast.walk(tw); + return widgets; +} + +function buildKendoConfig() { + var files = listKendoFiles(); + var template = JSON.parse(FS.readFileSync(PATH.join(__dirname, "..", "download-builder", "config", "categories.json"), "utf8")); + template.components = []; + files.forEach(function(f){ + var comp = getKendoFile(f); + var meta = comp.getMeta(); + if (!meta) { + SYS.error("*** No __meta__ declaration in " + f); + //throw new Error("No __meta__ declaration in " + f); + } else { + template.components.push(meta); + } + }); + return template; +} + +function loadComponents(files, maxLevel) { + var loads = []; + files.forEach(function(f){ + loadComponent(f, SRCDIR, loads, maxLevel); + }); + return loads; +} + +function bundleFiles_getMinAST(files) { + var code = loadComponents(files).reduce(function(a, f){ + var comp = getKendoFile(f); + if (!comp.isSubfile() && !comp.isBundle()) { + var ast = comp.buildMinAST(); + ast = walkAST(ast, findDefine).factory; + var body = ast.body.filter(function(node){ return !(node instanceof U2.AST_EmptyStatement) }); + if (body[0] instanceof U2.AST_Return + && body[0].value instanceof U2.AST_Seq + && body[0].value.car instanceof U2.AST_Call + && body[0].value.cdr.print_to_string() == "window.kendo") { + a.push(new U2.AST_SimpleStatement({ body: body[0].value.car })); + } else { + a.push(new U2.AST_SimpleStatement({ + body: new U2.AST_Call({ + expression: ast, + args: [], + }) + })); + } + } + return a; + }, []); + return get_wrapper().wrap([], { body: code }); +} + +// makes a bundle loading files and any dependencies in the right order +// adds the AMD wrapper, but depend on nothing since we bundle everything needed. +function bundleFiles(files, filename, min) { + if (min) { + var ast = bundleFiles_getMinAST(files); + var map = U2.SourceMap({ + file: filename, + // orig_line_diff: 8, + // dest_line_diff: 8, + root: "../../src/" // XXX: what's the source map root? + }); + code = ast.print_to_string({ source_map: map }); + return { + code : code, + map : map.toString(), + }; + } + else { + var code = loadComponents(files).reduce(function(a, f){ + var comp = getKendoFile(f); + if (!comp.isSubfile() && !comp.isBundle()) { + a.push(comp.getFullCode()); + } + return a; + }, []).join("\n\n"); + return { + code: wrapAMD([], code) + }; + } +} + +function loadAll() { + return loadComponents(listKendoFiles()); +} + +/* -----[ exports ]----- */ + +exports.getKendoFile = getKendoFile; +exports.listKendoFiles = listKendoFiles; +exports.buildKendoConfig = buildKendoConfig; +exports.loadComponents = loadComponents; +exports.loadAll = loadAll; +exports.bundleFiles = bundleFiles; +exports.wrapAMD = wrapAMD; +exports.minify = minify; + +/* -----[ CLI interface ]----- */ + +if (require.main === module) (function(){ + // invoked as CLI + var OPT = require("optimist"); + var ARGV = OPT + .describe("all-deps", "Show a list of all files required to load component(s)") + .describe("direct-deps", "Show direct dependencies of component(s))") + .describe("subfiles", "Show files that a component is made of") + .describe("bundle-all", "Generate kendo.all.js on stdout") + .describe("build", "Build a given component") + .describe("full", "Full build") + .describe("min", "Minified build") + .describe("kendo-config", "Generate kendo-config.json") + .boolean("all-deps") + .boolean("direct-deps") + .boolean("bundle-all") + .boolean("min") + .string("subfiles") + .string("build") + .wrap(80) + .argv; + + if (ARGV["kendo-config"]) { + var cf = buildKendoConfig(); + SYS.puts(JSON.stringify(cf, null, 2)); + return; + } + + var REST = ARGV._.slice(); + + var files; + + if (ARGV["subfiles"]) { + files = getKendoFile(ARGV["subfiles"]).getCompFiles(); + SYS.puts(beautify(files)); + return; + } + + if (ARGV["build"]) { + var comp = getKendoFile(ARGV["build"]); + if (ARGV["min"]) { + SYS.puts(comp.buildMinSource()); + } else { + SYS.puts(comp.buildFullSource()); + } + return; + } + + if (ARGV["all-deps"]) { + files = loadComponents(REST); + } + + if (ARGV["direct-deps"]) { + files = loadComponents(REST, 2); + } + + if (ARGV["bundle-all"]) { + files = loadAll(); + } + + if (ARGV["full"] || ARGV["min"]) { + var code = loadComponents(files).map(function(f){ + var comp = getKendoFile(f); + SYS.error("Adding " + comp.filename()); + if (comp.isSubfile()) { + return ""; + } else { + return comp.getFullCode() + "\n"; + } + }).join(""); + code = wrapAMD([], code); + if (ARGV["min"]) { + code = minify(code).print_to_string(); + } + SYS.puts(code); + return; + } + + SYS.puts(beautify(files)); + +})(); diff --git a/cultures/kendo.culture.af-ZA.js b/cultures/kendo.culture.af-ZA.js new file mode 100644 index 00000000000..5eb997c2b86 Binary files /dev/null and b/cultures/kendo.culture.af-ZA.js differ diff --git a/cultures/kendo.culture.af.js b/cultures/kendo.culture.af.js new file mode 100644 index 00000000000..cfe44bdaf84 Binary files /dev/null and b/cultures/kendo.culture.af.js differ diff --git a/cultures/kendo.culture.am-ET.js b/cultures/kendo.culture.am-ET.js new file mode 100644 index 00000000000..fe05458505b Binary files /dev/null and b/cultures/kendo.culture.am-ET.js differ diff --git a/cultures/kendo.culture.am.js b/cultures/kendo.culture.am.js new file mode 100644 index 00000000000..d131da80898 Binary files /dev/null and b/cultures/kendo.culture.am.js differ diff --git a/cultures/kendo.culture.ar-AE.js b/cultures/kendo.culture.ar-AE.js new file mode 100644 index 00000000000..3d5187c7a09 Binary files /dev/null and b/cultures/kendo.culture.ar-AE.js differ diff --git a/cultures/kendo.culture.ar-BH.js b/cultures/kendo.culture.ar-BH.js new file mode 100644 index 00000000000..fba2ab01390 Binary files /dev/null and b/cultures/kendo.culture.ar-BH.js differ diff --git a/cultures/kendo.culture.ar-DZ.js b/cultures/kendo.culture.ar-DZ.js new file mode 100644 index 00000000000..7ae9a6a94f7 Binary files /dev/null and b/cultures/kendo.culture.ar-DZ.js differ diff --git a/cultures/kendo.culture.ar-EG.js b/cultures/kendo.culture.ar-EG.js new file mode 100644 index 00000000000..27ccf8af83e Binary files /dev/null and b/cultures/kendo.culture.ar-EG.js differ diff --git a/cultures/kendo.culture.ar-IQ.js b/cultures/kendo.culture.ar-IQ.js new file mode 100644 index 00000000000..1f7e1d0b5ac Binary files /dev/null and b/cultures/kendo.culture.ar-IQ.js differ diff --git a/cultures/kendo.culture.ar-JO.js b/cultures/kendo.culture.ar-JO.js new file mode 100644 index 00000000000..00c1e1b285b Binary files /dev/null and b/cultures/kendo.culture.ar-JO.js differ diff --git a/cultures/kendo.culture.ar-KW.js b/cultures/kendo.culture.ar-KW.js new file mode 100644 index 00000000000..67402d56131 Binary files /dev/null and b/cultures/kendo.culture.ar-KW.js differ diff --git a/cultures/kendo.culture.ar-LB.js b/cultures/kendo.culture.ar-LB.js new file mode 100644 index 00000000000..572668e2e7d Binary files /dev/null and b/cultures/kendo.culture.ar-LB.js differ diff --git a/cultures/kendo.culture.ar-LY.js b/cultures/kendo.culture.ar-LY.js new file mode 100644 index 00000000000..34429971f7e Binary files /dev/null and b/cultures/kendo.culture.ar-LY.js differ diff --git a/cultures/kendo.culture.ar-MA.js b/cultures/kendo.culture.ar-MA.js new file mode 100644 index 00000000000..de963872c13 Binary files /dev/null and b/cultures/kendo.culture.ar-MA.js differ diff --git a/cultures/kendo.culture.ar-OM.js b/cultures/kendo.culture.ar-OM.js new file mode 100644 index 00000000000..595658d2c89 Binary files /dev/null and b/cultures/kendo.culture.ar-OM.js differ diff --git a/cultures/kendo.culture.ar-QA.js b/cultures/kendo.culture.ar-QA.js new file mode 100644 index 00000000000..367981bd943 Binary files /dev/null and b/cultures/kendo.culture.ar-QA.js differ diff --git a/cultures/kendo.culture.ar-SA.js b/cultures/kendo.culture.ar-SA.js new file mode 100644 index 00000000000..a2b65bfa29c Binary files /dev/null and b/cultures/kendo.culture.ar-SA.js differ diff --git a/cultures/kendo.culture.ar-SY.js b/cultures/kendo.culture.ar-SY.js new file mode 100644 index 00000000000..1e254fb7113 Binary files /dev/null and b/cultures/kendo.culture.ar-SY.js differ diff --git a/cultures/kendo.culture.ar-TN.js b/cultures/kendo.culture.ar-TN.js new file mode 100644 index 00000000000..2c12e95fc00 Binary files /dev/null and b/cultures/kendo.culture.ar-TN.js differ diff --git a/cultures/kendo.culture.ar-YE.js b/cultures/kendo.culture.ar-YE.js new file mode 100644 index 00000000000..e7f030d7a06 Binary files /dev/null and b/cultures/kendo.culture.ar-YE.js differ diff --git a/cultures/kendo.culture.ar.js b/cultures/kendo.culture.ar.js new file mode 100644 index 00000000000..ef3f0f896bf Binary files /dev/null and b/cultures/kendo.culture.ar.js differ diff --git a/cultures/kendo.culture.arn-CL.js b/cultures/kendo.culture.arn-CL.js new file mode 100644 index 00000000000..7b3badc48b0 Binary files /dev/null and b/cultures/kendo.culture.arn-CL.js differ diff --git a/cultures/kendo.culture.arn.js b/cultures/kendo.culture.arn.js new file mode 100644 index 00000000000..f31a7585087 Binary files /dev/null and b/cultures/kendo.culture.arn.js differ diff --git a/cultures/kendo.culture.as-IN.js b/cultures/kendo.culture.as-IN.js new file mode 100644 index 00000000000..645ed41a977 Binary files /dev/null and b/cultures/kendo.culture.as-IN.js differ diff --git a/cultures/kendo.culture.as.js b/cultures/kendo.culture.as.js new file mode 100644 index 00000000000..5d939e517dd Binary files /dev/null and b/cultures/kendo.culture.as.js differ diff --git a/cultures/kendo.culture.az-Cyrl-AZ.js b/cultures/kendo.culture.az-Cyrl-AZ.js new file mode 100644 index 00000000000..20139f88f9f Binary files /dev/null and b/cultures/kendo.culture.az-Cyrl-AZ.js differ diff --git a/cultures/kendo.culture.az-Cyrl.js b/cultures/kendo.culture.az-Cyrl.js new file mode 100644 index 00000000000..0ad78d1c67f Binary files /dev/null and b/cultures/kendo.culture.az-Cyrl.js differ diff --git a/cultures/kendo.culture.az-Latn-AZ.js b/cultures/kendo.culture.az-Latn-AZ.js new file mode 100644 index 00000000000..ddba8031179 Binary files /dev/null and b/cultures/kendo.culture.az-Latn-AZ.js differ diff --git a/cultures/kendo.culture.az-Latn.js b/cultures/kendo.culture.az-Latn.js new file mode 100644 index 00000000000..d9211dee0e1 Binary files /dev/null and b/cultures/kendo.culture.az-Latn.js differ diff --git a/cultures/kendo.culture.az.js b/cultures/kendo.culture.az.js new file mode 100644 index 00000000000..6d05b2337a6 Binary files /dev/null and b/cultures/kendo.culture.az.js differ diff --git a/cultures/kendo.culture.ba-RU.js b/cultures/kendo.culture.ba-RU.js new file mode 100644 index 00000000000..e00df571813 Binary files /dev/null and b/cultures/kendo.culture.ba-RU.js differ diff --git a/cultures/kendo.culture.ba.js b/cultures/kendo.culture.ba.js new file mode 100644 index 00000000000..2c53dd5fbc4 Binary files /dev/null and b/cultures/kendo.culture.ba.js differ diff --git a/cultures/kendo.culture.be-BY.js b/cultures/kendo.culture.be-BY.js new file mode 100644 index 00000000000..47c767beafb Binary files /dev/null and b/cultures/kendo.culture.be-BY.js differ diff --git a/cultures/kendo.culture.be.js b/cultures/kendo.culture.be.js new file mode 100644 index 00000000000..2cecefe1391 Binary files /dev/null and b/cultures/kendo.culture.be.js differ diff --git a/cultures/kendo.culture.bg-BG.js b/cultures/kendo.culture.bg-BG.js new file mode 100644 index 00000000000..6c91c44b38a Binary files /dev/null and b/cultures/kendo.culture.bg-BG.js differ diff --git a/cultures/kendo.culture.bg.js b/cultures/kendo.culture.bg.js new file mode 100644 index 00000000000..5619900d2b0 Binary files /dev/null and b/cultures/kendo.culture.bg.js differ diff --git a/cultures/kendo.culture.bn-BD.js b/cultures/kendo.culture.bn-BD.js new file mode 100644 index 00000000000..a14fe0abcbb Binary files /dev/null and b/cultures/kendo.culture.bn-BD.js differ diff --git a/cultures/kendo.culture.bn-IN.js b/cultures/kendo.culture.bn-IN.js new file mode 100644 index 00000000000..aae382c63f3 Binary files /dev/null and b/cultures/kendo.culture.bn-IN.js differ diff --git a/cultures/kendo.culture.bn.js b/cultures/kendo.culture.bn.js new file mode 100644 index 00000000000..08a910489ba Binary files /dev/null and b/cultures/kendo.culture.bn.js differ diff --git a/cultures/kendo.culture.bo-CN.js b/cultures/kendo.culture.bo-CN.js new file mode 100644 index 00000000000..320a34eda36 Binary files /dev/null and b/cultures/kendo.culture.bo-CN.js differ diff --git a/cultures/kendo.culture.bo.js b/cultures/kendo.culture.bo.js new file mode 100644 index 00000000000..5143b513c23 Binary files /dev/null and b/cultures/kendo.culture.bo.js differ diff --git a/cultures/kendo.culture.br-FR.js b/cultures/kendo.culture.br-FR.js new file mode 100644 index 00000000000..a2bfd4491c9 Binary files /dev/null and b/cultures/kendo.culture.br-FR.js differ diff --git a/cultures/kendo.culture.br.js b/cultures/kendo.culture.br.js new file mode 100644 index 00000000000..5167bdaaebf Binary files /dev/null and b/cultures/kendo.culture.br.js differ diff --git a/cultures/kendo.culture.bs-Cyrl-BA.js b/cultures/kendo.culture.bs-Cyrl-BA.js new file mode 100644 index 00000000000..b1e39eb1be9 Binary files /dev/null and b/cultures/kendo.culture.bs-Cyrl-BA.js differ diff --git a/cultures/kendo.culture.bs-Cyrl.js b/cultures/kendo.culture.bs-Cyrl.js new file mode 100644 index 00000000000..34792c8aaba Binary files /dev/null and b/cultures/kendo.culture.bs-Cyrl.js differ diff --git a/cultures/kendo.culture.bs-Latn-BA.js b/cultures/kendo.culture.bs-Latn-BA.js new file mode 100644 index 00000000000..785df4d9c2e Binary files /dev/null and b/cultures/kendo.culture.bs-Latn-BA.js differ diff --git a/cultures/kendo.culture.bs-Latn.js b/cultures/kendo.culture.bs-Latn.js new file mode 100644 index 00000000000..9f4ed5be923 Binary files /dev/null and b/cultures/kendo.culture.bs-Latn.js differ diff --git a/cultures/kendo.culture.bs.js b/cultures/kendo.culture.bs.js new file mode 100644 index 00000000000..e68c1a3bfdd Binary files /dev/null and b/cultures/kendo.culture.bs.js differ diff --git a/cultures/kendo.culture.ca-ES.js b/cultures/kendo.culture.ca-ES.js new file mode 100644 index 00000000000..c1420fadb2b Binary files /dev/null and b/cultures/kendo.culture.ca-ES.js differ diff --git a/cultures/kendo.culture.ca.js b/cultures/kendo.culture.ca.js new file mode 100644 index 00000000000..e5d74717d39 Binary files /dev/null and b/cultures/kendo.culture.ca.js differ diff --git a/cultures/kendo.culture.co-FR.js b/cultures/kendo.culture.co-FR.js new file mode 100644 index 00000000000..0960297dbac Binary files /dev/null and b/cultures/kendo.culture.co-FR.js differ diff --git a/cultures/kendo.culture.co.js b/cultures/kendo.culture.co.js new file mode 100644 index 00000000000..8a097288c19 Binary files /dev/null and b/cultures/kendo.culture.co.js differ diff --git a/cultures/kendo.culture.cs-CZ.js b/cultures/kendo.culture.cs-CZ.js new file mode 100644 index 00000000000..b9d32bde909 Binary files /dev/null and b/cultures/kendo.culture.cs-CZ.js differ diff --git a/cultures/kendo.culture.cs.js b/cultures/kendo.culture.cs.js new file mode 100644 index 00000000000..2a8ce479914 Binary files /dev/null and b/cultures/kendo.culture.cs.js differ diff --git a/cultures/kendo.culture.cy-GB.js b/cultures/kendo.culture.cy-GB.js new file mode 100644 index 00000000000..30c6fe4aae5 Binary files /dev/null and b/cultures/kendo.culture.cy-GB.js differ diff --git a/cultures/kendo.culture.cy.js b/cultures/kendo.culture.cy.js new file mode 100644 index 00000000000..f27aff7c8c1 Binary files /dev/null and b/cultures/kendo.culture.cy.js differ diff --git a/cultures/kendo.culture.da-DK.js b/cultures/kendo.culture.da-DK.js new file mode 100644 index 00000000000..fd7e4902395 Binary files /dev/null and b/cultures/kendo.culture.da-DK.js differ diff --git a/cultures/kendo.culture.da.js b/cultures/kendo.culture.da.js new file mode 100644 index 00000000000..cd89e44de31 Binary files /dev/null and b/cultures/kendo.culture.da.js differ diff --git a/cultures/kendo.culture.de-AT.js b/cultures/kendo.culture.de-AT.js new file mode 100644 index 00000000000..f9752db3d66 Binary files /dev/null and b/cultures/kendo.culture.de-AT.js differ diff --git a/cultures/kendo.culture.de-CH.js b/cultures/kendo.culture.de-CH.js new file mode 100644 index 00000000000..c0076afa5a1 Binary files /dev/null and b/cultures/kendo.culture.de-CH.js differ diff --git a/cultures/kendo.culture.de-DE.js b/cultures/kendo.culture.de-DE.js new file mode 100644 index 00000000000..9c34e8a48de Binary files /dev/null and b/cultures/kendo.culture.de-DE.js differ diff --git a/cultures/kendo.culture.de-LI.js b/cultures/kendo.culture.de-LI.js new file mode 100644 index 00000000000..d53382b80d0 Binary files /dev/null and b/cultures/kendo.culture.de-LI.js differ diff --git a/cultures/kendo.culture.de-LU.js b/cultures/kendo.culture.de-LU.js new file mode 100644 index 00000000000..a8a98e9db7a Binary files /dev/null and b/cultures/kendo.culture.de-LU.js differ diff --git a/cultures/kendo.culture.de.js b/cultures/kendo.culture.de.js new file mode 100644 index 00000000000..5114aa9fc69 Binary files /dev/null and b/cultures/kendo.culture.de.js differ diff --git a/cultures/kendo.culture.dsb-DE.js b/cultures/kendo.culture.dsb-DE.js new file mode 100644 index 00000000000..bd5e78f89ec Binary files /dev/null and b/cultures/kendo.culture.dsb-DE.js differ diff --git a/cultures/kendo.culture.dsb.js b/cultures/kendo.culture.dsb.js new file mode 100644 index 00000000000..d87c4c5cc5f Binary files /dev/null and b/cultures/kendo.culture.dsb.js differ diff --git a/cultures/kendo.culture.dv-MV.js b/cultures/kendo.culture.dv-MV.js new file mode 100644 index 00000000000..d7ef67006b8 Binary files /dev/null and b/cultures/kendo.culture.dv-MV.js differ diff --git a/cultures/kendo.culture.dv.js b/cultures/kendo.culture.dv.js new file mode 100644 index 00000000000..57630ba2541 Binary files /dev/null and b/cultures/kendo.culture.dv.js differ diff --git a/cultures/kendo.culture.el-GR.js b/cultures/kendo.culture.el-GR.js new file mode 100644 index 00000000000..9f8e2fa08bf Binary files /dev/null and b/cultures/kendo.culture.el-GR.js differ diff --git a/cultures/kendo.culture.el.js b/cultures/kendo.culture.el.js new file mode 100644 index 00000000000..3de8c12c186 Binary files /dev/null and b/cultures/kendo.culture.el.js differ diff --git a/cultures/kendo.culture.en-029.js b/cultures/kendo.culture.en-029.js new file mode 100644 index 00000000000..22f2074fd01 Binary files /dev/null and b/cultures/kendo.culture.en-029.js differ diff --git a/cultures/kendo.culture.en-AU.js b/cultures/kendo.culture.en-AU.js new file mode 100644 index 00000000000..139dd4dc96e Binary files /dev/null and b/cultures/kendo.culture.en-AU.js differ diff --git a/cultures/kendo.culture.en-BZ.js b/cultures/kendo.culture.en-BZ.js new file mode 100644 index 00000000000..c91f3f44c76 Binary files /dev/null and b/cultures/kendo.culture.en-BZ.js differ diff --git a/cultures/kendo.culture.en-CA.js b/cultures/kendo.culture.en-CA.js new file mode 100644 index 00000000000..164fd2b0e33 Binary files /dev/null and b/cultures/kendo.culture.en-CA.js differ diff --git a/cultures/kendo.culture.en-GB.js b/cultures/kendo.culture.en-GB.js new file mode 100644 index 00000000000..19c60370750 Binary files /dev/null and b/cultures/kendo.culture.en-GB.js differ diff --git a/cultures/kendo.culture.en-IE.js b/cultures/kendo.culture.en-IE.js new file mode 100644 index 00000000000..294d00b81eb Binary files /dev/null and b/cultures/kendo.culture.en-IE.js differ diff --git a/cultures/kendo.culture.en-IN.js b/cultures/kendo.culture.en-IN.js new file mode 100644 index 00000000000..d31b4361eb2 Binary files /dev/null and b/cultures/kendo.culture.en-IN.js differ diff --git a/cultures/kendo.culture.en-JM.js b/cultures/kendo.culture.en-JM.js new file mode 100644 index 00000000000..87290490730 Binary files /dev/null and b/cultures/kendo.culture.en-JM.js differ diff --git a/cultures/kendo.culture.en-MY.js b/cultures/kendo.culture.en-MY.js new file mode 100644 index 00000000000..6e885694286 Binary files /dev/null and b/cultures/kendo.culture.en-MY.js differ diff --git a/cultures/kendo.culture.en-NZ.js b/cultures/kendo.culture.en-NZ.js new file mode 100644 index 00000000000..3ea3522affb Binary files /dev/null and b/cultures/kendo.culture.en-NZ.js differ diff --git a/cultures/kendo.culture.en-PH.js b/cultures/kendo.culture.en-PH.js new file mode 100644 index 00000000000..2abf26ebba3 Binary files /dev/null and b/cultures/kendo.culture.en-PH.js differ diff --git a/cultures/kendo.culture.en-SG.js b/cultures/kendo.culture.en-SG.js new file mode 100644 index 00000000000..a1c1454de3e Binary files /dev/null and b/cultures/kendo.culture.en-SG.js differ diff --git a/cultures/kendo.culture.en-TT.js b/cultures/kendo.culture.en-TT.js new file mode 100644 index 00000000000..c6d7e0d2c01 Binary files /dev/null and b/cultures/kendo.culture.en-TT.js differ diff --git a/cultures/kendo.culture.en-US.js b/cultures/kendo.culture.en-US.js new file mode 100644 index 00000000000..d767a799b22 Binary files /dev/null and b/cultures/kendo.culture.en-US.js differ diff --git a/cultures/kendo.culture.en-ZA.js b/cultures/kendo.culture.en-ZA.js new file mode 100644 index 00000000000..a31273c3b5c Binary files /dev/null and b/cultures/kendo.culture.en-ZA.js differ diff --git a/cultures/kendo.culture.en-ZW.js b/cultures/kendo.culture.en-ZW.js new file mode 100644 index 00000000000..f7b275e6f26 Binary files /dev/null and b/cultures/kendo.culture.en-ZW.js differ diff --git a/cultures/kendo.culture.en.js b/cultures/kendo.culture.en.js new file mode 100644 index 00000000000..eba7d6d47e0 Binary files /dev/null and b/cultures/kendo.culture.en.js differ diff --git a/cultures/kendo.culture.es-AR.js b/cultures/kendo.culture.es-AR.js new file mode 100644 index 00000000000..3bde30561b5 Binary files /dev/null and b/cultures/kendo.culture.es-AR.js differ diff --git a/cultures/kendo.culture.es-BO.js b/cultures/kendo.culture.es-BO.js new file mode 100644 index 00000000000..4d9bc443312 Binary files /dev/null and b/cultures/kendo.culture.es-BO.js differ diff --git a/cultures/kendo.culture.es-CL.js b/cultures/kendo.culture.es-CL.js new file mode 100644 index 00000000000..4177ea93bd6 Binary files /dev/null and b/cultures/kendo.culture.es-CL.js differ diff --git a/cultures/kendo.culture.es-CO.js b/cultures/kendo.culture.es-CO.js new file mode 100644 index 00000000000..b436b69de0c Binary files /dev/null and b/cultures/kendo.culture.es-CO.js differ diff --git a/cultures/kendo.culture.es-CR.js b/cultures/kendo.culture.es-CR.js new file mode 100644 index 00000000000..61f353da70f Binary files /dev/null and b/cultures/kendo.culture.es-CR.js differ diff --git a/cultures/kendo.culture.es-DO.js b/cultures/kendo.culture.es-DO.js new file mode 100644 index 00000000000..4232a1fe408 Binary files /dev/null and b/cultures/kendo.culture.es-DO.js differ diff --git a/cultures/kendo.culture.es-EC.js b/cultures/kendo.culture.es-EC.js new file mode 100644 index 00000000000..97601e20317 Binary files /dev/null and b/cultures/kendo.culture.es-EC.js differ diff --git a/cultures/kendo.culture.es-ES.js b/cultures/kendo.culture.es-ES.js new file mode 100644 index 00000000000..1dee6e03395 Binary files /dev/null and b/cultures/kendo.culture.es-ES.js differ diff --git a/cultures/kendo.culture.es-GT.js b/cultures/kendo.culture.es-GT.js new file mode 100644 index 00000000000..af6834892fe Binary files /dev/null and b/cultures/kendo.culture.es-GT.js differ diff --git a/cultures/kendo.culture.es-HN.js b/cultures/kendo.culture.es-HN.js new file mode 100644 index 00000000000..94ed0048c64 Binary files /dev/null and b/cultures/kendo.culture.es-HN.js differ diff --git a/cultures/kendo.culture.es-MX.js b/cultures/kendo.culture.es-MX.js new file mode 100644 index 00000000000..ad2af18fe51 Binary files /dev/null and b/cultures/kendo.culture.es-MX.js differ diff --git a/cultures/kendo.culture.es-NI.js b/cultures/kendo.culture.es-NI.js new file mode 100644 index 00000000000..4548484e385 Binary files /dev/null and b/cultures/kendo.culture.es-NI.js differ diff --git a/cultures/kendo.culture.es-PA.js b/cultures/kendo.culture.es-PA.js new file mode 100644 index 00000000000..7d9f120a3de Binary files /dev/null and b/cultures/kendo.culture.es-PA.js differ diff --git a/cultures/kendo.culture.es-PE.js b/cultures/kendo.culture.es-PE.js new file mode 100644 index 00000000000..9cb019767d9 Binary files /dev/null and b/cultures/kendo.culture.es-PE.js differ diff --git a/cultures/kendo.culture.es-PR.js b/cultures/kendo.culture.es-PR.js new file mode 100644 index 00000000000..c7f3cba2c3b Binary files /dev/null and b/cultures/kendo.culture.es-PR.js differ diff --git a/cultures/kendo.culture.es-PY.js b/cultures/kendo.culture.es-PY.js new file mode 100644 index 00000000000..2d602e0f9ab Binary files /dev/null and b/cultures/kendo.culture.es-PY.js differ diff --git a/cultures/kendo.culture.es-SV.js b/cultures/kendo.culture.es-SV.js new file mode 100644 index 00000000000..b8951fc0052 Binary files /dev/null and b/cultures/kendo.culture.es-SV.js differ diff --git a/cultures/kendo.culture.es-US.js b/cultures/kendo.culture.es-US.js new file mode 100644 index 00000000000..1e595c51a5d Binary files /dev/null and b/cultures/kendo.culture.es-US.js differ diff --git a/cultures/kendo.culture.es-UY.js b/cultures/kendo.culture.es-UY.js new file mode 100644 index 00000000000..744894d9fc8 Binary files /dev/null and b/cultures/kendo.culture.es-UY.js differ diff --git a/cultures/kendo.culture.es-VE.js b/cultures/kendo.culture.es-VE.js new file mode 100644 index 00000000000..bfe42ba0904 Binary files /dev/null and b/cultures/kendo.culture.es-VE.js differ diff --git a/cultures/kendo.culture.es.js b/cultures/kendo.culture.es.js new file mode 100644 index 00000000000..d72f572cb1c Binary files /dev/null and b/cultures/kendo.culture.es.js differ diff --git a/cultures/kendo.culture.et-EE.js b/cultures/kendo.culture.et-EE.js new file mode 100644 index 00000000000..bc965b8e09c Binary files /dev/null and b/cultures/kendo.culture.et-EE.js differ diff --git a/cultures/kendo.culture.et.js b/cultures/kendo.culture.et.js new file mode 100644 index 00000000000..7b228778da2 Binary files /dev/null and b/cultures/kendo.culture.et.js differ diff --git a/cultures/kendo.culture.eu-ES.js b/cultures/kendo.culture.eu-ES.js new file mode 100644 index 00000000000..e74b055ffe5 Binary files /dev/null and b/cultures/kendo.culture.eu-ES.js differ diff --git a/cultures/kendo.culture.eu.js b/cultures/kendo.culture.eu.js new file mode 100644 index 00000000000..19dc9d317ac Binary files /dev/null and b/cultures/kendo.culture.eu.js differ diff --git a/cultures/kendo.culture.fa-IR.js b/cultures/kendo.culture.fa-IR.js new file mode 100644 index 00000000000..dbb7849fb53 Binary files /dev/null and b/cultures/kendo.culture.fa-IR.js differ diff --git a/cultures/kendo.culture.fa.js b/cultures/kendo.culture.fa.js new file mode 100644 index 00000000000..defb97a79a2 Binary files /dev/null and b/cultures/kendo.culture.fa.js differ diff --git a/cultures/kendo.culture.fi-FI.js b/cultures/kendo.culture.fi-FI.js new file mode 100644 index 00000000000..a3251e204a8 Binary files /dev/null and b/cultures/kendo.culture.fi-FI.js differ diff --git a/cultures/kendo.culture.fi.js b/cultures/kendo.culture.fi.js new file mode 100644 index 00000000000..5ca0596340e Binary files /dev/null and b/cultures/kendo.culture.fi.js differ diff --git a/cultures/kendo.culture.fil-PH.js b/cultures/kendo.culture.fil-PH.js new file mode 100644 index 00000000000..26d4937294d Binary files /dev/null and b/cultures/kendo.culture.fil-PH.js differ diff --git a/cultures/kendo.culture.fil.js b/cultures/kendo.culture.fil.js new file mode 100644 index 00000000000..1ec6e0598ef Binary files /dev/null and b/cultures/kendo.culture.fil.js differ diff --git a/cultures/kendo.culture.fo-FO.js b/cultures/kendo.culture.fo-FO.js new file mode 100644 index 00000000000..9da65e0b542 Binary files /dev/null and b/cultures/kendo.culture.fo-FO.js differ diff --git a/cultures/kendo.culture.fo.js b/cultures/kendo.culture.fo.js new file mode 100644 index 00000000000..6c087c2f0bc Binary files /dev/null and b/cultures/kendo.culture.fo.js differ diff --git a/cultures/kendo.culture.fr-BE.js b/cultures/kendo.culture.fr-BE.js new file mode 100644 index 00000000000..4d054148135 Binary files /dev/null and b/cultures/kendo.culture.fr-BE.js differ diff --git a/cultures/kendo.culture.fr-CA.js b/cultures/kendo.culture.fr-CA.js new file mode 100644 index 00000000000..0f055d3f91b Binary files /dev/null and b/cultures/kendo.culture.fr-CA.js differ diff --git a/cultures/kendo.culture.fr-CH.js b/cultures/kendo.culture.fr-CH.js new file mode 100644 index 00000000000..3f06911908d Binary files /dev/null and b/cultures/kendo.culture.fr-CH.js differ diff --git a/cultures/kendo.culture.fr-FR.js b/cultures/kendo.culture.fr-FR.js new file mode 100644 index 00000000000..906316107bf Binary files /dev/null and b/cultures/kendo.culture.fr-FR.js differ diff --git a/cultures/kendo.culture.fr-LU.js b/cultures/kendo.culture.fr-LU.js new file mode 100644 index 00000000000..cc73141be70 Binary files /dev/null and b/cultures/kendo.culture.fr-LU.js differ diff --git a/cultures/kendo.culture.fr-MC.js b/cultures/kendo.culture.fr-MC.js new file mode 100644 index 00000000000..1438f1d29be Binary files /dev/null and b/cultures/kendo.culture.fr-MC.js differ diff --git a/cultures/kendo.culture.fr.js b/cultures/kendo.culture.fr.js new file mode 100644 index 00000000000..298641c6bec Binary files /dev/null and b/cultures/kendo.culture.fr.js differ diff --git a/cultures/kendo.culture.fy-NL.js b/cultures/kendo.culture.fy-NL.js new file mode 100644 index 00000000000..b9dd8a3530a Binary files /dev/null and b/cultures/kendo.culture.fy-NL.js differ diff --git a/cultures/kendo.culture.fy.js b/cultures/kendo.culture.fy.js new file mode 100644 index 00000000000..30ca765fc96 Binary files /dev/null and b/cultures/kendo.culture.fy.js differ diff --git a/cultures/kendo.culture.ga-IE.js b/cultures/kendo.culture.ga-IE.js new file mode 100644 index 00000000000..c7da759117b Binary files /dev/null and b/cultures/kendo.culture.ga-IE.js differ diff --git a/cultures/kendo.culture.ga.js b/cultures/kendo.culture.ga.js new file mode 100644 index 00000000000..d32606a54a1 Binary files /dev/null and b/cultures/kendo.culture.ga.js differ diff --git a/cultures/kendo.culture.gd-GB.js b/cultures/kendo.culture.gd-GB.js new file mode 100644 index 00000000000..f4fa8874d04 Binary files /dev/null and b/cultures/kendo.culture.gd-GB.js differ diff --git a/cultures/kendo.culture.gd.js b/cultures/kendo.culture.gd.js new file mode 100644 index 00000000000..74301d1f413 Binary files /dev/null and b/cultures/kendo.culture.gd.js differ diff --git a/cultures/kendo.culture.gl-ES.js b/cultures/kendo.culture.gl-ES.js new file mode 100644 index 00000000000..e4f42c20f05 Binary files /dev/null and b/cultures/kendo.culture.gl-ES.js differ diff --git a/cultures/kendo.culture.gl.js b/cultures/kendo.culture.gl.js new file mode 100644 index 00000000000..adfec95ceb2 Binary files /dev/null and b/cultures/kendo.culture.gl.js differ diff --git a/cultures/kendo.culture.gsw-FR.js b/cultures/kendo.culture.gsw-FR.js new file mode 100644 index 00000000000..db38ee4ba2d Binary files /dev/null and b/cultures/kendo.culture.gsw-FR.js differ diff --git a/cultures/kendo.culture.gsw.js b/cultures/kendo.culture.gsw.js new file mode 100644 index 00000000000..6c5d651f8dc Binary files /dev/null and b/cultures/kendo.culture.gsw.js differ diff --git a/cultures/kendo.culture.gu-IN.js b/cultures/kendo.culture.gu-IN.js new file mode 100644 index 00000000000..4c88f228656 Binary files /dev/null and b/cultures/kendo.culture.gu-IN.js differ diff --git a/cultures/kendo.culture.gu.js b/cultures/kendo.culture.gu.js new file mode 100644 index 00000000000..6430a4e5818 Binary files /dev/null and b/cultures/kendo.culture.gu.js differ diff --git a/cultures/kendo.culture.ha-Latn-NG.js b/cultures/kendo.culture.ha-Latn-NG.js new file mode 100644 index 00000000000..7612c8fbcf8 Binary files /dev/null and b/cultures/kendo.culture.ha-Latn-NG.js differ diff --git a/cultures/kendo.culture.ha-Latn.js b/cultures/kendo.culture.ha-Latn.js new file mode 100644 index 00000000000..fbe98605d7f Binary files /dev/null and b/cultures/kendo.culture.ha-Latn.js differ diff --git a/cultures/kendo.culture.ha.js b/cultures/kendo.culture.ha.js new file mode 100644 index 00000000000..a4cb0c461bd Binary files /dev/null and b/cultures/kendo.culture.ha.js differ diff --git a/cultures/kendo.culture.he-IL.js b/cultures/kendo.culture.he-IL.js new file mode 100644 index 00000000000..5260ce48414 Binary files /dev/null and b/cultures/kendo.culture.he-IL.js differ diff --git a/cultures/kendo.culture.he.js b/cultures/kendo.culture.he.js new file mode 100644 index 00000000000..2dfef42b08b Binary files /dev/null and b/cultures/kendo.culture.he.js differ diff --git a/cultures/kendo.culture.hi-IN.js b/cultures/kendo.culture.hi-IN.js new file mode 100644 index 00000000000..81805852ae7 Binary files /dev/null and b/cultures/kendo.culture.hi-IN.js differ diff --git a/cultures/kendo.culture.hi.js b/cultures/kendo.culture.hi.js new file mode 100644 index 00000000000..42db7eb75f6 Binary files /dev/null and b/cultures/kendo.culture.hi.js differ diff --git a/cultures/kendo.culture.hr-BA.js b/cultures/kendo.culture.hr-BA.js new file mode 100644 index 00000000000..4c8cfe0b87e Binary files /dev/null and b/cultures/kendo.culture.hr-BA.js differ diff --git a/cultures/kendo.culture.hr-HR.js b/cultures/kendo.culture.hr-HR.js new file mode 100644 index 00000000000..28a7de88811 Binary files /dev/null and b/cultures/kendo.culture.hr-HR.js differ diff --git a/cultures/kendo.culture.hr.js b/cultures/kendo.culture.hr.js new file mode 100644 index 00000000000..7263d1014e0 Binary files /dev/null and b/cultures/kendo.culture.hr.js differ diff --git a/cultures/kendo.culture.hsb-DE.js b/cultures/kendo.culture.hsb-DE.js new file mode 100644 index 00000000000..a71b8741b00 Binary files /dev/null and b/cultures/kendo.culture.hsb-DE.js differ diff --git a/cultures/kendo.culture.hsb.js b/cultures/kendo.culture.hsb.js new file mode 100644 index 00000000000..2edb499ac68 Binary files /dev/null and b/cultures/kendo.culture.hsb.js differ diff --git a/cultures/kendo.culture.hu-HU.js b/cultures/kendo.culture.hu-HU.js new file mode 100644 index 00000000000..ea6bea9d9c2 Binary files /dev/null and b/cultures/kendo.culture.hu-HU.js differ diff --git a/cultures/kendo.culture.hu.js b/cultures/kendo.culture.hu.js new file mode 100644 index 00000000000..9469debc9d7 Binary files /dev/null and b/cultures/kendo.culture.hu.js differ diff --git a/cultures/kendo.culture.hy-AM.js b/cultures/kendo.culture.hy-AM.js new file mode 100644 index 00000000000..c890024a6ee Binary files /dev/null and b/cultures/kendo.culture.hy-AM.js differ diff --git a/cultures/kendo.culture.hy.js b/cultures/kendo.culture.hy.js new file mode 100644 index 00000000000..aca0cc7e715 Binary files /dev/null and b/cultures/kendo.culture.hy.js differ diff --git a/cultures/kendo.culture.id-ID.js b/cultures/kendo.culture.id-ID.js new file mode 100644 index 00000000000..32015282ea8 Binary files /dev/null and b/cultures/kendo.culture.id-ID.js differ diff --git a/cultures/kendo.culture.id.js b/cultures/kendo.culture.id.js new file mode 100644 index 00000000000..7f4e6ab018a Binary files /dev/null and b/cultures/kendo.culture.id.js differ diff --git a/cultures/kendo.culture.ig-NG.js b/cultures/kendo.culture.ig-NG.js new file mode 100644 index 00000000000..bf77ce171b9 Binary files /dev/null and b/cultures/kendo.culture.ig-NG.js differ diff --git a/cultures/kendo.culture.ig.js b/cultures/kendo.culture.ig.js new file mode 100644 index 00000000000..d7cbc8ac8b7 Binary files /dev/null and b/cultures/kendo.culture.ig.js differ diff --git a/cultures/kendo.culture.ii-CN.js b/cultures/kendo.culture.ii-CN.js new file mode 100644 index 00000000000..ec70e17190f Binary files /dev/null and b/cultures/kendo.culture.ii-CN.js differ diff --git a/cultures/kendo.culture.ii.js b/cultures/kendo.culture.ii.js new file mode 100644 index 00000000000..3a74a5832d9 Binary files /dev/null and b/cultures/kendo.culture.ii.js differ diff --git a/cultures/kendo.culture.is-IS.js b/cultures/kendo.culture.is-IS.js new file mode 100644 index 00000000000..82a4335d51e Binary files /dev/null and b/cultures/kendo.culture.is-IS.js differ diff --git a/cultures/kendo.culture.is.js b/cultures/kendo.culture.is.js new file mode 100644 index 00000000000..9c6ad4f5e8f Binary files /dev/null and b/cultures/kendo.culture.is.js differ diff --git a/cultures/kendo.culture.it-CH.js b/cultures/kendo.culture.it-CH.js new file mode 100644 index 00000000000..4d45bb30f2e Binary files /dev/null and b/cultures/kendo.culture.it-CH.js differ diff --git a/cultures/kendo.culture.it-IT.js b/cultures/kendo.culture.it-IT.js new file mode 100644 index 00000000000..cb36b29047c Binary files /dev/null and b/cultures/kendo.culture.it-IT.js differ diff --git a/cultures/kendo.culture.it.js b/cultures/kendo.culture.it.js new file mode 100644 index 00000000000..6734bb1bc68 Binary files /dev/null and b/cultures/kendo.culture.it.js differ diff --git a/cultures/kendo.culture.iu-Cans-CA.js b/cultures/kendo.culture.iu-Cans-CA.js new file mode 100644 index 00000000000..4e2b815e1d4 Binary files /dev/null and b/cultures/kendo.culture.iu-Cans-CA.js differ diff --git a/cultures/kendo.culture.iu-Cans.js b/cultures/kendo.culture.iu-Cans.js new file mode 100644 index 00000000000..cdc8a2a2923 Binary files /dev/null and b/cultures/kendo.culture.iu-Cans.js differ diff --git a/cultures/kendo.culture.iu-Latn-CA.js b/cultures/kendo.culture.iu-Latn-CA.js new file mode 100644 index 00000000000..c21ae68964e Binary files /dev/null and b/cultures/kendo.culture.iu-Latn-CA.js differ diff --git a/cultures/kendo.culture.iu-Latn.js b/cultures/kendo.culture.iu-Latn.js new file mode 100644 index 00000000000..dbdeda190ae Binary files /dev/null and b/cultures/kendo.culture.iu-Latn.js differ diff --git a/cultures/kendo.culture.iu.js b/cultures/kendo.culture.iu.js new file mode 100644 index 00000000000..dd4026817c2 Binary files /dev/null and b/cultures/kendo.culture.iu.js differ diff --git a/cultures/kendo.culture.ja-JP.js b/cultures/kendo.culture.ja-JP.js new file mode 100644 index 00000000000..9472c73d429 Binary files /dev/null and b/cultures/kendo.culture.ja-JP.js differ diff --git a/cultures/kendo.culture.ja.js b/cultures/kendo.culture.ja.js new file mode 100644 index 00000000000..5f989884de9 Binary files /dev/null and b/cultures/kendo.culture.ja.js differ diff --git a/cultures/kendo.culture.ka-GE.js b/cultures/kendo.culture.ka-GE.js new file mode 100644 index 00000000000..1c06b90d385 Binary files /dev/null and b/cultures/kendo.culture.ka-GE.js differ diff --git a/cultures/kendo.culture.ka.js b/cultures/kendo.culture.ka.js new file mode 100644 index 00000000000..b1d28708829 Binary files /dev/null and b/cultures/kendo.culture.ka.js differ diff --git a/cultures/kendo.culture.kk-KZ.js b/cultures/kendo.culture.kk-KZ.js new file mode 100644 index 00000000000..f99d21d2b1d Binary files /dev/null and b/cultures/kendo.culture.kk-KZ.js differ diff --git a/cultures/kendo.culture.kk.js b/cultures/kendo.culture.kk.js new file mode 100644 index 00000000000..908b3d9c998 Binary files /dev/null and b/cultures/kendo.culture.kk.js differ diff --git a/cultures/kendo.culture.kl-GL.js b/cultures/kendo.culture.kl-GL.js new file mode 100644 index 00000000000..4da11ab61ec Binary files /dev/null and b/cultures/kendo.culture.kl-GL.js differ diff --git a/cultures/kendo.culture.kl.js b/cultures/kendo.culture.kl.js new file mode 100644 index 00000000000..b4af006a097 Binary files /dev/null and b/cultures/kendo.culture.kl.js differ diff --git a/cultures/kendo.culture.km-KH.js b/cultures/kendo.culture.km-KH.js new file mode 100644 index 00000000000..3612c846719 Binary files /dev/null and b/cultures/kendo.culture.km-KH.js differ diff --git a/cultures/kendo.culture.km.js b/cultures/kendo.culture.km.js new file mode 100644 index 00000000000..9fdf21ebecb Binary files /dev/null and b/cultures/kendo.culture.km.js differ diff --git a/cultures/kendo.culture.kn-IN.js b/cultures/kendo.culture.kn-IN.js new file mode 100644 index 00000000000..8f3c159fa16 Binary files /dev/null and b/cultures/kendo.culture.kn-IN.js differ diff --git a/cultures/kendo.culture.kn.js b/cultures/kendo.culture.kn.js new file mode 100644 index 00000000000..1a7ca807f76 Binary files /dev/null and b/cultures/kendo.culture.kn.js differ diff --git a/cultures/kendo.culture.ko-KR.js b/cultures/kendo.culture.ko-KR.js new file mode 100644 index 00000000000..cc06015b60d Binary files /dev/null and b/cultures/kendo.culture.ko-KR.js differ diff --git a/cultures/kendo.culture.ko.js b/cultures/kendo.culture.ko.js new file mode 100644 index 00000000000..97c37aa71b3 Binary files /dev/null and b/cultures/kendo.culture.ko.js differ diff --git a/cultures/kendo.culture.kok-IN.js b/cultures/kendo.culture.kok-IN.js new file mode 100644 index 00000000000..1f0952eb1d8 Binary files /dev/null and b/cultures/kendo.culture.kok-IN.js differ diff --git a/cultures/kendo.culture.kok.js b/cultures/kendo.culture.kok.js new file mode 100644 index 00000000000..9e65893eed2 Binary files /dev/null and b/cultures/kendo.culture.kok.js differ diff --git a/cultures/kendo.culture.ky-KG.js b/cultures/kendo.culture.ky-KG.js new file mode 100644 index 00000000000..4da82bc2813 Binary files /dev/null and b/cultures/kendo.culture.ky-KG.js differ diff --git a/cultures/kendo.culture.ky.js b/cultures/kendo.culture.ky.js new file mode 100644 index 00000000000..21255a7c357 Binary files /dev/null and b/cultures/kendo.culture.ky.js differ diff --git a/cultures/kendo.culture.lb-LU.js b/cultures/kendo.culture.lb-LU.js new file mode 100644 index 00000000000..3baddd2d55a Binary files /dev/null and b/cultures/kendo.culture.lb-LU.js differ diff --git a/cultures/kendo.culture.lb.js b/cultures/kendo.culture.lb.js new file mode 100644 index 00000000000..bd698e0e2f4 Binary files /dev/null and b/cultures/kendo.culture.lb.js differ diff --git a/cultures/kendo.culture.lo-LA.js b/cultures/kendo.culture.lo-LA.js new file mode 100644 index 00000000000..874935770dd Binary files /dev/null and b/cultures/kendo.culture.lo-LA.js differ diff --git a/cultures/kendo.culture.lo.js b/cultures/kendo.culture.lo.js new file mode 100644 index 00000000000..096c8e67f2e Binary files /dev/null and b/cultures/kendo.culture.lo.js differ diff --git a/cultures/kendo.culture.lt-LT.js b/cultures/kendo.culture.lt-LT.js new file mode 100644 index 00000000000..080ab15c049 Binary files /dev/null and b/cultures/kendo.culture.lt-LT.js differ diff --git a/cultures/kendo.culture.lt.js b/cultures/kendo.culture.lt.js new file mode 100644 index 00000000000..99f4571481f Binary files /dev/null and b/cultures/kendo.culture.lt.js differ diff --git a/cultures/kendo.culture.lv-LV.js b/cultures/kendo.culture.lv-LV.js new file mode 100644 index 00000000000..acf2bf03af1 Binary files /dev/null and b/cultures/kendo.culture.lv-LV.js differ diff --git a/cultures/kendo.culture.lv.js b/cultures/kendo.culture.lv.js new file mode 100644 index 00000000000..5fe043e4fb8 Binary files /dev/null and b/cultures/kendo.culture.lv.js differ diff --git a/cultures/kendo.culture.mi-NZ.js b/cultures/kendo.culture.mi-NZ.js new file mode 100644 index 00000000000..38a3cfb9922 Binary files /dev/null and b/cultures/kendo.culture.mi-NZ.js differ diff --git a/cultures/kendo.culture.mi.js b/cultures/kendo.culture.mi.js new file mode 100644 index 00000000000..964331755ca Binary files /dev/null and b/cultures/kendo.culture.mi.js differ diff --git a/cultures/kendo.culture.mk-MK.js b/cultures/kendo.culture.mk-MK.js new file mode 100644 index 00000000000..07b06a6ef68 Binary files /dev/null and b/cultures/kendo.culture.mk-MK.js differ diff --git a/cultures/kendo.culture.mk.js b/cultures/kendo.culture.mk.js new file mode 100644 index 00000000000..b4c18e1d31e Binary files /dev/null and b/cultures/kendo.culture.mk.js differ diff --git a/cultures/kendo.culture.ml-IN.js b/cultures/kendo.culture.ml-IN.js new file mode 100644 index 00000000000..3036f968cd3 Binary files /dev/null and b/cultures/kendo.culture.ml-IN.js differ diff --git a/cultures/kendo.culture.ml.js b/cultures/kendo.culture.ml.js new file mode 100644 index 00000000000..69490c19f47 Binary files /dev/null and b/cultures/kendo.culture.ml.js differ diff --git a/cultures/kendo.culture.mn-Cyrl.js b/cultures/kendo.culture.mn-Cyrl.js new file mode 100644 index 00000000000..f532e356cc3 Binary files /dev/null and b/cultures/kendo.culture.mn-Cyrl.js differ diff --git a/cultures/kendo.culture.mn-MN.js b/cultures/kendo.culture.mn-MN.js new file mode 100644 index 00000000000..c70bfa70ad2 Binary files /dev/null and b/cultures/kendo.culture.mn-MN.js differ diff --git a/cultures/kendo.culture.mn-Mong-CN.js b/cultures/kendo.culture.mn-Mong-CN.js new file mode 100644 index 00000000000..8ab8846153b Binary files /dev/null and b/cultures/kendo.culture.mn-Mong-CN.js differ diff --git a/cultures/kendo.culture.mn-Mong.js b/cultures/kendo.culture.mn-Mong.js new file mode 100644 index 00000000000..02f63b51459 Binary files /dev/null and b/cultures/kendo.culture.mn-Mong.js differ diff --git a/cultures/kendo.culture.mn.js b/cultures/kendo.culture.mn.js new file mode 100644 index 00000000000..231cd2f9b91 Binary files /dev/null and b/cultures/kendo.culture.mn.js differ diff --git a/cultures/kendo.culture.moh-CA.js b/cultures/kendo.culture.moh-CA.js new file mode 100644 index 00000000000..411f3daf8cf Binary files /dev/null and b/cultures/kendo.culture.moh-CA.js differ diff --git a/cultures/kendo.culture.moh.js b/cultures/kendo.culture.moh.js new file mode 100644 index 00000000000..3898b1166d4 Binary files /dev/null and b/cultures/kendo.culture.moh.js differ diff --git a/cultures/kendo.culture.mr-IN.js b/cultures/kendo.culture.mr-IN.js new file mode 100644 index 00000000000..8a02daeb693 Binary files /dev/null and b/cultures/kendo.culture.mr-IN.js differ diff --git a/cultures/kendo.culture.mr.js b/cultures/kendo.culture.mr.js new file mode 100644 index 00000000000..53de1e3991f Binary files /dev/null and b/cultures/kendo.culture.mr.js differ diff --git a/cultures/kendo.culture.ms-BN.js b/cultures/kendo.culture.ms-BN.js new file mode 100644 index 00000000000..0dc24c94ee0 Binary files /dev/null and b/cultures/kendo.culture.ms-BN.js differ diff --git a/cultures/kendo.culture.ms-MY.js b/cultures/kendo.culture.ms-MY.js new file mode 100644 index 00000000000..728e005a07f Binary files /dev/null and b/cultures/kendo.culture.ms-MY.js differ diff --git a/cultures/kendo.culture.ms.js b/cultures/kendo.culture.ms.js new file mode 100644 index 00000000000..5ef4c6c35df Binary files /dev/null and b/cultures/kendo.culture.ms.js differ diff --git a/cultures/kendo.culture.mt-MT.js b/cultures/kendo.culture.mt-MT.js new file mode 100644 index 00000000000..e4afa3ad84e Binary files /dev/null and b/cultures/kendo.culture.mt-MT.js differ diff --git a/cultures/kendo.culture.mt.js b/cultures/kendo.culture.mt.js new file mode 100644 index 00000000000..c700ab35fc6 Binary files /dev/null and b/cultures/kendo.culture.mt.js differ diff --git a/cultures/kendo.culture.nb-NO.js b/cultures/kendo.culture.nb-NO.js new file mode 100644 index 00000000000..08cb2e41870 Binary files /dev/null and b/cultures/kendo.culture.nb-NO.js differ diff --git a/cultures/kendo.culture.nb.js b/cultures/kendo.culture.nb.js new file mode 100644 index 00000000000..37024ba5f31 Binary files /dev/null and b/cultures/kendo.culture.nb.js differ diff --git a/cultures/kendo.culture.ne-NP.js b/cultures/kendo.culture.ne-NP.js new file mode 100644 index 00000000000..e16ce4700e3 Binary files /dev/null and b/cultures/kendo.culture.ne-NP.js differ diff --git a/cultures/kendo.culture.ne.js b/cultures/kendo.culture.ne.js new file mode 100644 index 00000000000..efd34abcd5d Binary files /dev/null and b/cultures/kendo.culture.ne.js differ diff --git a/cultures/kendo.culture.nl-BE.js b/cultures/kendo.culture.nl-BE.js new file mode 100644 index 00000000000..06febb32422 Binary files /dev/null and b/cultures/kendo.culture.nl-BE.js differ diff --git a/cultures/kendo.culture.nl-NL.js b/cultures/kendo.culture.nl-NL.js new file mode 100644 index 00000000000..dd02bafce4b Binary files /dev/null and b/cultures/kendo.culture.nl-NL.js differ diff --git a/cultures/kendo.culture.nl.js b/cultures/kendo.culture.nl.js new file mode 100644 index 00000000000..b15f9fd6177 Binary files /dev/null and b/cultures/kendo.culture.nl.js differ diff --git a/cultures/kendo.culture.nn-NO.js b/cultures/kendo.culture.nn-NO.js new file mode 100644 index 00000000000..758fdf1fddd Binary files /dev/null and b/cultures/kendo.culture.nn-NO.js differ diff --git a/cultures/kendo.culture.nn.js b/cultures/kendo.culture.nn.js new file mode 100644 index 00000000000..8fb3bff9d8d Binary files /dev/null and b/cultures/kendo.culture.nn.js differ diff --git a/cultures/kendo.culture.no.js b/cultures/kendo.culture.no.js new file mode 100644 index 00000000000..e6a972b9323 Binary files /dev/null and b/cultures/kendo.culture.no.js differ diff --git a/cultures/kendo.culture.nso-ZA.js b/cultures/kendo.culture.nso-ZA.js new file mode 100644 index 00000000000..06947c09bc1 Binary files /dev/null and b/cultures/kendo.culture.nso-ZA.js differ diff --git a/cultures/kendo.culture.nso.js b/cultures/kendo.culture.nso.js new file mode 100644 index 00000000000..393fce758fa Binary files /dev/null and b/cultures/kendo.culture.nso.js differ diff --git a/cultures/kendo.culture.oc-FR.js b/cultures/kendo.culture.oc-FR.js new file mode 100644 index 00000000000..d632d34943d Binary files /dev/null and b/cultures/kendo.culture.oc-FR.js differ diff --git a/cultures/kendo.culture.oc.js b/cultures/kendo.culture.oc.js new file mode 100644 index 00000000000..c60046b1ef8 Binary files /dev/null and b/cultures/kendo.culture.oc.js differ diff --git a/cultures/kendo.culture.or-IN.js b/cultures/kendo.culture.or-IN.js new file mode 100644 index 00000000000..5c8daa06663 Binary files /dev/null and b/cultures/kendo.culture.or-IN.js differ diff --git a/cultures/kendo.culture.or.js b/cultures/kendo.culture.or.js new file mode 100644 index 00000000000..2f3c5198c89 Binary files /dev/null and b/cultures/kendo.culture.or.js differ diff --git a/cultures/kendo.culture.pa-IN.js b/cultures/kendo.culture.pa-IN.js new file mode 100644 index 00000000000..aa22f5f077c Binary files /dev/null and b/cultures/kendo.culture.pa-IN.js differ diff --git a/cultures/kendo.culture.pa.js b/cultures/kendo.culture.pa.js new file mode 100644 index 00000000000..5a28cccfa89 Binary files /dev/null and b/cultures/kendo.culture.pa.js differ diff --git a/cultures/kendo.culture.pl-PL.js b/cultures/kendo.culture.pl-PL.js new file mode 100644 index 00000000000..10bc80fd341 Binary files /dev/null and b/cultures/kendo.culture.pl-PL.js differ diff --git a/cultures/kendo.culture.pl.js b/cultures/kendo.culture.pl.js new file mode 100644 index 00000000000..3828c510a13 Binary files /dev/null and b/cultures/kendo.culture.pl.js differ diff --git a/cultures/kendo.culture.prs-AF.js b/cultures/kendo.culture.prs-AF.js new file mode 100644 index 00000000000..8fca1359fdc Binary files /dev/null and b/cultures/kendo.culture.prs-AF.js differ diff --git a/cultures/kendo.culture.prs.js b/cultures/kendo.culture.prs.js new file mode 100644 index 00000000000..c4aed3d1ed7 Binary files /dev/null and b/cultures/kendo.culture.prs.js differ diff --git a/cultures/kendo.culture.ps-AF.js b/cultures/kendo.culture.ps-AF.js new file mode 100644 index 00000000000..ba860dbcccb Binary files /dev/null and b/cultures/kendo.culture.ps-AF.js differ diff --git a/cultures/kendo.culture.ps.js b/cultures/kendo.culture.ps.js new file mode 100644 index 00000000000..d904426cd15 Binary files /dev/null and b/cultures/kendo.culture.ps.js differ diff --git a/cultures/kendo.culture.pt-BR.js b/cultures/kendo.culture.pt-BR.js new file mode 100644 index 00000000000..1a9b423f905 Binary files /dev/null and b/cultures/kendo.culture.pt-BR.js differ diff --git a/cultures/kendo.culture.pt-PT.js b/cultures/kendo.culture.pt-PT.js new file mode 100644 index 00000000000..473d98aa509 Binary files /dev/null and b/cultures/kendo.culture.pt-PT.js differ diff --git a/cultures/kendo.culture.pt.js b/cultures/kendo.culture.pt.js new file mode 100644 index 00000000000..a41117fa611 Binary files /dev/null and b/cultures/kendo.culture.pt.js differ diff --git a/cultures/kendo.culture.qut-GT.js b/cultures/kendo.culture.qut-GT.js new file mode 100644 index 00000000000..dcbd9f60ab2 Binary files /dev/null and b/cultures/kendo.culture.qut-GT.js differ diff --git a/cultures/kendo.culture.qut.js b/cultures/kendo.culture.qut.js new file mode 100644 index 00000000000..0d2ad1d22b3 Binary files /dev/null and b/cultures/kendo.culture.qut.js differ diff --git a/cultures/kendo.culture.quz-BO.js b/cultures/kendo.culture.quz-BO.js new file mode 100644 index 00000000000..5bae4fbda3a Binary files /dev/null and b/cultures/kendo.culture.quz-BO.js differ diff --git a/cultures/kendo.culture.quz-EC.js b/cultures/kendo.culture.quz-EC.js new file mode 100644 index 00000000000..0cf39f81cd9 Binary files /dev/null and b/cultures/kendo.culture.quz-EC.js differ diff --git a/cultures/kendo.culture.quz-PE.js b/cultures/kendo.culture.quz-PE.js new file mode 100644 index 00000000000..bc5b482f270 Binary files /dev/null and b/cultures/kendo.culture.quz-PE.js differ diff --git a/cultures/kendo.culture.quz.js b/cultures/kendo.culture.quz.js new file mode 100644 index 00000000000..05edd293087 Binary files /dev/null and b/cultures/kendo.culture.quz.js differ diff --git a/cultures/kendo.culture.rm-CH.js b/cultures/kendo.culture.rm-CH.js new file mode 100644 index 00000000000..1874b37a936 Binary files /dev/null and b/cultures/kendo.culture.rm-CH.js differ diff --git a/cultures/kendo.culture.rm.js b/cultures/kendo.culture.rm.js new file mode 100644 index 00000000000..01da45fae3f Binary files /dev/null and b/cultures/kendo.culture.rm.js differ diff --git a/cultures/kendo.culture.ro-RO.js b/cultures/kendo.culture.ro-RO.js new file mode 100644 index 00000000000..f0405f50740 Binary files /dev/null and b/cultures/kendo.culture.ro-RO.js differ diff --git a/cultures/kendo.culture.ro.js b/cultures/kendo.culture.ro.js new file mode 100644 index 00000000000..1753e2ae5e1 Binary files /dev/null and b/cultures/kendo.culture.ro.js differ diff --git a/cultures/kendo.culture.ru-RU.js b/cultures/kendo.culture.ru-RU.js new file mode 100644 index 00000000000..69588145a43 Binary files /dev/null and b/cultures/kendo.culture.ru-RU.js differ diff --git a/cultures/kendo.culture.ru.js b/cultures/kendo.culture.ru.js new file mode 100644 index 00000000000..c12412e0d02 Binary files /dev/null and b/cultures/kendo.culture.ru.js differ diff --git a/cultures/kendo.culture.rw-RW.js b/cultures/kendo.culture.rw-RW.js new file mode 100644 index 00000000000..15394f4ebac Binary files /dev/null and b/cultures/kendo.culture.rw-RW.js differ diff --git a/cultures/kendo.culture.rw.js b/cultures/kendo.culture.rw.js new file mode 100644 index 00000000000..45f35873b7c Binary files /dev/null and b/cultures/kendo.culture.rw.js differ diff --git a/cultures/kendo.culture.sa-IN.js b/cultures/kendo.culture.sa-IN.js new file mode 100644 index 00000000000..b77c5d97f6b Binary files /dev/null and b/cultures/kendo.culture.sa-IN.js differ diff --git a/cultures/kendo.culture.sa.js b/cultures/kendo.culture.sa.js new file mode 100644 index 00000000000..1906b605a30 Binary files /dev/null and b/cultures/kendo.culture.sa.js differ diff --git a/cultures/kendo.culture.sah-RU.js b/cultures/kendo.culture.sah-RU.js new file mode 100644 index 00000000000..5c066ddfc80 Binary files /dev/null and b/cultures/kendo.culture.sah-RU.js differ diff --git a/cultures/kendo.culture.sah.js b/cultures/kendo.culture.sah.js new file mode 100644 index 00000000000..e8839ac665f Binary files /dev/null and b/cultures/kendo.culture.sah.js differ diff --git a/cultures/kendo.culture.se-FI.js b/cultures/kendo.culture.se-FI.js new file mode 100644 index 00000000000..d67ea73d623 Binary files /dev/null and b/cultures/kendo.culture.se-FI.js differ diff --git a/cultures/kendo.culture.se-NO.js b/cultures/kendo.culture.se-NO.js new file mode 100644 index 00000000000..debf4bfdb32 Binary files /dev/null and b/cultures/kendo.culture.se-NO.js differ diff --git a/cultures/kendo.culture.se-SE.js b/cultures/kendo.culture.se-SE.js new file mode 100644 index 00000000000..27fad406eaf Binary files /dev/null and b/cultures/kendo.culture.se-SE.js differ diff --git a/cultures/kendo.culture.se.js b/cultures/kendo.culture.se.js new file mode 100644 index 00000000000..7289b920914 Binary files /dev/null and b/cultures/kendo.culture.se.js differ diff --git a/cultures/kendo.culture.si-LK.js b/cultures/kendo.culture.si-LK.js new file mode 100644 index 00000000000..2d3e0ab2d20 Binary files /dev/null and b/cultures/kendo.culture.si-LK.js differ diff --git a/cultures/kendo.culture.si.js b/cultures/kendo.culture.si.js new file mode 100644 index 00000000000..47ec7e8b071 Binary files /dev/null and b/cultures/kendo.culture.si.js differ diff --git a/cultures/kendo.culture.sk-SK.js b/cultures/kendo.culture.sk-SK.js new file mode 100644 index 00000000000..97a6853bf6f Binary files /dev/null and b/cultures/kendo.culture.sk-SK.js differ diff --git a/cultures/kendo.culture.sk.js b/cultures/kendo.culture.sk.js new file mode 100644 index 00000000000..9f10d6fabab Binary files /dev/null and b/cultures/kendo.culture.sk.js differ diff --git a/cultures/kendo.culture.sl-SI.js b/cultures/kendo.culture.sl-SI.js new file mode 100644 index 00000000000..e8522928c09 Binary files /dev/null and b/cultures/kendo.culture.sl-SI.js differ diff --git a/cultures/kendo.culture.sl.js b/cultures/kendo.culture.sl.js new file mode 100644 index 00000000000..3499df090f6 Binary files /dev/null and b/cultures/kendo.culture.sl.js differ diff --git a/cultures/kendo.culture.sma-NO.js b/cultures/kendo.culture.sma-NO.js new file mode 100644 index 00000000000..3b2e0618e52 Binary files /dev/null and b/cultures/kendo.culture.sma-NO.js differ diff --git a/cultures/kendo.culture.sma-SE.js b/cultures/kendo.culture.sma-SE.js new file mode 100644 index 00000000000..d8aad6176c5 Binary files /dev/null and b/cultures/kendo.culture.sma-SE.js differ diff --git a/cultures/kendo.culture.sma.js b/cultures/kendo.culture.sma.js new file mode 100644 index 00000000000..f5e6c7db7df Binary files /dev/null and b/cultures/kendo.culture.sma.js differ diff --git a/cultures/kendo.culture.smj-NO.js b/cultures/kendo.culture.smj-NO.js new file mode 100644 index 00000000000..6dba4d997cb Binary files /dev/null and b/cultures/kendo.culture.smj-NO.js differ diff --git a/cultures/kendo.culture.smj-SE.js b/cultures/kendo.culture.smj-SE.js new file mode 100644 index 00000000000..dc116f01c1b Binary files /dev/null and b/cultures/kendo.culture.smj-SE.js differ diff --git a/cultures/kendo.culture.smj.js b/cultures/kendo.culture.smj.js new file mode 100644 index 00000000000..0d50dce6ede Binary files /dev/null and b/cultures/kendo.culture.smj.js differ diff --git a/cultures/kendo.culture.smn-FI.js b/cultures/kendo.culture.smn-FI.js new file mode 100644 index 00000000000..e9b9bba1112 Binary files /dev/null and b/cultures/kendo.culture.smn-FI.js differ diff --git a/cultures/kendo.culture.smn.js b/cultures/kendo.culture.smn.js new file mode 100644 index 00000000000..b9c9deafd2f Binary files /dev/null and b/cultures/kendo.culture.smn.js differ diff --git a/cultures/kendo.culture.sms-FI.js b/cultures/kendo.culture.sms-FI.js new file mode 100644 index 00000000000..2e086ede49d Binary files /dev/null and b/cultures/kendo.culture.sms-FI.js differ diff --git a/cultures/kendo.culture.sms.js b/cultures/kendo.culture.sms.js new file mode 100644 index 00000000000..a9bc78524d2 Binary files /dev/null and b/cultures/kendo.culture.sms.js differ diff --git a/cultures/kendo.culture.sq-AL.js b/cultures/kendo.culture.sq-AL.js new file mode 100644 index 00000000000..d39729001a8 Binary files /dev/null and b/cultures/kendo.culture.sq-AL.js differ diff --git a/cultures/kendo.culture.sq.js b/cultures/kendo.culture.sq.js new file mode 100644 index 00000000000..a1fa9ec0b16 Binary files /dev/null and b/cultures/kendo.culture.sq.js differ diff --git a/cultures/kendo.culture.sr-Cyrl-BA.js b/cultures/kendo.culture.sr-Cyrl-BA.js new file mode 100644 index 00000000000..16dda9387da Binary files /dev/null and b/cultures/kendo.culture.sr-Cyrl-BA.js differ diff --git a/cultures/kendo.culture.sr-Cyrl-CS.js b/cultures/kendo.culture.sr-Cyrl-CS.js new file mode 100644 index 00000000000..02260e2fdf1 Binary files /dev/null and b/cultures/kendo.culture.sr-Cyrl-CS.js differ diff --git a/cultures/kendo.culture.sr-Cyrl-ME.js b/cultures/kendo.culture.sr-Cyrl-ME.js new file mode 100644 index 00000000000..560fc17bb00 Binary files /dev/null and b/cultures/kendo.culture.sr-Cyrl-ME.js differ diff --git a/cultures/kendo.culture.sr-Cyrl-RS.js b/cultures/kendo.culture.sr-Cyrl-RS.js new file mode 100644 index 00000000000..4710b87fa14 Binary files /dev/null and b/cultures/kendo.culture.sr-Cyrl-RS.js differ diff --git a/cultures/kendo.culture.sr-Cyrl.js b/cultures/kendo.culture.sr-Cyrl.js new file mode 100644 index 00000000000..cfdd376b018 Binary files /dev/null and b/cultures/kendo.culture.sr-Cyrl.js differ diff --git a/cultures/kendo.culture.sr-Latn-BA.js b/cultures/kendo.culture.sr-Latn-BA.js new file mode 100644 index 00000000000..afc53c3d772 Binary files /dev/null and b/cultures/kendo.culture.sr-Latn-BA.js differ diff --git a/cultures/kendo.culture.sr-Latn-CS.js b/cultures/kendo.culture.sr-Latn-CS.js new file mode 100644 index 00000000000..95a71b6e736 Binary files /dev/null and b/cultures/kendo.culture.sr-Latn-CS.js differ diff --git a/cultures/kendo.culture.sr-Latn-ME.js b/cultures/kendo.culture.sr-Latn-ME.js new file mode 100644 index 00000000000..c25eb0b9e8f Binary files /dev/null and b/cultures/kendo.culture.sr-Latn-ME.js differ diff --git a/cultures/kendo.culture.sr-Latn-RS.js b/cultures/kendo.culture.sr-Latn-RS.js new file mode 100644 index 00000000000..a7dc013460a Binary files /dev/null and b/cultures/kendo.culture.sr-Latn-RS.js differ diff --git a/cultures/kendo.culture.sr-Latn.js b/cultures/kendo.culture.sr-Latn.js new file mode 100644 index 00000000000..cc51e5d57fe Binary files /dev/null and b/cultures/kendo.culture.sr-Latn.js differ diff --git a/cultures/kendo.culture.sr.js b/cultures/kendo.culture.sr.js new file mode 100644 index 00000000000..539aec6ea6b Binary files /dev/null and b/cultures/kendo.culture.sr.js differ diff --git a/cultures/kendo.culture.sv-FI.js b/cultures/kendo.culture.sv-FI.js new file mode 100644 index 00000000000..9f1d76510b8 Binary files /dev/null and b/cultures/kendo.culture.sv-FI.js differ diff --git a/cultures/kendo.culture.sv-SE.js b/cultures/kendo.culture.sv-SE.js new file mode 100644 index 00000000000..ba2c682d52c Binary files /dev/null and b/cultures/kendo.culture.sv-SE.js differ diff --git a/cultures/kendo.culture.sv.js b/cultures/kendo.culture.sv.js new file mode 100644 index 00000000000..fee6a4443c3 Binary files /dev/null and b/cultures/kendo.culture.sv.js differ diff --git a/cultures/kendo.culture.sw-KE.js b/cultures/kendo.culture.sw-KE.js new file mode 100644 index 00000000000..5d88ccbe852 Binary files /dev/null and b/cultures/kendo.culture.sw-KE.js differ diff --git a/cultures/kendo.culture.sw.js b/cultures/kendo.culture.sw.js new file mode 100644 index 00000000000..d6a9fcf1669 Binary files /dev/null and b/cultures/kendo.culture.sw.js differ diff --git a/cultures/kendo.culture.syr-SY.js b/cultures/kendo.culture.syr-SY.js new file mode 100644 index 00000000000..ea13b927724 Binary files /dev/null and b/cultures/kendo.culture.syr-SY.js differ diff --git a/cultures/kendo.culture.syr.js b/cultures/kendo.culture.syr.js new file mode 100644 index 00000000000..6b7da4f568b Binary files /dev/null and b/cultures/kendo.culture.syr.js differ diff --git a/cultures/kendo.culture.ta-IN.js b/cultures/kendo.culture.ta-IN.js new file mode 100644 index 00000000000..87f543e3113 Binary files /dev/null and b/cultures/kendo.culture.ta-IN.js differ diff --git a/cultures/kendo.culture.ta.js b/cultures/kendo.culture.ta.js new file mode 100644 index 00000000000..cb9e750043c Binary files /dev/null and b/cultures/kendo.culture.ta.js differ diff --git a/cultures/kendo.culture.te-IN.js b/cultures/kendo.culture.te-IN.js new file mode 100644 index 00000000000..92daf80f939 Binary files /dev/null and b/cultures/kendo.culture.te-IN.js differ diff --git a/cultures/kendo.culture.te.js b/cultures/kendo.culture.te.js new file mode 100644 index 00000000000..dbdd3642a3f Binary files /dev/null and b/cultures/kendo.culture.te.js differ diff --git a/cultures/kendo.culture.tg-Cyrl-TJ.js b/cultures/kendo.culture.tg-Cyrl-TJ.js new file mode 100644 index 00000000000..2730a9e2bb7 Binary files /dev/null and b/cultures/kendo.culture.tg-Cyrl-TJ.js differ diff --git a/cultures/kendo.culture.tg-Cyrl.js b/cultures/kendo.culture.tg-Cyrl.js new file mode 100644 index 00000000000..b781fecf048 Binary files /dev/null and b/cultures/kendo.culture.tg-Cyrl.js differ diff --git a/cultures/kendo.culture.tg.js b/cultures/kendo.culture.tg.js new file mode 100644 index 00000000000..2c1785da163 Binary files /dev/null and b/cultures/kendo.culture.tg.js differ diff --git a/cultures/kendo.culture.th-TH.js b/cultures/kendo.culture.th-TH.js new file mode 100644 index 00000000000..ed6817bbe9b Binary files /dev/null and b/cultures/kendo.culture.th-TH.js differ diff --git a/cultures/kendo.culture.th.js b/cultures/kendo.culture.th.js new file mode 100644 index 00000000000..bbf8f8d7097 Binary files /dev/null and b/cultures/kendo.culture.th.js differ diff --git a/cultures/kendo.culture.tk-TM.js b/cultures/kendo.culture.tk-TM.js new file mode 100644 index 00000000000..700deaa1b66 Binary files /dev/null and b/cultures/kendo.culture.tk-TM.js differ diff --git a/cultures/kendo.culture.tk.js b/cultures/kendo.culture.tk.js new file mode 100644 index 00000000000..0a0b8c50b81 Binary files /dev/null and b/cultures/kendo.culture.tk.js differ diff --git a/cultures/kendo.culture.tn-ZA.js b/cultures/kendo.culture.tn-ZA.js new file mode 100644 index 00000000000..47597a59a27 Binary files /dev/null and b/cultures/kendo.culture.tn-ZA.js differ diff --git a/cultures/kendo.culture.tn.js b/cultures/kendo.culture.tn.js new file mode 100644 index 00000000000..5d94292225d Binary files /dev/null and b/cultures/kendo.culture.tn.js differ diff --git a/cultures/kendo.culture.tr-TR.js b/cultures/kendo.culture.tr-TR.js new file mode 100644 index 00000000000..64869bba205 Binary files /dev/null and b/cultures/kendo.culture.tr-TR.js differ diff --git a/cultures/kendo.culture.tr.js b/cultures/kendo.culture.tr.js new file mode 100644 index 00000000000..3dc6b99ae09 Binary files /dev/null and b/cultures/kendo.culture.tr.js differ diff --git a/cultures/kendo.culture.tt-RU.js b/cultures/kendo.culture.tt-RU.js new file mode 100644 index 00000000000..311c6b74556 Binary files /dev/null and b/cultures/kendo.culture.tt-RU.js differ diff --git a/cultures/kendo.culture.tt.js b/cultures/kendo.culture.tt.js new file mode 100644 index 00000000000..5c38b08805d Binary files /dev/null and b/cultures/kendo.culture.tt.js differ diff --git a/cultures/kendo.culture.tzm-Latn-DZ.js b/cultures/kendo.culture.tzm-Latn-DZ.js new file mode 100644 index 00000000000..f9a145d25af Binary files /dev/null and b/cultures/kendo.culture.tzm-Latn-DZ.js differ diff --git a/cultures/kendo.culture.tzm-Latn.js b/cultures/kendo.culture.tzm-Latn.js new file mode 100644 index 00000000000..70d611f960e Binary files /dev/null and b/cultures/kendo.culture.tzm-Latn.js differ diff --git a/cultures/kendo.culture.tzm.js b/cultures/kendo.culture.tzm.js new file mode 100644 index 00000000000..7310efc6c6f Binary files /dev/null and b/cultures/kendo.culture.tzm.js differ diff --git a/cultures/kendo.culture.ug-CN.js b/cultures/kendo.culture.ug-CN.js new file mode 100644 index 00000000000..07b031b4d3f Binary files /dev/null and b/cultures/kendo.culture.ug-CN.js differ diff --git a/cultures/kendo.culture.ug.js b/cultures/kendo.culture.ug.js new file mode 100644 index 00000000000..d43e9fef425 Binary files /dev/null and b/cultures/kendo.culture.ug.js differ diff --git a/cultures/kendo.culture.uk-UA.js b/cultures/kendo.culture.uk-UA.js new file mode 100644 index 00000000000..570af75f598 Binary files /dev/null and b/cultures/kendo.culture.uk-UA.js differ diff --git a/cultures/kendo.culture.uk.js b/cultures/kendo.culture.uk.js new file mode 100644 index 00000000000..3232b0a13d9 Binary files /dev/null and b/cultures/kendo.culture.uk.js differ diff --git a/cultures/kendo.culture.ur-PK.js b/cultures/kendo.culture.ur-PK.js new file mode 100644 index 00000000000..2417488a420 Binary files /dev/null and b/cultures/kendo.culture.ur-PK.js differ diff --git a/cultures/kendo.culture.ur.js b/cultures/kendo.culture.ur.js new file mode 100644 index 00000000000..2606dfd0e57 Binary files /dev/null and b/cultures/kendo.culture.ur.js differ diff --git a/cultures/kendo.culture.uz-Cyrl-UZ.js b/cultures/kendo.culture.uz-Cyrl-UZ.js new file mode 100644 index 00000000000..d3eda7089c5 Binary files /dev/null and b/cultures/kendo.culture.uz-Cyrl-UZ.js differ diff --git a/cultures/kendo.culture.uz-Cyrl.js b/cultures/kendo.culture.uz-Cyrl.js new file mode 100644 index 00000000000..29723bc245c Binary files /dev/null and b/cultures/kendo.culture.uz-Cyrl.js differ diff --git a/cultures/kendo.culture.uz-Latn-UZ.js b/cultures/kendo.culture.uz-Latn-UZ.js new file mode 100644 index 00000000000..c0efd988723 Binary files /dev/null and b/cultures/kendo.culture.uz-Latn-UZ.js differ diff --git a/cultures/kendo.culture.uz-Latn.js b/cultures/kendo.culture.uz-Latn.js new file mode 100644 index 00000000000..39b3287c796 Binary files /dev/null and b/cultures/kendo.culture.uz-Latn.js differ diff --git a/cultures/kendo.culture.uz.js b/cultures/kendo.culture.uz.js new file mode 100644 index 00000000000..0238102d2bd Binary files /dev/null and b/cultures/kendo.culture.uz.js differ diff --git a/cultures/kendo.culture.vi-VN.js b/cultures/kendo.culture.vi-VN.js new file mode 100644 index 00000000000..b965136354a Binary files /dev/null and b/cultures/kendo.culture.vi-VN.js differ diff --git a/cultures/kendo.culture.vi.js b/cultures/kendo.culture.vi.js new file mode 100644 index 00000000000..ae84617b0ba Binary files /dev/null and b/cultures/kendo.culture.vi.js differ diff --git a/cultures/kendo.culture.wo-SN.js b/cultures/kendo.culture.wo-SN.js new file mode 100644 index 00000000000..f988d900aa5 Binary files /dev/null and b/cultures/kendo.culture.wo-SN.js differ diff --git a/cultures/kendo.culture.wo.js b/cultures/kendo.culture.wo.js new file mode 100644 index 00000000000..811c02e8b47 Binary files /dev/null and b/cultures/kendo.culture.wo.js differ diff --git a/cultures/kendo.culture.xh-ZA.js b/cultures/kendo.culture.xh-ZA.js new file mode 100644 index 00000000000..8e313db424c Binary files /dev/null and b/cultures/kendo.culture.xh-ZA.js differ diff --git a/cultures/kendo.culture.xh.js b/cultures/kendo.culture.xh.js new file mode 100644 index 00000000000..ad62fa63c5e Binary files /dev/null and b/cultures/kendo.culture.xh.js differ diff --git a/cultures/kendo.culture.yo-NG.js b/cultures/kendo.culture.yo-NG.js new file mode 100644 index 00000000000..0b65d8260ae Binary files /dev/null and b/cultures/kendo.culture.yo-NG.js differ diff --git a/cultures/kendo.culture.yo.js b/cultures/kendo.culture.yo.js new file mode 100644 index 00000000000..aa9aad6340e Binary files /dev/null and b/cultures/kendo.culture.yo.js differ diff --git a/cultures/kendo.culture.zh-CHS.js b/cultures/kendo.culture.zh-CHS.js new file mode 100644 index 00000000000..7f7a039e3d0 Binary files /dev/null and b/cultures/kendo.culture.zh-CHS.js differ diff --git a/cultures/kendo.culture.zh-CHT.js b/cultures/kendo.culture.zh-CHT.js new file mode 100644 index 00000000000..7382cc052e2 Binary files /dev/null and b/cultures/kendo.culture.zh-CHT.js differ diff --git a/cultures/kendo.culture.zh-CN.js b/cultures/kendo.culture.zh-CN.js new file mode 100644 index 00000000000..619b3cbdf84 Binary files /dev/null and b/cultures/kendo.culture.zh-CN.js differ diff --git a/cultures/kendo.culture.zh-HK.js b/cultures/kendo.culture.zh-HK.js new file mode 100644 index 00000000000..6b5d16a0805 Binary files /dev/null and b/cultures/kendo.culture.zh-HK.js differ diff --git a/cultures/kendo.culture.zh-Hans.js b/cultures/kendo.culture.zh-Hans.js new file mode 100644 index 00000000000..e858e940924 Binary files /dev/null and b/cultures/kendo.culture.zh-Hans.js differ diff --git a/cultures/kendo.culture.zh-Hant.js b/cultures/kendo.culture.zh-Hant.js new file mode 100644 index 00000000000..e0bacf750aa Binary files /dev/null and b/cultures/kendo.culture.zh-Hant.js differ diff --git a/cultures/kendo.culture.zh-MO.js b/cultures/kendo.culture.zh-MO.js new file mode 100644 index 00000000000..fd6bac8040f Binary files /dev/null and b/cultures/kendo.culture.zh-MO.js differ diff --git a/cultures/kendo.culture.zh-SG.js b/cultures/kendo.culture.zh-SG.js new file mode 100644 index 00000000000..12e5b3941c4 Binary files /dev/null and b/cultures/kendo.culture.zh-SG.js differ diff --git a/cultures/kendo.culture.zh-TW.js b/cultures/kendo.culture.zh-TW.js new file mode 100644 index 00000000000..3a7bb56aabb Binary files /dev/null and b/cultures/kendo.culture.zh-TW.js differ diff --git a/cultures/kendo.culture.zh.js b/cultures/kendo.culture.zh.js new file mode 100644 index 00000000000..63a2b7398db Binary files /dev/null and b/cultures/kendo.culture.zh.js differ diff --git a/cultures/kendo.culture.zu-ZA.js b/cultures/kendo.culture.zu-ZA.js new file mode 100644 index 00000000000..60a1dbd3c8b Binary files /dev/null and b/cultures/kendo.culture.zu-ZA.js differ diff --git a/cultures/kendo.culture.zu.js b/cultures/kendo.culture.zu.js new file mode 100644 index 00000000000..1030eb6a80b Binary files /dev/null and b/cultures/kendo.culture.zu.js differ diff --git a/globalization/CultureGenerator.exe b/globalization/CultureGenerator.exe new file mode 100644 index 00000000000..4252bdc532b Binary files /dev/null and b/globalization/CultureGenerator.exe differ diff --git a/globalization/kendo.culture.format.txt b/globalization/kendo.culture.format.txt new file mode 100644 index 00000000000..2ea532e20e6 --- /dev/null +++ b/globalization/kendo.culture.format.txt @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["{{Name}}"] = { + name: "{{Name}}", + numberFormat: { + pattern: {{NumberPattern}}, + decimals: {{NumberDecimalDigits}}, + ",": "{{NumberGroupSeparator}}", + ".": "{{NumberDecimalSeparator}}", + groupSize: {{NumberGroupSizes}}, + percent: { + pattern: {{PercentPattern}}, + decimals: {{PercentDecimalDigits}}, + ",": "{{PercentGroupSeparator}}", + ".": "{{PercentDecimalSeparator}}", + groupSize: {{PercentGroupSizes}}, + symbol: "{{PercentSymbol}}" + }, + currency: { + pattern: {{CurrencyPattern}}, + decimals: {{CurrencyDecimalDigits}}, + ",": "{{CurrencyGroupSeparator}}", + ".": "{{CurrencyDecimalSeparator}}", + groupSize: {{CurrencyGroupSizes}}, + symbol: "{{CurrencySymbol}}" + } + }, + calendars: { + standard: { + days: { + names: {{DayNames}}, + namesAbbr: {{AbbreviatedDayNames}}, + namesShort: {{ShortestDayNames}} + }, + months: { + names: {{MonthNames}}, + namesAbbr: {{AbbreviatedMonthNames}} + }, + AM: {{AM}}, + PM: {{PM}}, + patterns: { + d: "{{d}}", + D: "{{D}}", + F: "{{F}}", + g: "{{g}}", + G: "{{G}}", + m: "{{m}}", + M: "{{M}}", + s: "{{s}}", + t: "{{t}}", + T: "{{T}}", + u: "{{u}}", + y: "{{y}}", + Y: "{{Y}}" + }, + "/": "{{DateSeparator}}", + ":": "{{TimeSeparator}}", + firstDay: {{FirstDayOfWeek}} + } + } + } +})(this); diff --git a/globalization/source/CultureGenerator.sln b/globalization/source/CultureGenerator.sln new file mode 100644 index 00000000000..18326e721e5 --- /dev/null +++ b/globalization/source/CultureGenerator.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CultureGenerator", "CultureGenerator\CultureGenerator.csproj", "{74344FFE-8EA5-4308-9BE7-18E418A55699}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {74344FFE-8EA5-4308-9BE7-18E418A55699}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {74344FFE-8EA5-4308-9BE7-18E418A55699}.Debug|Any CPU.Build.0 = Debug|Any CPU + {74344FFE-8EA5-4308-9BE7-18E418A55699}.Release|Any CPU.ActiveCfg = Release|Any CPU + {74344FFE-8EA5-4308-9BE7-18E418A55699}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/globalization/source/CultureGenerator/CultureGenerator.csproj b/globalization/source/CultureGenerator/CultureGenerator.csproj new file mode 100644 index 00000000000..55913d4bea7 --- /dev/null +++ b/globalization/source/CultureGenerator/CultureGenerator.csproj @@ -0,0 +1,97 @@ + + + + Debug + x86 + 8.0.30703 + 2.0 + {74344FFE-8EA5-4308-9BE7-18E418A55699} + Exe + Properties + CultureGenerator + CultureGenerator + v4.0 + + + 512 + + + x86 + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + x86 + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + true + bin\Debug\ + DEBUG;TRACE + full + AnyCPU + bin\Debug\CultureGenerator.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + + + bin\Release\ + TRACE + true + pdbonly + AnyCPU + bin\Release\CultureGenerator.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/globalization/source/CultureGenerator/GlobalizationInfo.cs b/globalization/source/CultureGenerator/GlobalizationInfo.cs new file mode 100644 index 00000000000..d4d5c73439e --- /dev/null +++ b/globalization/source/CultureGenerator/GlobalizationInfo.cs @@ -0,0 +1,104 @@ +// (c) Copyright 2002-2010 Telerik +// This source is subject to the GNU General Public License, version 2 +// See http://www.gnu.org/licenses/gpl-2.0.html. +// All other rights reserved. + +namespace CultureGenerator +{ + using System.Globalization; + using System.Collections.Generic; + using System.Web.Script.Serialization; + + public static class GlobalizationInfo + { + static string[] numberNegativePatterns = new string[] { "(n)", "-n", "- n", "n-", "n -" }; + + static string[] currencyPositivePatterns = new string[] { "$n", "n$", "$ n", "n $" }; + static string[] currencyNegativePatterns = new string[] { "($n)", "-$n", "$-n", "$n-", "(n$)", "-n$", "n-$", "n$-", "-n $", "-$ n", "n $-", "$ n-", "$ -n", "n- $", "($ n)", "(n $)" }; + + static string[] percentPositivePatterns = new string[] { "n %", "n%", "%n", "% n" }; + static string[] percentNegativePatterns = new string[] { "-n %", "-n%", "-%n", "%-n", "%n-", "n-%", "n%-", "-% n", "n %-", "% n-", "% -n", "n- %" }; + + private static IDictionary BuildFlatDictionary(CultureInfo cultureInfo) + { + NumberFormatInfo numberFormats = cultureInfo.NumberFormat; + DateTimeFormatInfo dateTimeFormats = cultureInfo.DateTimeFormat; + + IDictionary globalization = new Dictionary(); + + globalization["Name"] = cultureInfo.Name; + + //number info + globalization["NumberPattern"] = new string[] { numberNegativePatterns[cultureInfo.NumberFormat.NumberNegativePattern] }; + globalization["NumberDecimalDigits"] = cultureInfo.NumberFormat.NumberDecimalDigits; + globalization["NumberGroupSeparator"] = numberFormats.NumberGroupSeparator; + globalization["NumberDecimalSeparator"] = numberFormats.NumberDecimalSeparator; + globalization["NumberGroupSizes"] = numberFormats.NumberGroupSizes; + + //percent info + globalization["PercentPattern"] = new string[] { percentNegativePatterns[cultureInfo.NumberFormat.PercentNegativePattern], percentPositivePatterns[cultureInfo.NumberFormat.PercentPositivePattern] }; + globalization["PercentDecimalDigits"] = cultureInfo.NumberFormat.PercentDecimalDigits; + globalization["PercentGroupSeparator"] = numberFormats.PercentGroupSeparator; + globalization["PercentDecimalSeparator"] = numberFormats.PercentDecimalSeparator; + globalization["PercentGroupSizes"] = numberFormats.PercentGroupSizes; + globalization["PercentSymbol"] = numberFormats.PercentSymbol; + + //currency info + globalization["CurrencyPattern"] = new string[] { currencyNegativePatterns[cultureInfo.NumberFormat.CurrencyNegativePattern], currencyPositivePatterns[cultureInfo.NumberFormat.CurrencyPositivePattern] }; + globalization["CurrencyDecimalDigits"] = cultureInfo.NumberFormat.CurrencyDecimalDigits; + globalization["CurrencyGroupSeparator"] = numberFormats.CurrencyGroupSeparator; + globalization["CurrencyDecimalSeparator"] = numberFormats.CurrencyDecimalSeparator; + globalization["CurrencyGroupSizes"] = numberFormats.CurrencyGroupSizes; + globalization["CurrencySymbol"] = numberFormats.CurrencySymbol; + + //standard calendar info + globalization["DayNames"] = dateTimeFormats.DayNames; + globalization["AbbreviatedDayNames"] = dateTimeFormats.AbbreviatedDayNames; + globalization["ShortestDayNames"] = dateTimeFormats.ShortestDayNames; + + globalization["MonthNames"] = dateTimeFormats.MonthNames; + globalization["AbbreviatedMonthNames"] = dateTimeFormats.AbbreviatedMonthNames; + + globalization["d"] = dateTimeFormats.ShortDatePattern; + globalization["D"] = dateTimeFormats.LongDatePattern; + globalization["F"] = dateTimeFormats.FullDateTimePattern; + globalization["g"] = dateTimeFormats.ShortDatePattern + " " + dateTimeFormats.ShortTimePattern; + globalization["G"] = dateTimeFormats.ShortDatePattern + " " + dateTimeFormats.LongTimePattern; + globalization["m"] = dateTimeFormats.MonthDayPattern; + globalization["M"] = dateTimeFormats.MonthDayPattern; + globalization["s"] = dateTimeFormats.SortableDateTimePattern; + globalization["t"] = dateTimeFormats.ShortTimePattern; + globalization["T"] = dateTimeFormats.LongTimePattern; + globalization["u"] = dateTimeFormats.UniversalSortableDateTimePattern; + globalization["y"] = dateTimeFormats.YearMonthPattern; + globalization["Y"] = dateTimeFormats.YearMonthPattern; + + var am = dateTimeFormats.AMDesignator; + var pm = dateTimeFormats.PMDesignator; + + globalization["AM"] = string.IsNullOrEmpty(am) ? new string[] { am } : new string[] { am, am.ToLower(cultureInfo), am.ToUpper(cultureInfo) }; + globalization["PM"] = string.IsNullOrEmpty(pm) ? new string[] { am } : new string[] { pm, pm.ToLower(cultureInfo), pm.ToUpper(cultureInfo) }; + globalization["DateSeparator"] = dateTimeFormats.DateSeparator; + globalization["TimeSeparator"] = dateTimeFormats.TimeSeparator; + globalization["FirstDayOfWeek"] = (int)dateTimeFormats.FirstDayOfWeek; + + return globalization; + } + + public static string Format(this CultureInfo cultureInfo, string culturePattern) + { + var serializer = new JavaScriptSerializer(); + var cultureDictionary = BuildFlatDictionary(cultureInfo); + + foreach (KeyValuePair pair in cultureDictionary) + { + var key = pair.Key; + var value = pair.Value; + + culturePattern = culturePattern.Replace("{{" + key + "}}", value is System.Array ? serializer.Serialize(value) : System.Convert.ToString(value, cultureInfo)); + } + + return culturePattern; + } + } +} \ No newline at end of file diff --git a/globalization/source/CultureGenerator/Program.cs b/globalization/source/CultureGenerator/Program.cs new file mode 100644 index 00000000000..e5710bd92f4 --- /dev/null +++ b/globalization/source/CultureGenerator/Program.cs @@ -0,0 +1,107 @@ +namespace CultureGenerator +{ + using System; + using System.IO; + using System.Linq; + using System.Text; + using System.Globalization; + using System.Collections.Generic; + + class Program + { + static string filePrefix = "kendo.culture"; + static string outputPath = "C:\\work\\kendo\\src\\cultures"; + static string culturePatternPath = "kendo.culture.format.txt"; + static string culturePattern = ""; + + static void Main(string[] args) + { + Console.WriteLine("/*** Culture Generator ***/"); + + List cultures = null; + + foreach (string param in args) + { + if (param.StartsWith("--path=")) + { + outputPath = param.Substring("--path=".Length); + } + else if (param.StartsWith("--pattern-path=")) + { + culturePatternPath = param.Substring("--pattern-path=".Length); + } + else if (param.StartsWith("--culture=")) + { + try + { + cultures = new List { + new CultureInfo(param.Substring("--culture=".Length)) + }; + } + catch (Exception ex) + { + Console.WriteLine(ex.Message); + return; + } + } + else if (param.StartsWith("--file-prefix=")) + { + filePrefix = param.Substring("--file-prefix=".Length); + } + else if (param == "--help") + { + Console.Write(@" +Usage:CultureGenerator [] + +options: + --culture= The name of the culture to generate script from + + --path= The output path where the file will be created. Default: C:\Work\Kendo\src\cultures + + --pattern-path= Full Path to the culture pattern used to generate culture.js files. Default: current folder\pattern name => .\kendo.culture.format.txt + + --file-prefix= The prefix of the culture file name. Default: kendo.globalize +"); + return; + } + } + + Console.WriteLine("Retrieve culture pattern..."); + try + { + Console.WriteLine(culturePatternPath); + culturePattern = File.ReadAllText(culturePatternPath); + } + catch (FileNotFoundException ex) + { + Console.WriteLine("error: FileNotFoundException!"); + Console.WriteLine(ex.Message); + return; + } + + Directory.CreateDirectory(outputPath); + + Console.WriteLine("Start generating culture files..."); + + if (cultures == null) + { + cultures = CultureInfo.GetCultures(CultureTypes.AllCultures).ToList(); + } + + //Generate {filePrefix}.culture.{cultureName}.js for all cultures. + cultures.ForEach(WriteCulture); + + Console.WriteLine("End..."); + } + + private static void WriteCulture(CultureInfo cultureInfo) + { + if (!string.IsNullOrEmpty(cultureInfo.Name)) + { + var filePath = String.Format(@"{0}\{1}.{2}.js", outputPath, filePrefix, cultureInfo.Name); + File.WriteAllText(filePath, cultureInfo.Format(culturePattern), Encoding.UTF8); + Console.WriteLine(filePath); + } + } + } +} diff --git a/globalization/source/CultureGenerator/Properties/AssemblyInfo.cs b/globalization/source/CultureGenerator/Properties/AssemblyInfo.cs new file mode 100644 index 00000000000..ae14b2984b5 --- /dev/null +++ b/globalization/source/CultureGenerator/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("CultureGenerator")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyProduct("CultureGenerator")] +[assembly: AssemblyCopyright("Copyright © Microsoft 2011")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("555407d1-6b44-4557-b0d2-8d7c66c849eb")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/globalization/source/CultureGenerator/app.config b/globalization/source/CultureGenerator/app.config new file mode 100644 index 00000000000..cb2586beb1d --- /dev/null +++ b/globalization/source/CultureGenerator/app.config @@ -0,0 +1,3 @@ + + + diff --git a/globalization/source/CultureGenerator/kendo.culture.format.txt b/globalization/source/CultureGenerator/kendo.culture.format.txt new file mode 100644 index 00000000000..34ad9a24df7 --- /dev/null +++ b/globalization/source/CultureGenerator/kendo.culture.format.txt @@ -0,0 +1,70 @@ +/* + * Kendo Culture {{Name}} + * + * Copyright Software Freedom Conservancy, Inc. + * Dual licensed under the MIT or GPL Version 2 licenses. + * + * This file was generated by the Kendo Culture Generator + * Translation: bugs found in this file need to be fixed in the generator + */ + +(function( window, undefined ) { + kendo.cultures["{{Name}}"] = { + name: "{{Name}}", + numberFormat: { + pattern: {{NumberPattern}}, + decimals: {{NumberDecimalDigits}}, + ",": "{{NumberGroupSeparator}}", + ".": "{{NumberDecimalSeparator}}", + groupSize: {{NumberGroupSizes}}, + percent: { + pattern: {{PercentPattern}}, + decimals: {{PercentDecimalDigits}}, + ",": "{{PercentGroupSeparator}}", + ".": "{{PercentDecimalSeparator}}", + groupSize: {{PercentGroupSizes}}, + symbol: "{{PercentSymbol}}" + }, + currency: { + pattern: {{CurrencyPattern}}, + decimals: {{CurrencyDecimalDigits}}, + ",": "{{CurrencyGroupSeparator}}", + ".": "{{CurrencyDecimalSeparator}}", + groupSize: {{CurrencyGroupSizes}}, + symbol: "{{CurrencySymbol}}" + } + }, + calendars: { + standard: { + days: { + names: {{DayNames}}, + namesAbbr: {{AbbreviatedDayNames}}, + namesShort: {{ShortestDayNames}} + }, + months: { + names: {{MonthNames}}, + namesAbbr: {{AbbreviatedMonthNames}} + }, + AM: {{AM}}, + PM: {{PM}}, + patterns: { + d: "{{d}}", + D: "{{D}}", + F: "{{F}}", + g: "{{g}}", + G: "{{G}}", + m: "{{m}}", + M: "{{M}}", + s: "{{s}}", + t: "{{t}}", + T: "{{T}}", + u: "{{u}}", + y: "{{y}}", + Y: "{{Y}}" + }, + "/": "{{DateSeparator}}", + ":": "{{TimeSeparator}}" + } + } + } +})(this); diff --git a/package.json b/package.json new file mode 100644 index 00000000000..2389f54b0b7 --- /dev/null +++ b/package.json @@ -0,0 +1,40 @@ +{ + "name": "kendo", + "version": "1.0.0", + "dependencies": { + "optimist": "0.3.7", + "typescript": ">=0.9.1", + "uglify-js": "2.4.8", + "cssmin": "0.3.2", + "faye": "0.8.3", + "xmlbuilder": "0.4.2", + "colors": "0.6.0-1", + "cookiejar": "1.3.0", + "faye-websocket": "0.4.4", + "less": "1.3.3", + "jshint": "1.1.0" + }, + "devDependencies": { + "grunt": "~0.4.2", + "grunt-cli": "~0.1.0", + "grunt-contrib-jshint": "~0.7.2", + "grunt-contrib-copy": "~0.5.0", + "grunt-debug-task": "0.1.3", + "grunt-karma": "*", + + "qunitjs": "~1.12.0", + "karma": "~0.11", + "karma-browserstack-launcher": "*", + "karma-chrome-launcher": "*", + "karma-html2js-preprocessor": "*", + "karma": "0.10.5", + "karma-browserstack-launcher": "~0.0.1", + "karma-chrome-launcher": "~0.1", + "karma-html2js-preprocessor": "~0.1", + "karma-sauce-launcher": "*", + "karma-qunit": "*", + "karma-junit-reporter": "0.2.1", + "karma-osx-reporter": "0.0.4", + "karma-ie-launcher": "~0.1" + } +} diff --git a/resources/legal/public-license.txt b/resources/legal/public-license.txt new file mode 100644 index 00000000000..046b47cca0f --- /dev/null +++ b/resources/legal/public-license.txt @@ -0,0 +1,15 @@ +/** + * Copyright <%= year %> Telerik AD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ diff --git a/resources/legal/third-party/licenses.txt b/resources/legal/third-party/licenses.txt new file mode 100644 index 00000000000..f84e42103bb --- /dev/null +++ b/resources/legal/third-party/licenses.txt @@ -0,0 +1,27 @@ +The following open source libraries are used in Kendo UI + +-------------------------------------------------------------------------------- +jQuery JavaScript library + +Copyright (c) 2011 John Resig, http://jquery.com/ + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +https://raw.github.com/jquery/jquery/master/MIT-LICENSE.txt diff --git a/resources/psd/imagebrowser.psd b/resources/psd/imagebrowser.psd new file mode 100644 index 00000000000..528d2ee6d93 Binary files /dev/null and b/resources/psd/imagebrowser.psd differ diff --git a/resources/psd/sprite-vertical.psd b/resources/psd/sprite-vertical.psd new file mode 100644 index 00000000000..36475825a46 Binary files /dev/null and b/resources/psd/sprite-vertical.psd differ diff --git a/resources/psd/sprite.black.psd b/resources/psd/sprite.black.psd new file mode 100644 index 00000000000..acd53e90827 Binary files /dev/null and b/resources/psd/sprite.black.psd differ diff --git a/resources/psd/sprite.black@2x.psd b/resources/psd/sprite.black@2x.psd new file mode 100644 index 00000000000..32d89b93d0d Binary files /dev/null and b/resources/psd/sprite.black@2x.psd differ diff --git a/resources/psd/sprite.blueopal.psd b/resources/psd/sprite.blueopal.psd new file mode 100644 index 00000000000..4fd07b6ab7e Binary files /dev/null and b/resources/psd/sprite.blueopal.psd differ diff --git a/resources/psd/sprite.blueopal@2x.psd b/resources/psd/sprite.blueopal@2x.psd new file mode 100644 index 00000000000..1b8a0890ca7 Binary files /dev/null and b/resources/psd/sprite.blueopal@2x.psd differ diff --git a/resources/psd/sprite.bootstrap.psd b/resources/psd/sprite.bootstrap.psd new file mode 100644 index 00000000000..6870d47b50e Binary files /dev/null and b/resources/psd/sprite.bootstrap.psd differ diff --git a/resources/psd/sprite.bootstrap@2x.psd b/resources/psd/sprite.bootstrap@2x.psd new file mode 100644 index 00000000000..2ae6abea753 Binary files /dev/null and b/resources/psd/sprite.bootstrap@2x.psd differ diff --git a/resources/psd/sprite.default.psd b/resources/psd/sprite.default.psd new file mode 100644 index 00000000000..53a4a17383a Binary files /dev/null and b/resources/psd/sprite.default.psd differ diff --git a/resources/psd/sprite.default@2x.psd b/resources/psd/sprite.default@2x.psd new file mode 100644 index 00000000000..2afcb12c1f0 Binary files /dev/null and b/resources/psd/sprite.default@2x.psd differ diff --git a/resources/psd/sprite.devices.psd b/resources/psd/sprite.devices.psd new file mode 100644 index 00000000000..25e36d4ce55 Binary files /dev/null and b/resources/psd/sprite.devices.psd differ diff --git a/resources/psd/sprite.examples.misc.psd b/resources/psd/sprite.examples.misc.psd new file mode 100644 index 00000000000..9ce00b9b268 Binary files /dev/null and b/resources/psd/sprite.examples.misc.psd differ diff --git a/resources/psd/sprite.examples.psd b/resources/psd/sprite.examples.psd new file mode 100644 index 00000000000..c086e2eaeb3 Binary files /dev/null and b/resources/psd/sprite.examples.psd differ diff --git a/resources/psd/sprite.examples.widgets.psd b/resources/psd/sprite.examples.widgets.psd new file mode 100644 index 00000000000..cd36b6dc364 Binary files /dev/null and b/resources/psd/sprite.examples.widgets.psd differ diff --git a/resources/psd/sprite.flat.psd b/resources/psd/sprite.flat.psd new file mode 100644 index 00000000000..f963e5a0960 Binary files /dev/null and b/resources/psd/sprite.flat.psd differ diff --git a/resources/psd/sprite.flat@2x.psd b/resources/psd/sprite.flat@2x.psd new file mode 100644 index 00000000000..05649961c2e Binary files /dev/null and b/resources/psd/sprite.flat@2x.psd differ diff --git a/resources/psd/sprite.highcontrast.psd b/resources/psd/sprite.highcontrast.psd new file mode 100644 index 00000000000..133f4e54fba Binary files /dev/null and b/resources/psd/sprite.highcontrast.psd differ diff --git a/resources/psd/sprite.highcontrast@2x.psd b/resources/psd/sprite.highcontrast@2x.psd new file mode 100644 index 00000000000..97f6ae05011 Binary files /dev/null and b/resources/psd/sprite.highcontrast@2x.psd differ diff --git a/resources/psd/sprite.metrogreen.psd b/resources/psd/sprite.metrogreen.psd new file mode 100644 index 00000000000..4b2bdcebe1a Binary files /dev/null and b/resources/psd/sprite.metrogreen.psd differ diff --git a/resources/psd/sprite.minimal.psd b/resources/psd/sprite.minimal.psd new file mode 100644 index 00000000000..a760969f072 Binary files /dev/null and b/resources/psd/sprite.minimal.psd differ diff --git a/resources/psd/sprite.minimal@2x.psd b/resources/psd/sprite.minimal@2x.psd new file mode 100644 index 00000000000..daa1830e5ec Binary files /dev/null and b/resources/psd/sprite.minimal@2x.psd differ diff --git a/resources/psd/sprite.minimalblack.psd b/resources/psd/sprite.minimalblack.psd new file mode 100644 index 00000000000..2ab30a62a93 Binary files /dev/null and b/resources/psd/sprite.minimalblack.psd differ diff --git a/resources/psd/sprite.minimalblack@2x.psd b/resources/psd/sprite.minimalblack@2x.psd new file mode 100644 index 00000000000..2f7cbbd7022 Binary files /dev/null and b/resources/psd/sprite.minimalblack@2x.psd differ diff --git a/resources/psd/sprite.moonlight.psd b/resources/psd/sprite.moonlight.psd new file mode 100644 index 00000000000..49a49ae510e Binary files /dev/null and b/resources/psd/sprite.moonlight.psd differ diff --git a/resources/psd/sprite.moonlight@2x.psd b/resources/psd/sprite.moonlight@2x.psd new file mode 100644 index 00000000000..0ec1b8b041f Binary files /dev/null and b/resources/psd/sprite.moonlight@2x.psd differ diff --git a/resources/psd/sprite.silver.psd b/resources/psd/sprite.silver.psd new file mode 100644 index 00000000000..898e17bb1a5 Binary files /dev/null and b/resources/psd/sprite.silver.psd differ diff --git a/resources/psd/sprite.silver@2x.psd b/resources/psd/sprite.silver@2x.psd new file mode 100644 index 00000000000..397e219a9b6 Binary files /dev/null and b/resources/psd/sprite.silver@2x.psd differ diff --git a/resources/psd/sprite.uniform.psd b/resources/psd/sprite.uniform.psd new file mode 100644 index 00000000000..f5df9d43412 Binary files /dev/null and b/resources/psd/sprite.uniform.psd differ diff --git a/resources/psd/sprite.uniform@2x.psd b/resources/psd/sprite.uniform@2x.psd new file mode 100644 index 00000000000..10364fbf70b Binary files /dev/null and b/resources/psd/sprite.uniform@2x.psd differ diff --git a/src/cultures/kendo.culture.af-ZA.js b/src/cultures/kendo.culture.af-ZA.js new file mode 100644 index 00000000000..86a9a4dad38 --- /dev/null +++ b/src/cultures/kendo.culture.af-ZA.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["af-ZA"] = { + name: "af-ZA", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$-n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "R" + } + }, + calendars: { + standard: { + days: { + names: ["Sondag","Maandag","Dinsdag","Woensdag","Donderdag","Vrydag","Saterdag"], + namesAbbr: ["Son","Maan","Dins","Woen","Dond","Vry","Sat"], + namesShort: ["So","Ma","Di","Wo","Do","Vr","Sa"] + }, + months: { + names: ["Januarie","Februarie","Maart","April","Mei","Junie","Julie","Augustus","September","Oktober","November","Desember",""], + namesAbbr: ["Jan","Feb","Mar","Apr","Mei","Jun","Jul","Aug","Sep","Okt","Nov","Des",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "yyyy/MM/dd", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy hh:mm:ss tt", + g: "yyyy/MM/dd hh:mm tt", + G: "yyyy/MM/dd hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.af.js b/src/cultures/kendo.culture.af.js new file mode 100644 index 00000000000..3385f124f10 --- /dev/null +++ b/src/cultures/kendo.culture.af.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["af"] = { + name: "af", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$-n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "R" + } + }, + calendars: { + standard: { + days: { + names: ["Sondag","Maandag","Dinsdag","Woensdag","Donderdag","Vrydag","Saterdag"], + namesAbbr: ["Son","Maan","Dins","Woen","Dond","Vry","Sat"], + namesShort: ["So","Ma","Di","Wo","Do","Vr","Sa"] + }, + months: { + names: ["Januarie","Februarie","Maart","April","Mei","Junie","Julie","Augustus","September","Oktober","November","Desember",""], + namesAbbr: ["Jan","Feb","Mar","Apr","Mei","Jun","Jul","Aug","Sep","Okt","Nov","Des",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "yyyy/MM/dd", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy hh:mm:ss tt", + g: "yyyy/MM/dd hh:mm tt", + G: "yyyy/MM/dd hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.am-ET.js b/src/cultures/kendo.culture.am-ET.js new file mode 100644 index 00000000000..be96e09ce20 --- /dev/null +++ b/src/cultures/kendo.culture.am-ET.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["am-ET"] = { + name: "am-ET", + numberFormat: { + pattern: ["-n"], + decimals: 1, + ",": ",", + ".": ".", + groupSize: [3,0], + percent: { + pattern: ["-n%","n%"], + decimals: 1, + ",": ",", + ".": ".", + groupSize: [3,0], + symbol: "%" + }, + currency: { + pattern: ["-$n","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + symbol: "ETB" + } + }, + calendars: { + standard: { + days: { + names: ["እሑድ","ሰኞ","ማክሰኞ","ረቡዕ","ሐሙስ","ዓርብ","ቅዳሜ"], + namesAbbr: ["እሑድ","ሰኞ","ማክሰ","ረቡዕ","ሐሙስ","ዓርብ","ቅዳሜ"], + namesShort: ["እ","ሰ","ማ","ረ","ሐ","ዓ","ቅ"] + }, + months: { + names: ["ጃንዩወሪ","ፌብሩወሪ","ማርች","ኤፕረል","ሜይ","ጁን","ጁላይ","ኦገስት","ሴፕቴምበር","ኦክተውበር","ኖቬምበር","ዲሴምበር",""], + namesAbbr: ["ጃንዩ","ፌብሩ","ማርች","ኤፕረ","ሜይ","ጁን","ጁላይ","ኦገስ","ሴፕቴ","ኦክተ","ኖቬም","ዲሴም",""] + }, + AM: ["ጡዋት","ጡዋት","ጡዋት"], + PM: ["ከሰዓት","ከሰዓት","ከሰዓት"], + patterns: { + d: "d/M/yyyy", + D: "dddd '፣' MMMM d 'ቀን' yyyy", + F: "dddd '፣' MMMM d 'ቀን' yyyy h:mm:ss tt", + g: "d/M/yyyy h:mm tt", + G: "d/M/yyyy h:mm:ss tt", + m: "MMMM d ቀን", + M: "MMMM d ቀን", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.am.js b/src/cultures/kendo.culture.am.js new file mode 100644 index 00000000000..c4091692f1b --- /dev/null +++ b/src/cultures/kendo.culture.am.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["am"] = { + name: "am", + numberFormat: { + pattern: ["-n"], + decimals: 1, + ",": ",", + ".": ".", + groupSize: [3,0], + percent: { + pattern: ["-n%","n%"], + decimals: 1, + ",": ",", + ".": ".", + groupSize: [3,0], + symbol: "%" + }, + currency: { + pattern: ["-$n","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + symbol: "ETB" + } + }, + calendars: { + standard: { + days: { + names: ["እሑድ","ሰኞ","ማክሰኞ","ረቡዕ","ሐሙስ","ዓርብ","ቅዳሜ"], + namesAbbr: ["እሑድ","ሰኞ","ማክሰ","ረቡዕ","ሐሙስ","ዓርብ","ቅዳሜ"], + namesShort: ["እ","ሰ","ማ","ረ","ሐ","ዓ","ቅ"] + }, + months: { + names: ["ጃንዩወሪ","ፌብሩወሪ","ማርች","ኤፕረል","ሜይ","ጁን","ጁላይ","ኦገስት","ሴፕቴምበር","ኦክተውበር","ኖቬምበር","ዲሴምበር",""], + namesAbbr: ["ጃንዩ","ፌብሩ","ማርች","ኤፕረ","ሜይ","ጁን","ጁላይ","ኦገስ","ሴፕቴ","ኦክተ","ኖቬም","ዲሴም",""] + }, + AM: ["ጡዋት","ጡዋት","ጡዋት"], + PM: ["ከሰዓት","ከሰዓት","ከሰዓት"], + patterns: { + d: "d/M/yyyy", + D: "dddd '፣' MMMM d 'ቀን' yyyy", + F: "dddd '፣' MMMM d 'ቀን' yyyy h:mm:ss tt", + g: "d/M/yyyy h:mm tt", + G: "d/M/yyyy h:mm:ss tt", + m: "MMMM d ቀን", + M: "MMMM d ቀን", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ar-AE.js b/src/cultures/kendo.culture.ar-AE.js new file mode 100644 index 00000000000..755c7f75577 --- /dev/null +++ b/src/cultures/kendo.culture.ar-AE.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ar-AE"] = { + name: "ar-AE", + numberFormat: { + pattern: ["n-"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$n-","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "د.إ.‏" + } + }, + calendars: { + standard: { + days: { + names: ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"], + namesAbbr: ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"], + namesShort: ["ح","ن","ث","ر","خ","ج","س"] + }, + months: { + names: ["يناير","فبراير","مارس","أبريل","مايو","يونيو","يوليو","أغسطس","سبتمبر","أكتوبر","نوفمبر","ديسمبر",""], + namesAbbr: ["يناير","فبراير","مارس","أبريل","مايو","يونيو","يوليو","أغسطس","سبتمبر","أكتوبر","نوفمبر","ديسمبر",""] + }, + AM: ["ص","ص","ص"], + PM: ["م","م","م"], + patterns: { + d: "dd/MM/yyyy", + D: "dd MMMM, yyyy", + F: "dd MMMM, yyyy hh:mm:ss tt", + g: "dd/MM/yyyy hh:mm tt", + G: "dd/MM/yyyy hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 6 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ar-BH.js b/src/cultures/kendo.culture.ar-BH.js new file mode 100644 index 00000000000..2bc0a6e3d5e --- /dev/null +++ b/src/cultures/kendo.culture.ar-BH.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ar-BH"] = { + name: "ar-BH", + numberFormat: { + pattern: ["n-"], + decimals: 3, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 3, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$n-","$ n"], + decimals: 3, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "د.ب.‏" + } + }, + calendars: { + standard: { + days: { + names: ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"], + namesAbbr: ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"], + namesShort: ["ح","ن","ث","ر","خ","ج","س"] + }, + months: { + names: ["يناير","فبراير","مارس","أبريل","مايو","يونيو","يوليو","أغسطس","سبتمبر","أكتوبر","نوفمبر","ديسمبر",""], + namesAbbr: ["يناير","فبراير","مارس","ابريل","مايو","يونيو","يوليو","اغسطس","سبتمبر","اكتوبر","نوفمبر","ديسمبر",""] + }, + AM: ["ص","ص","ص"], + PM: ["م","م","م"], + patterns: { + d: "dd/MM/yyyy", + D: "dd MMMM, yyyy", + F: "dd MMMM, yyyy hh:mm:ss tt", + g: "dd/MM/yyyy hh:mm tt", + G: "dd/MM/yyyy hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 6 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ar-DZ.js b/src/cultures/kendo.culture.ar-DZ.js new file mode 100644 index 00000000000..e4297dd8dfa --- /dev/null +++ b/src/cultures/kendo.culture.ar-DZ.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ar-DZ"] = { + name: "ar-DZ", + numberFormat: { + pattern: ["n-"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$n-","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "د.ج.‏" + } + }, + calendars: { + standard: { + days: { + names: ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"], + namesAbbr: ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"], + namesShort: ["ح","ن","ث","ر","خ","ج","س"] + }, + months: { + names: ["جانفييه","فيفرييه","مارس","أفريل","مي","جوان","جوييه","أوت","سبتمبر","أكتوبر","نوفمبر","ديسمبر",""], + namesAbbr: ["جانفييه","فيفرييه","مارس","أفريل","مي","جوان","جوييه","أوت","سبتمبر","أكتوبر","نوفمبر","ديسمبر",""] + }, + AM: ["ص","ص","ص"], + PM: ["م","م","م"], + patterns: { + d: "dd-MM-yyyy", + D: "dd MMMM, yyyy", + F: "dd MMMM, yyyy H:mm:ss", + g: "dd-MM-yyyy H:mm", + G: "dd-MM-yyyy H:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "-", + ":": ":", + firstDay: 6 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ar-EG.js b/src/cultures/kendo.culture.ar-EG.js new file mode 100644 index 00000000000..aed0d294dfe --- /dev/null +++ b/src/cultures/kendo.culture.ar-EG.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ar-EG"] = { + name: "ar-EG", + numberFormat: { + pattern: ["n-"], + decimals: 3, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 3, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$n-","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "ج.م.‏" + } + }, + calendars: { + standard: { + days: { + names: ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"], + namesAbbr: ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"], + namesShort: ["ح","ن","ث","ر","خ","ج","س"] + }, + months: { + names: ["يناير","فبراير","مارس","أبريل","مايو","يونيو","يوليو","أغسطس","سبتمبر","أكتوبر","نوفمبر","ديسمبر",""], + namesAbbr: ["يناير","فبراير","مارس","أبريل","مايو","يونيو","يوليو","أغسطس","سبتمبر","أكتوبر","نوفمبر","ديسمبر",""] + }, + AM: ["ص","ص","ص"], + PM: ["م","م","م"], + patterns: { + d: "dd/MM/yyyy", + D: "dd MMMM, yyyy", + F: "dd MMMM, yyyy hh:mm:ss tt", + g: "dd/MM/yyyy hh:mm tt", + G: "dd/MM/yyyy hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 6 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ar-IQ.js b/src/cultures/kendo.culture.ar-IQ.js new file mode 100644 index 00000000000..332ca4f0f9b --- /dev/null +++ b/src/cultures/kendo.culture.ar-IQ.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ar-IQ"] = { + name: "ar-IQ", + numberFormat: { + pattern: ["n-"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$n-","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "د.ع.‏" + } + }, + calendars: { + standard: { + days: { + names: ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"], + namesAbbr: ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"], + namesShort: ["ح","ن","ث","ر","خ","ج","س"] + }, + months: { + names: ["كانون الثاني","شباط","آذار","نيسان","أيار","حزيران","تموز","آب","أيلول","تشرين الأول","تشرين الثاني","كانون الأول",""], + namesAbbr: ["كانون الثاني","شباط","آذار","نيسان","أيار","حزيران","تموز","آب","أيلول","تشرين الأول","تشرين الثاني","كانون الأول",""] + }, + AM: ["ص","ص","ص"], + PM: ["م","م","م"], + patterns: { + d: "dd/MM/yyyy", + D: "dd MMMM, yyyy", + F: "dd MMMM, yyyy hh:mm:ss tt", + g: "dd/MM/yyyy hh:mm tt", + G: "dd/MM/yyyy hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 6 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ar-JO.js b/src/cultures/kendo.culture.ar-JO.js new file mode 100644 index 00000000000..17428b94e6d --- /dev/null +++ b/src/cultures/kendo.culture.ar-JO.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ar-JO"] = { + name: "ar-JO", + numberFormat: { + pattern: ["n-"], + decimals: 3, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 3, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$n-","$ n"], + decimals: 3, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "د.ا.‏" + } + }, + calendars: { + standard: { + days: { + names: ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"], + namesAbbr: ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"], + namesShort: ["ح","ن","ث","ر","خ","ج","س"] + }, + months: { + names: ["كانون الثاني","شباط","آذار","نيسان","أيار","حزيران","تموز","آب","أيلول","تشرين الأول","تشرين الثاني","كانون الأول",""], + namesAbbr: ["كانون الثاني","شباط","آذار","نيسان","أيار","حزيران","تموز","آب","أيلول","تشرين الأول","تشرين الثاني","كانون الأول",""] + }, + AM: ["ص","ص","ص"], + PM: ["م","م","م"], + patterns: { + d: "dd/MM/yyyy", + D: "dd MMMM, yyyy", + F: "dd MMMM, yyyy hh:mm:ss tt", + g: "dd/MM/yyyy hh:mm tt", + G: "dd/MM/yyyy hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 6 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ar-KW.js b/src/cultures/kendo.culture.ar-KW.js new file mode 100644 index 00000000000..6a5b9da04e7 --- /dev/null +++ b/src/cultures/kendo.culture.ar-KW.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ar-KW"] = { + name: "ar-KW", + numberFormat: { + pattern: ["n-"], + decimals: 3, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 3, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$n-","$ n"], + decimals: 3, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "د.ك.‏" + } + }, + calendars: { + standard: { + days: { + names: ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"], + namesAbbr: ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"], + namesShort: ["ح","ن","ث","ر","خ","ج","س"] + }, + months: { + names: ["يناير","فبراير","مارس","أبريل","مايو","يونيو","يوليو","أغسطس","سبتمبر","أكتوبر","نوفمبر","ديسمبر",""], + namesAbbr: ["يناير","فبراير","مارس","أبريل","مايو","يونيو","يوليو","أغسطس","سبتمبر","أكتوبر","نوفمبر","ديسمبر",""] + }, + AM: ["ص","ص","ص"], + PM: ["م","م","م"], + patterns: { + d: "dd/MM/yyyy", + D: "dd MMMM, yyyy", + F: "dd MMMM, yyyy hh:mm:ss tt", + g: "dd/MM/yyyy hh:mm tt", + G: "dd/MM/yyyy hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 6 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ar-LB.js b/src/cultures/kendo.culture.ar-LB.js new file mode 100644 index 00000000000..eddf8e7257b --- /dev/null +++ b/src/cultures/kendo.culture.ar-LB.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ar-LB"] = { + name: "ar-LB", + numberFormat: { + pattern: ["n-"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$n-","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "ل.ل.‏" + } + }, + calendars: { + standard: { + days: { + names: ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"], + namesAbbr: ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"], + namesShort: ["ح","ن","ث","ر","خ","ج","س"] + }, + months: { + names: ["كانون الثاني","شباط","آذار","نيسان","أيار","حزيران","تموز","آب","أيلول","تشرين الأول","تشرين الثاني","كانون الأول",""], + namesAbbr: ["كانون الثاني","شباط","آذار","نيسان","أيار","حزيران","تموز","آب","أيلول","تشرين الأول","تشرين الثاني","كانون الأول",""] + }, + AM: ["ص","ص","ص"], + PM: ["م","م","م"], + patterns: { + d: "dd/MM/yyyy", + D: "dd MMMM, yyyy", + F: "dd MMMM, yyyy hh:mm:ss tt", + g: "dd/MM/yyyy hh:mm tt", + G: "dd/MM/yyyy hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ar-LY.js b/src/cultures/kendo.culture.ar-LY.js new file mode 100644 index 00000000000..c2c76df9847 --- /dev/null +++ b/src/cultures/kendo.culture.ar-LY.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ar-LY"] = { + name: "ar-LY", + numberFormat: { + pattern: ["n-"], + decimals: 3, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 3, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$n-","$n"], + decimals: 3, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "د.ل.‏" + } + }, + calendars: { + standard: { + days: { + names: ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"], + namesAbbr: ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"], + namesShort: ["ح","ن","ث","ر","خ","ج","س"] + }, + months: { + names: ["يناير","فبراير","مارس","أبريل","مايو","يونيو","يوليو","أغسطس","سبتمبر","أكتوبر","نوفمبر","ديسمبر",""], + namesAbbr: ["يناير","فبراير","مارس","أبريل","مايو","يونيو","يوليو","أغسطس","سبتمبر","أكتوبر","نوفمبر","ديسمبر",""] + }, + AM: ["ص","ص","ص"], + PM: ["م","م","م"], + patterns: { + d: "dd/MM/yyyy", + D: "dd MMMM, yyyy", + F: "dd MMMM, yyyy hh:mm:ss tt", + g: "dd/MM/yyyy hh:mm tt", + G: "dd/MM/yyyy hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 6 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ar-MA.js b/src/cultures/kendo.culture.ar-MA.js new file mode 100644 index 00000000000..ee9f9ea45b8 --- /dev/null +++ b/src/cultures/kendo.culture.ar-MA.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ar-MA"] = { + name: "ar-MA", + numberFormat: { + pattern: ["n-"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$n-","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "د.م.‏" + } + }, + calendars: { + standard: { + days: { + names: ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"], + namesAbbr: ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"], + namesShort: ["ح","ن","ث","ر","خ","ج","س"] + }, + months: { + names: ["يناير","فبراير","مارس","أبريل","ماي","يونيو","يوليوز","غشت","شتنبر","أكتوبر","نونبر","دجنبر",""], + namesAbbr: ["يناير","فبراير","مارس","أبريل","ماي","يونيو","يوليوز","غشت","شتنبر","أكتوبر","نونبر","دجنبر",""] + }, + AM: ["ص","ص","ص"], + PM: ["م","م","م"], + patterns: { + d: "dd-MM-yyyy", + D: "dd MMMM, yyyy", + F: "dd MMMM, yyyy H:mm:ss", + g: "dd-MM-yyyy H:mm", + G: "dd-MM-yyyy H:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "-", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ar-OM.js b/src/cultures/kendo.culture.ar-OM.js new file mode 100644 index 00000000000..f29515a7c11 --- /dev/null +++ b/src/cultures/kendo.culture.ar-OM.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ar-OM"] = { + name: "ar-OM", + numberFormat: { + pattern: ["n-"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$n-","$ n"], + decimals: 3, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "ر.ع.‏" + } + }, + calendars: { + standard: { + days: { + names: ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"], + namesAbbr: ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"], + namesShort: ["ح","ن","ث","ر","خ","ج","س"] + }, + months: { + names: ["يناير","فبراير","مارس","أبريل","مايو","يونيو","يوليو","أغسطس","سبتمبر","أكتوبر","نوفمبر","ديسمبر",""], + namesAbbr: ["يناير","فبراير","مارس","أبريل","مايو","يونيو","يوليو","أغسطس","سبتمبر","أكتوبر","نوفمبر","ديسمبر",""] + }, + AM: ["ص","ص","ص"], + PM: ["م","م","م"], + patterns: { + d: "dd/MM/yyyy", + D: "dd MMMM, yyyy", + F: "dd MMMM, yyyy hh:mm:ss tt", + g: "dd/MM/yyyy hh:mm tt", + G: "dd/MM/yyyy hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 6 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ar-QA.js b/src/cultures/kendo.culture.ar-QA.js new file mode 100644 index 00000000000..c02e9d468ac --- /dev/null +++ b/src/cultures/kendo.culture.ar-QA.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ar-QA"] = { + name: "ar-QA", + numberFormat: { + pattern: ["n-"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$n-","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "ر.ق.‏" + } + }, + calendars: { + standard: { + days: { + names: ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"], + namesAbbr: ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"], + namesShort: ["ح","ن","ث","ر","خ","ج","س"] + }, + months: { + names: ["يناير","فبراير","مارس","أبريل","مايو","يونيو","يوليو","أغسطس","سبتمبر","أكتوبر","نوفمبر","ديسمبر",""], + namesAbbr: ["يناير","فبراير","مارس","أبريل","مايو","يونيو","يوليو","أغسطس","سبتمبر","أكتوبر","نوفمبر","ديسمبر",""] + }, + AM: ["ص","ص","ص"], + PM: ["م","م","م"], + patterns: { + d: "dd/MM/yyyy", + D: "dd MMMM, yyyy", + F: "dd MMMM, yyyy hh:mm:ss tt", + g: "dd/MM/yyyy hh:mm tt", + G: "dd/MM/yyyy hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 6 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ar-SA.js b/src/cultures/kendo.culture.ar-SA.js new file mode 100644 index 00000000000..b6a6855424a --- /dev/null +++ b/src/cultures/kendo.culture.ar-SA.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ar-SA"] = { + name: "ar-SA", + numberFormat: { + pattern: ["n-"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$n-","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "ر.س.‏" + } + }, + calendars: { + standard: { + days: { + names: ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"], + namesAbbr: ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"], + namesShort: ["ح","ن","ث","ر","خ","ج","س"] + }, + months: { + names: ["محرم","صفر","ربيع الأول","ربيع الثاني","جمادى الأولى","جمادى الثانية","رجب","شعبان","رمضان","شوال","ذو القعدة","ذو الحجة",""], + namesAbbr: ["محرم","صفر","ربيع الأول","ربيع الثاني","جمادى الأولى","جمادى الثانية","رجب","شعبان","رمضان","شوال","ذو القعدة","ذو الحجة",""] + }, + AM: ["ص","ص","ص"], + PM: ["م","م","م"], + patterns: { + d: "dd/MM/yy", + D: "dd/MMMM/yyyy", + F: "dd/MMMM/yyyy hh:mm:ss tt", + g: "dd/MM/yy hh:mm tt", + G: "dd/MM/yy hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 6 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ar-SY.js b/src/cultures/kendo.culture.ar-SY.js new file mode 100644 index 00000000000..bc7dc9bfe68 --- /dev/null +++ b/src/cultures/kendo.culture.ar-SY.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ar-SY"] = { + name: "ar-SY", + numberFormat: { + pattern: ["n-"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$n-","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "ل.س.‏" + } + }, + calendars: { + standard: { + days: { + names: ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"], + namesAbbr: ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"], + namesShort: ["ح","ن","ث","ر","خ","ج","س"] + }, + months: { + names: ["كانون الثاني","شباط","آذار","نيسان","أيار","حزيران","تموز","آب","أيلول","تشرين الأول","تشرين الثاني","كانون الأول",""], + namesAbbr: ["كانون الثاني","شباط","آذار","نيسان","أيار","حزيران","تموز","آب","أيلول","تشرين الأول","تشرين الثاني","كانون الأول",""] + }, + AM: ["ص","ص","ص"], + PM: ["م","م","م"], + patterns: { + d: "dd/MM/yyyy", + D: "dd MMMM, yyyy", + F: "dd MMMM, yyyy hh:mm:ss tt", + g: "dd/MM/yyyy hh:mm tt", + G: "dd/MM/yyyy hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 6 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ar-TN.js b/src/cultures/kendo.culture.ar-TN.js new file mode 100644 index 00000000000..2b8bf4cfae7 --- /dev/null +++ b/src/cultures/kendo.culture.ar-TN.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ar-TN"] = { + name: "ar-TN", + numberFormat: { + pattern: ["n-"], + decimals: 3, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 3, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$n-","$ n"], + decimals: 3, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "د.ت.‏" + } + }, + calendars: { + standard: { + days: { + names: ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"], + namesAbbr: ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"], + namesShort: ["ح","ن","ث","ر","خ","ج","س"] + }, + months: { + names: ["جانفييه","فيفرييه","مارس","أفريل","مي","جوان","جوييه","أوت","سبتمبر","أكتوبر","نوفمبر","ديسمبر",""], + namesAbbr: ["جانفييه","فيفرييه","مارس","أفريل","مي","جوان","جوييه","أوت","سبتمبر","أكتوبر","نوفمبر","ديسمبر",""] + }, + AM: ["ص","ص","ص"], + PM: ["م","م","م"], + patterns: { + d: "dd-MM-yyyy", + D: "dd MMMM, yyyy", + F: "dd MMMM, yyyy H:mm:ss", + g: "dd-MM-yyyy H:mm", + G: "dd-MM-yyyy H:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "-", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ar-YE.js b/src/cultures/kendo.culture.ar-YE.js new file mode 100644 index 00000000000..037b7c8f725 --- /dev/null +++ b/src/cultures/kendo.culture.ar-YE.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ar-YE"] = { + name: "ar-YE", + numberFormat: { + pattern: ["n-"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$n-","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "ر.ي.‏" + } + }, + calendars: { + standard: { + days: { + names: ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"], + namesAbbr: ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"], + namesShort: ["ح","ن","ث","ر","خ","ج","س"] + }, + months: { + names: ["يناير","فبراير","مارس","أبريل","مايو","يونيو","يوليو","أغسطس","سبتمبر","أكتوبر","نوفمبر","ديسمبر",""], + namesAbbr: ["يناير","فبراير","مارس","أبريل","مايو","يونيو","يوليو","أغسطس","سبتمبر","أكتوبر","نوفمبر","ديسمبر",""] + }, + AM: ["ص","ص","ص"], + PM: ["م","م","م"], + patterns: { + d: "dd/MM/yyyy", + D: "dd MMMM, yyyy", + F: "dd MMMM, yyyy hh:mm:ss tt", + g: "dd/MM/yyyy hh:mm tt", + G: "dd/MM/yyyy hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 6 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ar.js b/src/cultures/kendo.culture.ar.js new file mode 100644 index 00000000000..851757eb861 --- /dev/null +++ b/src/cultures/kendo.culture.ar.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ar"] = { + name: "ar", + numberFormat: { + pattern: ["n-"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$n-","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "ر.س.‏" + } + }, + calendars: { + standard: { + days: { + names: ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"], + namesAbbr: ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"], + namesShort: ["ح","ن","ث","ر","خ","ج","س"] + }, + months: { + names: ["محرم","صفر","ربيع الأول","ربيع الثاني","جمادى الأولى","جمادى الثانية","رجب","شعبان","رمضان","شوال","ذو القعدة","ذو الحجة",""], + namesAbbr: ["محرم","صفر","ربيع الأول","ربيع الثاني","جمادى الأولى","جمادى الثانية","رجب","شعبان","رمضان","شوال","ذو القعدة","ذو الحجة",""] + }, + AM: ["ص","ص","ص"], + PM: ["م","م","م"], + patterns: { + d: "dd/MM/yy", + D: "dd/MMMM/yyyy", + F: "dd/MMMM/yyyy hh:mm:ss tt", + g: "dd/MM/yy hh:mm tt", + G: "dd/MM/yy hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 6 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.arn-CL.js b/src/cultures/kendo.culture.arn-CL.js new file mode 100644 index 00000000000..b49944903b0 --- /dev/null +++ b/src/cultures/kendo.culture.arn-CL.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["arn-CL"] = { + name: "arn-CL", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-$ n","$ n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "$" + } + }, + calendars: { + standard: { + days: { + names: ["domingo","lunes","martes","miércoles","jueves","viernes","sábado"], + namesAbbr: ["dom","lun","mar","mié","jue","vie","sáb"], + namesShort: ["do","lu","ma","mi","ju","vi","sá"] + }, + months: { + names: ["enero","febrero","marzo","abril","mayo","junio","julio","agosto","septiembre","octubre","noviembre","diciembre",""], + namesAbbr: ["ene","feb","mar","abr","may","jun","jul","ago","sep","oct","nov","dic",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd-MM-yyyy", + D: "dddd, dd' de 'MMMM' de 'yyyy", + F: "dddd, dd' de 'MMMM' de 'yyyy H:mm:ss", + g: "dd-MM-yyyy H:mm", + G: "dd-MM-yyyy H:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM' de 'yyyy", + Y: "MMMM' de 'yyyy" + }, + "/": "-", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.arn.js b/src/cultures/kendo.culture.arn.js new file mode 100644 index 00000000000..674084a8813 --- /dev/null +++ b/src/cultures/kendo.culture.arn.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["arn"] = { + name: "arn", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-$ n","$ n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "$" + } + }, + calendars: { + standard: { + days: { + names: ["domingo","lunes","martes","miércoles","jueves","viernes","sábado"], + namesAbbr: ["dom","lun","mar","mié","jue","vie","sáb"], + namesShort: ["do","lu","ma","mi","ju","vi","sá"] + }, + months: { + names: ["enero","febrero","marzo","abril","mayo","junio","julio","agosto","septiembre","octubre","noviembre","diciembre",""], + namesAbbr: ["ene","feb","mar","abr","may","jun","jul","ago","sep","oct","nov","dic",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd-MM-yyyy", + D: "dddd, dd' de 'MMMM' de 'yyyy", + F: "dddd, dd' de 'MMMM' de 'yyyy H:mm:ss", + g: "dd-MM-yyyy H:mm", + G: "dd-MM-yyyy H:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM' de 'yyyy", + Y: "MMMM' de 'yyyy" + }, + "/": "-", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.as-IN.js b/src/cultures/kendo.culture.as-IN.js new file mode 100644 index 00000000000..d7b7c7f9ee7 --- /dev/null +++ b/src/cultures/kendo.culture.as-IN.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["as-IN"] = { + name: "as-IN", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "%" + }, + currency: { + pattern: ["$ -n","n$"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "ট" + } + }, + calendars: { + standard: { + days: { + names: ["সোমবাৰ","মঙ্গলবাৰ","বুধবাৰ","বৃহস্পতিবাৰ","শুক্রবাৰ","শনিবাৰ","ৰবিবাৰ"], + namesAbbr: ["সোম.","মঙ্গল.","বুধ.","বৃহ.","শুক্র.","শনি.","ৰবি."], + namesShort: ["সো","ম","বু","বৃ","শু","শ","র"] + }, + months: { + names: ["জানুৱাৰী","ফেব্রুৱাৰী","মার্চ","এপ্রিল","মে","জুন","জুলাই","আগষ্ট","চেপ্টেম্বর","অক্টোবর","নবেম্বর","ডিচেম্বর",""], + namesAbbr: ["জানু","ফেব্রু","মার্চ","এপ্রিল","মে","জুন","জুলাই","আগষ্ট","চেপ্টে","অক্টো","নবে","ডিচে",""] + }, + AM: ["ৰাতিপু","ৰাতিপু","ৰাতিপু"], + PM: ["আবেলি","আবেলি","আবেলি"], + patterns: { + d: "dd-MM-yyyy", + D: "yyyy,MMMM dd, dddd", + F: "yyyy,MMMM dd, dddd tt h:mm:ss", + g: "dd-MM-yyyy tt h:mm", + G: "dd-MM-yyyy tt h:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "tt h:mm", + T: "tt h:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM,yy", + Y: "MMMM,yy" + }, + "/": "-", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.as.js b/src/cultures/kendo.culture.as.js new file mode 100644 index 00000000000..731872104ec --- /dev/null +++ b/src/cultures/kendo.culture.as.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["as"] = { + name: "as", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "%" + }, + currency: { + pattern: ["$ -n","n$"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "ট" + } + }, + calendars: { + standard: { + days: { + names: ["সোমবাৰ","মঙ্গলবাৰ","বুধবাৰ","বৃহস্পতিবাৰ","শুক্রবাৰ","শনিবাৰ","ৰবিবাৰ"], + namesAbbr: ["সোম.","মঙ্গল.","বুধ.","বৃহ.","শুক্র.","শনি.","ৰবি."], + namesShort: ["সো","ম","বু","বৃ","শু","শ","র"] + }, + months: { + names: ["জানুৱাৰী","ফেব্রুৱাৰী","মার্চ","এপ্রিল","মে","জুন","জুলাই","আগষ্ট","চেপ্টেম্বর","অক্টোবর","নবেম্বর","ডিচেম্বর",""], + namesAbbr: ["জানু","ফেব্রু","মার্চ","এপ্রিল","মে","জুন","জুলাই","আগষ্ট","চেপ্টে","অক্টো","নবে","ডিচে",""] + }, + AM: ["ৰাতিপু","ৰাতিপু","ৰাতিপু"], + PM: ["আবেলি","আবেলি","আবেলি"], + patterns: { + d: "dd-MM-yyyy", + D: "yyyy,MMMM dd, dddd", + F: "yyyy,MMMM dd, dddd tt h:mm:ss", + g: "dd-MM-yyyy tt h:mm", + G: "dd-MM-yyyy tt h:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "tt h:mm", + T: "tt h:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM,yy", + Y: "MMMM,yy" + }, + "/": "-", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.az-Cyrl-AZ.js b/src/cultures/kendo.culture.az-Cyrl-AZ.js new file mode 100644 index 00000000000..7e14a4b078f --- /dev/null +++ b/src/cultures/kendo.culture.az-Cyrl-AZ.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["az-Cyrl-AZ"] = { + name: "az-Cyrl-AZ", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "ман." + } + }, + calendars: { + standard: { + days: { + names: ["Базар","Базар ертәси","Чәршәнбә ахшамы","Чәршәнбә","Ҹүмә ахшамы","Ҹүмә","Шәнбә"], + namesAbbr: ["Б","Бе","Ча","Ч","Ҹа","Ҹ","Ш"], + namesShort: ["Б","Бе","Ча","Ч","Ҹа","Ҹ","Ш"] + }, + months: { + names: ["Јанвар","Феврал","Март","Апрел","Мај","Ијун","Ијул","Август","Сентјабр","Октјабр","Нојабр","Декабр",""], + namesAbbr: ["Јан","Фев","Мар","Апр","Мај","Ијун","Ијул","Авг","Сен","Окт","Ноя","Дек",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yyyy", + D: "d MMMM yyyy", + F: "d MMMM yyyy H:mm:ss", + g: "dd.MM.yyyy H:mm", + G: "dd.MM.yyyy H:mm:ss", + m: "d MMMM", + M: "d MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.az-Cyrl.js b/src/cultures/kendo.culture.az-Cyrl.js new file mode 100644 index 00000000000..21d621c1f1e --- /dev/null +++ b/src/cultures/kendo.culture.az-Cyrl.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["az-Cyrl"] = { + name: "az-Cyrl", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "ман." + } + }, + calendars: { + standard: { + days: { + names: ["Базар","Базар ертәси","Чәршәнбә ахшамы","Чәршәнбә","Ҹүмә ахшамы","Ҹүмә","Шәнбә"], + namesAbbr: ["Б","Бе","Ча","Ч","Ҹа","Ҹ","Ш"], + namesShort: ["Б","Бе","Ча","Ч","Ҹа","Ҹ","Ш"] + }, + months: { + names: ["Јанвар","Феврал","Март","Апрел","Мај","Ијун","Ијул","Август","Сентјабр","Октјабр","Нојабр","Декабр",""], + namesAbbr: ["Јан","Фев","Мар","Апр","Мај","Ијун","Ијул","Авг","Сен","Окт","Ноя","Дек",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yyyy", + D: "d MMMM yyyy", + F: "d MMMM yyyy H:mm:ss", + g: "dd.MM.yyyy H:mm", + G: "dd.MM.yyyy H:mm:ss", + m: "d MMMM", + M: "d MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.az-Latn-AZ.js b/src/cultures/kendo.culture.az-Latn-AZ.js new file mode 100644 index 00000000000..adec9c0ffe7 --- /dev/null +++ b/src/cultures/kendo.culture.az-Latn-AZ.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["az-Latn-AZ"] = { + name: "az-Latn-AZ", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "man." + } + }, + calendars: { + standard: { + days: { + names: ["Bazar","Bazar ertəsi","Çərşənbə axşamı","Çərşənbə","Cümə axşamı","Cümə","Şənbə"], + namesAbbr: ["B","Be","Ça","Ç","Ca","C","Ş"], + namesShort: ["B","Be","Ça","Ç","Ca","C","Ş"] + }, + months: { + names: ["Yanvar","Fevral","Mart","Aprel","May","İyun","İyul","Avgust","Sentyabr","Oktyabr","Noyabr","Dekabr",""], + namesAbbr: ["Yan","Fev","Mar","Apr","May","İyun","İyul","Avg","Sen","Okt","Noy","Dek",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yyyy", + D: "d MMMM yyyy", + F: "d MMMM yyyy H:mm:ss", + g: "dd.MM.yyyy H:mm", + G: "dd.MM.yyyy H:mm:ss", + m: "d MMMM", + M: "d MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.az-Latn.js b/src/cultures/kendo.culture.az-Latn.js new file mode 100644 index 00000000000..adcd6b2ad4f --- /dev/null +++ b/src/cultures/kendo.culture.az-Latn.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["az-Latn"] = { + name: "az-Latn", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "man." + } + }, + calendars: { + standard: { + days: { + names: ["Bazar","Bazar ertəsi","Çərşənbə axşamı","Çərşənbə","Cümə axşamı","Cümə","Şənbə"], + namesAbbr: ["B","Be","Ça","Ç","Ca","C","Ş"], + namesShort: ["B","Be","Ça","Ç","Ca","C","Ş"] + }, + months: { + names: ["Yanvar","Fevral","Mart","Aprel","May","İyun","İyul","Avgust","Sentyabr","Oktyabr","Noyabr","Dekabr",""], + namesAbbr: ["Yan","Fev","Mar","Apr","May","İyun","İyul","Avg","Sen","Okt","Noy","Dek",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yyyy", + D: "d MMMM yyyy", + F: "d MMMM yyyy H:mm:ss", + g: "dd.MM.yyyy H:mm", + G: "dd.MM.yyyy H:mm:ss", + m: "d MMMM", + M: "d MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.az.js b/src/cultures/kendo.culture.az.js new file mode 100644 index 00000000000..52107235b9e --- /dev/null +++ b/src/cultures/kendo.culture.az.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["az"] = { + name: "az", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "man." + } + }, + calendars: { + standard: { + days: { + names: ["Bazar","Bazar ertəsi","Çərşənbə axşamı","Çərşənbə","Cümə axşamı","Cümə","Şənbə"], + namesAbbr: ["B","Be","Ça","Ç","Ca","C","Ş"], + namesShort: ["B","Be","Ça","Ç","Ca","C","Ş"] + }, + months: { + names: ["Yanvar","Fevral","Mart","Aprel","May","İyun","İyul","Avgust","Sentyabr","Oktyabr","Noyabr","Dekabr",""], + namesAbbr: ["Yan","Fev","Mar","Apr","May","İyun","İyul","Avg","Sen","Okt","Noy","Dek",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yyyy", + D: "d MMMM yyyy", + F: "d MMMM yyyy H:mm:ss", + g: "dd.MM.yyyy H:mm", + G: "dd.MM.yyyy H:mm:ss", + m: "d MMMM", + M: "d MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ba-RU.js b/src/cultures/kendo.culture.ba-RU.js new file mode 100644 index 00000000000..df022dff09c --- /dev/null +++ b/src/cultures/kendo.culture.ba-RU.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ba-RU"] = { + name: "ba-RU", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3,0], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3,0], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3,0], + symbol: "һ." + } + }, + calendars: { + standard: { + days: { + names: ["Йәкшәмбе","Дүшәмбе","Шишәмбе","Шаршамбы","Кесаҙна","Йома","Шәмбе"], + namesAbbr: ["Йш","Дш","Шш","Шр","Кс","Йм","Шб"], + namesShort: ["Йш","Дш","Шш","Шр","Кс","Йм","Шб"] + }, + months: { + names: ["ғинуар","февраль","март","апрель","май","июнь","июль","август","сентябрь","октябрь","ноябрь","декабрь",""], + namesAbbr: ["ғин","фев","мар","апр","май","июн","июл","авг","сен","окт","ноя","дек",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yy", + D: "d MMMM yyyy 'й'", + F: "d MMMM yyyy 'й' H:mm:ss", + g: "dd.MM.yy H:mm", + G: "dd.MM.yy H:mm:ss", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ba.js b/src/cultures/kendo.culture.ba.js new file mode 100644 index 00000000000..88e49c7fc8f --- /dev/null +++ b/src/cultures/kendo.culture.ba.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ba"] = { + name: "ba", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3,0], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3,0], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3,0], + symbol: "һ." + } + }, + calendars: { + standard: { + days: { + names: ["Йәкшәмбе","Дүшәмбе","Шишәмбе","Шаршамбы","Кесаҙна","Йома","Шәмбе"], + namesAbbr: ["Йш","Дш","Шш","Шр","Кс","Йм","Шб"], + namesShort: ["Йш","Дш","Шш","Шр","Кс","Йм","Шб"] + }, + months: { + names: ["ғинуар","февраль","март","апрель","май","июнь","июль","август","сентябрь","октябрь","ноябрь","декабрь",""], + namesAbbr: ["ғин","фев","мар","апр","май","июн","июл","авг","сен","окт","ноя","дек",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yy", + D: "d MMMM yyyy 'й'", + F: "d MMMM yyyy 'й' H:mm:ss", + g: "dd.MM.yy H:mm", + G: "dd.MM.yy H:mm:ss", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.be-BY.js b/src/cultures/kendo.culture.be-BY.js new file mode 100644 index 00000000000..f34289b40a0 --- /dev/null +++ b/src/cultures/kendo.culture.be-BY.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["be-BY"] = { + name: "be-BY", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "р." + } + }, + calendars: { + standard: { + days: { + names: ["нядзеля","панядзелак","аўторак","серада","чацвер","пятніца","субота"], + namesAbbr: ["нд","пн","аў","ср","чц","пт","сб"], + namesShort: ["нд","пн","аў","ср","чц","пт","сб"] + }, + months: { + names: ["Студзень","Люты","Сакавік","Красавік","Май","Чэрвень","Ліпень","Жнівень","Верасень","Кастрычнік","Лістапад","Снежань",""], + namesAbbr: ["Сту","Лют","Сак","Кра","Май","Чэр","Ліп","Жні","Вер","Кас","Ліс","Сне",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yyyy", + D: "d MMMM yyyy", + F: "d MMMM yyyy H:mm:ss", + g: "dd.MM.yyyy H:mm", + G: "dd.MM.yyyy H:mm:ss", + m: "d MMMM", + M: "d MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.be.js b/src/cultures/kendo.culture.be.js new file mode 100644 index 00000000000..d19836b04db --- /dev/null +++ b/src/cultures/kendo.culture.be.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["be"] = { + name: "be", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "р." + } + }, + calendars: { + standard: { + days: { + names: ["нядзеля","панядзелак","аўторак","серада","чацвер","пятніца","субота"], + namesAbbr: ["нд","пн","аў","ср","чц","пт","сб"], + namesShort: ["нд","пн","аў","ср","чц","пт","сб"] + }, + months: { + names: ["Студзень","Люты","Сакавік","Красавік","Май","Чэрвень","Ліпень","Жнівень","Верасень","Кастрычнік","Лістапад","Снежань",""], + namesAbbr: ["Сту","Лют","Сак","Кра","Май","Чэр","Ліп","Жні","Вер","Кас","Ліс","Сне",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yyyy", + D: "d MMMM yyyy", + F: "d MMMM yyyy H:mm:ss", + g: "dd.MM.yyyy H:mm", + G: "dd.MM.yyyy H:mm:ss", + m: "d MMMM", + M: "d MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.bg-BG.js b/src/cultures/kendo.culture.bg-BG.js new file mode 100644 index 00000000000..560113aabc3 --- /dev/null +++ b/src/cultures/kendo.culture.bg-BG.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["bg-BG"] = { + name: "bg-BG", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "лв." + } + }, + calendars: { + standard: { + days: { + names: ["неделя","понеделник","вторник","сряда","четвъртък","петък","събота"], + namesAbbr: ["нед","пон","вт","ср","четв","пет","съб"], + namesShort: ["н","п","в","с","ч","п","с"] + }, + months: { + names: ["януари","февруари","март","април","май","юни","юли","август","септември","октомври","ноември","декември",""], + namesAbbr: ["ян","февр","март","апр","май","юни","юли","авг","септ","окт","ноември","дек",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "d.M.yyyy 'г.'", + D: "dd MMMM yyyy 'г.'", + F: "dd MMMM yyyy 'г.' HH:mm:ss 'ч.'", + g: "d.M.yyyy 'г.' HH:mm 'ч.'", + G: "d.M.yyyy 'г.' HH:mm:ss 'ч.'", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm 'ч.'", + T: "HH:mm:ss 'ч.'", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy 'г.'", + Y: "MMMM yyyy 'г.'" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.bg.js b/src/cultures/kendo.culture.bg.js new file mode 100644 index 00000000000..095233199b7 --- /dev/null +++ b/src/cultures/kendo.culture.bg.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["bg"] = { + name: "bg", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "лв." + } + }, + calendars: { + standard: { + days: { + names: ["неделя","понеделник","вторник","сряда","четвъртък","петък","събота"], + namesAbbr: ["нед","пон","вт","ср","четв","пет","съб"], + namesShort: ["н","п","в","с","ч","п","с"] + }, + months: { + names: ["януари","февруари","март","април","май","юни","юли","август","септември","октомври","ноември","декември",""], + namesAbbr: ["ян","февр","март","апр","май","юни","юли","авг","септ","окт","ноември","дек",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "d.M.yyyy 'г.'", + D: "dd MMMM yyyy 'г.'", + F: "dd MMMM yyyy 'г.' HH:mm:ss 'ч.'", + g: "d.M.yyyy 'г.' HH:mm 'ч.'", + G: "d.M.yyyy 'г.' HH:mm:ss 'ч.'", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm 'ч.'", + T: "HH:mm:ss 'ч.'", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy 'г.'", + Y: "MMMM yyyy 'г.'" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.bn-BD.js b/src/cultures/kendo.culture.bn-BD.js new file mode 100644 index 00000000000..0158449c44c --- /dev/null +++ b/src/cultures/kendo.culture.bn-BD.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["bn-BD"] = { + name: "bn-BD", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + percent: { + pattern: ["-%n","%n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "৳" + } + }, + calendars: { + standard: { + days: { + names: ["রবিবার","সোমবার","মঙ্গলবার","বুধবার","বৃহস্পতিবার","শুক্রবার","শনিবার"], + namesAbbr: ["রবি.","সোম.","মঙ্গল.","বুধ.","বৃহস্পতি.","শুক্র.","শনি."], + namesShort: ["র","স","ম","ব","ব","শ","শ"] + }, + months: { + names: ["জানুয়ারী","ফেব্রুয়ারী","মার্চ","এপ্রিল","মে","জুন","জুলাই","আগস্ট","সেপ্টেম্বর","অক্টোবর","নভেম্বর","ডিসেম্বর",""], + namesAbbr: ["জানু.","ফেব্রু.","মার্চ","এপ্রিল","মে","জুন","জুলাই","আগ.","সেপ্টে.","অক্টো.","নভে.","ডিসে.",""] + }, + AM: ["পুর্বাহ্ন","পুর্বাহ্ন","পুর্বাহ্ন"], + PM: ["অপরাহ্ন","অপরাহ্ন","অপরাহ্ন"], + patterns: { + d: "dd-MM-yy", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy HH.mm.ss", + g: "dd-MM-yy HH.mm", + G: "dd-MM-yy HH.mm.ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH.mm", + T: "HH.mm.ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "-", + ":": ".", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.bn-IN.js b/src/cultures/kendo.culture.bn-IN.js new file mode 100644 index 00000000000..f6a81bdcd0b --- /dev/null +++ b/src/cultures/kendo.culture.bn-IN.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["bn-IN"] = { + name: "bn-IN", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + percent: { + pattern: ["-%n","%n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "টা" + } + }, + calendars: { + standard: { + days: { + names: ["রবিবার","সোমবার","মঙ্গলবার","বুধবার","বৃহস্পতিবার","শুক্রবার","শনিবার"], + namesAbbr: ["রবি.","সোম.","মঙ্গল.","বুধ.","বৃহস্পতি.","শুক্র.","শনি."], + namesShort: ["র","স","ম","ব","ব","শ","শ"] + }, + months: { + names: ["জানুয়ারী","ফেব্রুয়ারী","মার্চ","এপ্রিল","মে","জুন","জুলাই","আগস্ট","সেপ্টেম্বর","অক্টোবর","নভেম্বর","ডিসেম্বর",""], + namesAbbr: ["জানু.","ফেব্রু.","মার্চ","এপ্রিল","মে","জুন","জুলাই","আগ.","সেপ্টে.","অক্টো.","নভে.","ডিসে.",""] + }, + AM: ["পুর্বাহ্ন","পুর্বাহ্ন","পুর্বাহ্ন"], + PM: ["অপরাহ্ন","অপরাহ্ন","অপরাহ্ন"], + patterns: { + d: "dd-MM-yy", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy HH.mm.ss", + g: "dd-MM-yy HH.mm", + G: "dd-MM-yy HH.mm.ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH.mm", + T: "HH.mm.ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "-", + ":": ".", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.bn.js b/src/cultures/kendo.culture.bn.js new file mode 100644 index 00000000000..a670a365720 --- /dev/null +++ b/src/cultures/kendo.culture.bn.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["bn"] = { + name: "bn", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + percent: { + pattern: ["-%n","%n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "টা" + } + }, + calendars: { + standard: { + days: { + names: ["রবিবার","সোমবার","মঙ্গলবার","বুধবার","বৃহস্পতিবার","শুক্রবার","শনিবার"], + namesAbbr: ["রবি.","সোম.","মঙ্গল.","বুধ.","বৃহস্পতি.","শুক্র.","শনি."], + namesShort: ["র","স","ম","ব","ব","শ","শ"] + }, + months: { + names: ["জানুয়ারী","ফেব্রুয়ারী","মার্চ","এপ্রিল","মে","জুন","জুলাই","আগস্ট","সেপ্টেম্বর","অক্টোবর","নভেম্বর","ডিসেম্বর",""], + namesAbbr: ["জানু.","ফেব্রু.","মার্চ","এপ্রিল","মে","জুন","জুলাই","আগ.","সেপ্টে.","অক্টো.","নভে.","ডিসে.",""] + }, + AM: ["পুর্বাহ্ন","পুর্বাহ্ন","পুর্বাহ্ন"], + PM: ["অপরাহ্ন","অপরাহ্ন","অপরাহ্ন"], + patterns: { + d: "dd-MM-yy", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy HH.mm.ss", + g: "dd-MM-yy HH.mm", + G: "dd-MM-yy HH.mm.ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH.mm", + T: "HH.mm.ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "-", + ":": ".", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.bo-CN.js b/src/cultures/kendo.culture.bo-CN.js new file mode 100644 index 00000000000..5adba69e90b --- /dev/null +++ b/src/cultures/kendo.culture.bo-CN.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["bo-CN"] = { + name: "bo-CN", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + symbol: "%" + }, + currency: { + pattern: ["$-n","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + symbol: "¥" + } + }, + calendars: { + standard: { + days: { + names: ["གཟའ་ཉི་མ།","གཟའ་ཟླ་བ།","གཟའ་མིག་དམར།","གཟའ་ལྷག་པ།","གཟའ་ཕུར་བུ།","གཟའ་པ་སངས།","གཟའ་སྤེན་པ།"], + namesAbbr: ["ཉི་མ།","ཟླ་བ།","མིག་དམར།","ལྷག་པ།","ཕུར་བུ།","པ་སངས།","སྤེན་པ།"], + namesShort: ["༧","༡","༢","༣","༤","༥","༦"] + }, + months: { + names: ["སྤྱི་ཟླ་དང་པོ།","སྤྱི་ཟླ་གཉིས་པ།","སྤྱི་ཟླ་གསུམ་པ།","སྤྱི་ཟླ་བཞི་པ།","སྤྱི་ཟླ་ལྔ་པ།","སྤྱི་ཟླ་དྲུག་པ།","སྤྱི་ཟླ་བདུན་པ།","སྤྱི་ཟླ་བརྒྱད་པ།","སྤྱི་ཟླ་དགུ་པ།","སྤྱི་ཟླ་བཅུ་པོ།","སྤྱི་ཟླ་བཅུ་གཅིག་པ།","སྤྱི་ཟླ་བཅུ་གཉིས་པ།",""], + namesAbbr: ["ཟླ་ ༡","ཟླ་ ༢","ཟླ་ ༣","ཟླ་ ༤","ཟླ་ ༥","ཟླ་ ༦","ཟླ་ ༧","ཟླ་ ༨","ཟླ་ ༩","ཟླ་ ༡༠","ཟླ་ ༡༡","ཟླ་ ༡༢",""] + }, + AM: ["སྔ་དྲོ","སྔ་དྲོ","སྔ་དྲོ"], + PM: ["ཕྱི་དྲོ","ཕྱི་དྲོ","ཕྱི་དྲོ"], + patterns: { + d: "yyyy/M/d", + D: "yyyy'ལོའི་ཟླ' M'ཚེས' d", + F: "yyyy'ལོའི་ཟླ' M'ཚེས' d HH:mm:ss", + g: "yyyy/M/d HH:mm", + G: "yyyy/M/d HH:mm:ss", + m: "'ཟླ་' M'ཚེས'd", + M: "'ཟླ་' M'ཚེས'd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "yyyy.M", + Y: "yyyy.M" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.bo.js b/src/cultures/kendo.culture.bo.js new file mode 100644 index 00000000000..01e091f5a8f --- /dev/null +++ b/src/cultures/kendo.culture.bo.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["bo"] = { + name: "bo", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + symbol: "%" + }, + currency: { + pattern: ["$-n","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + symbol: "¥" + } + }, + calendars: { + standard: { + days: { + names: ["གཟའ་ཉི་མ།","གཟའ་ཟླ་བ།","གཟའ་མིག་དམར།","གཟའ་ལྷག་པ།","གཟའ་ཕུར་བུ།","གཟའ་པ་སངས།","གཟའ་སྤེན་པ།"], + namesAbbr: ["ཉི་མ།","ཟླ་བ།","མིག་དམར།","ལྷག་པ།","ཕུར་བུ།","པ་སངས།","སྤེན་པ།"], + namesShort: ["༧","༡","༢","༣","༤","༥","༦"] + }, + months: { + names: ["སྤྱི་ཟླ་དང་པོ།","སྤྱི་ཟླ་གཉིས་པ།","སྤྱི་ཟླ་གསུམ་པ།","སྤྱི་ཟླ་བཞི་པ།","སྤྱི་ཟླ་ལྔ་པ།","སྤྱི་ཟླ་དྲུག་པ།","སྤྱི་ཟླ་བདུན་པ།","སྤྱི་ཟླ་བརྒྱད་པ།","སྤྱི་ཟླ་དགུ་པ།","སྤྱི་ཟླ་བཅུ་པོ།","སྤྱི་ཟླ་བཅུ་གཅིག་པ།","སྤྱི་ཟླ་བཅུ་གཉིས་པ།",""], + namesAbbr: ["ཟླ་ ༡","ཟླ་ ༢","ཟླ་ ༣","ཟླ་ ༤","ཟླ་ ༥","ཟླ་ ༦","ཟླ་ ༧","ཟླ་ ༨","ཟླ་ ༩","ཟླ་ ༡༠","ཟླ་ ༡༡","ཟླ་ ༡༢",""] + }, + AM: ["སྔ་དྲོ","སྔ་དྲོ","སྔ་དྲོ"], + PM: ["ཕྱི་དྲོ","ཕྱི་དྲོ","ཕྱི་དྲོ"], + patterns: { + d: "yyyy/M/d", + D: "yyyy'ལོའི་ཟླ' M'ཚེས' d", + F: "yyyy'ལོའི་ཟླ' M'ཚེས' d HH:mm:ss", + g: "yyyy/M/d HH:mm", + G: "yyyy/M/d HH:mm:ss", + m: "'ཟླ་' M'ཚེས'd", + M: "'ཟླ་' M'ཚེས'd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "yyyy.M", + Y: "yyyy.M" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.br-FR.js b/src/cultures/kendo.culture.br-FR.js new file mode 100644 index 00000000000..606c8aa15cf --- /dev/null +++ b/src/cultures/kendo.culture.br-FR.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["br-FR"] = { + name: "br-FR", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["Sul","Lun","Meurzh","Merc\u0027her","Yaou","Gwener","Sadorn"], + namesAbbr: ["Sul","Lun","Meu.","Mer.","Yaou","Gwe.","Sad."], + namesShort: ["Su","Lu","Mz","Mc","Ya","Gw","Sa"] + }, + months: { + names: ["Genver","C\u0027hwevrer","Meurzh","Ebrel","Mae","Mezheven","Gouere","Eost","Gwengolo","Here","Du","Kerzu",""], + namesAbbr: ["Gen.","C\u0027hwe.","Meur.","Ebr.","Mae","Mezh.","Goue.","Eost","Gwen.","Here","Du","Kzu",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd/MM/yyyy", + D: "dddd d MMMM yyyy", + F: "dddd d MMMM yyyy HH:mm:ss", + g: "dd/MM/yyyy HH:mm", + G: "dd/MM/yyyy HH:mm:ss", + m: "d MMMM", + M: "d MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.br.js b/src/cultures/kendo.culture.br.js new file mode 100644 index 00000000000..89604cdf262 --- /dev/null +++ b/src/cultures/kendo.culture.br.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["br"] = { + name: "br", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["Sul","Lun","Meurzh","Merc\u0027her","Yaou","Gwener","Sadorn"], + namesAbbr: ["Sul","Lun","Meu.","Mer.","Yaou","Gwe.","Sad."], + namesShort: ["Su","Lu","Mz","Mc","Ya","Gw","Sa"] + }, + months: { + names: ["Genver","C\u0027hwevrer","Meurzh","Ebrel","Mae","Mezheven","Gouere","Eost","Gwengolo","Here","Du","Kerzu",""], + namesAbbr: ["Gen.","C\u0027hwe.","Meur.","Ebr.","Mae","Mezh.","Goue.","Eost","Gwen.","Here","Du","Kzu",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd/MM/yyyy", + D: "dddd d MMMM yyyy", + F: "dddd d MMMM yyyy HH:mm:ss", + g: "dd/MM/yyyy HH:mm", + G: "dd/MM/yyyy HH:mm:ss", + m: "d MMMM", + M: "d MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.bs-Cyrl-BA.js b/src/cultures/kendo.culture.bs-Cyrl-BA.js new file mode 100644 index 00000000000..c151e739a66 --- /dev/null +++ b/src/cultures/kendo.culture.bs-Cyrl-BA.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["bs-Cyrl-BA"] = { + name: "bs-Cyrl-BA", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "КМ" + } + }, + calendars: { + standard: { + days: { + names: ["недјеља","понедјељак","уторак","сриједа","четвртак","петак","субота"], + namesAbbr: ["нед","пон","уто","сре","чет","пет","суб"], + namesShort: ["н","п","у","с","ч","п","с"] + }, + months: { + names: ["јануар","фебруар","март","април","мај","јун","јул","август","септембар","октобар","новембар","децембар",""], + namesAbbr: ["јан","феб","мар","апр","мај","јун","јул","авг","сеп","окт","нов","дец",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "d.M.yyyy", + D: "d. MMMM yyyy", + F: "d. MMMM yyyy H:mm:ss", + g: "d.M.yyyy H:mm", + G: "d.M.yyyy H:mm:ss", + m: "d. MMMM", + M: "d. MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.bs-Cyrl.js b/src/cultures/kendo.culture.bs-Cyrl.js new file mode 100644 index 00000000000..ba5d979f983 --- /dev/null +++ b/src/cultures/kendo.culture.bs-Cyrl.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["bs-Cyrl"] = { + name: "bs-Cyrl", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "КМ" + } + }, + calendars: { + standard: { + days: { + names: ["недјеља","понедјељак","уторак","сриједа","четвртак","петак","субота"], + namesAbbr: ["нед","пон","уто","сре","чет","пет","суб"], + namesShort: ["н","п","у","с","ч","п","с"] + }, + months: { + names: ["јануар","фебруар","март","април","мај","јун","јул","август","септембар","октобар","новембар","децембар",""], + namesAbbr: ["јан","феб","мар","апр","мај","јун","јул","авг","сеп","окт","нов","дец",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "d.M.yyyy", + D: "d. MMMM yyyy", + F: "d. MMMM yyyy H:mm:ss", + g: "d.M.yyyy H:mm", + G: "d.M.yyyy H:mm:ss", + m: "d. MMMM", + M: "d. MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.bs-Latn-BA.js b/src/cultures/kendo.culture.bs-Latn-BA.js new file mode 100644 index 00000000000..732ee0bf9b2 --- /dev/null +++ b/src/cultures/kendo.culture.bs-Latn-BA.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["bs-Latn-BA"] = { + name: "bs-Latn-BA", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "KM" + } + }, + calendars: { + standard: { + days: { + names: ["nedjelja","ponedjeljak","utorak","srijeda","četvrtak","petak","subota"], + namesAbbr: ["ned","pon","uto","sri","čet","pet","sub"], + namesShort: ["ne","po","ut","sr","če","pe","su"] + }, + months: { + names: ["januar","februar","mart","april","maj","juni","juli","avgust","septembar","oktobar","novembar","decembar",""], + namesAbbr: ["jan","feb","mar","apr","maj","jun","jul","avg","sep","okt","nov","dec",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "d.M.yyyy", + D: "d. MMMM yyyy", + F: "d. MMMM yyyy H:mm:ss", + g: "d.M.yyyy H:mm", + G: "d.M.yyyy H:mm:ss", + m: "d. MMMM", + M: "d. MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.bs-Latn.js b/src/cultures/kendo.culture.bs-Latn.js new file mode 100644 index 00000000000..a613e4509c8 --- /dev/null +++ b/src/cultures/kendo.culture.bs-Latn.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["bs-Latn"] = { + name: "bs-Latn", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "KM" + } + }, + calendars: { + standard: { + days: { + names: ["nedjelja","ponedjeljak","utorak","srijeda","četvrtak","petak","subota"], + namesAbbr: ["ned","pon","uto","sri","čet","pet","sub"], + namesShort: ["ne","po","ut","sr","če","pe","su"] + }, + months: { + names: ["januar","februar","mart","april","maj","juni","juli","avgust","septembar","oktobar","novembar","decembar",""], + namesAbbr: ["jan","feb","mar","apr","maj","jun","jul","avg","sep","okt","nov","dec",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "d.M.yyyy", + D: "d. MMMM yyyy", + F: "d. MMMM yyyy H:mm:ss", + g: "d.M.yyyy H:mm", + G: "d.M.yyyy H:mm:ss", + m: "d. MMMM", + M: "d. MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.bs.js b/src/cultures/kendo.culture.bs.js new file mode 100644 index 00000000000..24f2b529032 --- /dev/null +++ b/src/cultures/kendo.culture.bs.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["bs"] = { + name: "bs", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "KM" + } + }, + calendars: { + standard: { + days: { + names: ["nedjelja","ponedjeljak","utorak","srijeda","četvrtak","petak","subota"], + namesAbbr: ["ned","pon","uto","sri","čet","pet","sub"], + namesShort: ["ne","po","ut","sr","če","pe","su"] + }, + months: { + names: ["januar","februar","mart","april","maj","juni","juli","avgust","septembar","oktobar","novembar","decembar",""], + namesAbbr: ["jan","feb","mar","apr","maj","jun","jul","avg","sep","okt","nov","dec",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "d.M.yyyy", + D: "d. MMMM yyyy", + F: "d. MMMM yyyy H:mm:ss", + g: "d.M.yyyy H:mm", + G: "d.M.yyyy H:mm:ss", + m: "d. MMMM", + M: "d. MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ca-ES.js b/src/cultures/kendo.culture.ca-ES.js new file mode 100644 index 00000000000..0ce30190e8e --- /dev/null +++ b/src/cultures/kendo.culture.ca-ES.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ca-ES"] = { + name: "ca-ES", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["diumenge","dilluns","dimarts","dimecres","dijous","divendres","dissabte"], + namesAbbr: ["dg.","dl.","dt.","dc.","dj.","dv.","ds."], + namesShort: ["dg","dl","dt","dc","dj","dv","ds"] + }, + months: { + names: ["gener","febrer","març","abril","maig","juny","juliol","agost","setembre","octubre","novembre","desembre",""], + namesAbbr: ["gen","feb","març","abr","maig","juny","jul","ag","set","oct","nov","des",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd/MM/yyyy", + D: "dddd, d' / 'MMMM' / 'yyyy", + F: "dddd, d' / 'MMMM' / 'yyyy HH:mm:ss", + g: "dd/MM/yyyy HH:mm", + G: "dd/MM/yyyy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM' / 'yyyy", + Y: "MMMM' / 'yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ca.js b/src/cultures/kendo.culture.ca.js new file mode 100644 index 00000000000..5b97ea0441e --- /dev/null +++ b/src/cultures/kendo.culture.ca.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ca"] = { + name: "ca", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["diumenge","dilluns","dimarts","dimecres","dijous","divendres","dissabte"], + namesAbbr: ["dg.","dl.","dt.","dc.","dj.","dv.","ds."], + namesShort: ["dg","dl","dt","dc","dj","dv","ds"] + }, + months: { + names: ["gener","febrer","març","abril","maig","juny","juliol","agost","setembre","octubre","novembre","desembre",""], + namesAbbr: ["gen","feb","març","abr","maig","juny","jul","ag","set","oct","nov","des",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd/MM/yyyy", + D: "dddd, d' / 'MMMM' / 'yyyy", + F: "dddd, d' / 'MMMM' / 'yyyy HH:mm:ss", + g: "dd/MM/yyyy HH:mm", + G: "dd/MM/yyyy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM' / 'yyyy", + Y: "MMMM' / 'yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.co-FR.js b/src/cultures/kendo.culture.co-FR.js new file mode 100644 index 00000000000..ac6de151bf4 --- /dev/null +++ b/src/cultures/kendo.culture.co-FR.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["co-FR"] = { + name: "co-FR", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["dumenica","luni","marti","mercuri","ghjovi","venderi","sabbatu"], + namesAbbr: ["dum.","lun.","mar.","mer.","ghj.","ven.","sab."], + namesShort: ["du","lu","ma","me","gh","ve","sa"] + }, + months: { + names: ["ghjennaghju","ferraghju","marzu","aprile","maghju","ghjunghju","lugliu","aostu","settembre","ottobre","nuvembre","dicembre",""], + namesAbbr: ["ghje","ferr","marz","apri","magh","ghju","lugl","aost","sett","otto","nuve","dice",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd/MM/yyyy", + D: "dddd d MMMM yyyy", + F: "dddd d MMMM yyyy HH:mm:ss", + g: "dd/MM/yyyy HH:mm", + G: "dd/MM/yyyy HH:mm:ss", + m: "d MMMM", + M: "d MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.co.js b/src/cultures/kendo.culture.co.js new file mode 100644 index 00000000000..e8aca904a1f --- /dev/null +++ b/src/cultures/kendo.culture.co.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["co"] = { + name: "co", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["dumenica","luni","marti","mercuri","ghjovi","venderi","sabbatu"], + namesAbbr: ["dum.","lun.","mar.","mer.","ghj.","ven.","sab."], + namesShort: ["du","lu","ma","me","gh","ve","sa"] + }, + months: { + names: ["ghjennaghju","ferraghju","marzu","aprile","maghju","ghjunghju","lugliu","aostu","settembre","ottobre","nuvembre","dicembre",""], + namesAbbr: ["ghje","ferr","marz","apri","magh","ghju","lugl","aost","sett","otto","nuve","dice",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd/MM/yyyy", + D: "dddd d MMMM yyyy", + F: "dddd d MMMM yyyy HH:mm:ss", + g: "dd/MM/yyyy HH:mm", + G: "dd/MM/yyyy HH:mm:ss", + m: "d MMMM", + M: "d MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.cs-CZ.js b/src/cultures/kendo.culture.cs-CZ.js new file mode 100644 index 00000000000..7b9790378da --- /dev/null +++ b/src/cultures/kendo.culture.cs-CZ.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["cs-CZ"] = { + name: "cs-CZ", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "Kč" + } + }, + calendars: { + standard: { + days: { + names: ["neděle","pondělí","úterý","středa","čtvrtek","pátek","sobota"], + namesAbbr: ["ne","po","út","st","čt","pá","so"], + namesShort: ["ne","po","út","st","čt","pá","so"] + }, + months: { + names: ["leden","únor","březen","duben","květen","červen","červenec","srpen","září","říjen","listopad","prosinec",""], + namesAbbr: ["I","II","III","IV","V","VI","VII","VIII","IX","X","XI","XII",""] + }, + AM: ["dop.","dop.","DOP."], + PM: ["odp.","odp.","ODP."], + patterns: { + d: "d. M. yyyy", + D: "d. MMMM yyyy", + F: "d. MMMM yyyy H:mm:ss", + g: "d. M. yyyy H:mm", + G: "d. M. yyyy H:mm:ss", + m: "d. MMMM", + M: "d. MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ". ", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.cs.js b/src/cultures/kendo.culture.cs.js new file mode 100644 index 00000000000..c28c195d430 --- /dev/null +++ b/src/cultures/kendo.culture.cs.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["cs"] = { + name: "cs", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "Kč" + } + }, + calendars: { + standard: { + days: { + names: ["neděle","pondělí","úterý","středa","čtvrtek","pátek","sobota"], + namesAbbr: ["ne","po","út","st","čt","pá","so"], + namesShort: ["ne","po","út","st","čt","pá","so"] + }, + months: { + names: ["leden","únor","březen","duben","květen","červen","červenec","srpen","září","říjen","listopad","prosinec",""], + namesAbbr: ["I","II","III","IV","V","VI","VII","VIII","IX","X","XI","XII",""] + }, + AM: ["dop.","dop.","DOP."], + PM: ["odp.","odp.","ODP."], + patterns: { + d: "d. M. yyyy", + D: "d. MMMM yyyy", + F: "d. MMMM yyyy H:mm:ss", + g: "d. M. yyyy H:mm", + G: "d. M. yyyy H:mm:ss", + m: "d. MMMM", + M: "d. MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ". ", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.cy-GB.js b/src/cultures/kendo.culture.cy-GB.js new file mode 100644 index 00000000000..1a8e1e8f874 --- /dev/null +++ b/src/cultures/kendo.culture.cy-GB.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["cy-GB"] = { + name: "cy-GB", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-%n","%n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-$n","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "£" + } + }, + calendars: { + standard: { + days: { + names: ["Dydd Sul","Dydd Llun","Dydd Mawrth","Dydd Mercher","Dydd Iau","Dydd Gwener","Dydd Sadwrn"], + namesAbbr: ["Sul","Llun","Maw","Mer","Iau","Gwe","Sad"], + namesShort: ["Su","Ll","Ma","Me","Ia","Gw","Sa"] + }, + months: { + names: ["Ionawr","Chwefror","Mawrth","Ebrill","Mai","Mehefin","Gorffennaf","Awst","Medi","Hydref","Tachwedd","Rhagfyr",""], + namesAbbr: ["Ion","Chwe","Maw","Ebr","Mai","Meh","Gor","Aws","Med","Hyd","Tach","Rhag",""] + }, + AM: ["a.m.","a.m.","A.M."], + PM: ["p.m.","p.m.","P.M."], + patterns: { + d: "dd/MM/yyyy", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy HH:mm:ss", + g: "dd/MM/yyyy HH:mm", + G: "dd/MM/yyyy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.cy.js b/src/cultures/kendo.culture.cy.js new file mode 100644 index 00000000000..73b92f63180 --- /dev/null +++ b/src/cultures/kendo.culture.cy.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["cy"] = { + name: "cy", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-%n","%n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-$n","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "£" + } + }, + calendars: { + standard: { + days: { + names: ["Dydd Sul","Dydd Llun","Dydd Mawrth","Dydd Mercher","Dydd Iau","Dydd Gwener","Dydd Sadwrn"], + namesAbbr: ["Sul","Llun","Maw","Mer","Iau","Gwe","Sad"], + namesShort: ["Su","Ll","Ma","Me","Ia","Gw","Sa"] + }, + months: { + names: ["Ionawr","Chwefror","Mawrth","Ebrill","Mai","Mehefin","Gorffennaf","Awst","Medi","Hydref","Tachwedd","Rhagfyr",""], + namesAbbr: ["Ion","Chwe","Maw","Ebr","Mai","Meh","Gor","Aws","Med","Hyd","Tach","Rhag",""] + }, + AM: ["a.m.","a.m.","A.M."], + PM: ["p.m.","p.m.","P.M."], + patterns: { + d: "dd/MM/yyyy", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy HH:mm:ss", + g: "dd/MM/yyyy HH:mm", + G: "dd/MM/yyyy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.da-DK.js b/src/cultures/kendo.culture.da-DK.js new file mode 100644 index 00000000000..792cbea1a85 --- /dev/null +++ b/src/cultures/kendo.culture.da-DK.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["da-DK"] = { + name: "da-DK", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "kr." + } + }, + calendars: { + standard: { + days: { + names: ["søndag","mandag","tirsdag","onsdag","torsdag","fredag","lørdag"], + namesAbbr: ["sø","ma","ti","on","to","fr","lø"], + namesShort: ["sø","ma","ti","on","to","fr","lø"] + }, + months: { + names: ["januar","februar","marts","april","maj","juni","juli","august","september","oktober","november","december",""], + namesAbbr: ["jan","feb","mar","apr","maj","jun","jul","aug","sep","okt","nov","dec",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd-MM-yyyy", + D: "d. MMMM yyyy", + F: "d. MMMM yyyy HH:mm:ss", + g: "dd-MM-yyyy HH:mm", + G: "dd-MM-yyyy HH:mm:ss", + m: "d. MMMM", + M: "d. MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "-", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.da.js b/src/cultures/kendo.culture.da.js new file mode 100644 index 00000000000..3432ebd2892 --- /dev/null +++ b/src/cultures/kendo.culture.da.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["da"] = { + name: "da", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "kr." + } + }, + calendars: { + standard: { + days: { + names: ["søndag","mandag","tirsdag","onsdag","torsdag","fredag","lørdag"], + namesAbbr: ["sø","ma","ti","on","to","fr","lø"], + namesShort: ["sø","ma","ti","on","to","fr","lø"] + }, + months: { + names: ["januar","februar","marts","april","maj","juni","juli","august","september","oktober","november","december",""], + namesAbbr: ["jan","feb","mar","apr","maj","jun","jul","aug","sep","okt","nov","dec",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd-MM-yyyy", + D: "d. MMMM yyyy", + F: "d. MMMM yyyy HH:mm:ss", + g: "dd-MM-yyyy HH:mm", + G: "dd-MM-yyyy HH:mm:ss", + m: "d. MMMM", + M: "d. MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "-", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.de-AT.js b/src/cultures/kendo.culture.de-AT.js new file mode 100644 index 00000000000..c4ad0a85fec --- /dev/null +++ b/src/cultures/kendo.culture.de-AT.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["de-AT"] = { + name: "de-AT", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-$ n","$ n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag"], + namesAbbr: ["So","Mo","Di","Mi","Do","Fr","Sa"], + namesShort: ["So","Mo","Di","Mi","Do","Fr","Sa"] + }, + months: { + names: ["Jänner","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember",""], + namesAbbr: ["Jän","Feb","Mär","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yyyy", + D: "dddd, dd. MMMM yyyy", + F: "dddd, dd. MMMM yyyy HH:mm:ss", + g: "dd.MM.yyyy HH:mm", + G: "dd.MM.yyyy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.de-CH.js b/src/cultures/kendo.culture.de-CH.js new file mode 100644 index 00000000000..587056ea60a --- /dev/null +++ b/src/cultures/kendo.culture.de-CH.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["de-CH"] = { + name: "de-CH", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": "'", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": "'", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$-n","$ n"], + decimals: 2, + ",": "'", + ".": ".", + groupSize: [3], + symbol: "Fr." + } + }, + calendars: { + standard: { + days: { + names: ["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag"], + namesAbbr: ["So","Mo","Di","Mi","Do","Fr","Sa"], + namesShort: ["So","Mo","Di","Mi","Do","Fr","Sa"] + }, + months: { + names: ["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember",""], + namesAbbr: ["Jan","Feb","Mrz","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yyyy", + D: "dddd, d. MMMM yyyy", + F: "dddd, d. MMMM yyyy HH:mm:ss", + g: "dd.MM.yyyy HH:mm", + G: "dd.MM.yyyy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.de-DE.js b/src/cultures/kendo.culture.de-DE.js new file mode 100644 index 00000000000..44a6a05b738 --- /dev/null +++ b/src/cultures/kendo.culture.de-DE.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["de-DE"] = { + name: "de-DE", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag"], + namesAbbr: ["So","Mo","Di","Mi","Do","Fr","Sa"], + namesShort: ["So","Mo","Di","Mi","Do","Fr","Sa"] + }, + months: { + names: ["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember",""], + namesAbbr: ["Jan","Feb","Mrz","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yyyy", + D: "dddd, d. MMMM yyyy", + F: "dddd, d. MMMM yyyy HH:mm:ss", + g: "dd.MM.yyyy HH:mm", + G: "dd.MM.yyyy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.de-LI.js b/src/cultures/kendo.culture.de-LI.js new file mode 100644 index 00000000000..78523afc750 --- /dev/null +++ b/src/cultures/kendo.culture.de-LI.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["de-LI"] = { + name: "de-LI", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": "'", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": "'", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$-n","$ n"], + decimals: 2, + ",": "'", + ".": ".", + groupSize: [3], + symbol: "CHF" + } + }, + calendars: { + standard: { + days: { + names: ["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag"], + namesAbbr: ["So","Mo","Di","Mi","Do","Fr","Sa"], + namesShort: ["So","Mo","Di","Mi","Do","Fr","Sa"] + }, + months: { + names: ["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember",""], + namesAbbr: ["Jan","Feb","Mrz","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yyyy", + D: "dddd, d. MMMM yyyy", + F: "dddd, d. MMMM yyyy HH:mm:ss", + g: "dd.MM.yyyy HH:mm", + G: "dd.MM.yyyy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.de-LU.js b/src/cultures/kendo.culture.de-LU.js new file mode 100644 index 00000000000..ffc53c2edc5 --- /dev/null +++ b/src/cultures/kendo.culture.de-LU.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["de-LU"] = { + name: "de-LU", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag"], + namesAbbr: ["So","Mo","Di","Mi","Do","Fr","Sa"], + namesShort: ["So","Mo","Di","Mi","Do","Fr","Sa"] + }, + months: { + names: ["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember",""], + namesAbbr: ["Jan","Feb","Mrz","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yyyy", + D: "dddd, d. MMMM yyyy", + F: "dddd, d. MMMM yyyy HH:mm:ss", + g: "dd.MM.yyyy HH:mm", + G: "dd.MM.yyyy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.de.js b/src/cultures/kendo.culture.de.js new file mode 100644 index 00000000000..257d01d6097 --- /dev/null +++ b/src/cultures/kendo.culture.de.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["de"] = { + name: "de", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag"], + namesAbbr: ["So","Mo","Di","Mi","Do","Fr","Sa"], + namesShort: ["So","Mo","Di","Mi","Do","Fr","Sa"] + }, + months: { + names: ["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember",""], + namesAbbr: ["Jan","Feb","Mrz","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yyyy", + D: "dddd, d. MMMM yyyy", + F: "dddd, d. MMMM yyyy HH:mm:ss", + g: "dd.MM.yyyy HH:mm", + G: "dd.MM.yyyy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.dsb-DE.js b/src/cultures/kendo.culture.dsb-DE.js new file mode 100644 index 00000000000..7fe7d09d8a9 --- /dev/null +++ b/src/cultures/kendo.culture.dsb-DE.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["dsb-DE"] = { + name: "dsb-DE", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["njeźela","ponjeźele","wałtora","srjoda","stwortk","pětk","sobota"], + namesAbbr: ["nje","pon","wał","srj","stw","pět","sob"], + namesShort: ["n","p","w","s","s","p","s"] + }, + months: { + names: ["januar","februar","měrc","apryl","maj","junij","julij","awgust","september","oktober","nowember","december",""], + namesAbbr: ["jan","feb","měr","apr","maj","jun","jul","awg","sep","okt","now","dec",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "d. M. yyyy", + D: "dddd, 'dnja' d. MMMM yyyy", + F: "dddd, 'dnja' d. MMMM yyyy H:mm:ss", + g: "d. M. yyyy H.mm 'goź.'", + G: "d. M. yyyy H:mm:ss", + m: "d. MMMM", + M: "d. MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H.mm 'goź.'", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ". ", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.dsb.js b/src/cultures/kendo.culture.dsb.js new file mode 100644 index 00000000000..e5d1577578b --- /dev/null +++ b/src/cultures/kendo.culture.dsb.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["dsb"] = { + name: "dsb", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["njeźela","ponjeźele","wałtora","srjoda","stwortk","pětk","sobota"], + namesAbbr: ["nje","pon","wał","srj","stw","pět","sob"], + namesShort: ["n","p","w","s","s","p","s"] + }, + months: { + names: ["januar","februar","měrc","apryl","maj","junij","julij","awgust","september","oktober","nowember","december",""], + namesAbbr: ["jan","feb","měr","apr","maj","jun","jul","awg","sep","okt","now","dec",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "d. M. yyyy", + D: "dddd, 'dnja' d. MMMM yyyy", + F: "dddd, 'dnja' d. MMMM yyyy H:mm:ss", + g: "d. M. yyyy H.mm 'goź.'", + G: "d. M. yyyy H:mm:ss", + m: "d. MMMM", + M: "d. MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H.mm 'goź.'", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ". ", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.dv-MV.js b/src/cultures/kendo.culture.dv-MV.js new file mode 100644 index 00000000000..8b804622c87 --- /dev/null +++ b/src/cultures/kendo.culture.dv-MV.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["dv-MV"] = { + name: "dv-MV", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["n $-","n $"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "ރ." + } + }, + calendars: { + standard: { + days: { + names: ["އާދީއްތަ","ހޯމަ","އަންގާރަ","ބުދަ","ބުރާސްފަތި","ހުކުރު","ހޮނިހިރު"], + namesAbbr: ["އާދީއްތަ","ހޯމަ","އަންގާރަ","ބުދަ","ބުރާސްފަތި","ހުކުރު","ހޮނިހިރު"], + namesShort: ["އާ","ހޯ","އަ","ބު","ބު","ހު","ހޮ"] + }, + months: { + names: ["މުޙައްރަމް","ޞަފަރު","ރަބީޢުލްއައްވަލް","ރަބީޢުލްއާޚިރު","ޖުމާދަލްއޫލާ","ޖުމާދަލްއާޚިރާ","ރަޖަބް","ޝަޢްބާން","ރަމަޟާން","ޝައްވާލް","ޛުލްޤަޢިދާ","ޛުލްޙިއްޖާ",""], + namesAbbr: ["މުޙައްރަމް","ޞަފަރު","ރަބީޢުލްއައްވަލް","ރަބީޢުލްއާޚިރު","ޖުމާދަލްއޫލާ","ޖުމާދަލްއާޚިރާ","ރަޖަބް","ޝަޢްބާން","ރަމަޟާން","ޝައްވާލް","ޛުލްޤަޢިދާ","ޛުލްޙިއްޖާ",""] + }, + AM: ["މކ","މކ","މކ"], + PM: ["މފ","މފ","މފ"], + patterns: { + d: "dd/MM/yy", + D: "dd/MM/yyyy", + F: "dd/MM/yyyy HH:mm:ss", + g: "dd/MM/yy HH:mm", + G: "dd/MM/yy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.dv.js b/src/cultures/kendo.culture.dv.js new file mode 100644 index 00000000000..1cebc5461ee --- /dev/null +++ b/src/cultures/kendo.culture.dv.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["dv"] = { + name: "dv", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["n $-","n $"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "ރ." + } + }, + calendars: { + standard: { + days: { + names: ["އާދީއްތަ","ހޯމަ","އަންގާރަ","ބުދަ","ބުރާސްފަތި","ހުކުރު","ހޮނިހިރު"], + namesAbbr: ["އާދީއްތަ","ހޯމަ","އަންގާރަ","ބުދަ","ބުރާސްފަތި","ހުކުރު","ހޮނިހިރު"], + namesShort: ["އާ","ހޯ","އަ","ބު","ބު","ހު","ހޮ"] + }, + months: { + names: ["މުޙައްރަމް","ޞަފަރު","ރަބީޢުލްއައްވަލް","ރަބީޢުލްއާޚިރު","ޖުމާދަލްއޫލާ","ޖުމާދަލްއާޚިރާ","ރަޖަބް","ޝަޢްބާން","ރަމަޟާން","ޝައްވާލް","ޛުލްޤަޢިދާ","ޛުލްޙިއްޖާ",""], + namesAbbr: ["މުޙައްރަމް","ޞަފަރު","ރަބީޢުލްއައްވަލް","ރަބީޢުލްއާޚިރު","ޖުމާދަލްއޫލާ","ޖުމާދަލްއާޚިރާ","ރަޖަބް","ޝަޢްބާން","ރަމަޟާން","ޝައްވާލް","ޛުލްޤަޢިދާ","ޛުލްޙިއްޖާ",""] + }, + AM: ["މކ","މކ","މކ"], + PM: ["މފ","މފ","މފ"], + patterns: { + d: "dd/MM/yy", + D: "dd/MM/yyyy", + F: "dd/MM/yyyy HH:mm:ss", + g: "dd/MM/yy HH:mm", + G: "dd/MM/yy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.el-GR.js b/src/cultures/kendo.culture.el-GR.js new file mode 100644 index 00000000000..eccacb339ef --- /dev/null +++ b/src/cultures/kendo.culture.el-GR.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["el-GR"] = { + name: "el-GR", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["Κυριακή","Δευτέρα","Τρίτη","Τετάρτη","Πέμπτη","Παρασκευή","Σάββατο"], + namesAbbr: ["Κυρ","Δευ","Τρι","Τετ","Πεμ","Παρ","Σαβ"], + namesShort: ["Κυ","Δε","Τρ","Τε","Πε","Πα","Σά"] + }, + months: { + names: ["Ιανουάριος","Φεβρουάριος","Μάρτιος","Απρίλιος","Μάιος","Ιούνιος","Ιούλιος","Αύγουστος","Σεπτέμβριος","Οκτώβριος","Νοέμβριος","Δεκέμβριος",""], + namesAbbr: ["Ιαν","Φεβ","Μαρ","Απρ","Μαϊ","Ιουν","Ιουλ","Αυγ","Σεπ","Οκτ","Νοε","Δεκ",""] + }, + AM: ["πμ","πμ","ΠΜ"], + PM: ["μμ","μμ","ΜΜ"], + patterns: { + d: "d/M/yyyy", + D: "dddd, d MMMM yyyy", + F: "dddd, d MMMM yyyy h:mm:ss tt", + g: "d/M/yyyy h:mm tt", + G: "d/M/yyyy h:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.el.js b/src/cultures/kendo.culture.el.js new file mode 100644 index 00000000000..6066724d2fc --- /dev/null +++ b/src/cultures/kendo.culture.el.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["el"] = { + name: "el", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["Κυριακή","Δευτέρα","Τρίτη","Τετάρτη","Πέμπτη","Παρασκευή","Σάββατο"], + namesAbbr: ["Κυρ","Δευ","Τρι","Τετ","Πεμ","Παρ","Σαβ"], + namesShort: ["Κυ","Δε","Τρ","Τε","Πε","Πα","Σά"] + }, + months: { + names: ["Ιανουάριος","Φεβρουάριος","Μάρτιος","Απρίλιος","Μάιος","Ιούνιος","Ιούλιος","Αύγουστος","Σεπτέμβριος","Οκτώβριος","Νοέμβριος","Δεκέμβριος",""], + namesAbbr: ["Ιαν","Φεβ","Μαρ","Απρ","Μαϊ","Ιουν","Ιουλ","Αυγ","Σεπ","Οκτ","Νοε","Δεκ",""] + }, + AM: ["πμ","πμ","ΠΜ"], + PM: ["μμ","μμ","ΜΜ"], + patterns: { + d: "d/M/yyyy", + D: "dddd, d MMMM yyyy", + F: "dddd, d MMMM yyyy h:mm:ss tt", + g: "d/M/yyyy h:mm tt", + G: "d/M/yyyy h:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.en-029.js b/src/cultures/kendo.culture.en-029.js new file mode 100644 index 00000000000..775b09a4bc5 --- /dev/null +++ b/src/cultures/kendo.culture.en-029.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["en-029"] = { + name: "en-029", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-$n","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "$" + } + }, + calendars: { + standard: { + days: { + names: ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"], + namesAbbr: ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"], + namesShort: ["Su","Mo","Tu","We","Th","Fr","Sa"] + }, + months: { + names: ["January","February","March","April","May","June","July","August","September","October","November","December",""], + namesAbbr: ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "MM/dd/yyyy", + D: "dddd, MMMM dd, yyyy", + F: "dddd, MMMM dd, yyyy h:mm:ss tt", + g: "MM/dd/yyyy h:mm tt", + G: "MM/dd/yyyy h:mm:ss tt", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.en-AU.js b/src/cultures/kendo.culture.en-AU.js new file mode 100644 index 00000000000..e98ac82be12 --- /dev/null +++ b/src/cultures/kendo.culture.en-AU.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["en-AU"] = { + name: "en-AU", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-$n","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "$" + } + }, + calendars: { + standard: { + days: { + names: ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"], + namesAbbr: ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"], + namesShort: ["Su","Mo","Tu","We","Th","Fr","Sa"] + }, + months: { + names: ["January","February","March","April","May","June","July","August","September","October","November","December",""], + namesAbbr: ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "d/MM/yyyy", + D: "dddd, d MMMM yyyy", + F: "dddd, d MMMM yyyy h:mm:ss tt", + g: "d/MM/yyyy h:mm tt", + G: "d/MM/yyyy h:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.en-BZ.js b/src/cultures/kendo.culture.en-BZ.js new file mode 100644 index 00000000000..2328c170a4c --- /dev/null +++ b/src/cultures/kendo.culture.en-BZ.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["en-BZ"] = { + name: "en-BZ", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["($n)","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + symbol: "BZ$" + } + }, + calendars: { + standard: { + days: { + names: ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"], + namesAbbr: ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"], + namesShort: ["Su","Mo","Tu","We","Th","Fr","Sa"] + }, + months: { + names: ["January","February","March","April","May","June","July","August","September","October","November","December",""], + namesAbbr: ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "dd/MM/yyyy", + D: "dddd, dd MMMM yyyy", + F: "dddd, dd MMMM yyyy hh:mm:ss tt", + g: "dd/MM/yyyy hh:mm tt", + G: "dd/MM/yyyy hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.en-CA.js b/src/cultures/kendo.culture.en-CA.js new file mode 100644 index 00000000000..45486d828c7 --- /dev/null +++ b/src/cultures/kendo.culture.en-CA.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["en-CA"] = { + name: "en-CA", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-$n","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "$" + } + }, + calendars: { + standard: { + days: { + names: ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"], + namesAbbr: ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"], + namesShort: ["Su","Mo","Tu","We","Th","Fr","Sa"] + }, + months: { + names: ["January","February","March","April","May","June","July","August","September","October","November","December",""], + namesAbbr: ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "yyyy-MM-dd", + D: "MMMM d, yyyy", + F: "MMMM d, yyyy h:mm:ss tt", + g: "yyyy-MM-dd h:mm tt", + G: "yyyy-MM-dd h:mm:ss tt", + m: "d MMMM", + M: "d MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "-", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.en-GB.js b/src/cultures/kendo.culture.en-GB.js new file mode 100644 index 00000000000..99d6e220c16 --- /dev/null +++ b/src/cultures/kendo.culture.en-GB.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["en-GB"] = { + name: "en-GB", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-$n","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "£" + } + }, + calendars: { + standard: { + days: { + names: ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"], + namesAbbr: ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"], + namesShort: ["Su","Mo","Tu","We","Th","Fr","Sa"] + }, + months: { + names: ["January","February","March","April","May","June","July","August","September","October","November","December",""], + namesAbbr: ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "dd/MM/yyyy", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy HH:mm:ss", + g: "dd/MM/yyyy HH:mm", + G: "dd/MM/yyyy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.en-IE.js b/src/cultures/kendo.culture.en-IE.js new file mode 100644 index 00000000000..e8ee57598d9 --- /dev/null +++ b/src/cultures/kendo.culture.en-IE.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["en-IE"] = { + name: "en-IE", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-$n","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"], + namesAbbr: ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"], + namesShort: ["Su","Mo","Tu","We","Th","Fr","Sa"] + }, + months: { + names: ["January","February","March","April","May","June","July","August","September","October","November","December",""], + namesAbbr: ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd/MM/yyyy", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy HH:mm:ss", + g: "dd/MM/yyyy HH:mm", + G: "dd/MM/yyyy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.en-IN.js b/src/cultures/kendo.culture.en-IN.js new file mode 100644 index 00000000000..bf92abf7a09 --- /dev/null +++ b/src/cultures/kendo.culture.en-IN.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["en-IN"] = { + name: "en-IN", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "Rs." + } + }, + calendars: { + standard: { + days: { + names: ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"], + namesAbbr: ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"], + namesShort: ["Su","Mo","Tu","We","Th","Fr","Sa"] + }, + months: { + names: ["January","February","March","April","May","June","July","August","September","October","November","December",""], + namesAbbr: ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "dd-MM-yyyy", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy HH:mm:ss", + g: "dd-MM-yyyy HH:mm", + G: "dd-MM-yyyy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "-", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.en-JM.js b/src/cultures/kendo.culture.en-JM.js new file mode 100644 index 00000000000..b87ebfb1522 --- /dev/null +++ b/src/cultures/kendo.culture.en-JM.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["en-JM"] = { + name: "en-JM", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-$n","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "J$" + } + }, + calendars: { + standard: { + days: { + names: ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"], + namesAbbr: ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"], + namesShort: ["Su","Mo","Tu","We","Th","Fr","Sa"] + }, + months: { + names: ["January","February","March","April","May","June","July","August","September","October","November","December",""], + namesAbbr: ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "dd/MM/yyyy", + D: "dddd, MMMM dd, yyyy", + F: "dddd, MMMM dd, yyyy hh:mm:ss tt", + g: "dd/MM/yyyy hh:mm tt", + G: "dd/MM/yyyy hh:mm:ss tt", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.en-MY.js b/src/cultures/kendo.culture.en-MY.js new file mode 100644 index 00000000000..cd51261fdcc --- /dev/null +++ b/src/cultures/kendo.culture.en-MY.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["en-MY"] = { + name: "en-MY", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["($n)","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "RM" + } + }, + calendars: { + standard: { + days: { + names: ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"], + namesAbbr: ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"], + namesShort: ["S","M","T","W","T","F","S"] + }, + months: { + names: ["January","February","March","April","May","June","July","August","September","October","November","December",""], + namesAbbr: ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "d/M/yyyy", + D: "dddd, d MMMM, yyyy", + F: "dddd, d MMMM, yyyy h:mm:ss tt", + g: "d/M/yyyy h:mm tt", + G: "d/M/yyyy h:mm:ss tt", + m: "d MMMM", + M: "d MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.en-NZ.js b/src/cultures/kendo.culture.en-NZ.js new file mode 100644 index 00000000000..3c33e36f158 --- /dev/null +++ b/src/cultures/kendo.culture.en-NZ.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["en-NZ"] = { + name: "en-NZ", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-$n","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "$" + } + }, + calendars: { + standard: { + days: { + names: ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"], + namesAbbr: ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"], + namesShort: ["Su","Mo","Tu","We","Th","Fr","Sa"] + }, + months: { + names: ["January","February","March","April","May","June","July","August","September","October","November","December",""], + namesAbbr: ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",""] + }, + AM: ["a.m.","a.m.","A.M."], + PM: ["p.m.","p.m.","P.M."], + patterns: { + d: "d/MM/yyyy", + D: "dddd, d MMMM yyyy", + F: "dddd, d MMMM yyyy h:mm:ss tt", + g: "d/MM/yyyy h:mm tt", + G: "d/MM/yyyy h:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.en-PH.js b/src/cultures/kendo.culture.en-PH.js new file mode 100644 index 00000000000..0805e8852fd --- /dev/null +++ b/src/cultures/kendo.culture.en-PH.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["en-PH"] = { + name: "en-PH", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["($n)","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "Php" + } + }, + calendars: { + standard: { + days: { + names: ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"], + namesAbbr: ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"], + namesShort: ["Su","Mo","Tu","We","Th","Fr","Sa"] + }, + months: { + names: ["January","February","March","April","May","June","July","August","September","October","November","December",""], + namesAbbr: ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "M/d/yyyy", + D: "dddd, MMMM dd, yyyy", + F: "dddd, MMMM dd, yyyy h:mm:ss tt", + g: "M/d/yyyy h:mm tt", + G: "M/d/yyyy h:mm:ss tt", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.en-SG.js b/src/cultures/kendo.culture.en-SG.js new file mode 100644 index 00000000000..fe2781af948 --- /dev/null +++ b/src/cultures/kendo.culture.en-SG.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["en-SG"] = { + name: "en-SG", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["($n)","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "$" + } + }, + calendars: { + standard: { + days: { + names: ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"], + namesAbbr: ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"], + namesShort: ["S","M","T","W","T","F","S"] + }, + months: { + names: ["January","February","March","April","May","June","July","August","September","October","November","December",""], + namesAbbr: ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "d/M/yyyy", + D: "dddd, d MMMM, yyyy", + F: "dddd, d MMMM, yyyy h:mm:ss tt", + g: "d/M/yyyy h:mm tt", + G: "d/M/yyyy h:mm:ss tt", + m: "d MMMM", + M: "d MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.en-TT.js b/src/cultures/kendo.culture.en-TT.js new file mode 100644 index 00000000000..d1e40712714 --- /dev/null +++ b/src/cultures/kendo.culture.en-TT.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["en-TT"] = { + name: "en-TT", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["($n)","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + symbol: "TT$" + } + }, + calendars: { + standard: { + days: { + names: ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"], + namesAbbr: ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"], + namesShort: ["Su","Mo","Tu","We","Th","Fr","Sa"] + }, + months: { + names: ["January","February","March","April","May","June","July","August","September","October","November","December",""], + namesAbbr: ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "dd/MM/yyyy", + D: "dddd, dd MMMM yyyy", + F: "dddd, dd MMMM yyyy hh:mm:ss tt", + g: "dd/MM/yyyy hh:mm tt", + G: "dd/MM/yyyy hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.en-US.js b/src/cultures/kendo.culture.en-US.js new file mode 100644 index 00000000000..7f3cdd44100 --- /dev/null +++ b/src/cultures/kendo.culture.en-US.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["en-US"] = { + name: "en-US", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["($n)","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "$" + } + }, + calendars: { + standard: { + days: { + names: ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"], + namesAbbr: ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"], + namesShort: ["Su","Mo","Tu","We","Th","Fr","Sa"] + }, + months: { + names: ["January","February","March","April","May","June","July","August","September","October","November","December",""], + namesAbbr: ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "M/d/yyyy", + D: "dddd, MMMM dd, yyyy", + F: "dddd, MMMM dd, yyyy h:mm:ss tt", + g: "M/d/yyyy h:mm tt", + G: "M/d/yyyy h:mm:ss tt", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.en-ZA.js b/src/cultures/kendo.culture.en-ZA.js new file mode 100644 index 00000000000..773497bbf45 --- /dev/null +++ b/src/cultures/kendo.culture.en-ZA.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["en-ZA"] = { + name: "en-ZA", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": " ", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$-n","$ n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "R" + } + }, + calendars: { + standard: { + days: { + names: ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"], + namesAbbr: ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"], + namesShort: ["Su","Mo","Tu","We","Th","Fr","Sa"] + }, + months: { + names: ["January","February","March","April","May","June","July","August","September","October","November","December",""], + namesAbbr: ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "yyyy/MM/dd", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy hh:mm:ss tt", + g: "yyyy/MM/dd hh:mm tt", + G: "yyyy/MM/dd hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.en-ZW.js b/src/cultures/kendo.culture.en-ZW.js new file mode 100644 index 00000000000..53959529f7a --- /dev/null +++ b/src/cultures/kendo.culture.en-ZW.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["en-ZW"] = { + name: "en-ZW", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["($n)","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "Z$" + } + }, + calendars: { + standard: { + days: { + names: ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"], + namesAbbr: ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"], + namesShort: ["Su","Mo","Tu","We","Th","Fr","Sa"] + }, + months: { + names: ["January","February","March","April","May","June","July","August","September","October","November","December",""], + namesAbbr: ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "M/d/yyyy", + D: "dddd, MMMM dd, yyyy", + F: "dddd, MMMM dd, yyyy h:mm:ss tt", + g: "M/d/yyyy h:mm tt", + G: "M/d/yyyy h:mm:ss tt", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.en.js b/src/cultures/kendo.culture.en.js new file mode 100644 index 00000000000..da83a147136 --- /dev/null +++ b/src/cultures/kendo.culture.en.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["en"] = { + name: "en", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["($n)","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "$" + } + }, + calendars: { + standard: { + days: { + names: ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"], + namesAbbr: ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"], + namesShort: ["Su","Mo","Tu","We","Th","Fr","Sa"] + }, + months: { + names: ["January","February","March","April","May","June","July","August","September","October","November","December",""], + namesAbbr: ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "M/d/yyyy", + D: "dddd, MMMM dd, yyyy", + F: "dddd, MMMM dd, yyyy h:mm:ss tt", + g: "M/d/yyyy h:mm tt", + G: "M/d/yyyy h:mm:ss tt", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.es-AR.js b/src/cultures/kendo.culture.es-AR.js new file mode 100644 index 00000000000..fcc805ff01a --- /dev/null +++ b/src/cultures/kendo.culture.es-AR.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["es-AR"] = { + name: "es-AR", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$-n","$ n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "$" + } + }, + calendars: { + standard: { + days: { + names: ["domingo","lunes","martes","miércoles","jueves","viernes","sábado"], + namesAbbr: ["dom","lun","mar","mié","jue","vie","sáb"], + namesShort: ["do","lu","ma","mi","ju","vi","sá"] + }, + months: { + names: ["enero","febrero","marzo","abril","mayo","junio","julio","agosto","septiembre","octubre","noviembre","diciembre",""], + namesAbbr: ["ene","feb","mar","abr","may","jun","jul","ago","sep","oct","nov","dic",""] + }, + AM: ["a.m.","a.m.","A.M."], + PM: ["p.m.","p.m.","P.M."], + patterns: { + d: "dd/MM/yyyy", + D: "dddd, dd' de 'MMMM' de 'yyyy", + F: "dddd, dd' de 'MMMM' de 'yyyy hh:mm:ss tt", + g: "dd/MM/yyyy hh:mm tt", + G: "dd/MM/yyyy hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM' de 'yyyy", + Y: "MMMM' de 'yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.es-BO.js b/src/cultures/kendo.culture.es-BO.js new file mode 100644 index 00000000000..afa642538d6 --- /dev/null +++ b/src/cultures/kendo.culture.es-BO.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["es-BO"] = { + name: "es-BO", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["($ n)","$ n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "$b" + } + }, + calendars: { + standard: { + days: { + names: ["domingo","lunes","martes","miércoles","jueves","viernes","sábado"], + namesAbbr: ["dom","lun","mar","mié","jue","vie","sáb"], + namesShort: ["do","lu","ma","mi","ju","vi","sá"] + }, + months: { + names: ["enero","febrero","marzo","abril","mayo","junio","julio","agosto","septiembre","octubre","noviembre","diciembre",""], + namesAbbr: ["ene","feb","mar","abr","may","jun","jul","ago","sep","oct","nov","dic",""] + }, + AM: ["a.m.","a.m.","A.M."], + PM: ["p.m.","p.m.","P.M."], + patterns: { + d: "dd/MM/yyyy", + D: "dddd, dd' de 'MMMM' de 'yyyy", + F: "dddd, dd' de 'MMMM' de 'yyyy hh:mm:ss tt", + g: "dd/MM/yyyy hh:mm tt", + G: "dd/MM/yyyy hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM' de 'yyyy", + Y: "MMMM' de 'yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.es-CL.js b/src/cultures/kendo.culture.es-CL.js new file mode 100644 index 00000000000..41b486d05af --- /dev/null +++ b/src/cultures/kendo.culture.es-CL.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["es-CL"] = { + name: "es-CL", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-$ n","$ n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "$" + } + }, + calendars: { + standard: { + days: { + names: ["domingo","lunes","martes","miércoles","jueves","viernes","sábado"], + namesAbbr: ["dom","lun","mar","mié","jue","vie","sáb"], + namesShort: ["do","lu","ma","mi","ju","vi","sá"] + }, + months: { + names: ["enero","febrero","marzo","abril","mayo","junio","julio","agosto","septiembre","octubre","noviembre","diciembre",""], + namesAbbr: ["ene","feb","mar","abr","may","jun","jul","ago","sep","oct","nov","dic",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd-MM-yyyy", + D: "dddd, dd' de 'MMMM' de 'yyyy", + F: "dddd, dd' de 'MMMM' de 'yyyy H:mm:ss", + g: "dd-MM-yyyy H:mm", + G: "dd-MM-yyyy H:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM' de 'yyyy", + Y: "MMMM' de 'yyyy" + }, + "/": "-", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.es-CO.js b/src/cultures/kendo.culture.es-CO.js new file mode 100644 index 00000000000..9ffb65032f8 --- /dev/null +++ b/src/cultures/kendo.culture.es-CO.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["es-CO"] = { + name: "es-CO", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["($ n)","$ n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "$" + } + }, + calendars: { + standard: { + days: { + names: ["domingo","lunes","martes","miércoles","jueves","viernes","sábado"], + namesAbbr: ["dom","lun","mar","mié","jue","vie","sáb"], + namesShort: ["do","lu","ma","mi","ju","vi","sá"] + }, + months: { + names: ["enero","febrero","marzo","abril","mayo","junio","julio","agosto","septiembre","octubre","noviembre","diciembre",""], + namesAbbr: ["ene","feb","mar","abr","may","jun","jul","ago","sep","oct","nov","dic",""] + }, + AM: ["a.m.","a.m.","A.M."], + PM: ["p.m.","p.m.","P.M."], + patterns: { + d: "dd/MM/yyyy", + D: "dddd, dd' de 'MMMM' de 'yyyy", + F: "dddd, dd' de 'MMMM' de 'yyyy hh:mm:ss tt", + g: "dd/MM/yyyy hh:mm tt", + G: "dd/MM/yyyy hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM' de 'yyyy", + Y: "MMMM' de 'yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.es-CR.js b/src/cultures/kendo.culture.es-CR.js new file mode 100644 index 00000000000..1a2b8ef1cd3 --- /dev/null +++ b/src/cultures/kendo.culture.es-CR.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["es-CR"] = { + name: "es-CR", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["($n)","$n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "₡" + } + }, + calendars: { + standard: { + days: { + names: ["domingo","lunes","martes","miércoles","jueves","viernes","sábado"], + namesAbbr: ["dom","lun","mar","mié","jue","vie","sáb"], + namesShort: ["do","lu","ma","mi","ju","vi","sá"] + }, + months: { + names: ["enero","febrero","marzo","abril","mayo","junio","julio","agosto","septiembre","octubre","noviembre","diciembre",""], + namesAbbr: ["ene","feb","mar","abr","may","jun","jul","ago","sep","oct","nov","dic",""] + }, + AM: ["a.m.","a.m.","A.M."], + PM: ["p.m.","p.m.","P.M."], + patterns: { + d: "dd/MM/yyyy", + D: "dddd, dd' de 'MMMM' de 'yyyy", + F: "dddd, dd' de 'MMMM' de 'yyyy hh:mm:ss tt", + g: "dd/MM/yyyy hh:mm tt", + G: "dd/MM/yyyy hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM' de 'yyyy", + Y: "MMMM' de 'yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.es-DO.js b/src/cultures/kendo.culture.es-DO.js new file mode 100644 index 00000000000..8d594ef721a --- /dev/null +++ b/src/cultures/kendo.culture.es-DO.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["es-DO"] = { + name: "es-DO", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["($n)","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "RD$" + } + }, + calendars: { + standard: { + days: { + names: ["domingo","lunes","martes","miércoles","jueves","viernes","sábado"], + namesAbbr: ["dom","lun","mar","mié","jue","vie","sáb"], + namesShort: ["do","lu","ma","mi","ju","vi","sá"] + }, + months: { + names: ["enero","febrero","marzo","abril","mayo","junio","julio","agosto","septiembre","octubre","noviembre","diciembre",""], + namesAbbr: ["ene","feb","mar","abr","may","jun","jul","ago","sep","oct","nov","dic",""] + }, + AM: ["a.m.","a.m.","A.M."], + PM: ["p.m.","p.m.","P.M."], + patterns: { + d: "dd/MM/yyyy", + D: "dddd, dd' de 'MMMM' de 'yyyy", + F: "dddd, dd' de 'MMMM' de 'yyyy hh:mm:ss tt", + g: "dd/MM/yyyy hh:mm tt", + G: "dd/MM/yyyy hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM' de 'yyyy", + Y: "MMMM' de 'yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.es-EC.js b/src/cultures/kendo.culture.es-EC.js new file mode 100644 index 00000000000..9b9d5a44d46 --- /dev/null +++ b/src/cultures/kendo.culture.es-EC.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["es-EC"] = { + name: "es-EC", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["($ n)","$ n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "$" + } + }, + calendars: { + standard: { + days: { + names: ["domingo","lunes","martes","miércoles","jueves","viernes","sábado"], + namesAbbr: ["dom","lun","mar","mié","jue","vie","sáb"], + namesShort: ["do","lu","ma","mi","ju","vi","sá"] + }, + months: { + names: ["enero","febrero","marzo","abril","mayo","junio","julio","agosto","septiembre","octubre","noviembre","diciembre",""], + namesAbbr: ["ene","feb","mar","abr","may","jun","jul","ago","sep","oct","nov","dic",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd/MM/yyyy", + D: "dddd, dd' de 'MMMM' de 'yyyy", + F: "dddd, dd' de 'MMMM' de 'yyyy H:mm:ss", + g: "dd/MM/yyyy H:mm", + G: "dd/MM/yyyy H:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM' de 'yyyy", + Y: "MMMM' de 'yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.es-ES.js b/src/cultures/kendo.culture.es-ES.js new file mode 100644 index 00000000000..de3166205f5 --- /dev/null +++ b/src/cultures/kendo.culture.es-ES.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["es-ES"] = { + name: "es-ES", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["domingo","lunes","martes","miércoles","jueves","viernes","sábado"], + namesAbbr: ["dom","lun","mar","mié","jue","vie","sáb"], + namesShort: ["do","lu","ma","mi","ju","vi","sá"] + }, + months: { + names: ["enero","febrero","marzo","abril","mayo","junio","julio","agosto","septiembre","octubre","noviembre","diciembre",""], + namesAbbr: ["ene","feb","mar","abr","may","jun","jul","ago","sep","oct","nov","dic",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd/MM/yyyy", + D: "dddd, dd' de 'MMMM' de 'yyyy", + F: "dddd, dd' de 'MMMM' de 'yyyy H:mm:ss", + g: "dd/MM/yyyy H:mm", + G: "dd/MM/yyyy H:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM' de 'yyyy", + Y: "MMMM' de 'yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.es-GT.js b/src/cultures/kendo.culture.es-GT.js new file mode 100644 index 00000000000..7605839de77 --- /dev/null +++ b/src/cultures/kendo.culture.es-GT.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["es-GT"] = { + name: "es-GT", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["($n)","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "Q" + } + }, + calendars: { + standard: { + days: { + names: ["domingo","lunes","martes","miércoles","jueves","viernes","sábado"], + namesAbbr: ["dom","lun","mar","mié","jue","vie","sáb"], + namesShort: ["do","lu","ma","mi","ju","vi","sá"] + }, + months: { + names: ["enero","febrero","marzo","abril","mayo","junio","julio","agosto","septiembre","octubre","noviembre","diciembre",""], + namesAbbr: ["ene","feb","mar","abr","may","jun","jul","ago","sep","oct","nov","dic",""] + }, + AM: ["a.m.","a.m.","A.M."], + PM: ["p.m.","p.m.","P.M."], + patterns: { + d: "dd/MM/yyyy", + D: "dddd, dd' de 'MMMM' de 'yyyy", + F: "dddd, dd' de 'MMMM' de 'yyyy hh:mm:ss tt", + g: "dd/MM/yyyy hh:mm tt", + G: "dd/MM/yyyy hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM' de 'yyyy", + Y: "MMMM' de 'yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.es-HN.js b/src/cultures/kendo.culture.es-HN.js new file mode 100644 index 00000000000..fae1b09586a --- /dev/null +++ b/src/cultures/kendo.culture.es-HN.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["es-HN"] = { + name: "es-HN", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + symbol: "L." + } + }, + calendars: { + standard: { + days: { + names: ["domingo","lunes","martes","miércoles","jueves","viernes","sábado"], + namesAbbr: ["dom","lun","mar","mié","jue","vie","sáb"], + namesShort: ["do","lu","ma","mi","ju","vi","sá"] + }, + months: { + names: ["enero","febrero","marzo","abril","mayo","junio","julio","agosto","septiembre","octubre","noviembre","diciembre",""], + namesAbbr: ["ene","feb","mar","abr","may","jun","jul","ago","sep","oct","nov","dic",""] + }, + AM: ["a.m.","a.m.","A.M."], + PM: ["p.m.","p.m.","P.M."], + patterns: { + d: "dd/MM/yyyy", + D: "dddd, dd' de 'MMMM' de 'yyyy", + F: "dddd, dd' de 'MMMM' de 'yyyy hh:mm:ss tt", + g: "dd/MM/yyyy hh:mm tt", + G: "dd/MM/yyyy hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM' de 'yyyy", + Y: "MMMM' de 'yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.es-MX.js b/src/cultures/kendo.culture.es-MX.js new file mode 100644 index 00000000000..f6f7d04153a --- /dev/null +++ b/src/cultures/kendo.culture.es-MX.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["es-MX"] = { + name: "es-MX", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-$n","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "$" + } + }, + calendars: { + standard: { + days: { + names: ["domingo","lunes","martes","miércoles","jueves","viernes","sábado"], + namesAbbr: ["dom","lun","mar","mié","jue","vie","sáb"], + namesShort: ["do","lu","ma","mi","ju","vi","sá"] + }, + months: { + names: ["enero","febrero","marzo","abril","mayo","junio","julio","agosto","septiembre","octubre","noviembre","diciembre",""], + namesAbbr: ["ene","feb","mar","abr","may","jun","jul","ago","sep","oct","nov","dic",""] + }, + AM: ["a.m.","a.m.","A.M."], + PM: ["p.m.","p.m.","P.M."], + patterns: { + d: "dd/MM/yyyy", + D: "dddd, dd' de 'MMMM' de 'yyyy", + F: "dddd, dd' de 'MMMM' de 'yyyy hh:mm:ss tt", + g: "dd/MM/yyyy hh:mm tt", + G: "dd/MM/yyyy hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM' de 'yyyy", + Y: "MMMM' de 'yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.es-NI.js b/src/cultures/kendo.culture.es-NI.js new file mode 100644 index 00000000000..cec0113e935 --- /dev/null +++ b/src/cultures/kendo.culture.es-NI.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["es-NI"] = { + name: "es-NI", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["($ n)","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + symbol: "C$" + } + }, + calendars: { + standard: { + days: { + names: ["domingo","lunes","martes","miércoles","jueves","viernes","sábado"], + namesAbbr: ["dom","lun","mar","mié","jue","vie","sáb"], + namesShort: ["do","lu","ma","mi","ju","vi","sá"] + }, + months: { + names: ["enero","febrero","marzo","abril","mayo","junio","julio","agosto","septiembre","octubre","noviembre","diciembre",""], + namesAbbr: ["ene","feb","mar","abr","may","jun","jul","ago","sep","oct","nov","dic",""] + }, + AM: ["a.m.","a.m.","A.M."], + PM: ["p.m.","p.m.","P.M."], + patterns: { + d: "dd/MM/yyyy", + D: "dddd, dd' de 'MMMM' de 'yyyy", + F: "dddd, dd' de 'MMMM' de 'yyyy hh:mm:ss tt", + g: "dd/MM/yyyy hh:mm tt", + G: "dd/MM/yyyy hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM' de 'yyyy", + Y: "MMMM' de 'yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.es-PA.js b/src/cultures/kendo.culture.es-PA.js new file mode 100644 index 00000000000..7e90f4d1e27 --- /dev/null +++ b/src/cultures/kendo.culture.es-PA.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["es-PA"] = { + name: "es-PA", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["($ n)","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "B/." + } + }, + calendars: { + standard: { + days: { + names: ["domingo","lunes","martes","miércoles","jueves","viernes","sábado"], + namesAbbr: ["dom","lun","mar","mié","jue","vie","sáb"], + namesShort: ["do","lu","ma","mi","ju","vi","sá"] + }, + months: { + names: ["enero","febrero","marzo","abril","mayo","junio","julio","agosto","septiembre","octubre","noviembre","diciembre",""], + namesAbbr: ["ene","feb","mar","abr","may","jun","jul","ago","sep","oct","nov","dic",""] + }, + AM: ["a.m.","a.m.","A.M."], + PM: ["p.m.","p.m.","P.M."], + patterns: { + d: "MM/dd/yyyy", + D: "dddd, dd' de 'MMMM' de 'yyyy", + F: "dddd, dd' de 'MMMM' de 'yyyy hh:mm:ss tt", + g: "MM/dd/yyyy hh:mm tt", + G: "MM/dd/yyyy hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM' de 'yyyy", + Y: "MMMM' de 'yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.es-PE.js b/src/cultures/kendo.culture.es-PE.js new file mode 100644 index 00000000000..30b77c3d82a --- /dev/null +++ b/src/cultures/kendo.culture.es-PE.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["es-PE"] = { + name: "es-PE", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "S/." + } + }, + calendars: { + standard: { + days: { + names: ["domingo","lunes","martes","miércoles","jueves","viernes","sábado"], + namesAbbr: ["dom","lun","mar","mié","jue","vie","sáb"], + namesShort: ["do","lu","ma","mi","ju","vi","sá"] + }, + months: { + names: ["enero","febrero","marzo","abril","mayo","junio","julio","agosto","septiembre","octubre","noviembre","diciembre",""], + namesAbbr: ["ene","feb","mar","abr","may","jun","jul","ago","sep","oct","nov","dic",""] + }, + AM: ["a.m.","a.m.","A.M."], + PM: ["p.m.","p.m.","P.M."], + patterns: { + d: "dd/MM/yyyy", + D: "dddd, dd' de 'MMMM' de 'yyyy", + F: "dddd, dd' de 'MMMM' de 'yyyy hh:mm:ss tt", + g: "dd/MM/yyyy hh:mm tt", + G: "dd/MM/yyyy hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM' de 'yyyy", + Y: "MMMM' de 'yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.es-PR.js b/src/cultures/kendo.culture.es-PR.js new file mode 100644 index 00000000000..43346c7c9f4 --- /dev/null +++ b/src/cultures/kendo.culture.es-PR.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["es-PR"] = { + name: "es-PR", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["($ n)","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + symbol: "$" + } + }, + calendars: { + standard: { + days: { + names: ["domingo","lunes","martes","miércoles","jueves","viernes","sábado"], + namesAbbr: ["dom","lun","mar","mié","jue","vie","sáb"], + namesShort: ["do","lu","ma","mi","ju","vi","sá"] + }, + months: { + names: ["enero","febrero","marzo","abril","mayo","junio","julio","agosto","septiembre","octubre","noviembre","diciembre",""], + namesAbbr: ["ene","feb","mar","abr","may","jun","jul","ago","sep","oct","nov","dic",""] + }, + AM: ["a.m.","a.m.","A.M."], + PM: ["p.m.","p.m.","P.M."], + patterns: { + d: "dd/MM/yyyy", + D: "dddd, dd' de 'MMMM' de 'yyyy", + F: "dddd, dd' de 'MMMM' de 'yyyy hh:mm:ss tt", + g: "dd/MM/yyyy hh:mm tt", + G: "dd/MM/yyyy hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM' de 'yyyy", + Y: "MMMM' de 'yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.es-PY.js b/src/cultures/kendo.culture.es-PY.js new file mode 100644 index 00000000000..d1a0fb1ba96 --- /dev/null +++ b/src/cultures/kendo.culture.es-PY.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["es-PY"] = { + name: "es-PY", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["($ n)","$ n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "Gs" + } + }, + calendars: { + standard: { + days: { + names: ["domingo","lunes","martes","miércoles","jueves","viernes","sábado"], + namesAbbr: ["dom","lun","mar","mié","jue","vie","sáb"], + namesShort: ["do","lu","ma","mi","ju","vi","sá"] + }, + months: { + names: ["enero","febrero","marzo","abril","mayo","junio","julio","agosto","septiembre","octubre","noviembre","diciembre",""], + namesAbbr: ["ene","feb","mar","abr","may","jun","jul","ago","sep","oct","nov","dic",""] + }, + AM: ["a.m.","a.m.","A.M."], + PM: ["p.m.","p.m.","P.M."], + patterns: { + d: "dd/MM/yyyy", + D: "dddd, dd' de 'MMMM' de 'yyyy", + F: "dddd, dd' de 'MMMM' de 'yyyy hh:mm:ss tt", + g: "dd/MM/yyyy hh:mm tt", + G: "dd/MM/yyyy hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM' de 'yyyy", + Y: "MMMM' de 'yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.es-SV.js b/src/cultures/kendo.culture.es-SV.js new file mode 100644 index 00000000000..8b6887cfe07 --- /dev/null +++ b/src/cultures/kendo.culture.es-SV.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["es-SV"] = { + name: "es-SV", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["($n)","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + symbol: "$" + } + }, + calendars: { + standard: { + days: { + names: ["domingo","lunes","martes","miércoles","jueves","viernes","sábado"], + namesAbbr: ["dom","lun","mar","mié","jue","vie","sáb"], + namesShort: ["do","lu","ma","mi","ju","vi","sá"] + }, + months: { + names: ["enero","febrero","marzo","abril","mayo","junio","julio","agosto","septiembre","octubre","noviembre","diciembre",""], + namesAbbr: ["ene","feb","mar","abr","may","jun","jul","ago","sep","oct","nov","dic",""] + }, + AM: ["a.m.","a.m.","A.M."], + PM: ["p.m.","p.m.","P.M."], + patterns: { + d: "dd/MM/yyyy", + D: "dddd, dd' de 'MMMM' de 'yyyy", + F: "dddd, dd' de 'MMMM' de 'yyyy hh:mm:ss tt", + g: "dd/MM/yyyy hh:mm tt", + G: "dd/MM/yyyy hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM' de 'yyyy", + Y: "MMMM' de 'yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.es-US.js b/src/cultures/kendo.culture.es-US.js new file mode 100644 index 00000000000..0af26bfca2f --- /dev/null +++ b/src/cultures/kendo.culture.es-US.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["es-US"] = { + name: "es-US", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + symbol: "%" + }, + currency: { + pattern: ["($n)","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "$" + } + }, + calendars: { + standard: { + days: { + names: ["domingo","lunes","martes","miércoles","jueves","viernes","sábado"], + namesAbbr: ["dom","lun","mar","mié","jue","vie","sáb"], + namesShort: ["do","lu","ma","mi","ju","vi","sa"] + }, + months: { + names: ["enero","febrero","marzo","abril","mayo","junio","julio","agosto","septiembre","octubre","noviembre","diciembre",""], + namesAbbr: ["ene","feb","mar","abr","may","jun","jul","ago","sep","oct","nov","dic",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "M/d/yyyy", + D: "dddd, MMMM dd, yyyy", + F: "dddd, MMMM dd, yyyy h:mm:ss tt", + g: "M/d/yyyy h:mm tt", + G: "M/d/yyyy h:mm:ss tt", + m: "dd' de 'MMMM", + M: "dd' de 'MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM' de 'yyyy", + Y: "MMMM' de 'yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.es-UY.js b/src/cultures/kendo.culture.es-UY.js new file mode 100644 index 00000000000..ba15fadda10 --- /dev/null +++ b/src/cultures/kendo.culture.es-UY.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["es-UY"] = { + name: "es-UY", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["($ n)","$ n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "$U" + } + }, + calendars: { + standard: { + days: { + names: ["domingo","lunes","martes","miércoles","jueves","viernes","sábado"], + namesAbbr: ["dom","lun","mar","mié","jue","vie","sáb"], + namesShort: ["do","lu","ma","mi","ju","vi","sá"] + }, + months: { + names: ["enero","febrero","marzo","abril","mayo","junio","julio","agosto","septiembre","octubre","noviembre","diciembre",""], + namesAbbr: ["ene","feb","mar","abr","may","jun","jul","ago","sep","oct","nov","dic",""] + }, + AM: ["a.m.","a.m.","A.M."], + PM: ["p.m.","p.m.","P.M."], + patterns: { + d: "dd/MM/yyyy", + D: "dddd, dd' de 'MMMM' de 'yyyy", + F: "dddd, dd' de 'MMMM' de 'yyyy hh:mm:ss tt", + g: "dd/MM/yyyy hh:mm tt", + G: "dd/MM/yyyy hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM' de 'yyyy", + Y: "MMMM' de 'yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.es-VE.js b/src/cultures/kendo.culture.es-VE.js new file mode 100644 index 00000000000..bb19dc08c61 --- /dev/null +++ b/src/cultures/kendo.culture.es-VE.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["es-VE"] = { + name: "es-VE", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "Bs. F." + } + }, + calendars: { + standard: { + days: { + names: ["domingo","lunes","martes","miércoles","jueves","viernes","sábado"], + namesAbbr: ["dom","lun","mar","mié","jue","vie","sáb"], + namesShort: ["do","lu","ma","mi","ju","vi","sá"] + }, + months: { + names: ["enero","febrero","marzo","abril","mayo","junio","julio","agosto","septiembre","octubre","noviembre","diciembre",""], + namesAbbr: ["ene","feb","mar","abr","may","jun","jul","ago","sep","oct","nov","dic",""] + }, + AM: ["a.m.","a.m.","A.M."], + PM: ["p.m.","p.m.","P.M."], + patterns: { + d: "dd/MM/yyyy", + D: "dddd, dd' de 'MMMM' de 'yyyy", + F: "dddd, dd' de 'MMMM' de 'yyyy hh:mm:ss tt", + g: "dd/MM/yyyy hh:mm tt", + G: "dd/MM/yyyy hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM' de 'yyyy", + Y: "MMMM' de 'yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.es.js b/src/cultures/kendo.culture.es.js new file mode 100644 index 00000000000..0387c62f263 --- /dev/null +++ b/src/cultures/kendo.culture.es.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["es"] = { + name: "es", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["domingo","lunes","martes","miércoles","jueves","viernes","sábado"], + namesAbbr: ["dom","lun","mar","mié","jue","vie","sáb"], + namesShort: ["do","lu","ma","mi","ju","vi","sá"] + }, + months: { + names: ["enero","febrero","marzo","abril","mayo","junio","julio","agosto","septiembre","octubre","noviembre","diciembre",""], + namesAbbr: ["ene","feb","mar","abr","may","jun","jul","ago","sep","oct","nov","dic",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd/MM/yyyy", + D: "dddd, dd' de 'MMMM' de 'yyyy", + F: "dddd, dd' de 'MMMM' de 'yyyy H:mm:ss", + g: "dd/MM/yyyy H:mm", + G: "dd/MM/yyyy H:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM' de 'yyyy", + Y: "MMMM' de 'yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.et-EE.js b/src/cultures/kendo.culture.et-EE.js new file mode 100644 index 00000000000..69d3aa68b5a --- /dev/null +++ b/src/cultures/kendo.culture.et-EE.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["et-EE"] = { + name: "et-EE", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ".", + groupSize: [3], + symbol: "kr" + } + }, + calendars: { + standard: { + days: { + names: ["pühapäev","esmaspäev","teisipäev","kolmapäev","neljapäev","reede","laupäev"], + namesAbbr: ["P","E","T","K","N","R","L"], + namesShort: ["P","E","T","K","N","R","L"] + }, + months: { + names: ["jaanuar","veebruar","märts","aprill","mai","juuni","juuli","august","september","oktoober","november","detsember",""], + namesAbbr: ["jaan","veebr","märts","apr","mai","juuni","juuli","aug","sept","okt","nov","dets",""] + }, + AM: ["EL","el","EL"], + PM: ["PL","pl","PL"], + patterns: { + d: "d.MM.yyyy", + D: "d. MMMM yyyy'. a.'", + F: "d. MMMM yyyy'. a.' H:mm:ss", + g: "d.MM.yyyy H:mm", + G: "d.MM.yyyy H:mm:ss", + m: "d. MMMM", + M: "d. MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy'. a.'", + Y: "MMMM yyyy'. a.'" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.et.js b/src/cultures/kendo.culture.et.js new file mode 100644 index 00000000000..4e6af5c6d10 --- /dev/null +++ b/src/cultures/kendo.culture.et.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["et"] = { + name: "et", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ".", + groupSize: [3], + symbol: "kr" + } + }, + calendars: { + standard: { + days: { + names: ["pühapäev","esmaspäev","teisipäev","kolmapäev","neljapäev","reede","laupäev"], + namesAbbr: ["P","E","T","K","N","R","L"], + namesShort: ["P","E","T","K","N","R","L"] + }, + months: { + names: ["jaanuar","veebruar","märts","aprill","mai","juuni","juuli","august","september","oktoober","november","detsember",""], + namesAbbr: ["jaan","veebr","märts","apr","mai","juuni","juuli","aug","sept","okt","nov","dets",""] + }, + AM: ["EL","el","EL"], + PM: ["PL","pl","PL"], + patterns: { + d: "d.MM.yyyy", + D: "d. MMMM yyyy'. a.'", + F: "d. MMMM yyyy'. a.' H:mm:ss", + g: "d.MM.yyyy H:mm", + G: "d.MM.yyyy H:mm:ss", + m: "d. MMMM", + M: "d. MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy'. a.'", + Y: "MMMM yyyy'. a.'" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.eu-ES.js b/src/cultures/kendo.culture.eu-ES.js new file mode 100644 index 00000000000..02388b4beea --- /dev/null +++ b/src/cultures/kendo.culture.eu-ES.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["eu-ES"] = { + name: "eu-ES", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["igandea","astelehena","asteartea","asteazkena","osteguna","ostirala","larunbata"], + namesAbbr: ["ig.","al.","as.","az.","og.","or.","lr."], + namesShort: ["ig","al","as","az","og","or","lr"] + }, + months: { + names: ["urtarrila","otsaila","martxoa","apirila","maiatza","ekaina","uztaila","abuztua","iraila","urria","azaroa","abendua",""], + namesAbbr: ["urt.","ots.","mar.","api.","mai.","eka.","uzt.","abu.","ira.","urr.","aza.","abe.",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "yyyy/MM/dd", + D: "dddd, yyyy.'eko' MMMM'k 'd", + F: "dddd, yyyy.'eko' MMMM'k 'd H:mm:ss", + g: "yyyy/MM/dd HH:mm", + G: "yyyy/MM/dd H:mm:ss", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "yyyy.'eko' MMMM", + Y: "yyyy.'eko' MMMM" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.eu.js b/src/cultures/kendo.culture.eu.js new file mode 100644 index 00000000000..bd2476a6193 --- /dev/null +++ b/src/cultures/kendo.culture.eu.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["eu"] = { + name: "eu", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["igandea","astelehena","asteartea","asteazkena","osteguna","ostirala","larunbata"], + namesAbbr: ["ig.","al.","as.","az.","og.","or.","lr."], + namesShort: ["ig","al","as","az","og","or","lr"] + }, + months: { + names: ["urtarrila","otsaila","martxoa","apirila","maiatza","ekaina","uztaila","abuztua","iraila","urria","azaroa","abendua",""], + namesAbbr: ["urt.","ots.","mar.","api.","mai.","eka.","uzt.","abu.","ira.","urr.","aza.","abe.",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "yyyy/MM/dd", + D: "dddd, yyyy.'eko' MMMM'k 'd", + F: "dddd, yyyy.'eko' MMMM'k 'd H:mm:ss", + g: "yyyy/MM/dd HH:mm", + G: "yyyy/MM/dd H:mm:ss", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "yyyy.'eko' MMMM", + Y: "yyyy.'eko' MMMM" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.fa-IR.js b/src/cultures/kendo.culture.fa-IR.js new file mode 100644 index 00000000000..2577199fa75 --- /dev/null +++ b/src/cultures/kendo.culture.fa-IR.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["fa-IR"] = { + name: "fa-IR", + numberFormat: { + pattern: ["n-"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$n-","$ n"], + decimals: 2, + ",": ",", + ".": "/", + groupSize: [3], + symbol: "ريال" + } + }, + calendars: { + standard: { + days: { + names: ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"], + namesAbbr: ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"], + namesShort: ["ح","ن","ث","ر","خ","ج","س"] + }, + months: { + names: ["جانفييه","فيفرييه","مارس","أفريل","مي","جوان","جوييه","أوت","سبتمبر","اكتوبر","نوفمبر","ديسمبر",""], + namesAbbr: ["جانفييه","فيفرييه","مارس","أفريل","مي","جوان","جوييه","أوت","سبتمبر","اكتوبر","نوفمبر","ديسمبر",""] + }, + AM: ["ق.ظ","ق.ظ","ق.ظ"], + PM: ["ب.ظ","ب.ظ","ب.ظ"], + patterns: { + d: "MM/dd/yyyy", + D: "dddd, MMMM dd, yyyy", + F: "dddd, MMMM dd, yyyy hh:mm:ss tt", + g: "MM/dd/yyyy hh:mm tt", + G: "MM/dd/yyyy hh:mm:ss tt", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 6 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.fa.js b/src/cultures/kendo.culture.fa.js new file mode 100644 index 00000000000..e3a88ddb70a --- /dev/null +++ b/src/cultures/kendo.culture.fa.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["fa"] = { + name: "fa", + numberFormat: { + pattern: ["n-"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$n-","$ n"], + decimals: 2, + ",": ",", + ".": "/", + groupSize: [3], + symbol: "ريال" + } + }, + calendars: { + standard: { + days: { + names: ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"], + namesAbbr: ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"], + namesShort: ["ح","ن","ث","ر","خ","ج","س"] + }, + months: { + names: ["جانفييه","فيفرييه","مارس","أفريل","مي","جوان","جوييه","أوت","سبتمبر","اكتوبر","نوفمبر","ديسمبر",""], + namesAbbr: ["جانفييه","فيفرييه","مارس","أفريل","مي","جوان","جوييه","أوت","سبتمبر","اكتوبر","نوفمبر","ديسمبر",""] + }, + AM: ["ق.ظ","ق.ظ","ق.ظ"], + PM: ["ب.ظ","ب.ظ","ب.ظ"], + patterns: { + d: "MM/dd/yyyy", + D: "dddd, MMMM dd, yyyy", + F: "dddd, MMMM dd, yyyy hh:mm:ss tt", + g: "MM/dd/yyyy hh:mm tt", + G: "MM/dd/yyyy hh:mm:ss tt", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 6 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.fi-FI.js b/src/cultures/kendo.culture.fi-FI.js new file mode 100644 index 00000000000..f33a7b74c5f --- /dev/null +++ b/src/cultures/kendo.culture.fi-FI.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["fi-FI"] = { + name: "fi-FI", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["sunnuntai","maanantai","tiistai","keskiviikko","torstai","perjantai","lauantai"], + namesAbbr: ["su","ma","ti","ke","to","pe","la"], + namesShort: ["su","ma","ti","ke","to","pe","la"] + }, + months: { + names: ["tammikuu","helmikuu","maaliskuu","huhtikuu","toukokuu","kesäkuu","heinäkuu","elokuu","syyskuu","lokakuu","marraskuu","joulukuu",""], + namesAbbr: ["tammi","helmi","maalis","huhti","touko","kesä","heinä","elo","syys","loka","marras","joulu",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "d.M.yyyy", + D: "d. MMMM'ta 'yyyy", + F: "d. MMMM'ta 'yyyy H:mm:ss", + g: "d.M.yyyy H:mm", + G: "d.M.yyyy H:mm:ss", + m: "d. MMMM'ta'", + M: "d. MMMM'ta'", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.fi.js b/src/cultures/kendo.culture.fi.js new file mode 100644 index 00000000000..e1316f5bd19 --- /dev/null +++ b/src/cultures/kendo.culture.fi.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["fi"] = { + name: "fi", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["sunnuntai","maanantai","tiistai","keskiviikko","torstai","perjantai","lauantai"], + namesAbbr: ["su","ma","ti","ke","to","pe","la"], + namesShort: ["su","ma","ti","ke","to","pe","la"] + }, + months: { + names: ["tammikuu","helmikuu","maaliskuu","huhtikuu","toukokuu","kesäkuu","heinäkuu","elokuu","syyskuu","lokakuu","marraskuu","joulukuu",""], + namesAbbr: ["tammi","helmi","maalis","huhti","touko","kesä","heinä","elo","syys","loka","marras","joulu",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "d.M.yyyy", + D: "d. MMMM'ta 'yyyy", + F: "d. MMMM'ta 'yyyy H:mm:ss", + g: "d.M.yyyy H:mm", + G: "d.M.yyyy H:mm:ss", + m: "d. MMMM'ta'", + M: "d. MMMM'ta'", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.fil-PH.js b/src/cultures/kendo.culture.fil-PH.js new file mode 100644 index 00000000000..039d1cc97b4 --- /dev/null +++ b/src/cultures/kendo.culture.fil-PH.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["fil-PH"] = { + name: "fil-PH", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["($n)","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "PhP" + } + }, + calendars: { + standard: { + days: { + names: ["Linggo","Lunes","Martes","Mierkoles","Huebes","Biernes","Sabado"], + namesAbbr: ["Lin","Lun","Mar","Mier","Hueb","Bier","Saba"], + namesShort: ["L","L","M","M","H","B","S"] + }, + months: { + names: ["Enero","Pebrero","Marso","Abril","Mayo","Hunyo","Hulyo","Agosto","Septyembre","Oktubre","Nobyembre","Disyembre",""], + namesAbbr: ["En","Peb","Mar","Abr","Mayo","Hun","Hul","Agos","Sept","Okt","Nob","Dis",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "M/d/yyyy", + D: "dddd, MMMM dd, yyyy", + F: "dddd, MMMM dd, yyyy h:mm:ss tt", + g: "M/d/yyyy h:mm tt", + G: "M/d/yyyy h:mm:ss tt", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.fil.js b/src/cultures/kendo.culture.fil.js new file mode 100644 index 00000000000..f19b03c35ff --- /dev/null +++ b/src/cultures/kendo.culture.fil.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["fil"] = { + name: "fil", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["($n)","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "PhP" + } + }, + calendars: { + standard: { + days: { + names: ["Linggo","Lunes","Martes","Mierkoles","Huebes","Biernes","Sabado"], + namesAbbr: ["Lin","Lun","Mar","Mier","Hueb","Bier","Saba"], + namesShort: ["L","L","M","M","H","B","S"] + }, + months: { + names: ["Enero","Pebrero","Marso","Abril","Mayo","Hunyo","Hulyo","Agosto","Septyembre","Oktubre","Nobyembre","Disyembre",""], + namesAbbr: ["En","Peb","Mar","Abr","Mayo","Hun","Hul","Agos","Sept","Okt","Nob","Dis",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "M/d/yyyy", + D: "dddd, MMMM dd, yyyy", + F: "dddd, MMMM dd, yyyy h:mm:ss tt", + g: "M/d/yyyy h:mm tt", + G: "M/d/yyyy h:mm:ss tt", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.fo-FO.js b/src/cultures/kendo.culture.fo-FO.js new file mode 100644 index 00000000000..666ddb7c33b --- /dev/null +++ b/src/cultures/kendo.culture.fo-FO.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["fo-FO"] = { + name: "fo-FO", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "kr." + } + }, + calendars: { + standard: { + days: { + names: ["sunnudagur","mánadagur","týsdagur","mikudagur","hósdagur","fríggjadagur","leygardagur"], + namesAbbr: ["sun","mán","týs","mik","hós","frí","leyg"], + namesShort: ["su","má","tý","mi","hó","fr","ley"] + }, + months: { + names: ["januar","februar","mars","apríl","mai","juni","juli","august","september","oktober","november","desember",""], + namesAbbr: ["jan","feb","mar","apr","mai","jun","jul","aug","sep","okt","nov","des",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd-MM-yyyy", + D: "d. MMMM yyyy", + F: "d. MMMM yyyy HH:mm:ss", + g: "dd-MM-yyyy HH:mm", + G: "dd-MM-yyyy HH:mm:ss", + m: "d. MMMM", + M: "d. MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "-", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.fo.js b/src/cultures/kendo.culture.fo.js new file mode 100644 index 00000000000..b6279cf0322 --- /dev/null +++ b/src/cultures/kendo.culture.fo.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["fo"] = { + name: "fo", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "kr." + } + }, + calendars: { + standard: { + days: { + names: ["sunnudagur","mánadagur","týsdagur","mikudagur","hósdagur","fríggjadagur","leygardagur"], + namesAbbr: ["sun","mán","týs","mik","hós","frí","leyg"], + namesShort: ["su","má","tý","mi","hó","fr","ley"] + }, + months: { + names: ["januar","februar","mars","apríl","mai","juni","juli","august","september","oktober","november","desember",""], + namesAbbr: ["jan","feb","mar","apr","mai","jun","jul","aug","sep","okt","nov","des",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd-MM-yyyy", + D: "d. MMMM yyyy", + F: "d. MMMM yyyy HH:mm:ss", + g: "dd-MM-yyyy HH:mm", + G: "dd-MM-yyyy HH:mm:ss", + m: "d. MMMM", + M: "d. MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "-", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.fr-BE.js b/src/cultures/kendo.culture.fr-BE.js new file mode 100644 index 00000000000..8888f98b991 --- /dev/null +++ b/src/cultures/kendo.culture.fr-BE.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["fr-BE"] = { + name: "fr-BE", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"], + namesAbbr: ["dim.","lun.","mar.","mer.","jeu.","ven.","sam."], + namesShort: ["di","lu","ma","me","je","ve","sa"] + }, + months: { + names: ["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre",""], + namesAbbr: ["janv.","févr.","mars","avr.","mai","juin","juil.","août","sept.","oct.","nov.","déc.",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "d/MM/yyyy", + D: "dddd d MMMM yyyy", + F: "dddd d MMMM yyyy HH:mm:ss", + g: "d/MM/yyyy HH:mm", + G: "d/MM/yyyy HH:mm:ss", + m: "d MMMM", + M: "d MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.fr-CA.js b/src/cultures/kendo.culture.fr-CA.js new file mode 100644 index 00000000000..1c0c9b62d47 --- /dev/null +++ b/src/cultures/kendo.culture.fr-CA.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["fr-CA"] = { + name: "fr-CA", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["(n $)","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "$" + } + }, + calendars: { + standard: { + days: { + names: ["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"], + namesAbbr: ["dim.","lun.","mar.","mer.","jeu.","ven.","sam."], + namesShort: ["di","lu","ma","me","je","ve","sa"] + }, + months: { + names: ["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre",""], + namesAbbr: ["janv.","févr.","mars","avr.","mai","juin","juil.","août","sept.","oct.","nov.","déc.",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "yyyy-MM-dd", + D: "d MMMM yyyy", + F: "d MMMM yyyy HH:mm:ss", + g: "yyyy-MM-dd HH:mm", + G: "yyyy-MM-dd HH:mm:ss", + m: "d MMMM", + M: "d MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "-", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.fr-CH.js b/src/cultures/kendo.culture.fr-CH.js new file mode 100644 index 00000000000..d71ce40a47b --- /dev/null +++ b/src/cultures/kendo.culture.fr-CH.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["fr-CH"] = { + name: "fr-CH", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": "'", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": "'", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$-n","$ n"], + decimals: 2, + ",": "'", + ".": ".", + groupSize: [3], + symbol: "fr." + } + }, + calendars: { + standard: { + days: { + names: ["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"], + namesAbbr: ["dim.","lun.","mar.","mer.","jeu.","ven.","sam."], + namesShort: ["di","lu","ma","me","je","ve","sa"] + }, + months: { + names: ["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre",""], + namesAbbr: ["janv.","févr.","mars","avr.","mai","juin","juil.","août","sept.","oct.","nov.","déc.",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yyyy", + D: "dddd d MMMM yyyy", + F: "dddd d MMMM yyyy HH:mm:ss", + g: "dd.MM.yyyy HH:mm", + G: "dd.MM.yyyy HH:mm:ss", + m: "d MMMM", + M: "d MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.fr-FR.js b/src/cultures/kendo.culture.fr-FR.js new file mode 100644 index 00000000000..43478c637b4 --- /dev/null +++ b/src/cultures/kendo.culture.fr-FR.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["fr-FR"] = { + name: "fr-FR", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"], + namesAbbr: ["dim.","lun.","mar.","mer.","jeu.","ven.","sam."], + namesShort: ["di","lu","ma","me","je","ve","sa"] + }, + months: { + names: ["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre",""], + namesAbbr: ["janv.","févr.","mars","avr.","mai","juin","juil.","août","sept.","oct.","nov.","déc.",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd/MM/yyyy", + D: "dddd d MMMM yyyy", + F: "dddd d MMMM yyyy HH:mm:ss", + g: "dd/MM/yyyy HH:mm", + G: "dd/MM/yyyy HH:mm:ss", + m: "d MMMM", + M: "d MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.fr-LU.js b/src/cultures/kendo.culture.fr-LU.js new file mode 100644 index 00000000000..3af3011d53c --- /dev/null +++ b/src/cultures/kendo.culture.fr-LU.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["fr-LU"] = { + name: "fr-LU", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"], + namesAbbr: ["dim.","lun.","mar.","mer.","jeu.","ven.","sam."], + namesShort: ["di","lu","ma","me","je","ve","sa"] + }, + months: { + names: ["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre",""], + namesAbbr: ["janv.","févr.","mars","avr.","mai","juin","juil.","août","sept.","oct.","nov.","déc.",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd/MM/yyyy", + D: "dddd d MMMM yyyy", + F: "dddd d MMMM yyyy HH:mm:ss", + g: "dd/MM/yyyy HH:mm", + G: "dd/MM/yyyy HH:mm:ss", + m: "d MMMM", + M: "d MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.fr-MC.js b/src/cultures/kendo.culture.fr-MC.js new file mode 100644 index 00000000000..dfbcb517663 --- /dev/null +++ b/src/cultures/kendo.culture.fr-MC.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["fr-MC"] = { + name: "fr-MC", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"], + namesAbbr: ["dim.","lun.","mar.","mer.","jeu.","ven.","sam."], + namesShort: ["di","lu","ma","me","je","ve","sa"] + }, + months: { + names: ["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre",""], + namesAbbr: ["janv.","févr.","mars","avr.","mai","juin","juil.","août","sept.","oct.","nov.","déc.",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd/MM/yyyy", + D: "dddd d MMMM yyyy", + F: "dddd d MMMM yyyy HH:mm:ss", + g: "dd/MM/yyyy HH:mm", + G: "dd/MM/yyyy HH:mm:ss", + m: "d MMMM", + M: "d MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.fr.js b/src/cultures/kendo.culture.fr.js new file mode 100644 index 00000000000..5ec6848298e --- /dev/null +++ b/src/cultures/kendo.culture.fr.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["fr"] = { + name: "fr", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"], + namesAbbr: ["dim.","lun.","mar.","mer.","jeu.","ven.","sam."], + namesShort: ["di","lu","ma","me","je","ve","sa"] + }, + months: { + names: ["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre",""], + namesAbbr: ["janv.","févr.","mars","avr.","mai","juin","juil.","août","sept.","oct.","nov.","déc.",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd/MM/yyyy", + D: "dddd d MMMM yyyy", + F: "dddd d MMMM yyyy HH:mm:ss", + g: "dd/MM/yyyy HH:mm", + G: "dd/MM/yyyy HH:mm:ss", + m: "d MMMM", + M: "d MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.fy-NL.js b/src/cultures/kendo.culture.fy-NL.js new file mode 100644 index 00000000000..db2c4c60d2d --- /dev/null +++ b/src/cultures/kendo.culture.fy-NL.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["fy-NL"] = { + name: "fy-NL", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["Snein","Moandei","Tiisdei","Woansdei","Tongersdei","Freed","Sneon"], + namesAbbr: ["Sn","Mo","Ti","Wo","To","Fr","Sn"], + namesShort: ["S","M","T","W","T","F","S"] + }, + months: { + names: ["jannewaris","febrewaris","maart","april","maaie","juny","july","augustus","septimber","oktober","novimber","desimber",""], + namesAbbr: ["jann","febr","mrt","apr","maaie","jun","jul","aug","sept","okt","nov","des",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "d-M-yyyy", + D: "dddd d MMMM yyyy", + F: "dddd d MMMM yyyy H:mm:ss", + g: "d-M-yyyy H:mm", + G: "d-M-yyyy H:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "-", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.fy.js b/src/cultures/kendo.culture.fy.js new file mode 100644 index 00000000000..528f8fe7001 --- /dev/null +++ b/src/cultures/kendo.culture.fy.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["fy"] = { + name: "fy", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["Snein","Moandei","Tiisdei","Woansdei","Tongersdei","Freed","Sneon"], + namesAbbr: ["Sn","Mo","Ti","Wo","To","Fr","Sn"], + namesShort: ["S","M","T","W","T","F","S"] + }, + months: { + names: ["jannewaris","febrewaris","maart","april","maaie","juny","july","augustus","septimber","oktober","novimber","desimber",""], + namesAbbr: ["jann","febr","mrt","apr","maaie","jun","jul","aug","sept","okt","nov","des",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "d-M-yyyy", + D: "dddd d MMMM yyyy", + F: "dddd d MMMM yyyy H:mm:ss", + g: "d-M-yyyy H:mm", + G: "d-M-yyyy H:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "-", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ga-IE.js b/src/cultures/kendo.culture.ga-IE.js new file mode 100644 index 00000000000..9bcae4134b6 --- /dev/null +++ b/src/cultures/kendo.culture.ga-IE.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ga-IE"] = { + name: "ga-IE", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-$n","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["Dé Domhnaigh","Dé Luain","Dé Máirt","Dé Céadaoin","Déardaoin","Dé hAoine","Dé Sathairn"], + namesAbbr: ["Domh","Luan","Máir","Céad","Déar","Aoi","Sath"], + namesShort: ["Do","Lu","Má","Cé","De","Ao","Sa"] + }, + months: { + names: ["Eanáir","Feabhra","Márta","Aibreán","Bealtaine","Meitheamh","Iúil","Lúnasa","Meán Fómhair","Deireadh Fómhair","Samhain","Nollaig",""], + namesAbbr: ["Ean","Feabh","Már","Aib","Bealt","Meith","Iúil","Lún","M.Fómh","D.Fómh","Samh","Noll",""] + }, + AM: ["r.n.","r.n.","R.N."], + PM: ["i.n.","i.n.","I.N."], + patterns: { + d: "dd/MM/yyyy", + D: "d MMMM yyyy", + F: "d MMMM yyyy HH:mm:ss", + g: "dd/MM/yyyy HH:mm", + G: "dd/MM/yyyy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ga.js b/src/cultures/kendo.culture.ga.js new file mode 100644 index 00000000000..852937c9a18 --- /dev/null +++ b/src/cultures/kendo.culture.ga.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ga"] = { + name: "ga", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-$n","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["Dé Domhnaigh","Dé Luain","Dé Máirt","Dé Céadaoin","Déardaoin","Dé hAoine","Dé Sathairn"], + namesAbbr: ["Domh","Luan","Máir","Céad","Déar","Aoi","Sath"], + namesShort: ["Do","Lu","Má","Cé","De","Ao","Sa"] + }, + months: { + names: ["Eanáir","Feabhra","Márta","Aibreán","Bealtaine","Meitheamh","Iúil","Lúnasa","Meán Fómhair","Deireadh Fómhair","Samhain","Nollaig",""], + namesAbbr: ["Ean","Feabh","Már","Aib","Bealt","Meith","Iúil","Lún","M.Fómh","D.Fómh","Samh","Noll",""] + }, + AM: ["r.n.","r.n.","R.N."], + PM: ["i.n.","i.n.","I.N."], + patterns: { + d: "dd/MM/yyyy", + D: "d MMMM yyyy", + F: "d MMMM yyyy HH:mm:ss", + g: "dd/MM/yyyy HH:mm", + G: "dd/MM/yyyy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.gd-GB.js b/src/cultures/kendo.culture.gd-GB.js new file mode 100644 index 00000000000..b868f25b34d --- /dev/null +++ b/src/cultures/kendo.culture.gd-GB.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["gd-GB"] = { + name: "gd-GB", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-$n","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "£" + } + }, + calendars: { + standard: { + days: { + names: ["Didòmhnaich","Diluain","Dimàirt","Diciadain","Diardaoin","Dihaoine","Disathairne"], + namesAbbr: ["Dòm","Lua","Mài","Cia","Ard","Hao","Sat"], + namesShort: ["D","L","M","C","A","H","S"] + }, + months: { + names: ["Am Faoilleach","An Gearran","Am Màrt","An Giblean","An Cèitean","An t-Ògmhios","An t-Iuchar","An Lùnastal","An t-Sultain","An Dàmhair","An t-Samhain","An Dùbhlachd",""], + namesAbbr: ["Fao","Gea","Màr","Gib","Cèi","Ògm","Iuc","Lùn","Sul","Dàm","Sam","Dùb",""] + }, + AM: ["m","m","M"], + PM: ["f","f","F"], + patterns: { + d: "dd/MM/yyyy", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy HH:mm:ss", + g: "dd/MM/yyyy HH:mm", + G: "dd/MM/yyyy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.gd.js b/src/cultures/kendo.culture.gd.js new file mode 100644 index 00000000000..3072a346ee6 --- /dev/null +++ b/src/cultures/kendo.culture.gd.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["gd"] = { + name: "gd", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-$n","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "£" + } + }, + calendars: { + standard: { + days: { + names: ["Didòmhnaich","Diluain","Dimàirt","Diciadain","Diardaoin","Dihaoine","Disathairne"], + namesAbbr: ["Dòm","Lua","Mài","Cia","Ard","Hao","Sat"], + namesShort: ["D","L","M","C","A","H","S"] + }, + months: { + names: ["Am Faoilleach","An Gearran","Am Màrt","An Giblean","An Cèitean","An t-Ògmhios","An t-Iuchar","An Lùnastal","An t-Sultain","An Dàmhair","An t-Samhain","An Dùbhlachd",""], + namesAbbr: ["Fao","Gea","Màr","Gib","Cèi","Ògm","Iuc","Lùn","Sul","Dàm","Sam","Dùb",""] + }, + AM: ["m","m","M"], + PM: ["f","f","F"], + patterns: { + d: "dd/MM/yyyy", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy HH:mm:ss", + g: "dd/MM/yyyy HH:mm", + G: "dd/MM/yyyy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.gl-ES.js b/src/cultures/kendo.culture.gl-ES.js new file mode 100644 index 00000000000..9f88fb05cf1 --- /dev/null +++ b/src/cultures/kendo.culture.gl-ES.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["gl-ES"] = { + name: "gl-ES", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["domingo","luns","martes","mércores","xoves","venres","sábado"], + namesAbbr: ["dom","luns","mar","mér","xov","ven","sáb"], + namesShort: ["do","lu","ma","mé","xo","ve","sá"] + }, + months: { + names: ["xaneiro","febreiro","marzo","abril","maio","xuño","xullo","agosto","setembro","outubro","novembro","decembro",""], + namesAbbr: ["xan","feb","mar","abr","maio","xuñ","xull","ago","set","out","nov","dec",""] + }, + AM: ["a.m.","a.m.","A.M."], + PM: ["p.m.","p.m.","P.M."], + patterns: { + d: "dd/MM/yyyy", + D: "dddd, dd' de 'MMMM' de 'yyyy", + F: "dddd, dd' de 'MMMM' de 'yyyy H:mm:ss", + g: "dd/MM/yyyy H:mm", + G: "dd/MM/yyyy H:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM' de 'yyyy", + Y: "MMMM' de 'yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.gl.js b/src/cultures/kendo.culture.gl.js new file mode 100644 index 00000000000..e9c4a8eb9bb --- /dev/null +++ b/src/cultures/kendo.culture.gl.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["gl"] = { + name: "gl", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["domingo","luns","martes","mércores","xoves","venres","sábado"], + namesAbbr: ["dom","luns","mar","mér","xov","ven","sáb"], + namesShort: ["do","lu","ma","mé","xo","ve","sá"] + }, + months: { + names: ["xaneiro","febreiro","marzo","abril","maio","xuño","xullo","agosto","setembro","outubro","novembro","decembro",""], + namesAbbr: ["xan","feb","mar","abr","maio","xuñ","xull","ago","set","out","nov","dec",""] + }, + AM: ["a.m.","a.m.","A.M."], + PM: ["p.m.","p.m.","P.M."], + patterns: { + d: "dd/MM/yyyy", + D: "dddd, dd' de 'MMMM' de 'yyyy", + F: "dddd, dd' de 'MMMM' de 'yyyy H:mm:ss", + g: "dd/MM/yyyy H:mm", + G: "dd/MM/yyyy H:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM' de 'yyyy", + Y: "MMMM' de 'yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.gsw-FR.js b/src/cultures/kendo.culture.gsw-FR.js new file mode 100644 index 00000000000..0b2b13856c4 --- /dev/null +++ b/src/cultures/kendo.culture.gsw-FR.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["gsw-FR"] = { + name: "gsw-FR", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["Sundàà","Mondàà","Dienschdàà","Mittwuch","Dunnerschdàà","Fridàà","Sàmschdàà"], + namesAbbr: ["Su.","Mo.","Di.","Mi.","Du.","Fr.","Sà."], + namesShort: ["Su","Mo","Di","Mi","Du","Fr","Sà"] + }, + months: { + names: ["Jänner","Feverje","März","Àpril","Mai","Jüni","Jüli","Augscht","September","Oktower","Nowember","Dezember",""], + namesAbbr: ["Jän.","Fev.","März","Apr.","Mai","Jüni","Jüli","Aug.","Sept.","Okt.","Now.","Dez.",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd/MM/yyyy", + D: "dddd d MMMM yyyy", + F: "dddd d MMMM yyyy HH:mm:ss", + g: "dd/MM/yyyy HH:mm", + G: "dd/MM/yyyy HH:mm:ss", + m: "d MMMM", + M: "d MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.gsw.js b/src/cultures/kendo.culture.gsw.js new file mode 100644 index 00000000000..727651f3c43 --- /dev/null +++ b/src/cultures/kendo.culture.gsw.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["gsw"] = { + name: "gsw", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["Sundàà","Mondàà","Dienschdàà","Mittwuch","Dunnerschdàà","Fridàà","Sàmschdàà"], + namesAbbr: ["Su.","Mo.","Di.","Mi.","Du.","Fr.","Sà."], + namesShort: ["Su","Mo","Di","Mi","Du","Fr","Sà"] + }, + months: { + names: ["Jänner","Feverje","März","Àpril","Mai","Jüni","Jüli","Augscht","September","Oktower","Nowember","Dezember",""], + namesAbbr: ["Jän.","Fev.","März","Apr.","Mai","Jüni","Jüli","Aug.","Sept.","Okt.","Now.","Dez.",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd/MM/yyyy", + D: "dddd d MMMM yyyy", + F: "dddd d MMMM yyyy HH:mm:ss", + g: "dd/MM/yyyy HH:mm", + G: "dd/MM/yyyy HH:mm:ss", + m: "d MMMM", + M: "d MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.gu-IN.js b/src/cultures/kendo.culture.gu-IN.js new file mode 100644 index 00000000000..97eb144a93b --- /dev/null +++ b/src/cultures/kendo.culture.gu-IN.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["gu-IN"] = { + name: "gu-IN", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "રૂ" + } + }, + calendars: { + standard: { + days: { + names: ["રવિવાર","સોમવાર","મંગળવાર","બુધવાર","ગુરુવાર","શુક્રવાર","શનિવાર"], + namesAbbr: ["રવિ","સોમ","મંગળ","બુધ","ગુરુ","શુક્ર","શનિ"], + namesShort: ["ર","સ","મ","બ","ગ","શ","શ"] + }, + months: { + names: ["જાન્યુઆરી","ફેબ્રુઆરી","માર્ચ","એપ્રિલ","મે","જૂન","જુલાઈ","ઑગસ્ટ","સપ્ટેમ્બર","ઑક્ટ્બર","નવેમ્બર","ડિસેમ્બર",""], + namesAbbr: ["જાન્યુ","ફેબ્રુ","માર્ચ","એપ્રિલ","મે","જૂન","જુલાઈ","ઑગસ્ટ","સપ્ટે","ઑક્ટો","નવે","ડિસે",""] + }, + AM: ["પૂર્વ મધ્યાહ્ન","પૂર્વ મધ્યાહ્ન","પૂર્વ મધ્યાહ્ન"], + PM: ["ઉત્તર મધ્યાહ્ન","ઉત્તર મધ્યાહ્ન","ઉત્તર મધ્યાહ્ન"], + patterns: { + d: "dd-MM-yy", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy HH:mm:ss", + g: "dd-MM-yy HH:mm", + G: "dd-MM-yy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "-", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.gu.js b/src/cultures/kendo.culture.gu.js new file mode 100644 index 00000000000..0c56e7b49a7 --- /dev/null +++ b/src/cultures/kendo.culture.gu.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["gu"] = { + name: "gu", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "રૂ" + } + }, + calendars: { + standard: { + days: { + names: ["રવિવાર","સોમવાર","મંગળવાર","બુધવાર","ગુરુવાર","શુક્રવાર","શનિવાર"], + namesAbbr: ["રવિ","સોમ","મંગળ","બુધ","ગુરુ","શુક્ર","શનિ"], + namesShort: ["ર","સ","મ","બ","ગ","શ","શ"] + }, + months: { + names: ["જાન્યુઆરી","ફેબ્રુઆરી","માર્ચ","એપ્રિલ","મે","જૂન","જુલાઈ","ઑગસ્ટ","સપ્ટેમ્બર","ઑક્ટ્બર","નવેમ્બર","ડિસેમ્બર",""], + namesAbbr: ["જાન્યુ","ફેબ્રુ","માર્ચ","એપ્રિલ","મે","જૂન","જુલાઈ","ઑગસ્ટ","સપ્ટે","ઑક્ટો","નવે","ડિસે",""] + }, + AM: ["પૂર્વ મધ્યાહ્ન","પૂર્વ મધ્યાહ્ન","પૂર્વ મધ્યાહ્ન"], + PM: ["ઉત્તર મધ્યાહ્ન","ઉત્તર મધ્યાહ્ન","ઉત્તર મધ્યાહ્ન"], + patterns: { + d: "dd-MM-yy", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy HH:mm:ss", + g: "dd-MM-yy HH:mm", + G: "dd-MM-yy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "-", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ha-Latn-NG.js b/src/cultures/kendo.culture.ha-Latn-NG.js new file mode 100644 index 00000000000..70c689d9bb4 --- /dev/null +++ b/src/cultures/kendo.culture.ha-Latn-NG.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ha-Latn-NG"] = { + name: "ha-Latn-NG", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$-n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "N" + } + }, + calendars: { + standard: { + days: { + names: ["Lahadi","Litinin","Talata","Laraba","Alhamis","Juma\u0027a","Asabar"], + namesAbbr: ["Lah","Lit","Tal","Lar","Alh","Jum","Asa"], + namesShort: ["L","L","T","L","A","J","A"] + }, + months: { + names: ["Januwaru","Febreru","Maris","Afrilu","Mayu","Yuni","Yuli","Agusta","Satumba","Oktocba","Nuwamba","Disamba",""], + namesAbbr: ["Jan","Feb","Mar","Afr","May","Yun","Yul","Agu","Sat","Okt","Nuw","Dis",""] + }, + AM: ["Safe","safe","SAFE"], + PM: ["Yamma","yamma","YAMMA"], + patterns: { + d: "d/M/yyyy", + D: "dddd, MMMM dd, yyyy", + F: "dddd, MMMM dd, yyyy h:mm:ss tt", + g: "d/M/yyyy h:mm tt", + G: "d/M/yyyy h:mm:ss tt", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ha-Latn.js b/src/cultures/kendo.culture.ha-Latn.js new file mode 100644 index 00000000000..19bce84acde --- /dev/null +++ b/src/cultures/kendo.culture.ha-Latn.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ha-Latn"] = { + name: "ha-Latn", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$-n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "N" + } + }, + calendars: { + standard: { + days: { + names: ["Lahadi","Litinin","Talata","Laraba","Alhamis","Juma\u0027a","Asabar"], + namesAbbr: ["Lah","Lit","Tal","Lar","Alh","Jum","Asa"], + namesShort: ["L","L","T","L","A","J","A"] + }, + months: { + names: ["Januwaru","Febreru","Maris","Afrilu","Mayu","Yuni","Yuli","Agusta","Satumba","Oktocba","Nuwamba","Disamba",""], + namesAbbr: ["Jan","Feb","Mar","Afr","May","Yun","Yul","Agu","Sat","Okt","Nuw","Dis",""] + }, + AM: ["Safe","safe","SAFE"], + PM: ["Yamma","yamma","YAMMA"], + patterns: { + d: "d/M/yyyy", + D: "dddd, MMMM dd, yyyy", + F: "dddd, MMMM dd, yyyy h:mm:ss tt", + g: "d/M/yyyy h:mm tt", + G: "d/M/yyyy h:mm:ss tt", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ha.js b/src/cultures/kendo.culture.ha.js new file mode 100644 index 00000000000..82efcb37346 --- /dev/null +++ b/src/cultures/kendo.culture.ha.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ha"] = { + name: "ha", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$-n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "N" + } + }, + calendars: { + standard: { + days: { + names: ["Lahadi","Litinin","Talata","Laraba","Alhamis","Juma\u0027a","Asabar"], + namesAbbr: ["Lah","Lit","Tal","Lar","Alh","Jum","Asa"], + namesShort: ["L","L","T","L","A","J","A"] + }, + months: { + names: ["Januwaru","Febreru","Maris","Afrilu","Mayu","Yuni","Yuli","Agusta","Satumba","Oktocba","Nuwamba","Disamba",""], + namesAbbr: ["Jan","Feb","Mar","Afr","May","Yun","Yul","Agu","Sat","Okt","Nuw","Dis",""] + }, + AM: ["Safe","safe","SAFE"], + PM: ["Yamma","yamma","YAMMA"], + patterns: { + d: "d/M/yyyy", + D: "dddd, MMMM dd, yyyy", + F: "dddd, MMMM dd, yyyy h:mm:ss tt", + g: "d/M/yyyy h:mm tt", + G: "d/M/yyyy h:mm:ss tt", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.he-IL.js b/src/cultures/kendo.culture.he-IL.js new file mode 100644 index 00000000000..40dd9d81019 --- /dev/null +++ b/src/cultures/kendo.culture.he-IL.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["he-IL"] = { + name: "he-IL", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$-n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "₪" + } + }, + calendars: { + standard: { + days: { + names: ["יום ראשון","יום שני","יום שלישי","יום רביעי","יום חמישי","יום שישי","שבת"], + namesAbbr: ["יום א","יום ב","יום ג","יום ד","יום ה","יום ו","שבת"], + namesShort: ["א","ב","ג","ד","ה","ו","ש"] + }, + months: { + names: ["ינואר","פברואר","מרץ","אפריל","מאי","יוני","יולי","אוגוסט","ספטמבר","אוקטובר","נובמבר","דצמבר",""], + namesAbbr: ["ינו","פבר","מרץ","אפר","מאי","יונ","יול","אוג","ספט","אוק","נוב","דצמ",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "dd/MM/yyyy", + D: "dddd dd MMMM yyyy", + F: "dddd dd MMMM yyyy HH:mm:ss", + g: "dd/MM/yyyy HH:mm", + G: "dd/MM/yyyy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.he.js b/src/cultures/kendo.culture.he.js new file mode 100644 index 00000000000..8070663682d --- /dev/null +++ b/src/cultures/kendo.culture.he.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["he"] = { + name: "he", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$-n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "₪" + } + }, + calendars: { + standard: { + days: { + names: ["יום ראשון","יום שני","יום שלישי","יום רביעי","יום חמישי","יום שישי","שבת"], + namesAbbr: ["יום א","יום ב","יום ג","יום ד","יום ה","יום ו","שבת"], + namesShort: ["א","ב","ג","ד","ה","ו","ש"] + }, + months: { + names: ["ינואר","פברואר","מרץ","אפריל","מאי","יוני","יולי","אוגוסט","ספטמבר","אוקטובר","נובמבר","דצמבר",""], + namesAbbr: ["ינו","פבר","מרץ","אפר","מאי","יונ","יול","אוג","ספט","אוק","נוב","דצמ",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "dd/MM/yyyy", + D: "dddd dd MMMM yyyy", + F: "dddd dd MMMM yyyy HH:mm:ss", + g: "dd/MM/yyyy HH:mm", + G: "dd/MM/yyyy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.hi-IN.js b/src/cultures/kendo.culture.hi-IN.js new file mode 100644 index 00000000000..77a1fe5e524 --- /dev/null +++ b/src/cultures/kendo.culture.hi-IN.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["hi-IN"] = { + name: "hi-IN", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "रु" + } + }, + calendars: { + standard: { + days: { + names: ["रविवार","सोमवार","मंगलवार","बुधवार","गुरुवार","शुक्रवार","शनिवार"], + namesAbbr: ["रवि.","सोम.","मंगल.","बुध.","गुरु.","शुक्र.","शनि."], + namesShort: ["र","स","म","ब","ग","श","श"] + }, + months: { + names: ["जनवरी","फरवरी","मार्च","अप्रैल","मई","जून","जुलाई","अगस्त","सितम्बर","अक्तूबर","नवम्बर","दिसम्बर",""], + namesAbbr: ["जनवरी","फरवरी","मार्च","अप्रैल","मई","जून","जुलाई","अगस्त","सितम्बर","अक्तूबर","नवम्बर","दिसम्बर",""] + }, + AM: ["पूर्वाह्न","पूर्वाह्न","पूर्वाह्न"], + PM: ["अपराह्न","अपराह्न","अपराह्न"], + patterns: { + d: "dd-MM-yyyy", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy HH:mm:ss", + g: "dd-MM-yyyy HH:mm", + G: "dd-MM-yyyy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "-", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.hi.js b/src/cultures/kendo.culture.hi.js new file mode 100644 index 00000000000..5811ca8197a --- /dev/null +++ b/src/cultures/kendo.culture.hi.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["hi"] = { + name: "hi", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "रु" + } + }, + calendars: { + standard: { + days: { + names: ["रविवार","सोमवार","मंगलवार","बुधवार","गुरुवार","शुक्रवार","शनिवार"], + namesAbbr: ["रवि.","सोम.","मंगल.","बुध.","गुरु.","शुक्र.","शनि."], + namesShort: ["र","स","म","ब","ग","श","श"] + }, + months: { + names: ["जनवरी","फरवरी","मार्च","अप्रैल","मई","जून","जुलाई","अगस्त","सितम्बर","अक्तूबर","नवम्बर","दिसम्बर",""], + namesAbbr: ["जनवरी","फरवरी","मार्च","अप्रैल","मई","जून","जुलाई","अगस्त","सितम्बर","अक्तूबर","नवम्बर","दिसम्बर",""] + }, + AM: ["पूर्वाह्न","पूर्वाह्न","पूर्वाह्न"], + PM: ["अपराह्न","अपराह्न","अपराह्न"], + patterns: { + d: "dd-MM-yyyy", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy HH:mm:ss", + g: "dd-MM-yyyy HH:mm", + G: "dd-MM-yyyy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "-", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.hr-BA.js b/src/cultures/kendo.culture.hr-BA.js new file mode 100644 index 00000000000..4b1f6163ff4 --- /dev/null +++ b/src/cultures/kendo.culture.hr-BA.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["hr-BA"] = { + name: "hr-BA", + numberFormat: { + pattern: ["- n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "KM" + } + }, + calendars: { + standard: { + days: { + names: ["nedjelja","ponedjeljak","utorak","srijeda","četvrtak","petak","subota"], + namesAbbr: ["ned","pon","uto","sri","čet","pet","sub"], + namesShort: ["ne","po","ut","sr","če","pe","su"] + }, + months: { + names: ["siječanj","veljača","ožujak","travanj","svibanj","lipanj","srpanj","kolovoz","rujan","listopad","studeni","prosinac",""], + namesAbbr: ["sij","vlj","ožu","tra","svi","lip","srp","kol","ruj","lis","stu","pro",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "d.M.yyyy.", + D: "d. MMMM yyyy.", + F: "d. MMMM yyyy. H:mm:ss", + g: "d.M.yyyy. H:mm", + G: "d.M.yyyy. H:mm:ss", + m: "d. MMMM", + M: "d. MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.hr-HR.js b/src/cultures/kendo.culture.hr-HR.js new file mode 100644 index 00000000000..513b3a4e55a --- /dev/null +++ b/src/cultures/kendo.culture.hr-HR.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["hr-HR"] = { + name: "hr-HR", + numberFormat: { + pattern: ["- n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "kn" + } + }, + calendars: { + standard: { + days: { + names: ["nedjelja","ponedjeljak","utorak","srijeda","četvrtak","petak","subota"], + namesAbbr: ["ned","pon","uto","sri","čet","pet","sub"], + namesShort: ["ne","po","ut","sr","če","pe","su"] + }, + months: { + names: ["siječanj","veljača","ožujak","travanj","svibanj","lipanj","srpanj","kolovoz","rujan","listopad","studeni","prosinac",""], + namesAbbr: ["sij","vlj","ožu","tra","svi","lip","srp","kol","ruj","lis","stu","pro",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "d.M.yyyy.", + D: "d. MMMM yyyy.", + F: "d. MMMM yyyy. H:mm:ss", + g: "d.M.yyyy. H:mm", + G: "d.M.yyyy. H:mm:ss", + m: "d. MMMM", + M: "d. MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.hr.js b/src/cultures/kendo.culture.hr.js new file mode 100644 index 00000000000..4f084935cae --- /dev/null +++ b/src/cultures/kendo.culture.hr.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["hr"] = { + name: "hr", + numberFormat: { + pattern: ["- n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "kn" + } + }, + calendars: { + standard: { + days: { + names: ["nedjelja","ponedjeljak","utorak","srijeda","četvrtak","petak","subota"], + namesAbbr: ["ned","pon","uto","sri","čet","pet","sub"], + namesShort: ["ne","po","ut","sr","če","pe","su"] + }, + months: { + names: ["siječanj","veljača","ožujak","travanj","svibanj","lipanj","srpanj","kolovoz","rujan","listopad","studeni","prosinac",""], + namesAbbr: ["sij","vlj","ožu","tra","svi","lip","srp","kol","ruj","lis","stu","pro",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "d.M.yyyy.", + D: "d. MMMM yyyy.", + F: "d. MMMM yyyy. H:mm:ss", + g: "d.M.yyyy. H:mm", + G: "d.M.yyyy. H:mm:ss", + m: "d. MMMM", + M: "d. MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.hsb-DE.js b/src/cultures/kendo.culture.hsb-DE.js new file mode 100644 index 00000000000..6cccdab703a --- /dev/null +++ b/src/cultures/kendo.culture.hsb-DE.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["hsb-DE"] = { + name: "hsb-DE", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["njedźela","póndźela","wutora","srjeda","štwórtk","pjatk","sobota"], + namesAbbr: ["nje","pón","wut","srj","štw","pja","sob"], + namesShort: ["n","p","w","s","š","p","s"] + }, + months: { + names: ["januar","februar","měrc","apryl","meja","junij","julij","awgust","september","oktober","nowember","december",""], + namesAbbr: ["jan","feb","měr","apr","mej","jun","jul","awg","sep","okt","now","dec",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "d. M. yyyy", + D: "dddd, 'dnja' d. MMMM yyyy", + F: "dddd, 'dnja' d. MMMM yyyy H:mm:ss", + g: "d. M. yyyy H.mm 'hodź.'", + G: "d. M. yyyy H:mm:ss", + m: "d. MMMM", + M: "d. MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H.mm 'hodź.'", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ". ", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.hsb.js b/src/cultures/kendo.culture.hsb.js new file mode 100644 index 00000000000..9d3587eec52 --- /dev/null +++ b/src/cultures/kendo.culture.hsb.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["hsb"] = { + name: "hsb", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["njedźela","póndźela","wutora","srjeda","štwórtk","pjatk","sobota"], + namesAbbr: ["nje","pón","wut","srj","štw","pja","sob"], + namesShort: ["n","p","w","s","š","p","s"] + }, + months: { + names: ["januar","februar","měrc","apryl","meja","junij","julij","awgust","september","oktober","nowember","december",""], + namesAbbr: ["jan","feb","měr","apr","mej","jun","jul","awg","sep","okt","now","dec",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "d. M. yyyy", + D: "dddd, 'dnja' d. MMMM yyyy", + F: "dddd, 'dnja' d. MMMM yyyy H:mm:ss", + g: "d. M. yyyy H.mm 'hodź.'", + G: "d. M. yyyy H:mm:ss", + m: "d. MMMM", + M: "d. MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H.mm 'hodź.'", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ". ", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.hu-HU.js b/src/cultures/kendo.culture.hu-HU.js new file mode 100644 index 00000000000..3ddc479d0ec --- /dev/null +++ b/src/cultures/kendo.culture.hu-HU.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["hu-HU"] = { + name: "hu-HU", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "Ft" + } + }, + calendars: { + standard: { + days: { + names: ["vasárnap","hétfő","kedd","szerda","csütörtök","péntek","szombat"], + namesAbbr: ["V","H","K","Sze","Cs","P","Szo"], + namesShort: ["V","H","K","Sze","Cs","P","Szo"] + }, + months: { + names: ["január","február","március","április","május","június","július","augusztus","szeptember","október","november","december",""], + namesAbbr: ["jan.","febr.","márc.","ápr.","máj.","jún.","júl.","aug.","szept.","okt.","nov.","dec.",""] + }, + AM: ["de.","de.","DE."], + PM: ["du.","du.","DU."], + patterns: { + d: "yyyy.MM.dd.", + D: "yyyy. MMMM d.", + F: "yyyy. MMMM d. H:mm:ss", + g: "yyyy.MM.dd. H:mm", + G: "yyyy.MM.dd. H:mm:ss", + m: "MMMM d.", + M: "MMMM d.", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "yyyy. MMMM", + Y: "yyyy. MMMM" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.hu.js b/src/cultures/kendo.culture.hu.js new file mode 100644 index 00000000000..422f274d014 --- /dev/null +++ b/src/cultures/kendo.culture.hu.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["hu"] = { + name: "hu", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "Ft" + } + }, + calendars: { + standard: { + days: { + names: ["vasárnap","hétfő","kedd","szerda","csütörtök","péntek","szombat"], + namesAbbr: ["V","H","K","Sze","Cs","P","Szo"], + namesShort: ["V","H","K","Sze","Cs","P","Szo"] + }, + months: { + names: ["január","február","március","április","május","június","július","augusztus","szeptember","október","november","december",""], + namesAbbr: ["jan.","febr.","márc.","ápr.","máj.","jún.","júl.","aug.","szept.","okt.","nov.","dec.",""] + }, + AM: ["de.","de.","DE."], + PM: ["du.","du.","DU."], + patterns: { + d: "yyyy.MM.dd.", + D: "yyyy. MMMM d.", + F: "yyyy. MMMM d. H:mm:ss", + g: "yyyy.MM.dd. H:mm", + G: "yyyy.MM.dd. H:mm:ss", + m: "MMMM d.", + M: "MMMM d.", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "yyyy. MMMM", + Y: "yyyy. MMMM" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.hy-AM.js b/src/cultures/kendo.culture.hy-AM.js new file mode 100644 index 00000000000..5b5f72a98fb --- /dev/null +++ b/src/cultures/kendo.culture.hy-AM.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["hy-AM"] = { + name: "hy-AM", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "դր." + } + }, + calendars: { + standard: { + days: { + names: ["Կիրակի","Երկուշաբթի","Երեքշաբթի","Չորեքշաբթի","Հինգշաբթի","ՈՒրբաթ","Շաբաթ"], + namesAbbr: ["Կիր","Երկ","Երք","Չրք","Հնգ","ՈՒր","Շբթ"], + namesShort: ["Կ","Ե","Ե","Չ","Հ","Ո","Շ"] + }, + months: { + names: ["Հունվար","Փետրվար","Մարտ","Ապրիլ","Մայիս","Հունիս","Հուլիս","Օգոստոս","Սեպտեմբեր","Հոկտեմբեր","Նոյեմբեր","Դեկտեմբեր",""], + namesAbbr: ["ՀՆՎ","ՓՏՎ","ՄՐՏ","ԱՊՐ","ՄՅՍ","ՀՆՍ","ՀԼՍ","ՕԳՍ","ՍԵՊ","ՀՈԿ","ՆՈՅ","ԴԵԿ",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yyyy", + D: "d MMMM, yyyy", + F: "d MMMM, yyyy H:mm:ss", + g: "dd.MM.yyyy H:mm", + G: "dd.MM.yyyy H:mm:ss", + m: "d MMMM", + M: "d MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.hy.js b/src/cultures/kendo.culture.hy.js new file mode 100644 index 00000000000..06982553199 --- /dev/null +++ b/src/cultures/kendo.culture.hy.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["hy"] = { + name: "hy", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "դր." + } + }, + calendars: { + standard: { + days: { + names: ["Կիրակի","Երկուշաբթի","Երեքշաբթի","Չորեքշաբթի","Հինգշաբթի","ՈՒրբաթ","Շաբաթ"], + namesAbbr: ["Կիր","Երկ","Երք","Չրք","Հնգ","ՈՒր","Շբթ"], + namesShort: ["Կ","Ե","Ե","Չ","Հ","Ո","Շ"] + }, + months: { + names: ["Հունվար","Փետրվար","Մարտ","Ապրիլ","Մայիս","Հունիս","Հուլիս","Օգոստոս","Սեպտեմբեր","Հոկտեմբեր","Նոյեմբեր","Դեկտեմբեր",""], + namesAbbr: ["ՀՆՎ","ՓՏՎ","ՄՐՏ","ԱՊՐ","ՄՅՍ","ՀՆՍ","ՀԼՍ","ՕԳՍ","ՍԵՊ","ՀՈԿ","ՆՈՅ","ԴԵԿ",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yyyy", + D: "d MMMM, yyyy", + F: "d MMMM, yyyy H:mm:ss", + g: "dd.MM.yyyy H:mm", + G: "dd.MM.yyyy H:mm:ss", + m: "d MMMM", + M: "d MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.id-ID.js b/src/cultures/kendo.culture.id-ID.js new file mode 100644 index 00000000000..5548ee5ae43 --- /dev/null +++ b/src/cultures/kendo.culture.id-ID.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["id-ID"] = { + name: "id-ID", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["($n)","$n"], + decimals: 0, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "Rp" + } + }, + calendars: { + standard: { + days: { + names: ["Minggu","Senin","Selasa","Rabu","Kamis","Jumat","Sabtu"], + namesAbbr: ["Minggu","Sen","Sel","Rabu","Kamis","Jumat","Sabtu"], + namesShort: ["M","S","S","R","K","J","S"] + }, + months: { + names: ["Januari","Februari","Maret","April","Mei","Juni","Juli","Agustus","September","Oktober","Nopember","Desember",""], + namesAbbr: ["Jan","Feb","Mar","Apr","Mei","Jun","Jul","Agust","Sep","Okt","Nop","Des",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd/MM/yyyy", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy H:mm:ss", + g: "dd/MM/yyyy H:mm", + G: "dd/MM/yyyy H:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.id.js b/src/cultures/kendo.culture.id.js new file mode 100644 index 00000000000..9155434c93c --- /dev/null +++ b/src/cultures/kendo.culture.id.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["id"] = { + name: "id", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["($n)","$n"], + decimals: 0, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "Rp" + } + }, + calendars: { + standard: { + days: { + names: ["Minggu","Senin","Selasa","Rabu","Kamis","Jumat","Sabtu"], + namesAbbr: ["Minggu","Sen","Sel","Rabu","Kamis","Jumat","Sabtu"], + namesShort: ["M","S","S","R","K","J","S"] + }, + months: { + names: ["Januari","Februari","Maret","April","Mei","Juni","Juli","Agustus","September","Oktober","Nopember","Desember",""], + namesAbbr: ["Jan","Feb","Mar","Apr","Mei","Jun","Jul","Agust","Sep","Okt","Nop","Des",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd/MM/yyyy", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy H:mm:ss", + g: "dd/MM/yyyy H:mm", + G: "dd/MM/yyyy H:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ig-NG.js b/src/cultures/kendo.culture.ig-NG.js new file mode 100644 index 00000000000..5af973bba0d --- /dev/null +++ b/src/cultures/kendo.culture.ig-NG.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ig-NG"] = { + name: "ig-NG", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$-n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "N" + } + }, + calendars: { + standard: { + days: { + names: ["Aiku","Aje","Isegun","Ojo\u0027ru","Ojo\u0027bo","Eti","Abameta"], + namesAbbr: ["Aik","Aje","Ise","Ojo","Ojo","Eti","Aba"], + namesShort: ["A","A","I","O","O","E","A"] + }, + months: { + names: ["Onwa mbu","Onwa ibua","Onwa ato","Onwa ano","Onwa ise","Onwa isi","Onwa asa","Onwa asato","Onwa itolu","Onwa iri","Onwa iri n\u0027ofu","Onwa iri n\u0027ibua",""], + namesAbbr: ["mbu.","ibu.","ato.","ano.","ise","isi","asa","asa.","ito.","iri.","n\u0027of.","n\u0027ib.",""] + }, + AM: ["Ututu","ututu","UTUTU"], + PM: ["Efifie","efifie","EFIFIE"], + patterns: { + d: "d/M/yyyy", + D: "dddd, MMMM dd, yyyy", + F: "dddd, MMMM dd, yyyy h:mm:ss tt", + g: "d/M/yyyy h:mm tt", + G: "d/M/yyyy h:mm:ss tt", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ig.js b/src/cultures/kendo.culture.ig.js new file mode 100644 index 00000000000..c0aa13e1707 --- /dev/null +++ b/src/cultures/kendo.culture.ig.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ig"] = { + name: "ig", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$-n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "N" + } + }, + calendars: { + standard: { + days: { + names: ["Aiku","Aje","Isegun","Ojo\u0027ru","Ojo\u0027bo","Eti","Abameta"], + namesAbbr: ["Aik","Aje","Ise","Ojo","Ojo","Eti","Aba"], + namesShort: ["A","A","I","O","O","E","A"] + }, + months: { + names: ["Onwa mbu","Onwa ibua","Onwa ato","Onwa ano","Onwa ise","Onwa isi","Onwa asa","Onwa asato","Onwa itolu","Onwa iri","Onwa iri n\u0027ofu","Onwa iri n\u0027ibua",""], + namesAbbr: ["mbu.","ibu.","ato.","ano.","ise","isi","asa","asa.","ito.","iri.","n\u0027of.","n\u0027ib.",""] + }, + AM: ["Ututu","ututu","UTUTU"], + PM: ["Efifie","efifie","EFIFIE"], + patterns: { + d: "d/M/yyyy", + D: "dddd, MMMM dd, yyyy", + F: "dddd, MMMM dd, yyyy h:mm:ss tt", + g: "d/M/yyyy h:mm tt", + G: "d/M/yyyy h:mm:ss tt", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ii-CN.js b/src/cultures/kendo.culture.ii-CN.js new file mode 100644 index 00000000000..c8635d96bb6 --- /dev/null +++ b/src/cultures/kendo.culture.ii-CN.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ii-CN"] = { + name: "ii-CN", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + symbol: "%" + }, + currency: { + pattern: ["$-n","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "¥" + } + }, + calendars: { + standard: { + days: { + names: ["ꑭꆏꑍ","ꆏꊂ꒔","ꆏꊂꑍ","ꆏꊂꌕ","ꆏꊂꇖ","ꆏꊂꉬ","ꆏꊂꃘ"], + namesAbbr: ["ꑭꆏ","ꆏ꒔","ꆏꑍ","ꆏꌕ","ꆏꇖ","ꆏꉬ","ꆏꃘ"], + namesShort: ["ꆏ","꒔","ꑍ","ꌕ","ꇖ","ꉬ","ꃘ"] + }, + months: { + names: ["ꋍꆪ","ꑍꆪ","ꌕꆪ","ꇖꆪ","ꉬꆪ","ꃘꆪ","ꏃꆪ","ꉆꆪ","ꈬꆪ","ꊰꆪ","ꊯꊪꆪ","ꊰꑋꆪ",""], + namesAbbr: ["ꋍꆪ","ꑍꆪ","ꌕꆪ","ꇖꆪ","ꉬꆪ","ꃘꆪ","ꏃꆪ","ꉆꆪ","ꈬꆪ","ꊰꆪ","ꊯꊪꆪ","ꊰꑋꆪ",""] + }, + AM: ["ꂵꆪꈌꈐ","ꂵꆪꈌꈐ","ꂵꆪꈌꈐ"], + PM: ["ꂵꆪꈌꉈ","ꂵꆪꈌꉈ","ꂵꆪꈌꉈ"], + patterns: { + d: "yyyy/M/d", + D: "yyyy'ꈎ' M'ꆪ' d'ꑍ'", + F: "yyyy'ꈎ' M'ꆪ' d'ꑍ' H:mm:ss", + g: "yyyy/M/d tt h:mm", + G: "yyyy/M/d H:mm:ss", + m: "M'ꆪ' d'ꑍ'", + M: "M'ꆪ' d'ꑍ'", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "tt h:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "yyyy'ꈎ' M'ꆪ'", + Y: "yyyy'ꈎ' M'ꆪ'" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ii.js b/src/cultures/kendo.culture.ii.js new file mode 100644 index 00000000000..7cab9114e01 --- /dev/null +++ b/src/cultures/kendo.culture.ii.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ii"] = { + name: "ii", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + symbol: "%" + }, + currency: { + pattern: ["$-n","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "¥" + } + }, + calendars: { + standard: { + days: { + names: ["ꑭꆏꑍ","ꆏꊂ꒔","ꆏꊂꑍ","ꆏꊂꌕ","ꆏꊂꇖ","ꆏꊂꉬ","ꆏꊂꃘ"], + namesAbbr: ["ꑭꆏ","ꆏ꒔","ꆏꑍ","ꆏꌕ","ꆏꇖ","ꆏꉬ","ꆏꃘ"], + namesShort: ["ꆏ","꒔","ꑍ","ꌕ","ꇖ","ꉬ","ꃘ"] + }, + months: { + names: ["ꋍꆪ","ꑍꆪ","ꌕꆪ","ꇖꆪ","ꉬꆪ","ꃘꆪ","ꏃꆪ","ꉆꆪ","ꈬꆪ","ꊰꆪ","ꊯꊪꆪ","ꊰꑋꆪ",""], + namesAbbr: ["ꋍꆪ","ꑍꆪ","ꌕꆪ","ꇖꆪ","ꉬꆪ","ꃘꆪ","ꏃꆪ","ꉆꆪ","ꈬꆪ","ꊰꆪ","ꊯꊪꆪ","ꊰꑋꆪ",""] + }, + AM: ["ꂵꆪꈌꈐ","ꂵꆪꈌꈐ","ꂵꆪꈌꈐ"], + PM: ["ꂵꆪꈌꉈ","ꂵꆪꈌꉈ","ꂵꆪꈌꉈ"], + patterns: { + d: "yyyy/M/d", + D: "yyyy'ꈎ' M'ꆪ' d'ꑍ'", + F: "yyyy'ꈎ' M'ꆪ' d'ꑍ' H:mm:ss", + g: "yyyy/M/d tt h:mm", + G: "yyyy/M/d H:mm:ss", + m: "M'ꆪ' d'ꑍ'", + M: "M'ꆪ' d'ꑍ'", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "tt h:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "yyyy'ꈎ' M'ꆪ'", + Y: "yyyy'ꈎ' M'ꆪ'" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.is-IS.js b/src/cultures/kendo.culture.is-IS.js new file mode 100644 index 00000000000..e4062192380 --- /dev/null +++ b/src/cultures/kendo.culture.is-IS.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["is-IS"] = { + name: "is-IS", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 0, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "kr." + } + }, + calendars: { + standard: { + days: { + names: ["sunnudagur","mánudagur","þriðjudagur","miðvikudagur","fimmtudagur","föstudagur","laugardagur"], + namesAbbr: ["sun.","mán.","þri.","mið.","fim.","fös.","lau."], + namesShort: ["su","má","þr","mi","fi","fö","la"] + }, + months: { + names: ["janúar","febrúar","mars","apríl","maí","júní","júlí","ágúst","september","október","nóvember","desember",""], + namesAbbr: ["jan.","feb.","mar.","apr.","maí","jún.","júl.","ágú.","sep.","okt.","nóv.","des.",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "d.M.yyyy", + D: "d. MMMM yyyy", + F: "d. MMMM yyyy HH:mm:ss", + g: "d.M.yyyy HH:mm", + G: "d.M.yyyy HH:mm:ss", + m: "d. MMMM", + M: "d. MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.is.js b/src/cultures/kendo.culture.is.js new file mode 100644 index 00000000000..2bff45d2c0e --- /dev/null +++ b/src/cultures/kendo.culture.is.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["is"] = { + name: "is", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 0, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "kr." + } + }, + calendars: { + standard: { + days: { + names: ["sunnudagur","mánudagur","þriðjudagur","miðvikudagur","fimmtudagur","föstudagur","laugardagur"], + namesAbbr: ["sun.","mán.","þri.","mið.","fim.","fös.","lau."], + namesShort: ["su","má","þr","mi","fi","fö","la"] + }, + months: { + names: ["janúar","febrúar","mars","apríl","maí","júní","júlí","ágúst","september","október","nóvember","desember",""], + namesAbbr: ["jan.","feb.","mar.","apr.","maí","jún.","júl.","ágú.","sep.","okt.","nóv.","des.",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "d.M.yyyy", + D: "d. MMMM yyyy", + F: "d. MMMM yyyy HH:mm:ss", + g: "d.M.yyyy HH:mm", + G: "d.M.yyyy HH:mm:ss", + m: "d. MMMM", + M: "d. MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.it-CH.js b/src/cultures/kendo.culture.it-CH.js new file mode 100644 index 00000000000..9015d57b690 --- /dev/null +++ b/src/cultures/kendo.culture.it-CH.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["it-CH"] = { + name: "it-CH", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": "'", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": "'", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$-n","$ n"], + decimals: 2, + ",": "'", + ".": ".", + groupSize: [3], + symbol: "fr." + } + }, + calendars: { + standard: { + days: { + names: ["domenica","lunedì","martedì","mercoledì","giovedì","venerdì","sabato"], + namesAbbr: ["dom","lun","mar","mer","gio","ven","sab"], + namesShort: ["do","lu","ma","me","gi","ve","sa"] + }, + months: { + names: ["gennaio","febbraio","marzo","aprile","maggio","giugno","luglio","agosto","settembre","ottobre","novembre","dicembre",""], + namesAbbr: ["gen","feb","mar","apr","mag","giu","lug","ago","set","ott","nov","dic",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yyyy", + D: "dddd, d. MMMM yyyy", + F: "dddd, d. MMMM yyyy HH:mm:ss", + g: "dd.MM.yyyy HH:mm", + G: "dd.MM.yyyy HH:mm:ss", + m: "d. MMMM", + M: "d. MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.it-IT.js b/src/cultures/kendo.culture.it-IT.js new file mode 100644 index 00000000000..f804e0daa43 --- /dev/null +++ b/src/cultures/kendo.culture.it-IT.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["it-IT"] = { + name: "it-IT", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-$ n","$ n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["domenica","lunedì","martedì","mercoledì","giovedì","venerdì","sabato"], + namesAbbr: ["dom","lun","mar","mer","gio","ven","sab"], + namesShort: ["do","lu","ma","me","gi","ve","sa"] + }, + months: { + names: ["gennaio","febbraio","marzo","aprile","maggio","giugno","luglio","agosto","settembre","ottobre","novembre","dicembre",""], + namesAbbr: ["gen","feb","mar","apr","mag","giu","lug","ago","set","ott","nov","dic",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd/MM/yyyy", + D: "dddd d MMMM yyyy", + F: "dddd d MMMM yyyy HH:mm:ss", + g: "dd/MM/yyyy HH:mm", + G: "dd/MM/yyyy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.it.js b/src/cultures/kendo.culture.it.js new file mode 100644 index 00000000000..abcb5f9b67c --- /dev/null +++ b/src/cultures/kendo.culture.it.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["it"] = { + name: "it", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-$ n","$ n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["domenica","lunedì","martedì","mercoledì","giovedì","venerdì","sabato"], + namesAbbr: ["dom","lun","mar","mer","gio","ven","sab"], + namesShort: ["do","lu","ma","me","gi","ve","sa"] + }, + months: { + names: ["gennaio","febbraio","marzo","aprile","maggio","giugno","luglio","agosto","settembre","ottobre","novembre","dicembre",""], + namesAbbr: ["gen","feb","mar","apr","mag","giu","lug","ago","set","ott","nov","dic",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd/MM/yyyy", + D: "dddd d MMMM yyyy", + F: "dddd d MMMM yyyy HH:mm:ss", + g: "dd/MM/yyyy HH:mm", + G: "dd/MM/yyyy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.iu-Cans-CA.js b/src/cultures/kendo.culture.iu-Cans-CA.js new file mode 100644 index 00000000000..bf64c58d639 --- /dev/null +++ b/src/cultures/kendo.culture.iu-Cans-CA.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["iu-Cans-CA"] = { + name: "iu-Cans-CA", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + symbol: "%" + }, + currency: { + pattern: ["($n)","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + symbol: "$" + } + }, + calendars: { + standard: { + days: { + names: ["ᓈᑦᑏᖑᔭ","ᓇᒡᒐᔾᔭᐅ","ᐊᐃᑉᐱᖅ","ᐱᖓᑦᓯᖅ","ᓯᑕᒻᒥᖅ","ᑕᓪᓕᕐᒥᖅ","ᓯᕙᑖᕐᕕᒃ"], + namesAbbr: ["ᓈᑦᑏ","ᓇᒡᒐ","ᐊᐃᑉᐱ","ᐱᖓᑦᓯ","ᓯᑕ","ᑕᓪᓕ","ᓯᕙᑖᕐᕕᒃ"], + namesShort: ["ᓈ","ᓇ","ᐊ","ᐱ","ᓯ","ᑕ","ᓯ"] + }, + months: { + names: ["ᔮᓐᓄᐊᕆ","ᕖᕝᕗᐊᕆ","ᒫᑦᓯ","ᐄᐳᕆ","ᒪᐃ","ᔫᓂ","ᔪᓚᐃ","ᐋᒡᒌᓯ","ᓯᑎᐱᕆ","ᐅᑐᐱᕆ","ᓄᕕᐱᕆ","ᑎᓯᐱᕆ",""], + namesAbbr: ["ᔮᓐᓄ","ᕖᕝᕗ","ᒫᑦᓯ","ᐄᐳᕆ","ᒪᐃ","ᔫᓂ","ᔪᓚᐃ","ᐋᒡᒌ","ᓯᑎᐱ","ᐅᑐᐱ","ᓄᕕᐱ","ᑎᓯᐱ",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "d/M/yyyy", + D: "dddd,MMMM dd,yyyy", + F: "dddd,MMMM dd,yyyy h:mm:ss tt", + g: "d/M/yyyy h:mm tt", + G: "d/M/yyyy h:mm:ss tt", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM,yyyy", + Y: "MMMM,yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.iu-Cans.js b/src/cultures/kendo.culture.iu-Cans.js new file mode 100644 index 00000000000..26a0684f43d --- /dev/null +++ b/src/cultures/kendo.culture.iu-Cans.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["iu-Cans"] = { + name: "iu-Cans", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + symbol: "%" + }, + currency: { + pattern: ["($n)","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + symbol: "$" + } + }, + calendars: { + standard: { + days: { + names: ["ᓈᑦᑏᖑᔭ","ᓇᒡᒐᔾᔭᐅ","ᐊᐃᑉᐱᖅ","ᐱᖓᑦᓯᖅ","ᓯᑕᒻᒥᖅ","ᑕᓪᓕᕐᒥᖅ","ᓯᕙᑖᕐᕕᒃ"], + namesAbbr: ["ᓈᑦᑏ","ᓇᒡᒐ","ᐊᐃᑉᐱ","ᐱᖓᑦᓯ","ᓯᑕ","ᑕᓪᓕ","ᓯᕙᑖᕐᕕᒃ"], + namesShort: ["ᓈ","ᓇ","ᐊ","ᐱ","ᓯ","ᑕ","ᓯ"] + }, + months: { + names: ["ᔮᓐᓄᐊᕆ","ᕖᕝᕗᐊᕆ","ᒫᑦᓯ","ᐄᐳᕆ","ᒪᐃ","ᔫᓂ","ᔪᓚᐃ","ᐋᒡᒌᓯ","ᓯᑎᐱᕆ","ᐅᑐᐱᕆ","ᓄᕕᐱᕆ","ᑎᓯᐱᕆ",""], + namesAbbr: ["ᔮᓐᓄ","ᕖᕝᕗ","ᒫᑦᓯ","ᐄᐳᕆ","ᒪᐃ","ᔫᓂ","ᔪᓚᐃ","ᐋᒡᒌ","ᓯᑎᐱ","ᐅᑐᐱ","ᓄᕕᐱ","ᑎᓯᐱ",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "d/M/yyyy", + D: "dddd,MMMM dd,yyyy", + F: "dddd,MMMM dd,yyyy h:mm:ss tt", + g: "d/M/yyyy h:mm tt", + G: "d/M/yyyy h:mm:ss tt", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM,yyyy", + Y: "MMMM,yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.iu-Latn-CA.js b/src/cultures/kendo.culture.iu-Latn-CA.js new file mode 100644 index 00000000000..9820af4dc5b --- /dev/null +++ b/src/cultures/kendo.culture.iu-Latn-CA.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["iu-Latn-CA"] = { + name: "iu-Latn-CA", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + symbol: "%" + }, + currency: { + pattern: ["($n)","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "$" + } + }, + calendars: { + standard: { + days: { + names: ["Naattiinguja","Naggajjau","Aippiq","Pingatsiq","Sitammiq","Tallirmiq","Sivataarvik"], + namesAbbr: ["Nat","Nag","Aip","Pi","Sit","Tal","Siv"], + namesShort: ["N","N","A","P","S","T","S"] + }, + months: { + names: ["Jaannuari","Viivvuari","Maatsi","Iipuri","Mai","Juuni","Julai","Aaggiisi","Sitipiri","Utupiri","Nuvipiri","Tisipiri",""], + namesAbbr: ["Jan","Viv","Mas","Ipu","Mai","Jun","Jul","Agi","Sii","Uut","Nuv","Tis",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "d/MM/yyyy", + D: "ddd, MMMM dd,yyyy", + F: "ddd, MMMM dd,yyyy h:mm:ss tt", + g: "d/MM/yyyy h:mm tt", + G: "d/MM/yyyy h:mm:ss tt", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.iu-Latn.js b/src/cultures/kendo.culture.iu-Latn.js new file mode 100644 index 00000000000..30f50c7a74b --- /dev/null +++ b/src/cultures/kendo.culture.iu-Latn.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["iu-Latn"] = { + name: "iu-Latn", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + symbol: "%" + }, + currency: { + pattern: ["($n)","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "$" + } + }, + calendars: { + standard: { + days: { + names: ["Naattiinguja","Naggajjau","Aippiq","Pingatsiq","Sitammiq","Tallirmiq","Sivataarvik"], + namesAbbr: ["Nat","Nag","Aip","Pi","Sit","Tal","Siv"], + namesShort: ["N","N","A","P","S","T","S"] + }, + months: { + names: ["Jaannuari","Viivvuari","Maatsi","Iipuri","Mai","Juuni","Julai","Aaggiisi","Sitipiri","Utupiri","Nuvipiri","Tisipiri",""], + namesAbbr: ["Jan","Viv","Mas","Ipu","Mai","Jun","Jul","Agi","Sii","Uut","Nuv","Tis",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "d/MM/yyyy", + D: "ddd, MMMM dd,yyyy", + F: "ddd, MMMM dd,yyyy h:mm:ss tt", + g: "d/MM/yyyy h:mm tt", + G: "d/MM/yyyy h:mm:ss tt", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.iu.js b/src/cultures/kendo.culture.iu.js new file mode 100644 index 00000000000..4b99f16a610 --- /dev/null +++ b/src/cultures/kendo.culture.iu.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["iu"] = { + name: "iu", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + symbol: "%" + }, + currency: { + pattern: ["($n)","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "$" + } + }, + calendars: { + standard: { + days: { + names: ["Naattiinguja","Naggajjau","Aippiq","Pingatsiq","Sitammiq","Tallirmiq","Sivataarvik"], + namesAbbr: ["Nat","Nag","Aip","Pi","Sit","Tal","Siv"], + namesShort: ["N","N","A","P","S","T","S"] + }, + months: { + names: ["Jaannuari","Viivvuari","Maatsi","Iipuri","Mai","Juuni","Julai","Aaggiisi","Sitipiri","Utupiri","Nuvipiri","Tisipiri",""], + namesAbbr: ["Jan","Viv","Mas","Ipu","Mai","Jun","Jul","Agi","Sii","Uut","Nuv","Tis",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "d/MM/yyyy", + D: "ddd, MMMM dd,yyyy", + F: "ddd, MMMM dd,yyyy h:mm:ss tt", + g: "d/MM/yyyy h:mm tt", + G: "d/MM/yyyy h:mm:ss tt", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ja-JP.js b/src/cultures/kendo.culture.ja-JP.js new file mode 100644 index 00000000000..9c98d141b7c --- /dev/null +++ b/src/cultures/kendo.culture.ja-JP.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ja-JP"] = { + name: "ja-JP", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-$n","$n"], + decimals: 0, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "¥" + } + }, + calendars: { + standard: { + days: { + names: ["日曜日","月曜日","火曜日","水曜日","木曜日","金曜日","土曜日"], + namesAbbr: ["日","月","火","水","木","金","土"], + namesShort: ["日","月","火","水","木","金","土"] + }, + months: { + names: ["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月",""], + namesAbbr: ["1","2","3","4","5","6","7","8","9","10","11","12",""] + }, + AM: ["午前","午前","午前"], + PM: ["午後","午後","午後"], + patterns: { + d: "yyyy/MM/dd", + D: "yyyy'年'M'月'd'日'", + F: "yyyy'年'M'月'd'日' H:mm:ss", + g: "yyyy/MM/dd H:mm", + G: "yyyy/MM/dd H:mm:ss", + m: "M'月'd'日'", + M: "M'月'd'日'", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "yyyy'年'M'月'", + Y: "yyyy'年'M'月'" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ja.js b/src/cultures/kendo.culture.ja.js new file mode 100644 index 00000000000..46a1edc1ed5 --- /dev/null +++ b/src/cultures/kendo.culture.ja.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ja"] = { + name: "ja", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-$n","$n"], + decimals: 0, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "¥" + } + }, + calendars: { + standard: { + days: { + names: ["日曜日","月曜日","火曜日","水曜日","木曜日","金曜日","土曜日"], + namesAbbr: ["日","月","火","水","木","金","土"], + namesShort: ["日","月","火","水","木","金","土"] + }, + months: { + names: ["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月",""], + namesAbbr: ["1","2","3","4","5","6","7","8","9","10","11","12",""] + }, + AM: ["午前","午前","午前"], + PM: ["午後","午後","午後"], + patterns: { + d: "yyyy/MM/dd", + D: "yyyy'年'M'月'd'日'", + F: "yyyy'年'M'月'd'日' H:mm:ss", + g: "yyyy/MM/dd H:mm", + G: "yyyy/MM/dd H:mm:ss", + m: "M'月'd'日'", + M: "M'月'd'日'", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "yyyy'年'M'月'", + Y: "yyyy'年'M'月'" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ka-GE.js b/src/cultures/kendo.culture.ka-GE.js new file mode 100644 index 00000000000..f2b37a3467f --- /dev/null +++ b/src/cultures/kendo.culture.ka-GE.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ka-GE"] = { + name: "ka-GE", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "Lari" + } + }, + calendars: { + standard: { + days: { + names: ["კვირა","ორშაბათი","სამშაბათი","ოთხშაბათი","ხუთშაბათი","პარასკევი","შაბათი"], + namesAbbr: ["კვირა","ორშაბათი","სამშაბათი","ოთხშაბათი","ხუთშაბათი","პარასკევი","შაბათი"], + namesShort: ["კ","ო","ს","ო","ხ","პ","შ"] + }, + months: { + names: ["იანვარი","თებერვალი","მარტი","აპრილი","მაისი","ივნისი","ივლისი","აგვისტო","სექტემბერი","ოქტომბერი","ნოემბერი","დეკემბერი",""], + namesAbbr: ["იან","თებ","მარ","აპრ","მაის","ივნ","ივლ","აგვ","სექ","ოქტ","ნოემ","დეკ",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yyyy", + D: "yyyy 'წლის' dd MM, dddd", + F: "yyyy 'წლის' dd MM, dddd H:mm:ss", + g: "dd.MM.yyyy H:mm", + G: "dd.MM.yyyy H:mm:ss", + m: "dd MM", + M: "dd MM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ka.js b/src/cultures/kendo.culture.ka.js new file mode 100644 index 00000000000..1b0f300fc26 --- /dev/null +++ b/src/cultures/kendo.culture.ka.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ka"] = { + name: "ka", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "Lari" + } + }, + calendars: { + standard: { + days: { + names: ["კვირა","ორშაბათი","სამშაბათი","ოთხშაბათი","ხუთშაბათი","პარასკევი","შაბათი"], + namesAbbr: ["კვირა","ორშაბათი","სამშაბათი","ოთხშაბათი","ხუთშაბათი","პარასკევი","შაბათი"], + namesShort: ["კ","ო","ს","ო","ხ","პ","შ"] + }, + months: { + names: ["იანვარი","თებერვალი","მარტი","აპრილი","მაისი","ივნისი","ივლისი","აგვისტო","სექტემბერი","ოქტომბერი","ნოემბერი","დეკემბერი",""], + namesAbbr: ["იან","თებ","მარ","აპრ","მაის","ივნ","ივლ","აგვ","სექ","ოქტ","ნოემ","დეკ",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yyyy", + D: "yyyy 'წლის' dd MM, dddd", + F: "yyyy 'წლის' dd MM, dddd H:mm:ss", + g: "dd.MM.yyyy H:mm", + G: "dd.MM.yyyy H:mm:ss", + m: "dd MM", + M: "dd MM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.kk-KZ.js b/src/cultures/kendo.culture.kk-KZ.js new file mode 100644 index 00000000000..1aa282d909f --- /dev/null +++ b/src/cultures/kendo.culture.kk-KZ.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["kk-KZ"] = { + name: "kk-KZ", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-$n","$n"], + decimals: 2, + ",": " ", + ".": "-", + groupSize: [3], + symbol: "Т" + } + }, + calendars: { + standard: { + days: { + names: ["Жексенбі","Дүйсенбі","Сейсенбі","Сәрсенбі","Бейсенбі","Жұма","Сенбі"], + namesAbbr: ["Жк","Дс","Сс","Ср","Бс","Жм","Сн"], + namesShort: ["Жк","Дс","Сс","Ср","Бс","Жм","Сн"] + }, + months: { + names: ["қаңтар","ақпан","наурыз","сәуір","мамыр","маусым","шілде","тамыз","қыркүйек","қазан","қараша","желтоқсан",""], + namesAbbr: ["Қаң","Ақп","Нау","Сәу","Мам","Мау","Шіл","Там","Қыр","Қаз","Қар","Жел",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yyyy", + D: "d MMMM yyyy 'ж.'", + F: "d MMMM yyyy 'ж.' H:mm:ss", + g: "dd.MM.yyyy H:mm", + G: "dd.MM.yyyy H:mm:ss", + m: "d MMMM", + M: "d MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.kk.js b/src/cultures/kendo.culture.kk.js new file mode 100644 index 00000000000..3c2e6a8bedc --- /dev/null +++ b/src/cultures/kendo.culture.kk.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["kk"] = { + name: "kk", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-$n","$n"], + decimals: 2, + ",": " ", + ".": "-", + groupSize: [3], + symbol: "Т" + } + }, + calendars: { + standard: { + days: { + names: ["Жексенбі","Дүйсенбі","Сейсенбі","Сәрсенбі","Бейсенбі","Жұма","Сенбі"], + namesAbbr: ["Жк","Дс","Сс","Ср","Бс","Жм","Сн"], + namesShort: ["Жк","Дс","Сс","Ср","Бс","Жм","Сн"] + }, + months: { + names: ["қаңтар","ақпан","наурыз","сәуір","мамыр","маусым","шілде","тамыз","қыркүйек","қазан","қараша","желтоқсан",""], + namesAbbr: ["Қаң","Ақп","Нау","Сәу","Мам","Мау","Шіл","Там","Қыр","Қаз","Қар","Жел",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yyyy", + D: "d MMMM yyyy 'ж.'", + F: "d MMMM yyyy 'ж.' H:mm:ss", + g: "dd.MM.yyyy H:mm", + G: "dd.MM.yyyy H:mm:ss", + m: "d MMMM", + M: "d MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.kl-GL.js b/src/cultures/kendo.culture.kl-GL.js new file mode 100644 index 00000000000..d2b7ca87317 --- /dev/null +++ b/src/cultures/kendo.culture.kl-GL.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["kl-GL"] = { + name: "kl-GL", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3,0], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3,0], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3,0], + symbol: "kr." + } + }, + calendars: { + standard: { + days: { + names: ["sapaat","ataasinngorneq","marlunngorneq","pingasunngorneq","sisamanngorneq","tallimanngorneq","arfininngorneq"], + namesAbbr: ["sap","ata","mar","ping","sis","tal","arf"], + namesShort: ["sa","at","ma","pi","si","ta","ar"] + }, + months: { + names: ["januari","februari","martsi","apriili","maaji","juni","juli","aggusti","septembari","oktobari","novembari","decembari",""], + namesAbbr: ["jan","feb","mar","apr","mai","jun","jul","aug","sep","okt","nov","dec",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd-MM-yyyy", + D: "d. MMMM yyyy", + F: "d. MMMM yyyy HH:mm:ss", + g: "dd-MM-yyyy HH:mm", + G: "dd-MM-yyyy HH:mm:ss", + m: "d. MMMM", + M: "d. MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "-", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.kl.js b/src/cultures/kendo.culture.kl.js new file mode 100644 index 00000000000..14ad18de4ce --- /dev/null +++ b/src/cultures/kendo.culture.kl.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["kl"] = { + name: "kl", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3,0], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3,0], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3,0], + symbol: "kr." + } + }, + calendars: { + standard: { + days: { + names: ["sapaat","ataasinngorneq","marlunngorneq","pingasunngorneq","sisamanngorneq","tallimanngorneq","arfininngorneq"], + namesAbbr: ["sap","ata","mar","ping","sis","tal","arf"], + namesShort: ["sa","at","ma","pi","si","ta","ar"] + }, + months: { + names: ["januari","februari","martsi","apriili","maaji","juni","juli","aggusti","septembari","oktobari","novembari","decembari",""], + namesAbbr: ["jan","feb","mar","apr","mai","jun","jul","aug","sep","okt","nov","dec",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd-MM-yyyy", + D: "d. MMMM yyyy", + F: "d. MMMM yyyy HH:mm:ss", + g: "dd-MM-yyyy HH:mm", + G: "dd-MM-yyyy HH:mm:ss", + m: "d. MMMM", + M: "d. MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "-", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.km-KH.js b/src/cultures/kendo.culture.km-KH.js new file mode 100644 index 00000000000..010cefa1570 --- /dev/null +++ b/src/cultures/kendo.culture.km-KH.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["km-KH"] = { + name: "km-KH", + numberFormat: { + pattern: ["- n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + symbol: "%" + }, + currency: { + pattern: ["-n$","n$"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "៛" + } + }, + calendars: { + standard: { + days: { + names: ["ថ្ងៃអាទិត្យ","ថ្ងៃច័ន្ទ","ថ្ងៃអង្គារ","ថ្ងៃពុធ","ថ្ងៃព្រហស្បតិ៍","ថ្ងៃសុក្រ","ថ្ងៃសៅរ៍"], + namesAbbr: ["អាទិ.","ច.","អ.","ពុ","ព្រហ.","សុ.","ស."], + namesShort: ["អា","ច","អ","ពុ","ព្","សុ","ស"] + }, + months: { + names: ["មករា","កុម្ភៈ","មិនា","មេសា","ឧសភា","មិថុនា","កក្កដា","សីហា","កញ្ញា","តុលា","វិច្ឆិកា","ធ្នូ",""], + namesAbbr: ["១","២","៣","៤","៥","៦","៧","៨","៩","១០","១១","១២",""] + }, + AM: ["ព្រឹក","ព្រឹក","ព្រឹក"], + PM: ["ល្ងាច","ល្ងាច","ល្ងាច"], + patterns: { + d: "yyyy-MM-dd", + D: "d MMMM yyyy", + F: "d MMMM yyyy HH:mm:ss", + g: "yyyy-MM-dd H:mm tt", + G: "yyyy-MM-dd HH:mm:ss", + m: "'ថ្ងៃទី' dd 'ខែ' MM", + M: "'ថ្ងៃទី' dd 'ខែ' MM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm tt", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "'ខែ' MM 'ឆ្នាំ' yyyy", + Y: "'ខែ' MM 'ឆ្នាំ' yyyy" + }, + "/": "-", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.km.js b/src/cultures/kendo.culture.km.js new file mode 100644 index 00000000000..c1d20baf653 --- /dev/null +++ b/src/cultures/kendo.culture.km.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["km"] = { + name: "km", + numberFormat: { + pattern: ["- n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + symbol: "%" + }, + currency: { + pattern: ["-n$","n$"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "៛" + } + }, + calendars: { + standard: { + days: { + names: ["ថ្ងៃអាទិត្យ","ថ្ងៃច័ន្ទ","ថ្ងៃអង្គារ","ថ្ងៃពុធ","ថ្ងៃព្រហស្បតិ៍","ថ្ងៃសុក្រ","ថ្ងៃសៅរ៍"], + namesAbbr: ["អាទិ.","ច.","អ.","ពុ","ព្រហ.","សុ.","ស."], + namesShort: ["អា","ច","អ","ពុ","ព្","សុ","ស"] + }, + months: { + names: ["មករា","កុម្ភៈ","មិនា","មេសា","ឧសភា","មិថុនា","កក្កដា","សីហា","កញ្ញា","តុលា","វិច្ឆិកា","ធ្នូ",""], + namesAbbr: ["១","២","៣","៤","៥","៦","៧","៨","៩","១០","១១","១២",""] + }, + AM: ["ព្រឹក","ព្រឹក","ព្រឹក"], + PM: ["ល្ងាច","ល្ងាច","ល្ងាច"], + patterns: { + d: "yyyy-MM-dd", + D: "d MMMM yyyy", + F: "d MMMM yyyy HH:mm:ss", + g: "yyyy-MM-dd H:mm tt", + G: "yyyy-MM-dd HH:mm:ss", + m: "'ថ្ងៃទី' dd 'ខែ' MM", + M: "'ថ្ងៃទី' dd 'ខែ' MM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm tt", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "'ខែ' MM 'ឆ្នាំ' yyyy", + Y: "'ខែ' MM 'ឆ្នាំ' yyyy" + }, + "/": "-", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.kn-IN.js b/src/cultures/kendo.culture.kn-IN.js new file mode 100644 index 00000000000..8a2c9574697 --- /dev/null +++ b/src/cultures/kendo.culture.kn-IN.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["kn-IN"] = { + name: "kn-IN", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "ರೂ" + } + }, + calendars: { + standard: { + days: { + names: ["ಭಾನುವಾರ","ಸೋಮವಾರ","ಮಂಗಳವಾರ","ಬುಧವಾರ","ಗುರುವಾರ","ಶುಕ್ರವಾರ","ಶನಿವಾರ"], + namesAbbr: ["ಭಾನು.","ಸೋಮ.","ಮಂಗಳ.","ಬುಧ.","ಗುರು.","ಶುಕ್ರ.","ಶನಿ."], + namesShort: ["ರ","ಸ","ಮ","ಬ","ಗ","ಶ","ಶ"] + }, + months: { + names: ["ಜನವರಿ","ಫೆಬ್ರವರಿ","ಮಾರ್ಚ್","ಎಪ್ರಿಲ್","ಮೇ","ಜೂನ್","ಜುಲೈ","ಆಗಸ್ಟ್","ಸೆಪ್ಟಂಬರ್","ಅಕ್ಟೋಬರ್","ನವೆಂಬರ್","ಡಿಸೆಂಬರ್",""], + namesAbbr: ["ಜನವರಿ","ಫೆಬ್ರವರಿ","ಮಾರ್ಚ್","ಎಪ್ರಿಲ್","ಮೇ","ಜೂನ್","ಜುಲೈ","ಆಗಸ್ಟ್","ಸೆಪ್ಟಂಬರ್","ಅಕ್ಟೋಬರ್","ನವೆಂಬರ್","ಡಿಸೆಂಬರ್",""] + }, + AM: ["ಪೂರ್ವಾಹ್ನ","ಪೂರ್ವಾಹ್ನ","ಪೂರ್ವಾಹ್ನ"], + PM: ["ಅಪರಾಹ್ನ","ಅಪರಾಹ್ನ","ಅಪರಾಹ್ನ"], + patterns: { + d: "dd-MM-yy", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy HH:mm:ss", + g: "dd-MM-yy HH:mm", + G: "dd-MM-yy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "-", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.kn.js b/src/cultures/kendo.culture.kn.js new file mode 100644 index 00000000000..5731a96536b --- /dev/null +++ b/src/cultures/kendo.culture.kn.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["kn"] = { + name: "kn", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "ರೂ" + } + }, + calendars: { + standard: { + days: { + names: ["ಭಾನುವಾರ","ಸೋಮವಾರ","ಮಂಗಳವಾರ","ಬುಧವಾರ","ಗುರುವಾರ","ಶುಕ್ರವಾರ","ಶನಿವಾರ"], + namesAbbr: ["ಭಾನು.","ಸೋಮ.","ಮಂಗಳ.","ಬುಧ.","ಗುರು.","ಶುಕ್ರ.","ಶನಿ."], + namesShort: ["ರ","ಸ","ಮ","ಬ","ಗ","ಶ","ಶ"] + }, + months: { + names: ["ಜನವರಿ","ಫೆಬ್ರವರಿ","ಮಾರ್ಚ್","ಎಪ್ರಿಲ್","ಮೇ","ಜೂನ್","ಜುಲೈ","ಆಗಸ್ಟ್","ಸೆಪ್ಟಂಬರ್","ಅಕ್ಟೋಬರ್","ನವೆಂಬರ್","ಡಿಸೆಂಬರ್",""], + namesAbbr: ["ಜನವರಿ","ಫೆಬ್ರವರಿ","ಮಾರ್ಚ್","ಎಪ್ರಿಲ್","ಮೇ","ಜೂನ್","ಜುಲೈ","ಆಗಸ್ಟ್","ಸೆಪ್ಟಂಬರ್","ಅಕ್ಟೋಬರ್","ನವೆಂಬರ್","ಡಿಸೆಂಬರ್",""] + }, + AM: ["ಪೂರ್ವಾಹ್ನ","ಪೂರ್ವಾಹ್ನ","ಪೂರ್ವಾಹ್ನ"], + PM: ["ಅಪರಾಹ್ನ","ಅಪರಾಹ್ನ","ಅಪರಾಹ್ನ"], + patterns: { + d: "dd-MM-yy", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy HH:mm:ss", + g: "dd-MM-yy HH:mm", + G: "dd-MM-yy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "-", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ko-KR.js b/src/cultures/kendo.culture.ko-KR.js new file mode 100644 index 00000000000..cb936c8befd --- /dev/null +++ b/src/cultures/kendo.culture.ko-KR.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ko-KR"] = { + name: "ko-KR", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-$n","$n"], + decimals: 0, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "₩" + } + }, + calendars: { + standard: { + days: { + names: ["일요일","월요일","화요일","수요일","목요일","금요일","토요일"], + namesAbbr: ["일","월","화","수","목","금","토"], + namesShort: ["일","월","화","수","목","금","토"] + }, + months: { + names: ["1월","2월","3월","4월","5월","6월","7월","8월","9월","10월","11월","12월",""], + namesAbbr: ["1","2","3","4","5","6","7","8","9","10","11","12",""] + }, + AM: ["오전","오전","오전"], + PM: ["오후","오후","오후"], + patterns: { + d: "yyyy-MM-dd", + D: "yyyy'년' M'월' d'일' dddd", + F: "yyyy'년' M'월' d'일' dddd tt h:mm:ss", + g: "yyyy-MM-dd tt h:mm", + G: "yyyy-MM-dd tt h:mm:ss", + m: "M'월' d'일'", + M: "M'월' d'일'", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "tt h:mm", + T: "tt h:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "yyyy'년' M'월'", + Y: "yyyy'년' M'월'" + }, + "/": "-", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ko.js b/src/cultures/kendo.culture.ko.js new file mode 100644 index 00000000000..a7dd5e487fe --- /dev/null +++ b/src/cultures/kendo.culture.ko.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ko"] = { + name: "ko", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-$n","$n"], + decimals: 0, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "₩" + } + }, + calendars: { + standard: { + days: { + names: ["일요일","월요일","화요일","수요일","목요일","금요일","토요일"], + namesAbbr: ["일","월","화","수","목","금","토"], + namesShort: ["일","월","화","수","목","금","토"] + }, + months: { + names: ["1월","2월","3월","4월","5월","6월","7월","8월","9월","10월","11월","12월",""], + namesAbbr: ["1","2","3","4","5","6","7","8","9","10","11","12",""] + }, + AM: ["오전","오전","오전"], + PM: ["오후","오후","오후"], + patterns: { + d: "yyyy-MM-dd", + D: "yyyy'년' M'월' d'일' dddd", + F: "yyyy'년' M'월' d'일' dddd tt h:mm:ss", + g: "yyyy-MM-dd tt h:mm", + G: "yyyy-MM-dd tt h:mm:ss", + m: "M'월' d'일'", + M: "M'월' d'일'", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "tt h:mm", + T: "tt h:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "yyyy'년' M'월'", + Y: "yyyy'년' M'월'" + }, + "/": "-", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.kok-IN.js b/src/cultures/kendo.culture.kok-IN.js new file mode 100644 index 00000000000..1ddd7031be8 --- /dev/null +++ b/src/cultures/kendo.culture.kok-IN.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["kok-IN"] = { + name: "kok-IN", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "रु" + } + }, + calendars: { + standard: { + days: { + names: ["आयतार","सोमार","मंगळार","बुधवार","बिरेस्तार","सुक्रार","शेनवार"], + namesAbbr: ["आय.","सोम.","मंगळ.","बुध.","बिरे.","सुक्र.","शेन."], + namesShort: ["आ","स","म","ब","ब","स","श"] + }, + months: { + names: ["जानेवारी","फेब्रुवारी","मार्च","एप्रिल","मे","जून","जुलै","ऑगस्ट","सप्टेंबर","ऑक्टोबर","नोवेम्बर","डिसेंबर",""], + namesAbbr: ["जानेवारी","फेब्रुवारी","मार्च","एप्रिल","मे","जून","जुलै","ऑगस्ट","सप्टेंबर","ऑक्टोबर","नोवेम्बर","डिसेंबर",""] + }, + AM: ["म.पू.","म.पू.","म.पू."], + PM: ["म.नं.","म.नं.","म.नं."], + patterns: { + d: "dd-MM-yyyy", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy HH:mm:ss", + g: "dd-MM-yyyy HH:mm", + G: "dd-MM-yyyy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "-", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.kok.js b/src/cultures/kendo.culture.kok.js new file mode 100644 index 00000000000..ed8111c55fd --- /dev/null +++ b/src/cultures/kendo.culture.kok.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["kok"] = { + name: "kok", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "रु" + } + }, + calendars: { + standard: { + days: { + names: ["आयतार","सोमार","मंगळार","बुधवार","बिरेस्तार","सुक्रार","शेनवार"], + namesAbbr: ["आय.","सोम.","मंगळ.","बुध.","बिरे.","सुक्र.","शेन."], + namesShort: ["आ","स","म","ब","ब","स","श"] + }, + months: { + names: ["जानेवारी","फेब्रुवारी","मार्च","एप्रिल","मे","जून","जुलै","ऑगस्ट","सप्टेंबर","ऑक्टोबर","नोवेम्बर","डिसेंबर",""], + namesAbbr: ["जानेवारी","फेब्रुवारी","मार्च","एप्रिल","मे","जून","जुलै","ऑगस्ट","सप्टेंबर","ऑक्टोबर","नोवेम्बर","डिसेंबर",""] + }, + AM: ["म.पू.","म.पू.","म.पू."], + PM: ["म.नं.","म.नं.","म.नं."], + patterns: { + d: "dd-MM-yyyy", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy HH:mm:ss", + g: "dd-MM-yyyy HH:mm", + G: "dd-MM-yyyy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "-", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ky-KG.js b/src/cultures/kendo.culture.ky-KG.js new file mode 100644 index 00000000000..11bd1fbafb1 --- /dev/null +++ b/src/cultures/kendo.culture.ky-KG.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ky-KG"] = { + name: "ky-KG", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": "-", + groupSize: [3], + symbol: "сом" + } + }, + calendars: { + standard: { + days: { + names: ["Жекшемби","Дүйшөмбү","Шейшемби","Шаршемби","Бейшемби","Жума","Ишемби"], + namesAbbr: ["Жш","Дш","Шш","Шр","Бш","Жм","Иш"], + namesShort: ["Жш","Дш","Шш","Шр","Бш","Жм","Иш"] + }, + months: { + names: ["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь",""], + namesAbbr: ["Янв","Фев","Мар","Апр","Май","Июн","Июл","Авг","Сен","Окт","Ноя","Дек",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yy", + D: "d'-'MMMM yyyy'-ж.'", + F: "d'-'MMMM yyyy'-ж.' H:mm:ss", + g: "dd.MM.yy H:mm", + G: "dd.MM.yy H:mm:ss", + m: "d MMMM", + M: "d MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy'-ж.'", + Y: "MMMM yyyy'-ж.'" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ky.js b/src/cultures/kendo.culture.ky.js new file mode 100644 index 00000000000..65554a1dc69 --- /dev/null +++ b/src/cultures/kendo.culture.ky.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ky"] = { + name: "ky", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": "-", + groupSize: [3], + symbol: "сом" + } + }, + calendars: { + standard: { + days: { + names: ["Жекшемби","Дүйшөмбү","Шейшемби","Шаршемби","Бейшемби","Жума","Ишемби"], + namesAbbr: ["Жш","Дш","Шш","Шр","Бш","Жм","Иш"], + namesShort: ["Жш","Дш","Шш","Шр","Бш","Жм","Иш"] + }, + months: { + names: ["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь",""], + namesAbbr: ["Янв","Фев","Мар","Апр","Май","Июн","Июл","Авг","Сен","Окт","Ноя","Дек",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yy", + D: "d'-'MMMM yyyy'-ж.'", + F: "d'-'MMMM yyyy'-ж.' H:mm:ss", + g: "dd.MM.yy H:mm", + G: "dd.MM.yy H:mm:ss", + m: "d MMMM", + M: "d MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy'-ж.'", + Y: "MMMM yyyy'-ж.'" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.lb-LU.js b/src/cultures/kendo.culture.lb-LU.js new file mode 100644 index 00000000000..d5d546c2a92 --- /dev/null +++ b/src/cultures/kendo.culture.lb-LU.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["lb-LU"] = { + name: "lb-LU", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["Sonndeg","Méindeg","Dënschdeg","Mëttwoch","Donneschdeg","Freideg","Samschdeg"], + namesAbbr: ["Son","Méi","Dën","Mët","Don","Fre","Sam"], + namesShort: ["So","Mé","Dë","Më","Do","Fr","Sa"] + }, + months: { + names: ["Januar","Februar","Mäerz","Abrëll","Mee","Juni","Juli","August","September","Oktober","November","Dezember",""], + namesAbbr: ["Jan","Feb","Mäe","Abr","Mee","Jun","Jul","Aug","Sep","Okt","Nov","Dez",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd/MM/yyyy", + D: "dddd d MMMM yyyy", + F: "dddd d MMMM yyyy HH:mm:ss", + g: "dd/MM/yyyy HH:mm", + G: "dd/MM/yyyy HH:mm:ss", + m: "d MMMM", + M: "d MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.lb.js b/src/cultures/kendo.culture.lb.js new file mode 100644 index 00000000000..b9ab8d6a17d --- /dev/null +++ b/src/cultures/kendo.culture.lb.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["lb"] = { + name: "lb", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["Sonndeg","Méindeg","Dënschdeg","Mëttwoch","Donneschdeg","Freideg","Samschdeg"], + namesAbbr: ["Son","Méi","Dën","Mët","Don","Fre","Sam"], + namesShort: ["So","Mé","Dë","Më","Do","Fr","Sa"] + }, + months: { + names: ["Januar","Februar","Mäerz","Abrëll","Mee","Juni","Juli","August","September","Oktober","November","Dezember",""], + namesAbbr: ["Jan","Feb","Mäe","Abr","Mee","Jun","Jul","Aug","Sep","Okt","Nov","Dez",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd/MM/yyyy", + D: "dddd d MMMM yyyy", + F: "dddd d MMMM yyyy HH:mm:ss", + g: "dd/MM/yyyy HH:mm", + G: "dd/MM/yyyy HH:mm:ss", + m: "d MMMM", + M: "d MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.lo-LA.js b/src/cultures/kendo.culture.lo-LA.js new file mode 100644 index 00000000000..cee5a0712da --- /dev/null +++ b/src/cultures/kendo.culture.lo-LA.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["lo-LA"] = { + name: "lo-LA", + numberFormat: { + pattern: ["(n)"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + symbol: "%" + }, + currency: { + pattern: ["(n$)","n$"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + symbol: "₭" + } + }, + calendars: { + standard: { + days: { + names: ["ວັນອາທິດ","ວັນຈັນ","ວັນອັງຄານ","ວັນພຸດ","ວັນພະຫັດ","ວັນສຸກ","ວັນເສົາ"], + namesAbbr: ["ອາທິດ","ຈັນ","ອັງຄານ","ພຸດ","ພະຫັດ","ສຸກ","ເສົາ"], + namesShort: ["ອ","ຈ","ອ","ພ","ພ","ສ","ເ"] + }, + months: { + names: ["ມັງກອນ","ກຸມພາ","ມີນາ","ເມສາ","ພຶດສະພາ","ມິຖຸນາ","ກໍລະກົດ","ສິງຫາ","ກັນຍາ","ຕຸລາ","ພະຈິກ","ທັນວາ",""], + namesAbbr: ["ມັງກອນ","ກຸມພາ","ມີນາ","ເມສາ","ພຶດສະພາ","ມິຖຸນາ","ກໍລະກົດ","ສິງຫາ","ກັນຍາ","ຕຸລາ","ພະຈິກ","ທັນວາ",""] + }, + AM: ["ເຊົ້າ","ເຊົ້າ","ເຊົ້າ"], + PM: ["ແລງ","ແລງ","ແລງ"], + patterns: { + d: "dd/MM/yyyy", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy HH:mm:ss", + g: "dd/MM/yyyy H:mm tt", + G: "dd/MM/yyyy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm tt", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.lo.js b/src/cultures/kendo.culture.lo.js new file mode 100644 index 00000000000..9b27b1b919f --- /dev/null +++ b/src/cultures/kendo.culture.lo.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["lo"] = { + name: "lo", + numberFormat: { + pattern: ["(n)"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + symbol: "%" + }, + currency: { + pattern: ["(n$)","n$"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + symbol: "₭" + } + }, + calendars: { + standard: { + days: { + names: ["ວັນອາທິດ","ວັນຈັນ","ວັນອັງຄານ","ວັນພຸດ","ວັນພະຫັດ","ວັນສຸກ","ວັນເສົາ"], + namesAbbr: ["ອາທິດ","ຈັນ","ອັງຄານ","ພຸດ","ພະຫັດ","ສຸກ","ເສົາ"], + namesShort: ["ອ","ຈ","ອ","ພ","ພ","ສ","ເ"] + }, + months: { + names: ["ມັງກອນ","ກຸມພາ","ມີນາ","ເມສາ","ພຶດສະພາ","ມິຖຸນາ","ກໍລະກົດ","ສິງຫາ","ກັນຍາ","ຕຸລາ","ພະຈິກ","ທັນວາ",""], + namesAbbr: ["ມັງກອນ","ກຸມພາ","ມີນາ","ເມສາ","ພຶດສະພາ","ມິຖຸນາ","ກໍລະກົດ","ສິງຫາ","ກັນຍາ","ຕຸລາ","ພະຈິກ","ທັນວາ",""] + }, + AM: ["ເຊົ້າ","ເຊົ້າ","ເຊົ້າ"], + PM: ["ແລງ","ແລງ","ແລງ"], + patterns: { + d: "dd/MM/yyyy", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy HH:mm:ss", + g: "dd/MM/yyyy H:mm tt", + G: "dd/MM/yyyy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm tt", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.lt-LT.js b/src/cultures/kendo.culture.lt-LT.js new file mode 100644 index 00000000000..a2e9a379d9b --- /dev/null +++ b/src/cultures/kendo.culture.lt-LT.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["lt-LT"] = { + name: "lt-LT", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "Lt" + } + }, + calendars: { + standard: { + days: { + names: ["sekmadienis","pirmadienis","antradienis","trečiadienis","ketvirtadienis","penktadienis","šeštadienis"], + namesAbbr: ["Sk","Pr","An","Tr","Kt","Pn","Št"], + namesShort: ["S","P","A","T","K","Pn","Š"] + }, + months: { + names: ["sausis","vasaris","kovas","balandis","gegužė","birželis","liepa","rugpjūtis","rugsėjis","spalis","lapkritis","gruodis",""], + namesAbbr: ["Sau","Vas","Kov","Bal","Geg","Bir","Lie","Rgp","Rgs","Spl","Lap","Grd",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "yyyy.MM.dd", + D: "yyyy 'm.' MMMM d 'd.'", + F: "yyyy 'm.' MMMM d 'd.' HH:mm:ss", + g: "yyyy.MM.dd HH:mm", + G: "yyyy.MM.dd HH:mm:ss", + m: "MMMM d 'd.'", + M: "MMMM d 'd.'", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "yyyy 'm.' MMMM", + Y: "yyyy 'm.' MMMM" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.lt.js b/src/cultures/kendo.culture.lt.js new file mode 100644 index 00000000000..48b73bbbdcb --- /dev/null +++ b/src/cultures/kendo.culture.lt.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["lt"] = { + name: "lt", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "Lt" + } + }, + calendars: { + standard: { + days: { + names: ["sekmadienis","pirmadienis","antradienis","trečiadienis","ketvirtadienis","penktadienis","šeštadienis"], + namesAbbr: ["Sk","Pr","An","Tr","Kt","Pn","Št"], + namesShort: ["S","P","A","T","K","Pn","Š"] + }, + months: { + names: ["sausis","vasaris","kovas","balandis","gegužė","birželis","liepa","rugpjūtis","rugsėjis","spalis","lapkritis","gruodis",""], + namesAbbr: ["Sau","Vas","Kov","Bal","Geg","Bir","Lie","Rgp","Rgs","Spl","Lap","Grd",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "yyyy.MM.dd", + D: "yyyy 'm.' MMMM d 'd.'", + F: "yyyy 'm.' MMMM d 'd.' HH:mm:ss", + g: "yyyy.MM.dd HH:mm", + G: "yyyy.MM.dd HH:mm:ss", + m: "MMMM d 'd.'", + M: "MMMM d 'd.'", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "yyyy 'm.' MMMM", + Y: "yyyy 'm.' MMMM" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.lv-LV.js b/src/cultures/kendo.culture.lv-LV.js new file mode 100644 index 00000000000..e19378d8500 --- /dev/null +++ b/src/cultures/kendo.culture.lv-LV.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["lv-LV"] = { + name: "lv-LV", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-$ n","$ n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "Ls" + } + }, + calendars: { + standard: { + days: { + names: ["svētdiena","pirmdiena","otrdiena","trešdiena","ceturtdiena","piektdiena","sestdiena"], + namesAbbr: ["sv","pr","ot","tr","ce","pk","se"], + namesShort: ["sv","pr","ot","tr","ce","pk","se"] + }, + months: { + names: ["janvāris","februāris","marts","aprīlis","maijs","jūnijs","jūlijs","augusts","septembris","oktobris","novembris","decembris",""], + namesAbbr: ["jan","feb","mar","apr","mai","jūn","jūl","aug","sep","okt","nov","dec",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "yyyy.MM.dd.", + D: "dddd, yyyy'. gada 'd. MMMM", + F: "dddd, yyyy'. gada 'd. MMMM H:mm:ss", + g: "yyyy.MM.dd. H:mm", + G: "yyyy.MM.dd. H:mm:ss", + m: "d. MMMM", + M: "d. MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "yyyy. MMMM", + Y: "yyyy. MMMM" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.lv.js b/src/cultures/kendo.culture.lv.js new file mode 100644 index 00000000000..053afeec692 --- /dev/null +++ b/src/cultures/kendo.culture.lv.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["lv"] = { + name: "lv", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-$ n","$ n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "Ls" + } + }, + calendars: { + standard: { + days: { + names: ["svētdiena","pirmdiena","otrdiena","trešdiena","ceturtdiena","piektdiena","sestdiena"], + namesAbbr: ["sv","pr","ot","tr","ce","pk","se"], + namesShort: ["sv","pr","ot","tr","ce","pk","se"] + }, + months: { + names: ["janvāris","februāris","marts","aprīlis","maijs","jūnijs","jūlijs","augusts","septembris","oktobris","novembris","decembris",""], + namesAbbr: ["jan","feb","mar","apr","mai","jūn","jūl","aug","sep","okt","nov","dec",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "yyyy.MM.dd.", + D: "dddd, yyyy'. gada 'd. MMMM", + F: "dddd, yyyy'. gada 'd. MMMM H:mm:ss", + g: "yyyy.MM.dd. H:mm", + G: "yyyy.MM.dd. H:mm:ss", + m: "d. MMMM", + M: "d. MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "yyyy. MMMM", + Y: "yyyy. MMMM" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.mi-NZ.js b/src/cultures/kendo.culture.mi-NZ.js new file mode 100644 index 00000000000..665463d5f62 --- /dev/null +++ b/src/cultures/kendo.culture.mi-NZ.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["mi-NZ"] = { + name: "mi-NZ", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-%n","%n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-$n","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "$" + } + }, + calendars: { + standard: { + days: { + names: ["Rātapu","Rāhina","Rātū","Rāapa","Rāpare","Rāmere","Rāhoroi"], + namesAbbr: ["Ta","Hi","Tū","Apa","Pa","Me","Ho"], + namesShort: ["Ta","Hi","Tū","Aa","Pa","Me","Ho"] + }, + months: { + names: ["Kohi-tātea","Hui-tanguru","Poutū-te-rangi","Paenga-whāwhā","Haratua","Pipiri","Hōngongoi","Here-turi-kōkā","Mahuru","Whiringa-ā-nuku","Whiringa-ā-rangi","Hakihea",""], + namesAbbr: ["Kohi","Hui","Pou","Pae","Hara","Pipi","Hōngo","Here","Mahu","Nuku","Rangi","Haki",""] + }, + AM: ["a.m.","a.m.","A.M."], + PM: ["p.m.","p.m.","P.M."], + patterns: { + d: "dd/MM/yyyy", + D: "dddd, dd MMMM, yyyy", + F: "dddd, dd MMMM, yyyy h:mm:ss tt", + g: "dd/MM/yyyy h:mm tt", + G: "dd/MM/yyyy h:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yy", + Y: "MMMM, yy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.mi.js b/src/cultures/kendo.culture.mi.js new file mode 100644 index 00000000000..23c2eaae9a6 --- /dev/null +++ b/src/cultures/kendo.culture.mi.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["mi"] = { + name: "mi", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-%n","%n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-$n","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "$" + } + }, + calendars: { + standard: { + days: { + names: ["Rātapu","Rāhina","Rātū","Rāapa","Rāpare","Rāmere","Rāhoroi"], + namesAbbr: ["Ta","Hi","Tū","Apa","Pa","Me","Ho"], + namesShort: ["Ta","Hi","Tū","Aa","Pa","Me","Ho"] + }, + months: { + names: ["Kohi-tātea","Hui-tanguru","Poutū-te-rangi","Paenga-whāwhā","Haratua","Pipiri","Hōngongoi","Here-turi-kōkā","Mahuru","Whiringa-ā-nuku","Whiringa-ā-rangi","Hakihea",""], + namesAbbr: ["Kohi","Hui","Pou","Pae","Hara","Pipi","Hōngo","Here","Mahu","Nuku","Rangi","Haki",""] + }, + AM: ["a.m.","a.m.","A.M."], + PM: ["p.m.","p.m.","P.M."], + patterns: { + d: "dd/MM/yyyy", + D: "dddd, dd MMMM, yyyy", + F: "dddd, dd MMMM, yyyy h:mm:ss tt", + g: "dd/MM/yyyy h:mm tt", + G: "dd/MM/yyyy h:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yy", + Y: "MMMM, yy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.mk-MK.js b/src/cultures/kendo.culture.mk-MK.js new file mode 100644 index 00000000000..ed844cde513 --- /dev/null +++ b/src/cultures/kendo.culture.mk-MK.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["mk-MK"] = { + name: "mk-MK", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "ден." + } + }, + calendars: { + standard: { + days: { + names: ["недела","понеделник","вторник","среда","четврток","петок","сабота"], + namesAbbr: ["нед","пон","втр","срд","чет","пет","саб"], + namesShort: ["не","по","вт","ср","че","пе","са"] + }, + months: { + names: ["јануари","февруари","март","април","мај","јуни","јули","август","септември","октомври","ноември","декември",""], + namesAbbr: ["јан","фев","мар","апр","мај","јун","јул","авг","сеп","окт","ное","дек",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yyyy", + D: "dddd, dd MMMM yyyy", + F: "dddd, dd MMMM yyyy HH:mm:ss", + g: "dd.MM.yyyy HH:mm", + G: "dd.MM.yyyy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.mk.js b/src/cultures/kendo.culture.mk.js new file mode 100644 index 00000000000..95176434b05 --- /dev/null +++ b/src/cultures/kendo.culture.mk.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["mk"] = { + name: "mk", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "ден." + } + }, + calendars: { + standard: { + days: { + names: ["недела","понеделник","вторник","среда","четврток","петок","сабота"], + namesAbbr: ["нед","пон","втр","срд","чет","пет","саб"], + namesShort: ["не","по","вт","ср","че","пе","са"] + }, + months: { + names: ["јануари","февруари","март","април","мај","јуни","јули","август","септември","октомври","ноември","декември",""], + namesAbbr: ["јан","фев","мар","апр","мај","јун","јул","авг","сеп","окт","ное","дек",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yyyy", + D: "dddd, dd MMMM yyyy", + F: "dddd, dd MMMM yyyy HH:mm:ss", + g: "dd.MM.yyyy HH:mm", + G: "dd.MM.yyyy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ml-IN.js b/src/cultures/kendo.culture.ml-IN.js new file mode 100644 index 00000000000..655cd15bf82 --- /dev/null +++ b/src/cultures/kendo.culture.ml-IN.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ml-IN"] = { + name: "ml-IN", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + percent: { + pattern: ["-%n","%n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "ക" + } + }, + calendars: { + standard: { + days: { + names: ["ഞായറാഴ്ച","തിങ്കളാഴ്ച","ചൊവ്വാഴ്ച","ബുധനാഴ്ച","വ്യാഴാഴ്ച","വെള്ളിയാഴ്ച","ശനിയാഴ്ച"], + namesAbbr: ["ഞായർ.","തിങ്കൾ.","ചൊവ്വ.","ബുധൻ.","വ്യാഴം.","വെള്ളി.","ശനി."], + namesShort: ["ഞ","ത","ച","ബ","വ","വെ","ശ"] + }, + months: { + names: ["ജനുവരി","ഫെബ്റുവരി","മാറ്ച്ച്","ഏപ്റില്","മെയ്","ജൂണ്","ജൂലൈ","ഓഗസ്ററ്","സെപ്ററംബറ്","ഒക്ടോബറ്","നവംബറ്","ഡിസംബറ്",""], + namesAbbr: ["ജനുവരി","ഫെബ്റുവരി","മാറ്ച്ച്","ഏപ്റില്","മെയ്","ജൂണ്","ജൂലൈ","ഓഗസ്ററ്","സെപ്ററംബറ്","ഒക്ടോബറ്","നവംബറ്","ഡിസംബറ്",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "dd-MM-yy", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy HH.mm.ss", + g: "dd-MM-yy HH.mm", + G: "dd-MM-yy HH.mm.ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH.mm", + T: "HH.mm.ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "-", + ":": ".", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ml.js b/src/cultures/kendo.culture.ml.js new file mode 100644 index 00000000000..64fd1ac6ce8 --- /dev/null +++ b/src/cultures/kendo.culture.ml.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ml"] = { + name: "ml", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + percent: { + pattern: ["-%n","%n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "ക" + } + }, + calendars: { + standard: { + days: { + names: ["ഞായറാഴ്ച","തിങ്കളാഴ്ച","ചൊവ്വാഴ്ച","ബുധനാഴ്ച","വ്യാഴാഴ്ച","വെള്ളിയാഴ്ച","ശനിയാഴ്ച"], + namesAbbr: ["ഞായർ.","തിങ്കൾ.","ചൊവ്വ.","ബുധൻ.","വ്യാഴം.","വെള്ളി.","ശനി."], + namesShort: ["ഞ","ത","ച","ബ","വ","വെ","ശ"] + }, + months: { + names: ["ജനുവരി","ഫെബ്റുവരി","മാറ്ച്ച്","ഏപ്റില്","മെയ്","ജൂണ്","ജൂലൈ","ഓഗസ്ററ്","സെപ്ററംബറ്","ഒക്ടോബറ്","നവംബറ്","ഡിസംബറ്",""], + namesAbbr: ["ജനുവരി","ഫെബ്റുവരി","മാറ്ച്ച്","ഏപ്റില്","മെയ്","ജൂണ്","ജൂലൈ","ഓഗസ്ററ്","സെപ്ററംബറ്","ഒക്ടോബറ്","നവംബറ്","ഡിസംബറ്",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "dd-MM-yy", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy HH.mm.ss", + g: "dd-MM-yy HH.mm", + G: "dd-MM-yy HH.mm.ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH.mm", + T: "HH.mm.ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "-", + ":": ".", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.mn-Cyrl.js b/src/cultures/kendo.culture.mn-Cyrl.js new file mode 100644 index 00000000000..fc1a5bb9b14 --- /dev/null +++ b/src/cultures/kendo.culture.mn-Cyrl.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["mn-Cyrl"] = { + name: "mn-Cyrl", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n$","n$"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "₮" + } + }, + calendars: { + standard: { + days: { + names: ["Ням","Даваа","Мягмар","Лхагва","Пүрэв","Баасан","Бямба"], + namesAbbr: ["Ня","Да","Мя","Лх","Пү","Ба","Бя"], + namesShort: ["Ня","Да","Мя","Лх","Пү","Ба","Бя"] + }, + months: { + names: ["1 дүгээр сар","2 дугаар сар","3 дугаар сар","4 дүгээр сар","5 дугаар сар","6 дугаар сар","7 дугаар сар","8 дугаар сар","9 дүгээр сар","10 дугаар сар","11 дүгээр сар","12 дугаар сар",""], + namesAbbr: ["I","II","III","IV","V","VI","VII","VIII","IX","X","XI","XII",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "yy.MM.dd", + D: "yyyy 'оны' MMMM d", + F: "yyyy 'оны' MMMM d H:mm:ss", + g: "yy.MM.dd H:mm", + G: "yy.MM.dd H:mm:ss", + m: "d MMMM", + M: "d MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "yyyy 'он' MMMM", + Y: "yyyy 'он' MMMM" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.mn-MN.js b/src/cultures/kendo.culture.mn-MN.js new file mode 100644 index 00000000000..284493e2cb9 --- /dev/null +++ b/src/cultures/kendo.culture.mn-MN.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["mn-MN"] = { + name: "mn-MN", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n$","n$"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "₮" + } + }, + calendars: { + standard: { + days: { + names: ["Ням","Даваа","Мягмар","Лхагва","Пүрэв","Баасан","Бямба"], + namesAbbr: ["Ня","Да","Мя","Лх","Пү","Ба","Бя"], + namesShort: ["Ня","Да","Мя","Лх","Пү","Ба","Бя"] + }, + months: { + names: ["1 дүгээр сар","2 дугаар сар","3 дугаар сар","4 дүгээр сар","5 дугаар сар","6 дугаар сар","7 дугаар сар","8 дугаар сар","9 дүгээр сар","10 дугаар сар","11 дүгээр сар","12 дугаар сар",""], + namesAbbr: ["I","II","III","IV","V","VI","VII","VIII","IX","X","XI","XII",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "yy.MM.dd", + D: "yyyy 'оны' MMMM d", + F: "yyyy 'оны' MMMM d H:mm:ss", + g: "yy.MM.dd H:mm", + G: "yy.MM.dd H:mm:ss", + m: "d MMMM", + M: "d MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "yyyy 'он' MMMM", + Y: "yyyy 'он' MMMM" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.mn-Mong-CN.js b/src/cultures/kendo.culture.mn-Mong-CN.js new file mode 100644 index 00000000000..9638fc07eca --- /dev/null +++ b/src/cultures/kendo.culture.mn-Mong-CN.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["mn-Mong-CN"] = { + name: "mn-Mong-CN", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + symbol: "%" + }, + currency: { + pattern: ["$-n","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + symbol: "¥" + } + }, + calendars: { + standard: { + days: { + names: ["ᠭᠠᠷᠠᠭ ᠤᠨ ᠡᠳᠦᠷ","ᠭᠠᠷᠠᠭ ᠤᠨ ᠨᠢᠭᠡᠨ","ᠭᠠᠷᠠᠭ ᠤᠨ ᠬᠣᠶᠠᠷ","ᠭᠠᠷᠠᠭ ᠤᠨ ᠭᠤᠷᠪᠠᠨ","ᠭᠠᠷᠠᠭ ᠤᠨ ᠳᠥᠷᠪᠡᠨ","ᠭᠠᠷᠠᠭ ᠤᠨ ᠲᠠᠪᠤᠨ","ᠭᠠᠷᠠᠭ ᠤᠨ ᠵᠢᠷᠭᠤᠭᠠᠨ"], + namesAbbr: ["ᠭᠠᠷᠠᠭ ᠤᠨ ᠡᠳᠦᠷ","ᠭᠠᠷᠠᠭ ᠤᠨ ᠨᠢᠭᠡᠨ","ᠭᠠᠷᠠᠭ ᠤᠨ ᠬᠣᠶᠠᠷ","ᠭᠠᠷᠠᠭ ᠤᠨ ᠭᠤᠷᠪᠠᠨ","ᠭᠠᠷᠠᠭ ᠤᠨ ᠳᠥᠷᠪᠡᠨ","ᠭᠠᠷᠠᠭ ᠤᠨ ᠲᠠᠪᠤᠨ","ᠭᠠᠷᠠᠭ ᠤᠨ ᠵᠢᠷᠭᠤᠭᠠᠨ"], + namesShort: ["ᠡ‍","ᠨᠢ‍","ᠬᠣ‍","ᠭᠤ‍","ᠳᠥ‍","ᠲᠠ‍","ᠵᠢ‍"] + }, + months: { + names: ["ᠨᠢᠭᠡᠳᠦᠭᠡᠷ ᠰᠠᠷ᠎ᠠ","ᠬᠤᠶ᠋ᠠᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ","ᠭᠤᠷᠪᠠᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ","ᠲᠦᠷᠪᠡᠳᠦᠭᠡᠷ ᠰᠠᠷ᠎ᠠ","ᠲᠠᠪᠤᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ","ᠵᠢᠷᠭᠤᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ","ᠲᠤᠯᠤᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ","ᠨᠠᠢᠮᠠᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ","ᠶᠢᠰᠦᠳᠦᠭᠡᠷ ᠰᠠᠷ᠎ᠠ","ᠠᠷᠪᠠᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ","ᠠᠷᠪᠠᠨ ᠨᠢᠭᠡᠳᠦᠭᠡᠷ ᠰᠠᠷ᠎ᠠ","ᠠᠷᠪᠠᠨ ᠬᠤᠶ᠋ᠠᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ",""], + namesAbbr: ["ᠨᠢᠭᠡᠳᠦᠭᠡᠷ ᠰᠠᠷ᠎ᠠ","ᠬᠤᠶ᠋ᠠᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ","ᠭᠤᠷᠪᠠᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ","ᠲᠦᠷᠪᠡᠳᠦᠭᠡᠷ ᠰᠠᠷ᠎ᠠ","ᠲᠠᠪᠤᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ","ᠵᠢᠷᠭᠤᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ","ᠲᠤᠯᠤᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ","ᠨᠠᠢᠮᠠᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ","ᠶᠢᠰᠦᠳᠦᠭᠡᠷ ᠰᠠᠷ᠎ᠠ","ᠠᠷᠪᠠᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ","ᠠᠷᠪᠠᠨ ᠨᠢᠭᠡᠳᠦᠭᠡᠷ ᠰᠠᠷ᠎ᠠ","ᠠᠷᠪᠠᠨ ᠬᠤᠶ᠋ᠠᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "yyyy/M/d", + D: "yyyy'ᠣᠨ ᠤ᠋' M'ᠰᠠᠷ᠎ᠠ  ᠢᠢᠨ 'd' ᠤ᠋ ᠡᠳᠦᠷ'", + F: "yyyy'ᠣᠨ ᠤ᠋' M'ᠰᠠᠷ᠎ᠠ  ᠢᠢᠨ 'd' ᠤ᠋ ᠡᠳᠦᠷ' H:mm:ss", + g: "yyyy/M/d H:mm", + G: "yyyy/M/d H:mm:ss", + m: "M'ᠰᠠᠷ᠎ᠠ' d'ᠡᠳᠦᠷ'", + M: "M'ᠰᠠᠷ᠎ᠠ' d'ᠡᠳᠦᠷ'", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "yyyy'ᠣᠨ' M'ᠰᠠᠷ᠎ᠠ'", + Y: "yyyy'ᠣᠨ' M'ᠰᠠᠷ᠎ᠠ'" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.mn-Mong.js b/src/cultures/kendo.culture.mn-Mong.js new file mode 100644 index 00000000000..5fc714cb232 --- /dev/null +++ b/src/cultures/kendo.culture.mn-Mong.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["mn-Mong"] = { + name: "mn-Mong", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + symbol: "%" + }, + currency: { + pattern: ["$-n","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + symbol: "¥" + } + }, + calendars: { + standard: { + days: { + names: ["ᠭᠠᠷᠠᠭ ᠤᠨ ᠡᠳᠦᠷ","ᠭᠠᠷᠠᠭ ᠤᠨ ᠨᠢᠭᠡᠨ","ᠭᠠᠷᠠᠭ ᠤᠨ ᠬᠣᠶᠠᠷ","ᠭᠠᠷᠠᠭ ᠤᠨ ᠭᠤᠷᠪᠠᠨ","ᠭᠠᠷᠠᠭ ᠤᠨ ᠳᠥᠷᠪᠡᠨ","ᠭᠠᠷᠠᠭ ᠤᠨ ᠲᠠᠪᠤᠨ","ᠭᠠᠷᠠᠭ ᠤᠨ ᠵᠢᠷᠭᠤᠭᠠᠨ"], + namesAbbr: ["ᠭᠠᠷᠠᠭ ᠤᠨ ᠡᠳᠦᠷ","ᠭᠠᠷᠠᠭ ᠤᠨ ᠨᠢᠭᠡᠨ","ᠭᠠᠷᠠᠭ ᠤᠨ ᠬᠣᠶᠠᠷ","ᠭᠠᠷᠠᠭ ᠤᠨ ᠭᠤᠷᠪᠠᠨ","ᠭᠠᠷᠠᠭ ᠤᠨ ᠳᠥᠷᠪᠡᠨ","ᠭᠠᠷᠠᠭ ᠤᠨ ᠲᠠᠪᠤᠨ","ᠭᠠᠷᠠᠭ ᠤᠨ ᠵᠢᠷᠭᠤᠭᠠᠨ"], + namesShort: ["ᠡ‍","ᠨᠢ‍","ᠬᠣ‍","ᠭᠤ‍","ᠳᠥ‍","ᠲᠠ‍","ᠵᠢ‍"] + }, + months: { + names: ["ᠨᠢᠭᠡᠳᠦᠭᠡᠷ ᠰᠠᠷ᠎ᠠ","ᠬᠤᠶ᠋ᠠᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ","ᠭᠤᠷᠪᠠᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ","ᠲᠦᠷᠪᠡᠳᠦᠭᠡᠷ ᠰᠠᠷ᠎ᠠ","ᠲᠠᠪᠤᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ","ᠵᠢᠷᠭᠤᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ","ᠲᠤᠯᠤᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ","ᠨᠠᠢᠮᠠᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ","ᠶᠢᠰᠦᠳᠦᠭᠡᠷ ᠰᠠᠷ᠎ᠠ","ᠠᠷᠪᠠᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ","ᠠᠷᠪᠠᠨ ᠨᠢᠭᠡᠳᠦᠭᠡᠷ ᠰᠠᠷ᠎ᠠ","ᠠᠷᠪᠠᠨ ᠬᠤᠶ᠋ᠠᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ",""], + namesAbbr: ["ᠨᠢᠭᠡᠳᠦᠭᠡᠷ ᠰᠠᠷ᠎ᠠ","ᠬᠤᠶ᠋ᠠᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ","ᠭᠤᠷᠪᠠᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ","ᠲᠦᠷᠪᠡᠳᠦᠭᠡᠷ ᠰᠠᠷ᠎ᠠ","ᠲᠠᠪᠤᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ","ᠵᠢᠷᠭᠤᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ","ᠲᠤᠯᠤᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ","ᠨᠠᠢᠮᠠᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ","ᠶᠢᠰᠦᠳᠦᠭᠡᠷ ᠰᠠᠷ᠎ᠠ","ᠠᠷᠪᠠᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ","ᠠᠷᠪᠠᠨ ᠨᠢᠭᠡᠳᠦᠭᠡᠷ ᠰᠠᠷ᠎ᠠ","ᠠᠷᠪᠠᠨ ᠬᠤᠶ᠋ᠠᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "yyyy/M/d", + D: "yyyy'ᠣᠨ ᠤ᠋' M'ᠰᠠᠷ᠎ᠠ  ᠢᠢᠨ 'd' ᠤ᠋ ᠡᠳᠦᠷ'", + F: "yyyy'ᠣᠨ ᠤ᠋' M'ᠰᠠᠷ᠎ᠠ  ᠢᠢᠨ 'd' ᠤ᠋ ᠡᠳᠦᠷ' H:mm:ss", + g: "yyyy/M/d H:mm", + G: "yyyy/M/d H:mm:ss", + m: "M'ᠰᠠᠷ᠎ᠠ' d'ᠡᠳᠦᠷ'", + M: "M'ᠰᠠᠷ᠎ᠠ' d'ᠡᠳᠦᠷ'", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "yyyy'ᠣᠨ' M'ᠰᠠᠷ᠎ᠠ'", + Y: "yyyy'ᠣᠨ' M'ᠰᠠᠷ᠎ᠠ'" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.mn.js b/src/cultures/kendo.culture.mn.js new file mode 100644 index 00000000000..dbfd3865864 --- /dev/null +++ b/src/cultures/kendo.culture.mn.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["mn"] = { + name: "mn", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n$","n$"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "₮" + } + }, + calendars: { + standard: { + days: { + names: ["Ням","Даваа","Мягмар","Лхагва","Пүрэв","Баасан","Бямба"], + namesAbbr: ["Ня","Да","Мя","Лх","Пү","Ба","Бя"], + namesShort: ["Ня","Да","Мя","Лх","Пү","Ба","Бя"] + }, + months: { + names: ["1 дүгээр сар","2 дугаар сар","3 дугаар сар","4 дүгээр сар","5 дугаар сар","6 дугаар сар","7 дугаар сар","8 дугаар сар","9 дүгээр сар","10 дугаар сар","11 дүгээр сар","12 дугаар сар",""], + namesAbbr: ["I","II","III","IV","V","VI","VII","VIII","IX","X","XI","XII",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "yy.MM.dd", + D: "yyyy 'оны' MMMM d", + F: "yyyy 'оны' MMMM d H:mm:ss", + g: "yy.MM.dd H:mm", + G: "yy.MM.dd H:mm:ss", + m: "d MMMM", + M: "d MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "yyyy 'он' MMMM", + Y: "yyyy 'он' MMMM" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.moh-CA.js b/src/cultures/kendo.culture.moh-CA.js new file mode 100644 index 00000000000..6a7013f69fd --- /dev/null +++ b/src/cultures/kendo.culture.moh-CA.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["moh-CA"] = { + name: "moh-CA", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + symbol: "%" + }, + currency: { + pattern: ["($n)","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "$" + } + }, + calendars: { + standard: { + days: { + names: ["Awentatokentì:ke","Awentataón\u0027ke","Ratironhia\u0027kehronòn:ke","Soséhne","Okaristiiáhne","Ronwaia\u0027tanentaktonhne","Entákta"], + namesAbbr: ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"], + namesShort: ["S","M","T","W","T","F","S"] + }, + months: { + names: ["Tsothohrkó:Wa","Enniska","Enniskó:Wa","Onerahtókha","Onerahtohkó:Wa","Ohiari:Ha","Ohiarihkó:Wa","Seskéha","Seskehkó:Wa","Kenténha","Kentenhkó:Wa","Tsothóhrha",""], + namesAbbr: ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "M/d/yyyy", + D: "dddd, MMMM dd, yyyy", + F: "dddd, MMMM dd, yyyy h:mm:ss tt", + g: "M/d/yyyy h:mm tt", + G: "M/d/yyyy h:mm:ss tt", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.moh.js b/src/cultures/kendo.culture.moh.js new file mode 100644 index 00000000000..7528fd14118 --- /dev/null +++ b/src/cultures/kendo.culture.moh.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["moh"] = { + name: "moh", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,0], + symbol: "%" + }, + currency: { + pattern: ["($n)","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "$" + } + }, + calendars: { + standard: { + days: { + names: ["Awentatokentì:ke","Awentataón\u0027ke","Ratironhia\u0027kehronòn:ke","Soséhne","Okaristiiáhne","Ronwaia\u0027tanentaktonhne","Entákta"], + namesAbbr: ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"], + namesShort: ["S","M","T","W","T","F","S"] + }, + months: { + names: ["Tsothohrkó:Wa","Enniska","Enniskó:Wa","Onerahtókha","Onerahtohkó:Wa","Ohiari:Ha","Ohiarihkó:Wa","Seskéha","Seskehkó:Wa","Kenténha","Kentenhkó:Wa","Tsothóhrha",""], + namesAbbr: ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "M/d/yyyy", + D: "dddd, MMMM dd, yyyy", + F: "dddd, MMMM dd, yyyy h:mm:ss tt", + g: "M/d/yyyy h:mm tt", + G: "M/d/yyyy h:mm:ss tt", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.mr-IN.js b/src/cultures/kendo.culture.mr-IN.js new file mode 100644 index 00000000000..ecfa23224b8 --- /dev/null +++ b/src/cultures/kendo.culture.mr-IN.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["mr-IN"] = { + name: "mr-IN", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "रु" + } + }, + calendars: { + standard: { + days: { + names: ["रविवार","सोमवार","मंगळवार","बुधवार","गुरुवार","शुक्रवार","शनिवार"], + namesAbbr: ["रवि.","सोम.","मंगळ.","बुध.","गुरु.","शुक्र.","शनि."], + namesShort: ["र","स","म","ब","ग","श","श"] + }, + months: { + names: ["जानेवारी","फेब्रुवारी","मार्च","एप्रिल","मे","जून","जुलै","ऑगस्ट","सप्टेंबर","ऑक्टोबर","नोव्हेंबर","डिसेंबर",""], + namesAbbr: ["जाने.","फेब्रु.","मार्च","एप्रिल","मे","जून","जुलै","ऑगस्ट","सप्टें.","ऑक्टो.","नोव्हें.","डिसें.",""] + }, + AM: ["म.पू.","म.पू.","म.पू."], + PM: ["म.नं.","म.नं.","म.नं."], + patterns: { + d: "dd-MM-yyyy", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy HH:mm:ss", + g: "dd-MM-yyyy HH:mm", + G: "dd-MM-yyyy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "-", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.mr.js b/src/cultures/kendo.culture.mr.js new file mode 100644 index 00000000000..4d91275e1a8 --- /dev/null +++ b/src/cultures/kendo.culture.mr.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["mr"] = { + name: "mr", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "रु" + } + }, + calendars: { + standard: { + days: { + names: ["रविवार","सोमवार","मंगळवार","बुधवार","गुरुवार","शुक्रवार","शनिवार"], + namesAbbr: ["रवि.","सोम.","मंगळ.","बुध.","गुरु.","शुक्र.","शनि."], + namesShort: ["र","स","म","ब","ग","श","श"] + }, + months: { + names: ["जानेवारी","फेब्रुवारी","मार्च","एप्रिल","मे","जून","जुलै","ऑगस्ट","सप्टेंबर","ऑक्टोबर","नोव्हेंबर","डिसेंबर",""], + namesAbbr: ["जाने.","फेब्रु.","मार्च","एप्रिल","मे","जून","जुलै","ऑगस्ट","सप्टें.","ऑक्टो.","नोव्हें.","डिसें.",""] + }, + AM: ["म.पू.","म.पू.","म.पू."], + PM: ["म.नं.","म.नं.","म.नं."], + patterns: { + d: "dd-MM-yyyy", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy HH:mm:ss", + g: "dd-MM-yyyy HH:mm", + G: "dd-MM-yyyy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "-", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ms-BN.js b/src/cultures/kendo.culture.ms-BN.js new file mode 100644 index 00000000000..d3f435599c4 --- /dev/null +++ b/src/cultures/kendo.culture.ms-BN.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ms-BN"] = { + name: "ms-BN", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["($n)","$n"], + decimals: 0, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "$" + } + }, + calendars: { + standard: { + days: { + names: ["Ahad","Isnin","Selasa","Rabu","Khamis","Jumaat","Sabtu"], + namesAbbr: ["Ahad","Isnin","Sel","Rabu","Khamis","Jumaat","Sabtu"], + namesShort: ["A","I","S","R","K","J","S"] + }, + months: { + names: ["Januari","Februari","Mac","April","Mei","Jun","Julai","Ogos","September","Oktober","November","Disember",""], + namesAbbr: ["Jan","Feb","Mac","Apr","Mei","Jun","Jul","Ogos","Sept","Okt","Nov","Dis",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd/MM/yyyy", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy H:mm:ss", + g: "dd/MM/yyyy H:mm", + G: "dd/MM/yyyy H:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ms-MY.js b/src/cultures/kendo.culture.ms-MY.js new file mode 100644 index 00000000000..d767dcb2d06 --- /dev/null +++ b/src/cultures/kendo.culture.ms-MY.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ms-MY"] = { + name: "ms-MY", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["($n)","$n"], + decimals: 0, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "RM" + } + }, + calendars: { + standard: { + days: { + names: ["Ahad","Isnin","Selasa","Rabu","Khamis","Jumaat","Sabtu"], + namesAbbr: ["Ahad","Isnin","Sel","Rabu","Khamis","Jumaat","Sabtu"], + namesShort: ["A","I","S","R","K","J","S"] + }, + months: { + names: ["Januari","Februari","Mac","April","Mei","Jun","Julai","Ogos","September","Oktober","November","Disember",""], + namesAbbr: ["Jan","Feb","Mac","Apr","Mei","Jun","Jul","Ogos","Sept","Okt","Nov","Dis",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd/MM/yyyy", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy H:mm:ss", + g: "dd/MM/yyyy H:mm", + G: "dd/MM/yyyy H:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ms.js b/src/cultures/kendo.culture.ms.js new file mode 100644 index 00000000000..844e57581df --- /dev/null +++ b/src/cultures/kendo.culture.ms.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ms"] = { + name: "ms", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["($n)","$n"], + decimals: 0, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "RM" + } + }, + calendars: { + standard: { + days: { + names: ["Ahad","Isnin","Selasa","Rabu","Khamis","Jumaat","Sabtu"], + namesAbbr: ["Ahad","Isnin","Sel","Rabu","Khamis","Jumaat","Sabtu"], + namesShort: ["A","I","S","R","K","J","S"] + }, + months: { + names: ["Januari","Februari","Mac","April","Mei","Jun","Julai","Ogos","September","Oktober","November","Disember",""], + namesAbbr: ["Jan","Feb","Mac","Apr","Mei","Jun","Jul","Ogos","Sept","Okt","Nov","Dis",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd/MM/yyyy", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy H:mm:ss", + g: "dd/MM/yyyy H:mm", + G: "dd/MM/yyyy H:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.mt-MT.js b/src/cultures/kendo.culture.mt-MT.js new file mode 100644 index 00000000000..cbbfd2734de --- /dev/null +++ b/src/cultures/kendo.culture.mt-MT.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["mt-MT"] = { + name: "mt-MT", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-%n","%n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-$n","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["Il-Ħadd","It-Tnejn","It-Tlieta","L-Erbgħa","Il-Ħamis","Il-Ġimgħa","Is-Sibt"], + namesAbbr: ["Ħad","Tne","Tli","Erb","Ħam","Ġim","Sib"], + namesShort: ["I","I","I","L","I","I","I"] + }, + months: { + names: ["Jannar","Frar","Marzu","April","Mejju","Ġunju","Lulju","Awissu","Settembru","Ottubru","Novembru","Diċembru",""], + namesAbbr: ["Jan","Fra","Mar","Apr","Mej","Ġun","Lul","Awi","Set","Ott","Nov","Diċ",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "dd/MM/yyyy", + D: "dddd, d' ta\' 'MMMM yyyy", + F: "dddd, d' ta\' 'MMMM yyyy HH:mm:ss", + g: "dd/MM/yyyy HH:mm", + G: "dd/MM/yyyy HH:mm:ss", + m: "d' ta\' 'MMMM", + M: "d' ta\' 'MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.mt.js b/src/cultures/kendo.culture.mt.js new file mode 100644 index 00000000000..21fe1c58d1b --- /dev/null +++ b/src/cultures/kendo.culture.mt.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["mt"] = { + name: "mt", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-%n","%n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-$n","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["Il-Ħadd","It-Tnejn","It-Tlieta","L-Erbgħa","Il-Ħamis","Il-Ġimgħa","Is-Sibt"], + namesAbbr: ["Ħad","Tne","Tli","Erb","Ħam","Ġim","Sib"], + namesShort: ["I","I","I","L","I","I","I"] + }, + months: { + names: ["Jannar","Frar","Marzu","April","Mejju","Ġunju","Lulju","Awissu","Settembru","Ottubru","Novembru","Diċembru",""], + namesAbbr: ["Jan","Fra","Mar","Apr","Mej","Ġun","Lul","Awi","Set","Ott","Nov","Diċ",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "dd/MM/yyyy", + D: "dddd, d' ta\' 'MMMM yyyy", + F: "dddd, d' ta\' 'MMMM yyyy HH:mm:ss", + g: "dd/MM/yyyy HH:mm", + G: "dd/MM/yyyy HH:mm:ss", + m: "d' ta\' 'MMMM", + M: "d' ta\' 'MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.nb-NO.js b/src/cultures/kendo.culture.nb-NO.js new file mode 100644 index 00000000000..1e581631250 --- /dev/null +++ b/src/cultures/kendo.culture.nb-NO.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["nb-NO"] = { + name: "nb-NO", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "kr" + } + }, + calendars: { + standard: { + days: { + names: ["søndag","mandag","tirsdag","onsdag","torsdag","fredag","lørdag"], + namesAbbr: ["sø","ma","ti","on","to","fr","lø"], + namesShort: ["sø","ma","ti","on","to","fr","lø"] + }, + months: { + names: ["januar","februar","mars","april","mai","juni","juli","august","september","oktober","november","desember",""], + namesAbbr: ["jan","feb","mar","apr","mai","jun","jul","aug","sep","okt","nov","des",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yyyy", + D: "d. MMMM yyyy", + F: "d. MMMM yyyy HH:mm:ss", + g: "dd.MM.yyyy HH:mm", + G: "dd.MM.yyyy HH:mm:ss", + m: "d. MMMM", + M: "d. MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.nb.js b/src/cultures/kendo.culture.nb.js new file mode 100644 index 00000000000..269d2264b8a --- /dev/null +++ b/src/cultures/kendo.culture.nb.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["nb"] = { + name: "nb", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "kr" + } + }, + calendars: { + standard: { + days: { + names: ["søndag","mandag","tirsdag","onsdag","torsdag","fredag","lørdag"], + namesAbbr: ["sø","ma","ti","on","to","fr","lø"], + namesShort: ["sø","ma","ti","on","to","fr","lø"] + }, + months: { + names: ["januar","februar","mars","april","mai","juni","juli","august","september","oktober","november","desember",""], + namesAbbr: ["jan","feb","mar","apr","mai","jun","jul","aug","sep","okt","nov","des",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yyyy", + D: "d. MMMM yyyy", + F: "d. MMMM yyyy HH:mm:ss", + g: "dd.MM.yyyy HH:mm", + G: "dd.MM.yyyy HH:mm:ss", + m: "d. MMMM", + M: "d. MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ne-NP.js b/src/cultures/kendo.culture.ne-NP.js new file mode 100644 index 00000000000..31a1627d22e --- /dev/null +++ b/src/cultures/kendo.culture.ne-NP.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ne-NP"] = { + name: "ne-NP", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "%" + }, + currency: { + pattern: ["-$n","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "रु" + } + }, + calendars: { + standard: { + days: { + names: ["आइतवार","सोमवार","मङ्गलवार","बुधवार","बिहीवार","शुक्रवार","शनिवार"], + namesAbbr: ["आइत","सोम","मङ्गल","बुध","बिही","शुक्र","शनि"], + namesShort: ["आ","सो","म","बु","बि","शु","श"] + }, + months: { + names: ["जनवरी","फेब्रुअरी","मार्च","अप्रिल","मे","जून","जुलाई","अगस्त","सेप्टेम्बर","अक्टोबर","नोभेम्बर","डिसेम्बर",""], + namesAbbr: ["जन","फेब","मार्च","अप्रिल","मे","जून","जुलाई","अग","सेप्ट","अक्ट","नोभ","डिस",""] + }, + AM: ["विहानी","विहानी","विहानी"], + PM: ["बेलुकी","बेलुकी","बेलुकी"], + patterns: { + d: "M/d/yyyy", + D: "dddd, MMMM dd, yyyy", + F: "dddd, MMMM dd, yyyy h:mm:ss tt", + g: "M/d/yyyy h:mm tt", + G: "M/d/yyyy h:mm:ss tt", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM,yyyy", + Y: "MMMM,yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ne.js b/src/cultures/kendo.culture.ne.js new file mode 100644 index 00000000000..d21e2989a00 --- /dev/null +++ b/src/cultures/kendo.culture.ne.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ne"] = { + name: "ne", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "%" + }, + currency: { + pattern: ["-$n","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "रु" + } + }, + calendars: { + standard: { + days: { + names: ["आइतवार","सोमवार","मङ्गलवार","बुधवार","बिहीवार","शुक्रवार","शनिवार"], + namesAbbr: ["आइत","सोम","मङ्गल","बुध","बिही","शुक्र","शनि"], + namesShort: ["आ","सो","म","बु","बि","शु","श"] + }, + months: { + names: ["जनवरी","फेब्रुअरी","मार्च","अप्रिल","मे","जून","जुलाई","अगस्त","सेप्टेम्बर","अक्टोबर","नोभेम्बर","डिसेम्बर",""], + namesAbbr: ["जन","फेब","मार्च","अप्रिल","मे","जून","जुलाई","अग","सेप्ट","अक्ट","नोभ","डिस",""] + }, + AM: ["विहानी","विहानी","विहानी"], + PM: ["बेलुकी","बेलुकी","बेलुकी"], + patterns: { + d: "M/d/yyyy", + D: "dddd, MMMM dd, yyyy", + F: "dddd, MMMM dd, yyyy h:mm:ss tt", + g: "M/d/yyyy h:mm tt", + G: "M/d/yyyy h:mm:ss tt", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM,yyyy", + Y: "MMMM,yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.nl-BE.js b/src/cultures/kendo.culture.nl-BE.js new file mode 100644 index 00000000000..d6d7496dbf6 --- /dev/null +++ b/src/cultures/kendo.culture.nl-BE.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["nl-BE"] = { + name: "nl-BE", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["zondag","maandag","dinsdag","woensdag","donderdag","vrijdag","zaterdag"], + namesAbbr: ["zo","ma","di","wo","do","vr","za"], + namesShort: ["zo","ma","di","wo","do","vr","za"] + }, + months: { + names: ["januari","februari","maart","april","mei","juni","juli","augustus","september","oktober","november","december",""], + namesAbbr: ["jan","feb","mrt","apr","mei","jun","jul","aug","sep","okt","nov","dec",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "d/MM/yyyy", + D: "dddd d MMMM yyyy", + F: "dddd d MMMM yyyy H:mm:ss", + g: "d/MM/yyyy H:mm", + G: "d/MM/yyyy H:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.nl-NL.js b/src/cultures/kendo.culture.nl-NL.js new file mode 100644 index 00000000000..bf2d5eabb01 --- /dev/null +++ b/src/cultures/kendo.culture.nl-NL.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["nl-NL"] = { + name: "nl-NL", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["zondag","maandag","dinsdag","woensdag","donderdag","vrijdag","zaterdag"], + namesAbbr: ["zo","ma","di","wo","do","vr","za"], + namesShort: ["zo","ma","di","wo","do","vr","za"] + }, + months: { + names: ["januari","februari","maart","april","mei","juni","juli","augustus","september","oktober","november","december",""], + namesAbbr: ["jan","feb","mrt","apr","mei","jun","jul","aug","sep","okt","nov","dec",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "d-M-yyyy", + D: "dddd d MMMM yyyy", + F: "dddd d MMMM yyyy H:mm:ss", + g: "d-M-yyyy H:mm", + G: "d-M-yyyy H:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "-", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.nl.js b/src/cultures/kendo.culture.nl.js new file mode 100644 index 00000000000..a912a697cd1 --- /dev/null +++ b/src/cultures/kendo.culture.nl.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["nl"] = { + name: "nl", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["zondag","maandag","dinsdag","woensdag","donderdag","vrijdag","zaterdag"], + namesAbbr: ["zo","ma","di","wo","do","vr","za"], + namesShort: ["zo","ma","di","wo","do","vr","za"] + }, + months: { + names: ["januari","februari","maart","april","mei","juni","juli","augustus","september","oktober","november","december",""], + namesAbbr: ["jan","feb","mrt","apr","mei","jun","jul","aug","sep","okt","nov","dec",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "d-M-yyyy", + D: "dddd d MMMM yyyy", + F: "dddd d MMMM yyyy H:mm:ss", + g: "d-M-yyyy H:mm", + G: "d-M-yyyy H:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "-", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.nn-NO.js b/src/cultures/kendo.culture.nn-NO.js new file mode 100644 index 00000000000..de035c3fa63 --- /dev/null +++ b/src/cultures/kendo.culture.nn-NO.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["nn-NO"] = { + name: "nn-NO", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "kr" + } + }, + calendars: { + standard: { + days: { + names: ["søndag","måndag","tysdag","onsdag","torsdag","fredag","laurdag"], + namesAbbr: ["sø","må","ty","on","to","fr","la"], + namesShort: ["sø","må","ty","on","to","fr","la"] + }, + months: { + names: ["januar","februar","mars","april","mai","juni","juli","august","september","oktober","november","desember",""], + namesAbbr: ["jan","feb","mar","apr","mai","jun","jul","aug","sep","okt","nov","des",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yyyy", + D: "d. MMMM yyyy", + F: "d. MMMM yyyy HH:mm:ss", + g: "dd.MM.yyyy HH:mm", + G: "dd.MM.yyyy HH:mm:ss", + m: "d. MMMM", + M: "d. MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.nn.js b/src/cultures/kendo.culture.nn.js new file mode 100644 index 00000000000..ac9a29a22dd --- /dev/null +++ b/src/cultures/kendo.culture.nn.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["nn"] = { + name: "nn", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "kr" + } + }, + calendars: { + standard: { + days: { + names: ["søndag","måndag","tysdag","onsdag","torsdag","fredag","laurdag"], + namesAbbr: ["sø","må","ty","on","to","fr","la"], + namesShort: ["sø","må","ty","on","to","fr","la"] + }, + months: { + names: ["januar","februar","mars","april","mai","juni","juli","august","september","oktober","november","desember",""], + namesAbbr: ["jan","feb","mar","apr","mai","jun","jul","aug","sep","okt","nov","des",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yyyy", + D: "d. MMMM yyyy", + F: "d. MMMM yyyy HH:mm:ss", + g: "dd.MM.yyyy HH:mm", + G: "dd.MM.yyyy HH:mm:ss", + m: "d. MMMM", + M: "d. MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.no.js b/src/cultures/kendo.culture.no.js new file mode 100644 index 00000000000..8d3aeb6be5d --- /dev/null +++ b/src/cultures/kendo.culture.no.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["no"] = { + name: "no", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "kr" + } + }, + calendars: { + standard: { + days: { + names: ["søndag","mandag","tirsdag","onsdag","torsdag","fredag","lørdag"], + namesAbbr: ["sø","ma","ti","on","to","fr","lø"], + namesShort: ["sø","ma","ti","on","to","fr","lø"] + }, + months: { + names: ["januar","februar","mars","april","mai","juni","juli","august","september","oktober","november","desember",""], + namesAbbr: ["jan","feb","mar","apr","mai","jun","jul","aug","sep","okt","nov","des",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yyyy", + D: "d. MMMM yyyy", + F: "d. MMMM yyyy HH:mm:ss", + g: "dd.MM.yyyy HH:mm", + G: "dd.MM.yyyy HH:mm:ss", + m: "d. MMMM", + M: "d. MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.nso-ZA.js b/src/cultures/kendo.culture.nso-ZA.js new file mode 100644 index 00000000000..dd4850f660b --- /dev/null +++ b/src/cultures/kendo.culture.nso-ZA.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["nso-ZA"] = { + name: "nso-ZA", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-%n","%n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$-n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "R" + } + }, + calendars: { + standard: { + days: { + names: ["Lamorena","Mošupologo","Labobedi","Laboraro","Labone","Labohlano","Mokibelo"], + namesAbbr: ["Lam","Moš","Lbb","Lbr","Lbn","Lbh","Mok"], + namesShort: ["L","M","L","L","L","L","M"] + }, + months: { + names: ["Pherekgong","Hlakola","Mopitlo","Moranang","Mosegamanye","Ngoatobošego","Phuphu","Phato","Lewedi","Diphalana","Dibatsela","Manthole",""], + namesAbbr: ["Pher","Hlak","Mop","Mor","Mos","Ngwat","Phup","Phat","Lew","Dip","Dib","Man",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "yyyy/MM/dd", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy hh:mm:ss tt", + g: "yyyy/MM/dd hh:mm tt", + G: "yyyy/MM/dd hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.nso.js b/src/cultures/kendo.culture.nso.js new file mode 100644 index 00000000000..f3839f104d2 --- /dev/null +++ b/src/cultures/kendo.culture.nso.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["nso"] = { + name: "nso", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-%n","%n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$-n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "R" + } + }, + calendars: { + standard: { + days: { + names: ["Lamorena","Mošupologo","Labobedi","Laboraro","Labone","Labohlano","Mokibelo"], + namesAbbr: ["Lam","Moš","Lbb","Lbr","Lbn","Lbh","Mok"], + namesShort: ["L","M","L","L","L","L","M"] + }, + months: { + names: ["Pherekgong","Hlakola","Mopitlo","Moranang","Mosegamanye","Ngoatobošego","Phuphu","Phato","Lewedi","Diphalana","Dibatsela","Manthole",""], + namesAbbr: ["Pher","Hlak","Mop","Mor","Mos","Ngwat","Phup","Phat","Lew","Dip","Dib","Man",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "yyyy/MM/dd", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy hh:mm:ss tt", + g: "yyyy/MM/dd hh:mm tt", + G: "yyyy/MM/dd hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.oc-FR.js b/src/cultures/kendo.culture.oc-FR.js new file mode 100644 index 00000000000..dfd31513338 --- /dev/null +++ b/src/cultures/kendo.culture.oc-FR.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["oc-FR"] = { + name: "oc-FR", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["dimenge","diluns","dimars","dimècres","dijòus","divendres","dissabte"], + namesAbbr: ["dim.","lun.","mar.","mèc.","jòu.","ven.","sab."], + namesShort: ["di","lu","ma","mè","jò","ve","sa"] + }, + months: { + names: ["genier","febrier","març","abril","mai","junh","julh","agost","setembre","octobre","novembre","desembre",""], + namesAbbr: ["gen.","feb.","mar.","abr.","mai.","jun.","jul.","ag.","set.","oct.","nov.","des.",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd/MM/yyyy", + D: "dddd,' lo 'd MMMM' de 'yyyy", + F: "dddd,' lo 'd MMMM' de 'yyyy HH:mm:ss", + g: "dd/MM/yyyy HH:mm", + G: "dd/MM/yyyy HH:mm:ss", + m: "d MMMM", + M: "d MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.oc.js b/src/cultures/kendo.culture.oc.js new file mode 100644 index 00000000000..4dbc33300fe --- /dev/null +++ b/src/cultures/kendo.culture.oc.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["oc"] = { + name: "oc", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["dimenge","diluns","dimars","dimècres","dijòus","divendres","dissabte"], + namesAbbr: ["dim.","lun.","mar.","mèc.","jòu.","ven.","sab."], + namesShort: ["di","lu","ma","mè","jò","ve","sa"] + }, + months: { + names: ["genier","febrier","març","abril","mai","junh","julh","agost","setembre","octobre","novembre","desembre",""], + namesAbbr: ["gen.","feb.","mar.","abr.","mai.","jun.","jul.","ag.","set.","oct.","nov.","des.",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd/MM/yyyy", + D: "dddd,' lo 'd MMMM' de 'yyyy", + F: "dddd,' lo 'd MMMM' de 'yyyy HH:mm:ss", + g: "dd/MM/yyyy HH:mm", + G: "dd/MM/yyyy HH:mm:ss", + m: "d MMMM", + M: "d MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.or-IN.js b/src/cultures/kendo.culture.or-IN.js new file mode 100644 index 00000000000..e3207f680c9 --- /dev/null +++ b/src/cultures/kendo.culture.or-IN.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["or-IN"] = { + name: "or-IN", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "ଟ" + } + }, + calendars: { + standard: { + days: { + names: ["ରବିବାର","ସୋମବାର","ମଙ୍ଗଳବାର","ବୁଧବାର","ଗୁରୁବାର","ଶୁକ୍ରବାର","ଶନିବାର"], + namesAbbr: ["ରବି.","ସୋମ.","ମଙ୍ଗଳ.","ବୁଧ.","ଗୁରୁ.","ଶୁକ୍ର.","ଶନି."], + namesShort: ["ର","ସୋ","ମ","ବୁ","ଗୁ","ଶୁ","ଶ"] + }, + months: { + names: ["ଜାନୁୟାରୀ","ଫ୍ରେବୃୟାରୀ","ମାର୍ଚ୍ଚ","ଏପ୍ରିଲ୍‌","ମେ","ଜୁନ୍‌","ଜୁଲାଇ","ଅଗଷ୍ଟ","ସେପ୍ଟେମ୍ବର","ଅକ୍ଟୋବର","ନଭେମ୍ବର","(ଡିସେମ୍ବର",""], + namesAbbr: ["ଜାନୁୟାରୀ","ଫ୍ରେବୃୟାରୀ","ମାର୍ଚ୍ଚ","ଏପ୍ରିଲ୍‌","ମେ","ଜୁନ୍‌","ଜୁଲାଇ","ଅଗଷ୍ଟ","ସେପ୍ଟେମ୍ବର","ଅକ୍ଟୋବର","ନଭେମ୍ବର","(ଡିସେମ୍ବର",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "dd-MM-yy", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy HH:mm:ss", + g: "dd-MM-yy HH:mm", + G: "dd-MM-yy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "-", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.or.js b/src/cultures/kendo.culture.or.js new file mode 100644 index 00000000000..8e94bac6483 --- /dev/null +++ b/src/cultures/kendo.culture.or.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["or"] = { + name: "or", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "ଟ" + } + }, + calendars: { + standard: { + days: { + names: ["ରବିବାର","ସୋମବାର","ମଙ୍ଗଳବାର","ବୁଧବାର","ଗୁରୁବାର","ଶୁକ୍ରବାର","ଶନିବାର"], + namesAbbr: ["ରବି.","ସୋମ.","ମଙ୍ଗଳ.","ବୁଧ.","ଗୁରୁ.","ଶୁକ୍ର.","ଶନି."], + namesShort: ["ର","ସୋ","ମ","ବୁ","ଗୁ","ଶୁ","ଶ"] + }, + months: { + names: ["ଜାନୁୟାରୀ","ଫ୍ରେବୃୟାରୀ","ମାର୍ଚ୍ଚ","ଏପ୍ରିଲ୍‌","ମେ","ଜୁନ୍‌","ଜୁଲାଇ","ଅଗଷ୍ଟ","ସେପ୍ଟେମ୍ବର","ଅକ୍ଟୋବର","ନଭେମ୍ବର","(ଡିସେମ୍ବର",""], + namesAbbr: ["ଜାନୁୟାରୀ","ଫ୍ରେବୃୟାରୀ","ମାର୍ଚ୍ଚ","ଏପ୍ରିଲ୍‌","ମେ","ଜୁନ୍‌","ଜୁଲାଇ","ଅଗଷ୍ଟ","ସେପ୍ଟେମ୍ବର","ଅକ୍ଟୋବର","ନଭେମ୍ବର","(ଡିସେମ୍ବର",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "dd-MM-yy", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy HH:mm:ss", + g: "dd-MM-yy HH:mm", + G: "dd-MM-yy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "-", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.pa-IN.js b/src/cultures/kendo.culture.pa-IN.js new file mode 100644 index 00000000000..8e06f7a6618 --- /dev/null +++ b/src/cultures/kendo.culture.pa-IN.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["pa-IN"] = { + name: "pa-IN", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "ਰੁ" + } + }, + calendars: { + standard: { + days: { + names: ["ਐਤਵਾਰ","ਸੋਮਵਾਰ","ਮੰਗਲਵਾਰ","ਬੁੱਧਵਾਰ","ਵੀਰਵਾਰ","ਸ਼ੁੱਕਰਵਾਰ","ਸ਼ਨਿੱਚਰਵਾਰ"], + namesAbbr: ["ਐਤ.","ਸੋਮ.","ਮੰਗਲ.","ਬੁੱਧ.","ਵੀਰ.","ਸ਼ੁਕਰ.","ਸ਼ਨਿੱਚਰ."], + namesShort: ["ਐ","ਸ","ਮ","ਬ","ਵ","ਸ਼","ਸ਼"] + }, + months: { + names: ["ਜਨਵਰੀ","ਫ਼ਰਵਰੀ","ਮਾਰਚ","ਅਪ੍ਰੈਲ","ਮਈ","ਜੂਨ","ਜੁਲਾਈ","ਅਗਸਤ","ਸਤੰਬਰ","ਅਕਤੂਬਰ","ਨਵੰਬਰ","ਦਸੰਬਰ",""], + namesAbbr: ["ਜਨਵਰੀ","ਫ਼ਰਵਰੀ","ਮਾਰਚ","ਅਪ੍ਰੈਲ","ਮਈ","ਜੂਨ","ਜੁਲਾਈ","ਅਗਸਤ","ਸਤੰਬਰ","ਅਕਤੂਬਰ","ਨਵੰਬਰ","ਦਸੰਬਰ",""] + }, + AM: ["ਸਵੇਰ","ਸਵੇਰ","ਸਵੇਰ"], + PM: ["ਸ਼ਾਮ","ਸ਼ਾਮ","ਸ਼ਾਮ"], + patterns: { + d: "dd-MM-yy", + D: "dd MMMM yyyy dddd", + F: "dd MMMM yyyy dddd tt hh:mm:ss", + g: "dd-MM-yy tt hh:mm", + G: "dd-MM-yy tt hh:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "tt hh:mm", + T: "tt hh:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "-", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.pa.js b/src/cultures/kendo.culture.pa.js new file mode 100644 index 00000000000..95bd57153a6 --- /dev/null +++ b/src/cultures/kendo.culture.pa.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["pa"] = { + name: "pa", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "ਰੁ" + } + }, + calendars: { + standard: { + days: { + names: ["ਐਤਵਾਰ","ਸੋਮਵਾਰ","ਮੰਗਲਵਾਰ","ਬੁੱਧਵਾਰ","ਵੀਰਵਾਰ","ਸ਼ੁੱਕਰਵਾਰ","ਸ਼ਨਿੱਚਰਵਾਰ"], + namesAbbr: ["ਐਤ.","ਸੋਮ.","ਮੰਗਲ.","ਬੁੱਧ.","ਵੀਰ.","ਸ਼ੁਕਰ.","ਸ਼ਨਿੱਚਰ."], + namesShort: ["ਐ","ਸ","ਮ","ਬ","ਵ","ਸ਼","ਸ਼"] + }, + months: { + names: ["ਜਨਵਰੀ","ਫ਼ਰਵਰੀ","ਮਾਰਚ","ਅਪ੍ਰੈਲ","ਮਈ","ਜੂਨ","ਜੁਲਾਈ","ਅਗਸਤ","ਸਤੰਬਰ","ਅਕਤੂਬਰ","ਨਵੰਬਰ","ਦਸੰਬਰ",""], + namesAbbr: ["ਜਨਵਰੀ","ਫ਼ਰਵਰੀ","ਮਾਰਚ","ਅਪ੍ਰੈਲ","ਮਈ","ਜੂਨ","ਜੁਲਾਈ","ਅਗਸਤ","ਸਤੰਬਰ","ਅਕਤੂਬਰ","ਨਵੰਬਰ","ਦਸੰਬਰ",""] + }, + AM: ["ਸਵੇਰ","ਸਵੇਰ","ਸਵੇਰ"], + PM: ["ਸ਼ਾਮ","ਸ਼ਾਮ","ਸ਼ਾਮ"], + patterns: { + d: "dd-MM-yy", + D: "dd MMMM yyyy dddd", + F: "dd MMMM yyyy dddd tt hh:mm:ss", + g: "dd-MM-yy tt hh:mm", + G: "dd-MM-yy tt hh:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "tt hh:mm", + T: "tt hh:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "-", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.pl-PL.js b/src/cultures/kendo.culture.pl-PL.js new file mode 100644 index 00000000000..361f60045d5 --- /dev/null +++ b/src/cultures/kendo.culture.pl-PL.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["pl-PL"] = { + name: "pl-PL", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "zł" + } + }, + calendars: { + standard: { + days: { + names: ["niedziela","poniedziałek","wtorek","środa","czwartek","piątek","sobota"], + namesAbbr: ["N","Pn","Wt","Śr","Cz","Pt","So"], + namesShort: ["N","Pn","Wt","Śr","Cz","Pt","So"] + }, + months: { + names: ["styczeń","luty","marzec","kwiecień","maj","czerwiec","lipiec","sierpień","wrzesień","październik","listopad","grudzień",""], + namesAbbr: ["sty","lut","mar","kwi","maj","cze","lip","sie","wrz","paź","lis","gru",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "yyyy-MM-dd", + D: "d MMMM yyyy", + F: "d MMMM yyyy HH:mm:ss", + g: "yyyy-MM-dd HH:mm", + G: "yyyy-MM-dd HH:mm:ss", + m: "d MMMM", + M: "d MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "-", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.pl.js b/src/cultures/kendo.culture.pl.js new file mode 100644 index 00000000000..cbb12ab3671 --- /dev/null +++ b/src/cultures/kendo.culture.pl.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["pl"] = { + name: "pl", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "zł" + } + }, + calendars: { + standard: { + days: { + names: ["niedziela","poniedziałek","wtorek","środa","czwartek","piątek","sobota"], + namesAbbr: ["N","Pn","Wt","Śr","Cz","Pt","So"], + namesShort: ["N","Pn","Wt","Śr","Cz","Pt","So"] + }, + months: { + names: ["styczeń","luty","marzec","kwiecień","maj","czerwiec","lipiec","sierpień","wrzesień","październik","listopad","grudzień",""], + namesAbbr: ["sty","lut","mar","kwi","maj","cze","lip","sie","wrz","paź","lis","gru",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "yyyy-MM-dd", + D: "d MMMM yyyy", + F: "d MMMM yyyy HH:mm:ss", + g: "yyyy-MM-dd HH:mm", + G: "yyyy-MM-dd HH:mm:ss", + m: "d MMMM", + M: "d MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "-", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.prs-AF.js b/src/cultures/kendo.culture.prs-AF.js new file mode 100644 index 00000000000..25c4ca3d08c --- /dev/null +++ b/src/cultures/kendo.culture.prs-AF.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["prs-AF"] = { + name: "prs-AF", + numberFormat: { + pattern: ["n-"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["%n-","%n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$n-","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "؋" + } + }, + calendars: { + standard: { + days: { + names: ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"], + namesAbbr: ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"], + namesShort: ["ح","ن","ث","ر","خ","ج","س"] + }, + months: { + names: ["محرم","صفر","ربيع الأول","ربيع الثاني","جمادى الأولى","جمادى الثانية","رجب","شعبان","رمضان","شوال","ذو القعدة","ذو الحجة",""], + namesAbbr: ["محرم","صفر","ربيع الأول","ربيع الثاني","جمادى الأولى","جمادى الثانية","رجب","شعبان","رمضان","شوال","ذو القعدة","ذو الحجة",""] + }, + AM: ["غ.م","غ.م","غ.م"], + PM: ["غ.و","غ.و","غ.و"], + patterns: { + d: "dd/MM/yy", + D: "dd/MM/yyyy", + F: "dd/MM/yyyy h:mm:ss tt", + g: "dd/MM/yy h:mm tt", + G: "dd/MM/yy h:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 5 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.prs.js b/src/cultures/kendo.culture.prs.js new file mode 100644 index 00000000000..729f9eb8d79 --- /dev/null +++ b/src/cultures/kendo.culture.prs.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["prs"] = { + name: "prs", + numberFormat: { + pattern: ["n-"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["%n-","%n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$n-","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "؋" + } + }, + calendars: { + standard: { + days: { + names: ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"], + namesAbbr: ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"], + namesShort: ["ح","ن","ث","ر","خ","ج","س"] + }, + months: { + names: ["محرم","صفر","ربيع الأول","ربيع الثاني","جمادى الأولى","جمادى الثانية","رجب","شعبان","رمضان","شوال","ذو القعدة","ذو الحجة",""], + namesAbbr: ["محرم","صفر","ربيع الأول","ربيع الثاني","جمادى الأولى","جمادى الثانية","رجب","شعبان","رمضان","شوال","ذو القعدة","ذو الحجة",""] + }, + AM: ["غ.م","غ.م","غ.م"], + PM: ["غ.و","غ.و","غ.و"], + patterns: { + d: "dd/MM/yy", + D: "dd/MM/yyyy", + F: "dd/MM/yyyy h:mm:ss tt", + g: "dd/MM/yy h:mm tt", + G: "dd/MM/yy h:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 5 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ps-AF.js b/src/cultures/kendo.culture.ps-AF.js new file mode 100644 index 00000000000..9378f8e0aeb --- /dev/null +++ b/src/cultures/kendo.culture.ps-AF.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ps-AF"] = { + name: "ps-AF", + numberFormat: { + pattern: ["n-"], + decimals: 2, + ",": "،", + ".": ",", + groupSize: [3], + percent: { + pattern: ["%n-","%n"], + decimals: 2, + ",": "،", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$n-","$n"], + decimals: 2, + ",": "٬", + ".": "٫", + groupSize: [3], + symbol: "؋" + } + }, + calendars: { + standard: { + days: { + names: ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"], + namesAbbr: ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"], + namesShort: ["ح","ن","ث","ر","خ","ج","س"] + }, + months: { + names: ["محرم","صفر","ربيع الأول","ربيع الثاني","جمادى الأولى","جمادى الثانية","رجب","شعبان","رمضان","شوال","ذو القعدة","ذو الحجة",""], + namesAbbr: ["محرم","صفر","ربيع الأول","ربيع الثاني","جمادى الأولى","جمادى الثانية","رجب","شعبان","رمضان","شوال","ذو القعدة","ذو الحجة",""] + }, + AM: ["غ.م","غ.م","غ.م"], + PM: ["غ.و","غ.و","غ.و"], + patterns: { + d: "dd/MM/yy", + D: "dd/MM/yyyy", + F: "dd/MM/yyyy h:mm:ss tt", + g: "dd/MM/yy h:mm tt", + G: "dd/MM/yy h:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 6 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ps.js b/src/cultures/kendo.culture.ps.js new file mode 100644 index 00000000000..7da7952dade --- /dev/null +++ b/src/cultures/kendo.culture.ps.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ps"] = { + name: "ps", + numberFormat: { + pattern: ["n-"], + decimals: 2, + ",": "،", + ".": ",", + groupSize: [3], + percent: { + pattern: ["%n-","%n"], + decimals: 2, + ",": "،", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$n-","$n"], + decimals: 2, + ",": "٬", + ".": "٫", + groupSize: [3], + symbol: "؋" + } + }, + calendars: { + standard: { + days: { + names: ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"], + namesAbbr: ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"], + namesShort: ["ح","ن","ث","ر","خ","ج","س"] + }, + months: { + names: ["محرم","صفر","ربيع الأول","ربيع الثاني","جمادى الأولى","جمادى الثانية","رجب","شعبان","رمضان","شوال","ذو القعدة","ذو الحجة",""], + namesAbbr: ["محرم","صفر","ربيع الأول","ربيع الثاني","جمادى الأولى","جمادى الثانية","رجب","شعبان","رمضان","شوال","ذو القعدة","ذو الحجة",""] + }, + AM: ["غ.م","غ.م","غ.م"], + PM: ["غ.و","غ.و","غ.و"], + patterns: { + d: "dd/MM/yy", + D: "dd/MM/yyyy", + F: "dd/MM/yyyy h:mm:ss tt", + g: "dd/MM/yy h:mm tt", + G: "dd/MM/yy h:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 6 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.pt-BR.js b/src/cultures/kendo.culture.pt-BR.js new file mode 100644 index 00000000000..7961823d3d6 --- /dev/null +++ b/src/cultures/kendo.culture.pt-BR.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["pt-BR"] = { + name: "pt-BR", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-$ n","$ n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "R$" + } + }, + calendars: { + standard: { + days: { + names: ["domingo","segunda-feira","terça-feira","quarta-feira","quinta-feira","sexta-feira","sábado"], + namesAbbr: ["dom","seg","ter","qua","qui","sex","sáb"], + namesShort: ["D","S","T","Q","Q","S","S"] + }, + months: { + names: ["janeiro","fevereiro","março","abril","maio","junho","julho","agosto","setembro","outubro","novembro","dezembro",""], + namesAbbr: ["jan","fev","mar","abr","mai","jun","jul","ago","set","out","nov","dez",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd/MM/yyyy", + D: "dddd, d' de 'MMMM' de 'yyyy", + F: "dddd, d' de 'MMMM' de 'yyyy HH:mm:ss", + g: "dd/MM/yyyy HH:mm", + G: "dd/MM/yyyy HH:mm:ss", + m: "dd' de 'MMMM", + M: "dd' de 'MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM' de 'yyyy", + Y: "MMMM' de 'yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.pt-PT.js b/src/cultures/kendo.culture.pt-PT.js new file mode 100644 index 00000000000..3ce703fb56a --- /dev/null +++ b/src/cultures/kendo.culture.pt-PT.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["pt-PT"] = { + name: "pt-PT", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["domingo","segunda-feira","terça-feira","quarta-feira","quinta-feira","sexta-feira","sábado"], + namesAbbr: ["dom","seg","ter","qua","qui","sex","sáb"], + namesShort: ["D","S","T","Q","Q","S","S"] + }, + months: { + names: ["Janeiro","Fevereiro","Março","Abril","Maio","Junho","Julho","Agosto","Setembro","Outubro","Novembro","Dezembro",""], + namesAbbr: ["Jan","Fev","Mar","Abr","Mai","Jun","Jul","Ago","Set","Out","Nov","Dez",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd-MM-yyyy", + D: "dddd, d' de 'MMMM' de 'yyyy", + F: "dddd, d' de 'MMMM' de 'yyyy HH:mm:ss", + g: "dd-MM-yyyy HH:mm", + G: "dd-MM-yyyy HH:mm:ss", + m: "d/M", + M: "d/M", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM' de 'yyyy", + Y: "MMMM' de 'yyyy" + }, + "/": "-", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.pt.js b/src/cultures/kendo.culture.pt.js new file mode 100644 index 00000000000..8bf74f7f31c --- /dev/null +++ b/src/cultures/kendo.culture.pt.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["pt"] = { + name: "pt", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-$ n","$ n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "R$" + } + }, + calendars: { + standard: { + days: { + names: ["domingo","segunda-feira","terça-feira","quarta-feira","quinta-feira","sexta-feira","sábado"], + namesAbbr: ["dom","seg","ter","qua","qui","sex","sáb"], + namesShort: ["D","S","T","Q","Q","S","S"] + }, + months: { + names: ["janeiro","fevereiro","março","abril","maio","junho","julho","agosto","setembro","outubro","novembro","dezembro",""], + namesAbbr: ["jan","fev","mar","abr","mai","jun","jul","ago","set","out","nov","dez",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd/MM/yyyy", + D: "dddd, d' de 'MMMM' de 'yyyy", + F: "dddd, d' de 'MMMM' de 'yyyy HH:mm:ss", + g: "dd/MM/yyyy HH:mm", + G: "dd/MM/yyyy HH:mm:ss", + m: "dd' de 'MMMM", + M: "dd' de 'MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM' de 'yyyy", + Y: "MMMM' de 'yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.qut-GT.js b/src/cultures/kendo.culture.qut-GT.js new file mode 100644 index 00000000000..33f13309caa --- /dev/null +++ b/src/cultures/kendo.culture.qut-GT.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["qut-GT"] = { + name: "qut-GT", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["($n)","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "Q" + } + }, + calendars: { + standard: { + days: { + names: ["juq\u0027ij","kaq\u0027ij","oxq\u0027ij","kajq\u0027ij","joq\u0027ij","waqq\u0027ij","wuqq\u0027ij"], + namesAbbr: ["juq","kaq","oxq","kajq","joq","waqq","wuqq"], + namesShort: ["ju","ka","ox","ka","jo","wa","wu"] + }, + months: { + names: ["nab\u0027e ik\u0027","ukab\u0027 ik\u0027","rox ik\u0027","ukaj ik\u0027","uro\u0027 ik\u0027","uwaq ik\u0027","uwuq ik\u0027","uwajxaq ik\u0027","ub\u0027elej ik\u0027","ulaj ik\u0027","ujulaj ik\u0027","ukab\u0027laj ik\u0027",""], + namesAbbr: ["nab\u0027e","ukab","rox","ukaj","uro","uwaq","uwuq","uwajxaq","ub\u0027elej","ulaj","ujulaj","ukab\u0027laj",""] + }, + AM: ["a.m.","a.m.","A.M."], + PM: ["p.m.","p.m.","P.M."], + patterns: { + d: "dd/MM/yyyy", + D: "dddd, dd' de 'MMMM' de 'yyyy", + F: "dddd, dd' de 'MMMM' de 'yyyy hh:mm:ss tt", + g: "dd/MM/yyyy hh:mm tt", + G: "dd/MM/yyyy hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM' de 'yyyy", + Y: "MMMM' de 'yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.qut.js b/src/cultures/kendo.culture.qut.js new file mode 100644 index 00000000000..59453aaca9d --- /dev/null +++ b/src/cultures/kendo.culture.qut.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["qut"] = { + name: "qut", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["($n)","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "Q" + } + }, + calendars: { + standard: { + days: { + names: ["juq\u0027ij","kaq\u0027ij","oxq\u0027ij","kajq\u0027ij","joq\u0027ij","waqq\u0027ij","wuqq\u0027ij"], + namesAbbr: ["juq","kaq","oxq","kajq","joq","waqq","wuqq"], + namesShort: ["ju","ka","ox","ka","jo","wa","wu"] + }, + months: { + names: ["nab\u0027e ik\u0027","ukab\u0027 ik\u0027","rox ik\u0027","ukaj ik\u0027","uro\u0027 ik\u0027","uwaq ik\u0027","uwuq ik\u0027","uwajxaq ik\u0027","ub\u0027elej ik\u0027","ulaj ik\u0027","ujulaj ik\u0027","ukab\u0027laj ik\u0027",""], + namesAbbr: ["nab\u0027e","ukab","rox","ukaj","uro","uwaq","uwuq","uwajxaq","ub\u0027elej","ulaj","ujulaj","ukab\u0027laj",""] + }, + AM: ["a.m.","a.m.","A.M."], + PM: ["p.m.","p.m.","P.M."], + patterns: { + d: "dd/MM/yyyy", + D: "dddd, dd' de 'MMMM' de 'yyyy", + F: "dddd, dd' de 'MMMM' de 'yyyy hh:mm:ss tt", + g: "dd/MM/yyyy hh:mm tt", + G: "dd/MM/yyyy hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM' de 'yyyy", + Y: "MMMM' de 'yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.quz-BO.js b/src/cultures/kendo.culture.quz-BO.js new file mode 100644 index 00000000000..bec14a6eb56 --- /dev/null +++ b/src/cultures/kendo.culture.quz-BO.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["quz-BO"] = { + name: "quz-BO", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-%n","%n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["($ n)","$ n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "$b" + } + }, + calendars: { + standard: { + days: { + names: ["intichaw","killachaw","atipachaw","quyllurchaw","Ch\u0027 askachaw","Illapachaw","k\u0027uychichaw"], + namesAbbr: ["int","kil","ati","quy","Ch\u0027","Ill","k\u0027u"], + namesShort: ["d","k","a","m","h","b","k"] + }, + months: { + names: ["Qulla puquy","Hatun puquy","Pauqar waray","ayriwa","Aymuray","Inti raymi","Anta Sitwa","Qhapaq Sitwa","Uma raymi","Kantaray","Ayamarq\u0027a","Kapaq Raymi",""], + namesAbbr: ["Qul","Hat","Pau","ayr","Aym","Int","Ant","Qha","Uma","Kan","Aya","Kap",""] + }, + AM: ["a.m.","a.m.","A.M."], + PM: ["p.m.","p.m.","P.M."], + patterns: { + d: "dd/MM/yyyy", + D: "dddd, dd' de 'MMMM' de 'yyyy", + F: "dddd, dd' de 'MMMM' de 'yyyy hh:mm:ss tt", + g: "dd/MM/yyyy hh:mm tt", + G: "dd/MM/yyyy hh:mm:ss tt", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM' de 'yyyy", + Y: "MMMM' de 'yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.quz-EC.js b/src/cultures/kendo.culture.quz-EC.js new file mode 100644 index 00000000000..b841014283f --- /dev/null +++ b/src/cultures/kendo.culture.quz-EC.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["quz-EC"] = { + name: "quz-EC", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-%n","%n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["($ n)","$ n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "$" + } + }, + calendars: { + standard: { + days: { + names: ["intichaw","killachaw","atipachaw","quyllurchaw","Ch\u0027 askachaw","Illapachaw","k\u0027uychichaw"], + namesAbbr: ["int","kil","ati","quy","Ch\u0027","Ill","k\u0027u"], + namesShort: ["d","k","a","m","h","b","k"] + }, + months: { + names: ["Qulla puquy","Hatun puquy","Pauqar waray","ayriwa","Aymuray","Inti raymi","Anta Sitwa","Qhapaq Sitwa","Uma raymi","Kantaray","Ayamarq\u0027a","Kapaq Raymi",""], + namesAbbr: ["Qul","Hat","Pau","ayr","Aym","Int","Ant","Qha","Uma","Kan","Aya","Kap",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd/MM/yyyy", + D: "dddd, dd' de 'MMMM' de 'yyyy", + F: "dddd, dd' de 'MMMM' de 'yyyy H:mm:ss", + g: "dd/MM/yyyy H:mm", + G: "dd/MM/yyyy H:mm:ss", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM' de 'yyyy", + Y: "MMMM' de 'yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.quz-PE.js b/src/cultures/kendo.culture.quz-PE.js new file mode 100644 index 00000000000..f289fdcf429 --- /dev/null +++ b/src/cultures/kendo.culture.quz-PE.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["quz-PE"] = { + name: "quz-PE", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-%n","%n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "S/." + } + }, + calendars: { + standard: { + days: { + names: ["intichaw","killachaw","atipachaw","quyllurchaw","Ch\u0027 askachaw","Illapachaw","k\u0027uychichaw"], + namesAbbr: ["int","kil","ati","quy","Ch\u0027","Ill","k\u0027u"], + namesShort: ["d","k","a","m","h","b","k"] + }, + months: { + names: ["Qulla puquy","Hatun puquy","Pauqar waray","ayriwa","Aymuray","Inti raymi","Anta Sitwa","Qhapaq Sitwa","Uma raymi","Kantaray","Ayamarq\u0027a","Kapaq Raymi",""], + namesAbbr: ["Qul","Hat","Pau","ayr","Aym","Int","Ant","Qha","Uma","Kan","Aya","Kap",""] + }, + AM: ["a.m.","a.m.","A.M."], + PM: ["p.m.","p.m.","P.M."], + patterns: { + d: "dd/MM/yyyy", + D: "dddd, dd' de 'MMMM' de 'yyyy", + F: "dddd, dd' de 'MMMM' de 'yyyy hh:mm:ss tt", + g: "dd/MM/yyyy hh:mm tt", + G: "dd/MM/yyyy hh:mm:ss tt", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM' de 'yyyy", + Y: "MMMM' de 'yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.quz.js b/src/cultures/kendo.culture.quz.js new file mode 100644 index 00000000000..86ea196d13f --- /dev/null +++ b/src/cultures/kendo.culture.quz.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["quz"] = { + name: "quz", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-%n","%n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["($ n)","$ n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "$b" + } + }, + calendars: { + standard: { + days: { + names: ["intichaw","killachaw","atipachaw","quyllurchaw","Ch\u0027 askachaw","Illapachaw","k\u0027uychichaw"], + namesAbbr: ["int","kil","ati","quy","Ch\u0027","Ill","k\u0027u"], + namesShort: ["d","k","a","m","h","b","k"] + }, + months: { + names: ["Qulla puquy","Hatun puquy","Pauqar waray","ayriwa","Aymuray","Inti raymi","Anta Sitwa","Qhapaq Sitwa","Uma raymi","Kantaray","Ayamarq\u0027a","Kapaq Raymi",""], + namesAbbr: ["Qul","Hat","Pau","ayr","Aym","Int","Ant","Qha","Uma","Kan","Aya","Kap",""] + }, + AM: ["a.m.","a.m.","A.M."], + PM: ["p.m.","p.m.","P.M."], + patterns: { + d: "dd/MM/yyyy", + D: "dddd, dd' de 'MMMM' de 'yyyy", + F: "dddd, dd' de 'MMMM' de 'yyyy hh:mm:ss tt", + g: "dd/MM/yyyy hh:mm tt", + G: "dd/MM/yyyy hh:mm:ss tt", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM' de 'yyyy", + Y: "MMMM' de 'yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.rm-CH.js b/src/cultures/kendo.culture.rm-CH.js new file mode 100644 index 00000000000..d193cd611ea --- /dev/null +++ b/src/cultures/kendo.culture.rm-CH.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["rm-CH"] = { + name: "rm-CH", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": "'", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": "'", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$-n","$ n"], + decimals: 2, + ",": "'", + ".": ".", + groupSize: [3], + symbol: "fr." + } + }, + calendars: { + standard: { + days: { + names: ["dumengia","glindesdi","mardi","mesemna","gievgia","venderdi","sonda"], + namesAbbr: ["du","gli","ma","me","gie","ve","so"], + namesShort: ["du","gli","ma","me","gie","ve","so"] + }, + months: { + names: ["schaner","favrer","mars","avrigl","matg","zercladur","fanadur","avust","settember","october","november","december",""], + namesAbbr: ["schan","favr","mars","avr","matg","zercl","fan","avust","sett","oct","nov","dec",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd/MM/yyyy", + D: "dddd, d MMMM yyyy", + F: "dddd, d MMMM yyyy HH:mm:ss", + g: "dd/MM/yyyy HH:mm", + G: "dd/MM/yyyy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.rm.js b/src/cultures/kendo.culture.rm.js new file mode 100644 index 00000000000..11c1acd2aeb --- /dev/null +++ b/src/cultures/kendo.culture.rm.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["rm"] = { + name: "rm", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": "'", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": "'", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$-n","$ n"], + decimals: 2, + ",": "'", + ".": ".", + groupSize: [3], + symbol: "fr." + } + }, + calendars: { + standard: { + days: { + names: ["dumengia","glindesdi","mardi","mesemna","gievgia","venderdi","sonda"], + namesAbbr: ["du","gli","ma","me","gie","ve","so"], + namesShort: ["du","gli","ma","me","gie","ve","so"] + }, + months: { + names: ["schaner","favrer","mars","avrigl","matg","zercladur","fanadur","avust","settember","october","november","december",""], + namesAbbr: ["schan","favr","mars","avr","matg","zercl","fan","avust","sett","oct","nov","dec",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd/MM/yyyy", + D: "dddd, d MMMM yyyy", + F: "dddd, d MMMM yyyy HH:mm:ss", + g: "dd/MM/yyyy HH:mm", + G: "dd/MM/yyyy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ro-RO.js b/src/cultures/kendo.culture.ro-RO.js new file mode 100644 index 00000000000..41538d3cc3b --- /dev/null +++ b/src/cultures/kendo.culture.ro-RO.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ro-RO"] = { + name: "ro-RO", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "lei" + } + }, + calendars: { + standard: { + days: { + names: ["duminică","luni","marţi","miercuri","joi","vineri","sâmbătă"], + namesAbbr: ["D","L","Ma","Mi","J","V","S"], + namesShort: ["D","L","Ma","Mi","J","V","S"] + }, + months: { + names: ["ianuarie","februarie","martie","aprilie","mai","iunie","iulie","august","septembrie","octombrie","noiembrie","decembrie",""], + namesAbbr: ["ian.","feb.","mar.","apr.","mai.","iun.","iul.","aug.","sep.","oct.","nov.","dec.",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yyyy", + D: "d MMMM yyyy", + F: "d MMMM yyyy HH:mm:ss", + g: "dd.MM.yyyy HH:mm", + G: "dd.MM.yyyy HH:mm:ss", + m: "d MMMM", + M: "d MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ro.js b/src/cultures/kendo.culture.ro.js new file mode 100644 index 00000000000..4701c92ceed --- /dev/null +++ b/src/cultures/kendo.culture.ro.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ro"] = { + name: "ro", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "lei" + } + }, + calendars: { + standard: { + days: { + names: ["duminică","luni","marţi","miercuri","joi","vineri","sâmbătă"], + namesAbbr: ["D","L","Ma","Mi","J","V","S"], + namesShort: ["D","L","Ma","Mi","J","V","S"] + }, + months: { + names: ["ianuarie","februarie","martie","aprilie","mai","iunie","iulie","august","septembrie","octombrie","noiembrie","decembrie",""], + namesAbbr: ["ian.","feb.","mar.","apr.","mai.","iun.","iul.","aug.","sep.","oct.","nov.","dec.",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yyyy", + D: "d MMMM yyyy", + F: "d MMMM yyyy HH:mm:ss", + g: "dd.MM.yyyy HH:mm", + G: "dd.MM.yyyy HH:mm:ss", + m: "d MMMM", + M: "d MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ru-RU.js b/src/cultures/kendo.culture.ru-RU.js new file mode 100644 index 00000000000..f8bedb7d1cc --- /dev/null +++ b/src/cultures/kendo.culture.ru-RU.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ru-RU"] = { + name: "ru-RU", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n$","n$"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "р." + } + }, + calendars: { + standard: { + days: { + names: ["воскресенье","понедельник","вторник","среда","четверг","пятница","суббота"], + namesAbbr: ["Вс","Пн","Вт","Ср","Чт","Пт","Сб"], + namesShort: ["Вс","Пн","Вт","Ср","Чт","Пт","Сб"] + }, + months: { + names: ["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь",""], + namesAbbr: ["янв","фев","мар","апр","май","июн","июл","авг","сен","окт","ноя","дек",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yyyy", + D: "d MMMM yyyy 'г.'", + F: "d MMMM yyyy 'г.' H:mm:ss", + g: "dd.MM.yyyy H:mm", + G: "dd.MM.yyyy H:mm:ss", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ru-UA.js b/src/cultures/kendo.culture.ru-UA.js new file mode 100644 index 00000000000..caac6c16797 --- /dev/null +++ b/src/cultures/kendo.culture.ru-UA.js @@ -0,0 +1,70 @@ +/* +* Kendo UI Web v2012.1.322 (http://kendoui.com) +* Copyright 2012 Telerik AD. All rights reserved. +* +* Kendo UI Web commercial licenses may be obtained at http://kendoui.com/web-license +* If you do not own a commercial license, this file shall be governed by the +* GNU General Public License (GPL) version 3. +* For GPL requirements, please review: http://www.gnu.org/copyleft/gpl.html +*/ +(function( window, undefined ) { + kendo.cultures["ru-UA"] = { + name: "ru-UA", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n$","n$"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "₴" + } + }, + calendars: { + standard: { + days: { + names: ["воскресенье","понедельник","вторник","среда","четверг","пятница","суббота"], + namesAbbr: ["Вс","Пн","Вт","Ср","Чт","Пт","Сб"], + namesShort: ["Вс","Пн","Вт","Ср","Чт","Пт","Сб"] + }, + months: { + names: ["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь",""], + namesAbbr: ["янв","фев","мар","апр","май","июн","июл","авг","сен","окт","ноя","дек",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yyyy", + D: "d MMMM yyyy 'г.'", + F: "d MMMM yyyy 'г.' H:mm:ss", + g: "dd.MM.yyyy H:mm", + G: "dd.MM.yyyy H:mm:ss", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ru.js b/src/cultures/kendo.culture.ru.js new file mode 100644 index 00000000000..ea399df1968 --- /dev/null +++ b/src/cultures/kendo.culture.ru.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ru"] = { + name: "ru", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n$","n$"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "р." + } + }, + calendars: { + standard: { + days: { + names: ["воскресенье","понедельник","вторник","среда","четверг","пятница","суббота"], + namesAbbr: ["Вс","Пн","Вт","Ср","Чт","Пт","Сб"], + namesShort: ["Вс","Пн","Вт","Ср","Чт","Пт","Сб"] + }, + months: { + names: ["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь",""], + namesAbbr: ["янв","фев","мар","апр","май","июн","июл","авг","сен","окт","ноя","дек",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yyyy", + D: "d MMMM yyyy 'г.'", + F: "d MMMM yyyy 'г.' H:mm:ss", + g: "dd.MM.yyyy H:mm", + G: "dd.MM.yyyy H:mm:ss", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.rw-RW.js b/src/cultures/kendo.culture.rw-RW.js new file mode 100644 index 00000000000..3df2f940941 --- /dev/null +++ b/src/cultures/kendo.culture.rw-RW.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["rw-RW"] = { + name: "rw-RW", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$-n","$ n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "RWF" + } + }, + calendars: { + standard: { + days: { + names: ["Ku wa mbere","Ku wa kabiri","Ku wa gatatu","Ku wa kane","Ku wa gatanu","Ku wa gatandatu","Ku cyumweru"], + namesAbbr: ["mbe.","kab.","gat.","kan.","gat.","gat.","cyu."], + namesShort: ["mb","ka","ga","ka","ga","ga","cy"] + }, + months: { + names: ["Mutarama","Gashyantare","Werurwe","Mata","Gicurasi","Kamena","Nyakanga","Kanama","Nzeli","Ukwakira","Ugushyingo","Ukuboza",""], + namesAbbr: ["Mut","Gas","Wer","Mat","Gic","Kam","Nya","Kan","Nze","Ukwa","Ugu","Uku",""] + }, + AM: ["saa moya z.m.","saa moya z.m.","SAA MOYA Z.M."], + PM: ["saa moya z.n.","saa moya z.n.","SAA MOYA Z.N."], + patterns: { + d: "M/d/yyyy", + D: "dddd, MMMM dd, yyyy", + F: "dddd, MMMM dd, yyyy h:mm:ss tt", + g: "M/d/yyyy h:mm tt", + G: "M/d/yyyy h:mm:ss tt", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.rw.js b/src/cultures/kendo.culture.rw.js new file mode 100644 index 00000000000..f59595bba94 --- /dev/null +++ b/src/cultures/kendo.culture.rw.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["rw"] = { + name: "rw", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$-n","$ n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "RWF" + } + }, + calendars: { + standard: { + days: { + names: ["Ku wa mbere","Ku wa kabiri","Ku wa gatatu","Ku wa kane","Ku wa gatanu","Ku wa gatandatu","Ku cyumweru"], + namesAbbr: ["mbe.","kab.","gat.","kan.","gat.","gat.","cyu."], + namesShort: ["mb","ka","ga","ka","ga","ga","cy"] + }, + months: { + names: ["Mutarama","Gashyantare","Werurwe","Mata","Gicurasi","Kamena","Nyakanga","Kanama","Nzeli","Ukwakira","Ugushyingo","Ukuboza",""], + namesAbbr: ["Mut","Gas","Wer","Mat","Gic","Kam","Nya","Kan","Nze","Ukwa","Ugu","Uku",""] + }, + AM: ["saa moya z.m.","saa moya z.m.","SAA MOYA Z.M."], + PM: ["saa moya z.n.","saa moya z.n.","SAA MOYA Z.N."], + patterns: { + d: "M/d/yyyy", + D: "dddd, MMMM dd, yyyy", + F: "dddd, MMMM dd, yyyy h:mm:ss tt", + g: "M/d/yyyy h:mm tt", + G: "M/d/yyyy h:mm:ss tt", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.sa-IN.js b/src/cultures/kendo.culture.sa-IN.js new file mode 100644 index 00000000000..7def77e6f5f --- /dev/null +++ b/src/cultures/kendo.culture.sa-IN.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["sa-IN"] = { + name: "sa-IN", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "रु" + } + }, + calendars: { + standard: { + days: { + names: ["रविवासरः","सोमवासरः","मङ्गलवासरः","बुधवासरः","गुरुवासरः","शुक्रवासरः","शनिवासरः"], + namesAbbr: ["रविवासरः","सोमवासरः","मङ्गलवासरः","बुधवासरः","गुरुवासरः","शुक्रवासरः","शनिवासरः"], + namesShort: ["र","स","म","ब","ग","श","श"] + }, + months: { + names: ["जनवरी","फरवरी","मार्च","अप्रैल","मई","जून","जुलाई","अगस्त","सितम्बर","अक्तूबर","नवम्बर","दिसम्बर",""], + namesAbbr: ["जनवरी","फरवरी","मार्च","अप्रैल","मई","जून","जुलाई","अगस्त","सितम्बर","अक्तूबर","नवम्बर","दिसम्बर",""] + }, + AM: ["पूर्वाह्न","पूर्वाह्न","पूर्वाह्न"], + PM: ["अपराह्न","अपराह्न","अपराह्न"], + patterns: { + d: "dd-MM-yyyy", + D: "dd MMMM yyyy dddd", + F: "dd MMMM yyyy dddd HH:mm:ss", + g: "dd-MM-yyyy HH:mm", + G: "dd-MM-yyyy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "-", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.sa.js b/src/cultures/kendo.culture.sa.js new file mode 100644 index 00000000000..0849e4e991d --- /dev/null +++ b/src/cultures/kendo.culture.sa.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["sa"] = { + name: "sa", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "रु" + } + }, + calendars: { + standard: { + days: { + names: ["रविवासरः","सोमवासरः","मङ्गलवासरः","बुधवासरः","गुरुवासरः","शुक्रवासरः","शनिवासरः"], + namesAbbr: ["रविवासरः","सोमवासरः","मङ्गलवासरः","बुधवासरः","गुरुवासरः","शुक्रवासरः","शनिवासरः"], + namesShort: ["र","स","म","ब","ग","श","श"] + }, + months: { + names: ["जनवरी","फरवरी","मार्च","अप्रैल","मई","जून","जुलाई","अगस्त","सितम्बर","अक्तूबर","नवम्बर","दिसम्बर",""], + namesAbbr: ["जनवरी","फरवरी","मार्च","अप्रैल","मई","जून","जुलाई","अगस्त","सितम्बर","अक्तूबर","नवम्बर","दिसम्बर",""] + }, + AM: ["पूर्वाह्न","पूर्वाह्न","पूर्वाह्न"], + PM: ["अपराह्न","अपराह्न","अपराह्न"], + patterns: { + d: "dd-MM-yyyy", + D: "dd MMMM yyyy dddd", + F: "dd MMMM yyyy dddd HH:mm:ss", + g: "dd-MM-yyyy HH:mm", + G: "dd-MM-yyyy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "-", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.sah-RU.js b/src/cultures/kendo.culture.sah-RU.js new file mode 100644 index 00000000000..60297d50e64 --- /dev/null +++ b/src/cultures/kendo.culture.sah-RU.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["sah-RU"] = { + name: "sah-RU", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n$","n$"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "с." + } + }, + calendars: { + standard: { + days: { + names: ["баскыһыанньа","бэнидиэнньик","оптуорунньук","сэрэдэ","чэппиэр","бээтинсэ","субуота"], + namesAbbr: ["Бс","Бн","Оп","Ср","Чп","Бт","Сб"], + namesShort: ["Бс","Бн","Оп","Ср","Чп","Бт","Сб"] + }, + months: { + names: ["Тохсунньу","Олунньу","Кулун тутар","Муус устар","Ыам ыйа","Бэс ыйа","От ыйа","Атырдьах ыйа","Балаҕан ыйа","Алтынньы","Сэтинньи","Ахсынньы",""], + namesAbbr: ["тхс","олн","кул","мст","ыам","бэс","отй","атр","блҕ","алт","стн","ахс",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "MM.dd.yyyy", + D: "MMMM d yyyy 'с.'", + F: "MMMM d yyyy 'с.' H:mm:ss", + g: "MM.dd.yyyy H:mm", + G: "MM.dd.yyyy H:mm:ss", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy 'с.'", + Y: "MMMM yyyy 'с.'" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.sah.js b/src/cultures/kendo.culture.sah.js new file mode 100644 index 00000000000..acf0b7c341f --- /dev/null +++ b/src/cultures/kendo.culture.sah.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["sah"] = { + name: "sah", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n$","n$"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "с." + } + }, + calendars: { + standard: { + days: { + names: ["баскыһыанньа","бэнидиэнньик","оптуорунньук","сэрэдэ","чэппиэр","бээтинсэ","субуота"], + namesAbbr: ["Бс","Бн","Оп","Ср","Чп","Бт","Сб"], + namesShort: ["Бс","Бн","Оп","Ср","Чп","Бт","Сб"] + }, + months: { + names: ["Тохсунньу","Олунньу","Кулун тутар","Муус устар","Ыам ыйа","Бэс ыйа","От ыйа","Атырдьах ыйа","Балаҕан ыйа","Алтынньы","Сэтинньи","Ахсынньы",""], + namesAbbr: ["тхс","олн","кул","мст","ыам","бэс","отй","атр","блҕ","алт","стн","ахс",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "MM.dd.yyyy", + D: "MMMM d yyyy 'с.'", + F: "MMMM d yyyy 'с.' H:mm:ss", + g: "MM.dd.yyyy H:mm", + G: "MM.dd.yyyy H:mm:ss", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy 'с.'", + Y: "MMMM yyyy 'с.'" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.se-FI.js b/src/cultures/kendo.culture.se-FI.js new file mode 100644 index 00000000000..426fc8df84e --- /dev/null +++ b/src/cultures/kendo.culture.se-FI.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["se-FI"] = { + name: "se-FI", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["sotnabeaivi","vuossárga","maŋŋebárga","gaskavahkku","duorastat","bearjadat","lávvardat"], + namesAbbr: ["sotn","vuos","maŋ","gask","duor","bear","láv"], + namesShort: ["s","m","d","g","d","b","l"] + }, + months: { + names: ["ođđajagemánnu","guovvamánnu","njukčamánnu","cuoŋománnu","miessemánnu","geassemánnu","suoidnemánnu","borgemánnu","čakčamánnu","golggotmánnu","skábmamánnu","juovlamánnu",""], + namesAbbr: ["ođđj","guov","njuk","cuo","mies","geas","suoi","borg","čakč","golg","skáb","juov",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "d.M.yyyy", + D: "MMMM d'. b. 'yyyy", + F: "MMMM d'. b. 'yyyy H:mm:ss", + g: "d.M.yyyy H:mm", + G: "d.M.yyyy H:mm:ss", + m: "MMMM d'. b. '", + M: "MMMM d'. b. '", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.se-NO.js b/src/cultures/kendo.culture.se-NO.js new file mode 100644 index 00000000000..f5cc36eaccf --- /dev/null +++ b/src/cultures/kendo.culture.se-NO.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["se-NO"] = { + name: "se-NO", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-%n","%n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "kr" + } + }, + calendars: { + standard: { + days: { + names: ["sotnabeaivi","vuossárga","maŋŋebárga","gaskavahkku","duorastat","bearjadat","lávvardat"], + namesAbbr: ["sotn","vuos","maŋ","gask","duor","bear","láv"], + namesShort: ["s","m","d","g","d","b","l"] + }, + months: { + names: ["ođđajagemánnu","guovvamánnu","njukčamánnu","cuoŋománnu","miessemánnu","geassemánnu","suoidnemánnu","borgemánnu","čakčamánnu","golggotmánnu","skábmamánnu","juovlamánnu",""], + namesAbbr: ["ođđj","guov","njuk","cuo","mies","geas","suoi","borg","čakč","golg","skáb","juov",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yyyy", + D: "MMMM d'. b. 'yyyy", + F: "MMMM d'. b. 'yyyy HH:mm:ss", + g: "dd.MM.yyyy HH:mm", + G: "dd.MM.yyyy HH:mm:ss", + m: "MMMM d'. b. '", + M: "MMMM d'. b. '", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.se-SE.js b/src/cultures/kendo.culture.se-SE.js new file mode 100644 index 00000000000..3b804fdb679 --- /dev/null +++ b/src/cultures/kendo.culture.se-SE.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["se-SE"] = { + name: "se-SE", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "kr" + } + }, + calendars: { + standard: { + days: { + names: ["sotnabeaivi","mánnodat","disdat","gaskavahkku","duorastat","bearjadat","lávvardat"], + namesAbbr: ["sotn","mán","dis","gask","duor","bear","láv"], + namesShort: ["s","m","d","g","d","b","l"] + }, + months: { + names: ["ođđajagemánnu","guovvamánnu","njukčamánnu","cuoŋománnu","miessemánnu","geassemánnu","suoidnemánnu","borgemánnu","čakčamánnu","golggotmánnu","skábmamánnu","juovlamánnu",""], + namesAbbr: ["ođđj","guov","njuk","cuo","mies","geas","suoi","borg","čakč","golg","skáb","juov",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "yyyy-MM-dd", + D: "MMMM d'. b. 'yyyy", + F: "MMMM d'. b. 'yyyy HH:mm:ss", + g: "yyyy-MM-dd HH:mm", + G: "yyyy-MM-dd HH:mm:ss", + m: "MMMM d'. b. '", + M: "MMMM d'. b. '", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "-", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.se.js b/src/cultures/kendo.culture.se.js new file mode 100644 index 00000000000..18e6b50ea57 --- /dev/null +++ b/src/cultures/kendo.culture.se.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["se"] = { + name: "se", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-%n","%n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "kr" + } + }, + calendars: { + standard: { + days: { + names: ["sotnabeaivi","vuossárga","maŋŋebárga","gaskavahkku","duorastat","bearjadat","lávvardat"], + namesAbbr: ["sotn","vuos","maŋ","gask","duor","bear","láv"], + namesShort: ["s","m","d","g","d","b","l"] + }, + months: { + names: ["ođđajagemánnu","guovvamánnu","njukčamánnu","cuoŋománnu","miessemánnu","geassemánnu","suoidnemánnu","borgemánnu","čakčamánnu","golggotmánnu","skábmamánnu","juovlamánnu",""], + namesAbbr: ["ođđj","guov","njuk","cuo","mies","geas","suoi","borg","čakč","golg","skáb","juov",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yyyy", + D: "MMMM d'. b. 'yyyy", + F: "MMMM d'. b. 'yyyy HH:mm:ss", + g: "dd.MM.yyyy HH:mm", + G: "dd.MM.yyyy HH:mm:ss", + m: "MMMM d'. b. '", + M: "MMMM d'. b. '", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.si-LK.js b/src/cultures/kendo.culture.si-LK.js new file mode 100644 index 00000000000..01e830f2e59 --- /dev/null +++ b/src/cultures/kendo.culture.si-LK.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["si-LK"] = { + name: "si-LK", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "%" + }, + currency: { + pattern: ["($ n)","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "රු." + } + }, + calendars: { + standard: { + days: { + names: ["ඉරිදා","සඳුදා","අඟහරුවාදා","බදාදා","බ්‍රහස්පතින්දා","සිකුරාදා","සෙනසුරාදා"], + namesAbbr: ["ඉරිදා","සඳුදා","කුජදා","බුදදා","ගුරුදා","කිවිදා","ශනිදා"], + namesShort: ["ඉ","ස","අ","බ","බ්‍ර","සි","සෙ"] + }, + months: { + names: ["ජනවාරි","පෙබරවාරි","මාර්තු","අ‌ප්‍රේල්","මැයි","ජූනි","ජූලි","අ‌ගෝස්තු","සැප්තැම්බර්","ඔක්තෝබර්","නොවැම්බර්","දෙසැම්බර්",""], + namesAbbr: ["ජන.","පෙබ.","මාර්තු.","අප්‍රේල්.","මැයි.","ජූනි.","ජූලි.","අගෝ.","සැප්.","ඔක්.","නොවැ.","දෙසැ.",""] + }, + AM: ["පෙ.ව.","පෙ.ව.","පෙ.ව."], + PM: ["ප.ව.","ප.ව.","ප.ව."], + patterns: { + d: "yyyy-MM-dd", + D: "yyyy MMMM' මස 'dd' වැනිදා 'dddd", + F: "yyyy MMMM' මස 'dd' වැනිදා 'dddd h:mm:ss tt", + g: "yyyy-MM-dd h:mm tt", + G: "yyyy-MM-dd h:mm:ss tt", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "yyyy MMMM", + Y: "yyyy MMMM" + }, + "/": "-", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.si.js b/src/cultures/kendo.culture.si.js new file mode 100644 index 00000000000..230011a5554 --- /dev/null +++ b/src/cultures/kendo.culture.si.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["si"] = { + name: "si", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "%" + }, + currency: { + pattern: ["($ n)","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "රු." + } + }, + calendars: { + standard: { + days: { + names: ["ඉරිදා","සඳුදා","අඟහරුවාදා","බදාදා","බ්‍රහස්පතින්දා","සිකුරාදා","සෙනසුරාදා"], + namesAbbr: ["ඉරිදා","සඳුදා","කුජදා","බුදදා","ගුරුදා","කිවිදා","ශනිදා"], + namesShort: ["ඉ","ස","අ","බ","බ්‍ර","සි","සෙ"] + }, + months: { + names: ["ජනවාරි","පෙබරවාරි","මාර්තු","අ‌ප්‍රේල්","මැයි","ජූනි","ජූලි","අ‌ගෝස්තු","සැප්තැම්බර්","ඔක්තෝබර්","නොවැම්බර්","දෙසැම්බර්",""], + namesAbbr: ["ජන.","පෙබ.","මාර්තු.","අප්‍රේල්.","මැයි.","ජූනි.","ජූලි.","අගෝ.","සැප්.","ඔක්.","නොවැ.","දෙසැ.",""] + }, + AM: ["පෙ.ව.","පෙ.ව.","පෙ.ව."], + PM: ["ප.ව.","ප.ව.","ප.ව."], + patterns: { + d: "yyyy-MM-dd", + D: "yyyy MMMM' මස 'dd' වැනිදා 'dddd", + F: "yyyy MMMM' මස 'dd' වැනිදා 'dddd h:mm:ss tt", + g: "yyyy-MM-dd h:mm tt", + G: "yyyy-MM-dd h:mm:ss tt", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "yyyy MMMM", + Y: "yyyy MMMM" + }, + "/": "-", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.sk-SK.js b/src/cultures/kendo.culture.sk-SK.js new file mode 100644 index 00000000000..45f17dfe4ff --- /dev/null +++ b/src/cultures/kendo.culture.sk-SK.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["sk-SK"] = { + name: "sk-SK", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["nedeľa","pondelok","utorok","streda","štvrtok","piatok","sobota"], + namesAbbr: ["ne","po","ut","st","št","pi","so"], + namesShort: ["ne","po","ut","st","št","pi","so"] + }, + months: { + names: ["január","február","marec","apríl","máj","jún","júl","august","september","október","november","december",""], + namesAbbr: ["1","2","3","4","5","6","7","8","9","10","11","12",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "d. M. yyyy", + D: "d. MMMM yyyy", + F: "d. MMMM yyyy H:mm:ss", + g: "d. M. yyyy H:mm", + G: "d. M. yyyy H:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ". ", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.sk.js b/src/cultures/kendo.culture.sk.js new file mode 100644 index 00000000000..a0060eaa78f --- /dev/null +++ b/src/cultures/kendo.culture.sk.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["sk"] = { + name: "sk", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["nedeľa","pondelok","utorok","streda","štvrtok","piatok","sobota"], + namesAbbr: ["ne","po","ut","st","št","pi","so"], + namesShort: ["ne","po","ut","st","št","pi","so"] + }, + months: { + names: ["január","február","marec","apríl","máj","jún","júl","august","september","október","november","december",""], + namesAbbr: ["1","2","3","4","5","6","7","8","9","10","11","12",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "d. M. yyyy", + D: "d. MMMM yyyy", + F: "d. MMMM yyyy H:mm:ss", + g: "d. M. yyyy H:mm", + G: "d. M. yyyy H:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ". ", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.sl-SI.js b/src/cultures/kendo.culture.sl-SI.js new file mode 100644 index 00000000000..b72434e80d1 --- /dev/null +++ b/src/cultures/kendo.culture.sl-SI.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["sl-SI"] = { + name: "sl-SI", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["nedelja","ponedeljek","torek","sreda","četrtek","petek","sobota"], + namesAbbr: ["ned","pon","tor","sre","čet","pet","sob"], + namesShort: ["ne","po","to","sr","če","pe","so"] + }, + months: { + names: ["januar","februar","marec","april","maj","junij","julij","avgust","september","oktober","november","december",""], + namesAbbr: ["jan","feb","mar","apr","maj","jun","jul","avg","sep","okt","nov","dec",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "d.M.yyyy", + D: "d. MMMM yyyy", + F: "d. MMMM yyyy H:mm:ss", + g: "d.M.yyyy H:mm", + G: "d.M.yyyy H:mm:ss", + m: "d. MMMM", + M: "d. MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.sl.js b/src/cultures/kendo.culture.sl.js new file mode 100644 index 00000000000..72310557e88 --- /dev/null +++ b/src/cultures/kendo.culture.sl.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["sl"] = { + name: "sl", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["nedelja","ponedeljek","torek","sreda","četrtek","petek","sobota"], + namesAbbr: ["ned","pon","tor","sre","čet","pet","sob"], + namesShort: ["ne","po","to","sr","če","pe","so"] + }, + months: { + names: ["januar","februar","marec","april","maj","junij","julij","avgust","september","oktober","november","december",""], + namesAbbr: ["jan","feb","mar","apr","maj","jun","jul","avg","sep","okt","nov","dec",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "d.M.yyyy", + D: "d. MMMM yyyy", + F: "d. MMMM yyyy H:mm:ss", + g: "d.M.yyyy H:mm", + G: "d.M.yyyy H:mm:ss", + m: "d. MMMM", + M: "d. MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.sma-NO.js b/src/cultures/kendo.culture.sma-NO.js new file mode 100644 index 00000000000..5cd41ad3c01 --- /dev/null +++ b/src/cultures/kendo.culture.sma-NO.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["sma-NO"] = { + name: "sma-NO", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-%n","%n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "kr" + } + }, + calendars: { + standard: { + days: { + names: ["aejlege","måanta","dæjsta","gaskevåhkoe","duarsta","bearjadahke","laavvardahke"], + namesAbbr: ["aej","måa","dæj","gask","duar","bearj","laav"], + namesShort: ["a","m","d","g","d","b","l"] + }, + months: { + names: ["tsïengele","goevte","njoktje","voerhtje","suehpede","ruffie","snjaltje","mïetske","skïerede","golke","rahka","goeve",""], + namesAbbr: ["tsïen","goevt","njok","voer","sueh","ruff","snja","mïet","skïer","golk","rahk","goev",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yyyy", + D: "MMMM d'. b. 'yyyy", + F: "MMMM d'. b. 'yyyy HH:mm:ss", + g: "dd.MM.yyyy HH:mm", + G: "dd.MM.yyyy HH:mm:ss", + m: "MMMM d'. b. '", + M: "MMMM d'. b. '", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.sma-SE.js b/src/cultures/kendo.culture.sma-SE.js new file mode 100644 index 00000000000..5a885daab58 --- /dev/null +++ b/src/cultures/kendo.culture.sma-SE.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["sma-SE"] = { + name: "sma-SE", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "kr" + } + }, + calendars: { + standard: { + days: { + names: ["aejlege","måanta","dæjsta","gaskevåhkoe","duarsta","bearjadahke","laavvardahke"], + namesAbbr: ["aej","måa","dæj","gask","duar","bearj","laav"], + namesShort: ["a","m","d","g","d","b","l"] + }, + months: { + names: ["tsïengele","goevte","njoktje","voerhtje","suehpede","ruffie","snjaltje","mïetske","skïerede","golke","rahka","goeve",""], + namesAbbr: ["tsïen","goevt","njok","voer","sueh","ruff","snja","mïet","skïer","golk","rahk","goev",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "yyyy-MM-dd", + D: "MMMM d'. b. 'yyyy", + F: "MMMM d'. b. 'yyyy HH:mm:ss", + g: "yyyy-MM-dd HH:mm", + G: "yyyy-MM-dd HH:mm:ss", + m: "MMMM d'. b. '", + M: "MMMM d'. b. '", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "-", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.sma.js b/src/cultures/kendo.culture.sma.js new file mode 100644 index 00000000000..b7ad148591b --- /dev/null +++ b/src/cultures/kendo.culture.sma.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["sma"] = { + name: "sma", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "kr" + } + }, + calendars: { + standard: { + days: { + names: ["aejlege","måanta","dæjsta","gaskevåhkoe","duarsta","bearjadahke","laavvardahke"], + namesAbbr: ["aej","måa","dæj","gask","duar","bearj","laav"], + namesShort: ["a","m","d","g","d","b","l"] + }, + months: { + names: ["tsïengele","goevte","njoktje","voerhtje","suehpede","ruffie","snjaltje","mïetske","skïerede","golke","rahka","goeve",""], + namesAbbr: ["tsïen","goevt","njok","voer","sueh","ruff","snja","mïet","skïer","golk","rahk","goev",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "yyyy-MM-dd", + D: "MMMM d'. b. 'yyyy", + F: "MMMM d'. b. 'yyyy HH:mm:ss", + g: "yyyy-MM-dd HH:mm", + G: "yyyy-MM-dd HH:mm:ss", + m: "MMMM d'. b. '", + M: "MMMM d'. b. '", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "-", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.smj-NO.js b/src/cultures/kendo.culture.smj-NO.js new file mode 100644 index 00000000000..3d68a7b3805 --- /dev/null +++ b/src/cultures/kendo.culture.smj-NO.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["smj-NO"] = { + name: "smj-NO", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-%n","%n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "kr" + } + }, + calendars: { + standard: { + days: { + names: ["sådnåbiejvve","mánnodahka","dijstahka","gasskavahkko","duorastahka","bierjjedahka","lávvodahka"], + namesAbbr: ["såd","mán","dis","gas","duor","bier","láv"], + namesShort: ["s","m","d","g","d","b","l"] + }, + months: { + names: ["ådåjakmánno","guovvamánno","sjnjuktjamánno","vuoratjismánno","moarmesmánno","biehtsemánno","sjnjilltjamánno","bårggemánno","ragátmánno","gålgådismánno","basádismánno","javllamánno",""], + namesAbbr: ["ådåj","guov","snju","vuor","moar","bieh","snji","bårg","ragá","gålg","basá","javl",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yyyy", + D: "MMMM d'. b. 'yyyy", + F: "MMMM d'. b. 'yyyy HH:mm:ss", + g: "dd.MM.yyyy HH:mm", + G: "dd.MM.yyyy HH:mm:ss", + m: "MMMM d'. b. '", + M: "MMMM d'. b. '", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.smj-SE.js b/src/cultures/kendo.culture.smj-SE.js new file mode 100644 index 00000000000..5bf6813beb6 --- /dev/null +++ b/src/cultures/kendo.culture.smj-SE.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["smj-SE"] = { + name: "smj-SE", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "kr" + } + }, + calendars: { + standard: { + days: { + names: ["ájllek","mánnodahka","dijstahka","gasskavahkko","duorastahka","bierjjedahka","lávvodahka"], + namesAbbr: ["ájl","mán","dis","gas","duor","bier","láv"], + namesShort: ["á","m","d","g","d","b","l"] + }, + months: { + names: ["ådåjakmánno","guovvamánno","sjnjuktjamánno","vuoratjismánno","moarmesmánno","biehtsemánno","sjnjilltjamánno","bårggemánno","ragátmánno","gålgådismánno","basádismánno","javllamánno",""], + namesAbbr: ["ådåj","guov","snju","vuor","moar","bieh","snji","bårg","ragá","gålg","basá","javl",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "yyyy-MM-dd", + D: "MMMM d'. b. 'yyyy", + F: "MMMM d'. b. 'yyyy HH:mm:ss", + g: "yyyy-MM-dd HH:mm", + G: "yyyy-MM-dd HH:mm:ss", + m: "MMMM d'. b. '", + M: "MMMM d'. b. '", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "-", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.smj.js b/src/cultures/kendo.culture.smj.js new file mode 100644 index 00000000000..18318fc4f33 --- /dev/null +++ b/src/cultures/kendo.culture.smj.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["smj"] = { + name: "smj", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "kr" + } + }, + calendars: { + standard: { + days: { + names: ["ájllek","mánnodahka","dijstahka","gasskavahkko","duorastahka","bierjjedahka","lávvodahka"], + namesAbbr: ["ájl","mán","dis","gas","duor","bier","láv"], + namesShort: ["á","m","d","g","d","b","l"] + }, + months: { + names: ["ådåjakmánno","guovvamánno","sjnjuktjamánno","vuoratjismánno","moarmesmánno","biehtsemánno","sjnjilltjamánno","bårggemánno","ragátmánno","gålgådismánno","basádismánno","javllamánno",""], + namesAbbr: ["ådåj","guov","snju","vuor","moar","bieh","snji","bårg","ragá","gålg","basá","javl",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "yyyy-MM-dd", + D: "MMMM d'. b. 'yyyy", + F: "MMMM d'. b. 'yyyy HH:mm:ss", + g: "yyyy-MM-dd HH:mm", + G: "yyyy-MM-dd HH:mm:ss", + m: "MMMM d'. b. '", + M: "MMMM d'. b. '", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "-", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.smn-FI.js b/src/cultures/kendo.culture.smn-FI.js new file mode 100644 index 00000000000..4b85b84b2b6 --- /dev/null +++ b/src/cultures/kendo.culture.smn-FI.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["smn-FI"] = { + name: "smn-FI", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["pasepeivi","vuossargâ","majebargâ","koskokko","tuorâstâh","vástuppeivi","lávárdâh"], + namesAbbr: ["pa","vu","ma","ko","tu","vá","lá"], + namesShort: ["p","v","m","k","t","v","l"] + }, + months: { + names: ["uđđâivemáánu","kuovâmáánu","njuhčâmáánu","cuáŋuimáánu","vyesimáánu","kesimáánu","syeinimáánu","porgemáánu","čohčâmáánu","roovvâdmáánu","skammâmáánu","juovlâmáánu",""], + namesAbbr: ["uđiv","kuov","njuh","cuoŋ","vyes","kesi","syei","porg","čoh","roov","ska","juov",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "d.M.yyyy", + D: "MMMM d'. p. 'yyyy", + F: "MMMM d'. p. 'yyyy H:mm:ss", + g: "d.M.yyyy H:mm", + G: "d.M.yyyy H:mm:ss", + m: "MMMM d'. p. '", + M: "MMMM d'. p. '", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.smn.js b/src/cultures/kendo.culture.smn.js new file mode 100644 index 00000000000..b6db3bd8c60 --- /dev/null +++ b/src/cultures/kendo.culture.smn.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["smn"] = { + name: "smn", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["pasepeivi","vuossargâ","majebargâ","koskokko","tuorâstâh","vástuppeivi","lávárdâh"], + namesAbbr: ["pa","vu","ma","ko","tu","vá","lá"], + namesShort: ["p","v","m","k","t","v","l"] + }, + months: { + names: ["uđđâivemáánu","kuovâmáánu","njuhčâmáánu","cuáŋuimáánu","vyesimáánu","kesimáánu","syeinimáánu","porgemáánu","čohčâmáánu","roovvâdmáánu","skammâmáánu","juovlâmáánu",""], + namesAbbr: ["uđiv","kuov","njuh","cuoŋ","vyes","kesi","syei","porg","čoh","roov","ska","juov",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "d.M.yyyy", + D: "MMMM d'. p. 'yyyy", + F: "MMMM d'. p. 'yyyy H:mm:ss", + g: "d.M.yyyy H:mm", + G: "d.M.yyyy H:mm:ss", + m: "MMMM d'. p. '", + M: "MMMM d'. p. '", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.sms-FI.js b/src/cultures/kendo.culture.sms-FI.js new file mode 100644 index 00000000000..b7c944cad58 --- /dev/null +++ b/src/cultures/kendo.culture.sms-FI.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["sms-FI"] = { + name: "sms-FI", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["pâ´sspei´vv","vuõssargg","mââibargg","seärad","nelljdpei´vv","piâtnâc","sue´vet"], + namesAbbr: ["pâ","vu","mâ","se","ne","pi","su"], + namesShort: ["p","v","m","s","n","p","s"] + }, + months: { + names: ["ođđee´jjmään","tä´lvvmään","pâ´zzlâšttammään","njuhččmään","vue´ssmään","ǩie´ssmään","suei´nnmään","på´rǧǧmään","čõhččmään","kålggmään","skamm´mään","rosttovmään",""], + namesAbbr: ["ođjm","tä´lvv","pâzl","njuh","vue","ǩie","suei","på´r","čõh","kålg","ska","rost",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "d.M.yyyy", + D: "MMMM d'. p. 'yyyy", + F: "MMMM d'. p. 'yyyy H:mm:ss", + g: "d.M.yyyy H:mm", + G: "d.M.yyyy H:mm:ss", + m: "MMMM d'. p. '", + M: "MMMM d'. p. '", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.sms.js b/src/cultures/kendo.culture.sms.js new file mode 100644 index 00000000000..af45a558d83 --- /dev/null +++ b/src/cultures/kendo.culture.sms.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["sms"] = { + name: "sms", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["pâ´sspei´vv","vuõssargg","mââibargg","seärad","nelljdpei´vv","piâtnâc","sue´vet"], + namesAbbr: ["pâ","vu","mâ","se","ne","pi","su"], + namesShort: ["p","v","m","s","n","p","s"] + }, + months: { + names: ["ođđee´jjmään","tä´lvvmään","pâ´zzlâšttammään","njuhččmään","vue´ssmään","ǩie´ssmään","suei´nnmään","på´rǧǧmään","čõhččmään","kålggmään","skamm´mään","rosttovmään",""], + namesAbbr: ["ođjm","tä´lvv","pâzl","njuh","vue","ǩie","suei","på´r","čõh","kålg","ska","rost",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "d.M.yyyy", + D: "MMMM d'. p. 'yyyy", + F: "MMMM d'. p. 'yyyy H:mm:ss", + g: "d.M.yyyy H:mm", + G: "d.M.yyyy H:mm:ss", + m: "MMMM d'. p. '", + M: "MMMM d'. p. '", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.sq-AL.js b/src/cultures/kendo.culture.sq-AL.js new file mode 100644 index 00000000000..f3bc744b1d4 --- /dev/null +++ b/src/cultures/kendo.culture.sq-AL.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["sq-AL"] = { + name: "sq-AL", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n$","n$"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "Lek" + } + }, + calendars: { + standard: { + days: { + names: ["e diel","e hënë","e martë","e mërkurë","e enjte","e premte","e shtunë"], + namesAbbr: ["Die","Hën","Mar","Mër","Enj","Pre","Sht"], + namesShort: ["Di","Hë","Ma","Më","En","Pr","Sh"] + }, + months: { + names: ["janar","shkurt","mars","prill","maj","qershor","korrik","gusht","shtator","tetor","nëntor","dhjetor",""], + namesAbbr: ["Jan","Shk","Mar","Pri","Maj","Qer","Kor","Gsh","Sht","Tet","Nën","Dhj",""] + }, + AM: ["PD","pd","PD"], + PM: ["MD","md","MD"], + patterns: { + d: "yyyy-MM-dd", + D: "yyyy-MM-dd", + F: "yyyy-MM-dd h:mm:ss.tt", + g: "yyyy-MM-dd h:mm.tt", + G: "yyyy-MM-dd h:mm:ss.tt", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm.tt", + T: "h:mm:ss.tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "yyyy-MM", + Y: "yyyy-MM" + }, + "/": "-", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.sq.js b/src/cultures/kendo.culture.sq.js new file mode 100644 index 00000000000..920f6bdfdcc --- /dev/null +++ b/src/cultures/kendo.culture.sq.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["sq"] = { + name: "sq", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n$","n$"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "Lek" + } + }, + calendars: { + standard: { + days: { + names: ["e diel","e hënë","e martë","e mërkurë","e enjte","e premte","e shtunë"], + namesAbbr: ["Die","Hën","Mar","Mër","Enj","Pre","Sht"], + namesShort: ["Di","Hë","Ma","Më","En","Pr","Sh"] + }, + months: { + names: ["janar","shkurt","mars","prill","maj","qershor","korrik","gusht","shtator","tetor","nëntor","dhjetor",""], + namesAbbr: ["Jan","Shk","Mar","Pri","Maj","Qer","Kor","Gsh","Sht","Tet","Nën","Dhj",""] + }, + AM: ["PD","pd","PD"], + PM: ["MD","md","MD"], + patterns: { + d: "yyyy-MM-dd", + D: "yyyy-MM-dd", + F: "yyyy-MM-dd h:mm:ss.tt", + g: "yyyy-MM-dd h:mm.tt", + G: "yyyy-MM-dd h:mm:ss.tt", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm.tt", + T: "h:mm:ss.tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "yyyy-MM", + Y: "yyyy-MM" + }, + "/": "-", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.sr-Cyrl-BA.js b/src/cultures/kendo.culture.sr-Cyrl-BA.js new file mode 100644 index 00000000000..56b5932eca3 --- /dev/null +++ b/src/cultures/kendo.culture.sr-Cyrl-BA.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["sr-Cyrl-BA"] = { + name: "sr-Cyrl-BA", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "КМ" + } + }, + calendars: { + standard: { + days: { + names: ["недеља","понедељак","уторак","среда","четвртак","петак","субота"], + namesAbbr: ["нед","пон","уто","сре","чет","пет","суб"], + namesShort: ["н","п","у","с","ч","п","с"] + }, + months: { + names: ["јануар","фебруар","март","април","мај","јун","јул","август","септембар","октобар","новембар","децембар",""], + namesAbbr: ["јан","феб","мар","апр","мај","јун","јул","авг","сеп","окт","нов","дец",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "d.M.yyyy", + D: "d. MMMM yyyy", + F: "d. MMMM yyyy H:mm:ss", + g: "d.M.yyyy H:mm", + G: "d.M.yyyy H:mm:ss", + m: "d. MMMM", + M: "d. MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.sr-Cyrl-CS.js b/src/cultures/kendo.culture.sr-Cyrl-CS.js new file mode 100644 index 00000000000..bca09ae1f4a --- /dev/null +++ b/src/cultures/kendo.culture.sr-Cyrl-CS.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["sr-Cyrl-CS"] = { + name: "sr-Cyrl-CS", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "Дин." + } + }, + calendars: { + standard: { + days: { + names: ["недеља","понедељак","уторак","среда","четвртак","петак","субота"], + namesAbbr: ["нед","пон","уто","сре","чет","пет","суб"], + namesShort: ["не","по","ут","ср","че","пе","су"] + }, + months: { + names: ["јануар","фебруар","март","април","мај","јун","јул","август","септембар","октобар","новембар","децембар",""], + namesAbbr: ["јан","феб","мар","апр","мај","јун","јул","авг","сеп","окт","нов","дец",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "d.M.yyyy", + D: "d. MMMM yyyy", + F: "d. MMMM yyyy H:mm:ss", + g: "d.M.yyyy H:mm", + G: "d.M.yyyy H:mm:ss", + m: "d. MMMM", + M: "d. MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.sr-Cyrl-ME.js b/src/cultures/kendo.culture.sr-Cyrl-ME.js new file mode 100644 index 00000000000..e0dcb56ee6b --- /dev/null +++ b/src/cultures/kendo.culture.sr-Cyrl-ME.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["sr-Cyrl-ME"] = { + name: "sr-Cyrl-ME", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["неђеља","понеђељак","уторак","сриједа","четвртак","петак","субота"], + namesAbbr: ["неђ","пон","уто","сри","чет","пет","суб"], + namesShort: ["не","по","ут","ср","че","пе","су"] + }, + months: { + names: ["јануар","фебруар","март","април","мај","јун","јул","август","септембар","октобар","новембар","децембар",""], + namesAbbr: ["јан","феб","мар","апр","мај","јун","јул","авг","сеп","окт","нов","дец",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "d.M.yyyy", + D: "d. MMMM yyyy", + F: "d. MMMM yyyy H:mm:ss", + g: "d.M.yyyy H:mm", + G: "d.M.yyyy H:mm:ss", + m: "d. MMMM", + M: "d. MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.sr-Cyrl-RS.js b/src/cultures/kendo.culture.sr-Cyrl-RS.js new file mode 100644 index 00000000000..680485f4311 --- /dev/null +++ b/src/cultures/kendo.culture.sr-Cyrl-RS.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["sr-Cyrl-RS"] = { + name: "sr-Cyrl-RS", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "Дин." + } + }, + calendars: { + standard: { + days: { + names: ["недеља","понедељак","уторак","среда","четвртак","петак","субота"], + namesAbbr: ["нед","пон","уто","сре","чет","пет","суб"], + namesShort: ["не","по","ут","ср","че","пе","су"] + }, + months: { + names: ["јануар","фебруар","март","април","мај","јун","јул","август","септембар","октобар","новембар","децембар",""], + namesAbbr: ["јан","феб","мар","апр","мај","јун","јул","авг","сеп","окт","нов","дец",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "d.M.yyyy", + D: "d. MMMM yyyy", + F: "d. MMMM yyyy H:mm:ss", + g: "d.M.yyyy H:mm", + G: "d.M.yyyy H:mm:ss", + m: "d. MMMM", + M: "d. MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.sr-Cyrl.js b/src/cultures/kendo.culture.sr-Cyrl.js new file mode 100644 index 00000000000..90efbc0b3dd --- /dev/null +++ b/src/cultures/kendo.culture.sr-Cyrl.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["sr-Cyrl"] = { + name: "sr-Cyrl", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "Дин." + } + }, + calendars: { + standard: { + days: { + names: ["недеља","понедељак","уторак","среда","четвртак","петак","субота"], + namesAbbr: ["нед","пон","уто","сре","чет","пет","суб"], + namesShort: ["не","по","ут","ср","че","пе","су"] + }, + months: { + names: ["јануар","фебруар","март","април","мај","јун","јул","август","септембар","октобар","новембар","децембар",""], + namesAbbr: ["јан","феб","мар","апр","мај","јун","јул","авг","сеп","окт","нов","дец",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "d.M.yyyy", + D: "d. MMMM yyyy", + F: "d. MMMM yyyy H:mm:ss", + g: "d.M.yyyy H:mm", + G: "d.M.yyyy H:mm:ss", + m: "d. MMMM", + M: "d. MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.sr-Latn-BA.js b/src/cultures/kendo.culture.sr-Latn-BA.js new file mode 100644 index 00000000000..fc6b7768fe4 --- /dev/null +++ b/src/cultures/kendo.culture.sr-Latn-BA.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["sr-Latn-BA"] = { + name: "sr-Latn-BA", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "KM" + } + }, + calendars: { + standard: { + days: { + names: ["nedelja","ponedeljak","utorak","sreda","četvrtak","petak","subota"], + namesAbbr: ["ned","pon","uto","sre","čet","pet","sub"], + namesShort: ["ne","po","ut","sr","če","pe","su"] + }, + months: { + names: ["januar","februar","mart","april","maj","jun","jul","avgust","septembar","oktobar","novembar","decembar",""], + namesAbbr: ["jan","feb","mar","apr","maj","jun","jul","avg","sep","okt","nov","dec",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "d.M.yyyy", + D: "d. MMMM yyyy", + F: "d. MMMM yyyy H:mm:ss", + g: "d.M.yyyy H:mm", + G: "d.M.yyyy H:mm:ss", + m: "d. MMMM", + M: "d. MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.sr-Latn-CS.js b/src/cultures/kendo.culture.sr-Latn-CS.js new file mode 100644 index 00000000000..31cbf0609db --- /dev/null +++ b/src/cultures/kendo.culture.sr-Latn-CS.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["sr-Latn-CS"] = { + name: "sr-Latn-CS", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "Din." + } + }, + calendars: { + standard: { + days: { + names: ["nedelja","ponedeljak","utorak","sreda","četvrtak","petak","subota"], + namesAbbr: ["ned","pon","uto","sre","čet","pet","sub"], + namesShort: ["ne","po","ut","sr","če","pe","su"] + }, + months: { + names: ["januar","februar","mart","april","maj","jun","jul","avgust","septembar","oktobar","novembar","decembar",""], + namesAbbr: ["jan","feb","mar","apr","maj","jun","jul","avg","sep","okt","nov","dec",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "d.M.yyyy", + D: "d. MMMM yyyy", + F: "d. MMMM yyyy H:mm:ss", + g: "d.M.yyyy H:mm", + G: "d.M.yyyy H:mm:ss", + m: "d. MMMM", + M: "d. MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.sr-Latn-ME.js b/src/cultures/kendo.culture.sr-Latn-ME.js new file mode 100644 index 00000000000..feb7d1b03e8 --- /dev/null +++ b/src/cultures/kendo.culture.sr-Latn-ME.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["sr-Latn-ME"] = { + name: "sr-Latn-ME", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["neđelja","poneđeljak","utorak","srijeda","četvrtak","petak","subota"], + namesAbbr: ["neđ","pon","uto","sri","čet","pet","sub"], + namesShort: ["ne","po","ut","sr","če","pe","su"] + }, + months: { + names: ["januar","februar","mart","april","maj","jun","jul","avgust","septembar","oktobar","novembar","decembar",""], + namesAbbr: ["jan","feb","mar","apr","maj","jun","jul","avg","sep","okt","nov","dec",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "d.M.yyyy", + D: "d. MMMM yyyy", + F: "d. MMMM yyyy H:mm:ss", + g: "d.M.yyyy H:mm", + G: "d.M.yyyy H:mm:ss", + m: "d. MMMM", + M: "d. MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.sr-Latn-RS.js b/src/cultures/kendo.culture.sr-Latn-RS.js new file mode 100644 index 00000000000..033d09ffd99 --- /dev/null +++ b/src/cultures/kendo.culture.sr-Latn-RS.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["sr-Latn-RS"] = { + name: "sr-Latn-RS", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "Din." + } + }, + calendars: { + standard: { + days: { + names: ["nedelja","ponedeljak","utorak","sreda","četvrtak","petak","subota"], + namesAbbr: ["ned","pon","uto","sre","čet","pet","sub"], + namesShort: ["ne","po","ut","sr","če","pe","su"] + }, + months: { + names: ["januar","februar","mart","april","maj","jun","jul","avgust","septembar","oktobar","novembar","decembar",""], + namesAbbr: ["jan","feb","mar","apr","maj","jun","jul","avg","sep","okt","nov","dec",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "d.M.yyyy", + D: "d. MMMM yyyy", + F: "d. MMMM yyyy H:mm:ss", + g: "d.M.yyyy H:mm", + G: "d.M.yyyy H:mm:ss", + m: "d. MMMM", + M: "d. MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.sr-Latn.js b/src/cultures/kendo.culture.sr-Latn.js new file mode 100644 index 00000000000..5056619fcc1 --- /dev/null +++ b/src/cultures/kendo.culture.sr-Latn.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["sr-Latn"] = { + name: "sr-Latn", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "Din." + } + }, + calendars: { + standard: { + days: { + names: ["nedelja","ponedeljak","utorak","sreda","četvrtak","petak","subota"], + namesAbbr: ["ned","pon","uto","sre","čet","pet","sub"], + namesShort: ["ne","po","ut","sr","če","pe","su"] + }, + months: { + names: ["januar","februar","mart","april","maj","jun","jul","avgust","septembar","oktobar","novembar","decembar",""], + namesAbbr: ["jan","feb","mar","apr","maj","jun","jul","avg","sep","okt","nov","dec",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "d.M.yyyy", + D: "d. MMMM yyyy", + F: "d. MMMM yyyy H:mm:ss", + g: "d.M.yyyy H:mm", + G: "d.M.yyyy H:mm:ss", + m: "d. MMMM", + M: "d. MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.sr.js b/src/cultures/kendo.culture.sr.js new file mode 100644 index 00000000000..9e6138d3188 --- /dev/null +++ b/src/cultures/kendo.culture.sr.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["sr"] = { + name: "sr", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "Din." + } + }, + calendars: { + standard: { + days: { + names: ["nedelja","ponedeljak","utorak","sreda","četvrtak","petak","subota"], + namesAbbr: ["ned","pon","uto","sre","čet","pet","sub"], + namesShort: ["ne","po","ut","sr","če","pe","su"] + }, + months: { + names: ["januar","februar","mart","april","maj","jun","jul","avgust","septembar","oktobar","novembar","decembar",""], + namesAbbr: ["jan","feb","mar","apr","maj","jun","jul","avg","sep","okt","nov","dec",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "d.M.yyyy", + D: "d. MMMM yyyy", + F: "d. MMMM yyyy H:mm:ss", + g: "d.M.yyyy H:mm", + G: "d.M.yyyy H:mm:ss", + m: "d. MMMM", + M: "d. MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.sv-FI.js b/src/cultures/kendo.culture.sv-FI.js new file mode 100644 index 00000000000..99585811eb8 --- /dev/null +++ b/src/cultures/kendo.culture.sv-FI.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["sv-FI"] = { + name: "sv-FI", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "€" + } + }, + calendars: { + standard: { + days: { + names: ["söndag","måndag","tisdag","onsdag","torsdag","fredag","lördag"], + namesAbbr: ["sö","må","ti","on","to","fr","lö"], + namesShort: ["sö","må","ti","on","to","fr","lö"] + }, + months: { + names: ["januari","februari","mars","april","maj","juni","juli","augusti","september","oktober","november","december",""], + namesAbbr: ["jan","feb","mar","apr","maj","jun","jul","aug","sep","okt","nov","dec",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "d.M.yyyy", + D: "'den 'd MMMM yyyy", + F: "'den 'd MMMM yyyy HH:mm:ss", + g: "d.M.yyyy HH:mm", + G: "d.M.yyyy HH:mm:ss", + m: "'den 'd MMMM", + M: "'den 'd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.sv-SE.js b/src/cultures/kendo.culture.sv-SE.js new file mode 100644 index 00000000000..efc3b7da4d5 --- /dev/null +++ b/src/cultures/kendo.culture.sv-SE.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["sv-SE"] = { + name: "sv-SE", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "kr" + } + }, + calendars: { + standard: { + days: { + names: ["söndag","måndag","tisdag","onsdag","torsdag","fredag","lördag"], + namesAbbr: ["sö","må","ti","on","to","fr","lö"], + namesShort: ["sö","må","ti","on","to","fr","lö"] + }, + months: { + names: ["januari","februari","mars","april","maj","juni","juli","augusti","september","oktober","november","december",""], + namesAbbr: ["jan","feb","mar","apr","maj","jun","jul","aug","sep","okt","nov","dec",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "yyyy-MM-dd", + D: "'den 'd MMMM yyyy", + F: "'den 'd MMMM yyyy HH:mm:ss", + g: "yyyy-MM-dd HH:mm", + G: "yyyy-MM-dd HH:mm:ss", + m: "'den 'd MMMM", + M: "'den 'd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "-", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.sv.js b/src/cultures/kendo.culture.sv.js new file mode 100644 index 00000000000..f44f553559e --- /dev/null +++ b/src/cultures/kendo.culture.sv.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["sv"] = { + name: "sv", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "kr" + } + }, + calendars: { + standard: { + days: { + names: ["söndag","måndag","tisdag","onsdag","torsdag","fredag","lördag"], + namesAbbr: ["sö","må","ti","on","to","fr","lö"], + namesShort: ["sö","må","ti","on","to","fr","lö"] + }, + months: { + names: ["januari","februari","mars","april","maj","juni","juli","augusti","september","oktober","november","december",""], + namesAbbr: ["jan","feb","mar","apr","maj","jun","jul","aug","sep","okt","nov","dec",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "yyyy-MM-dd", + D: "'den 'd MMMM yyyy", + F: "'den 'd MMMM yyyy HH:mm:ss", + g: "yyyy-MM-dd HH:mm", + G: "yyyy-MM-dd HH:mm:ss", + m: "'den 'd MMMM", + M: "'den 'd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "-", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.sw-KE.js b/src/cultures/kendo.culture.sw-KE.js new file mode 100644 index 00000000000..2ce9ea873e4 --- /dev/null +++ b/src/cultures/kendo.culture.sw-KE.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["sw-KE"] = { + name: "sw-KE", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["($n)","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "S" + } + }, + calendars: { + standard: { + days: { + names: ["Jumapili","Jumatatu","Jumanne","Jumatano","Alhamisi","Ijumaa","Jumamosi"], + namesAbbr: ["Jumap.","Jumat.","Juman.","Jumat.","Alh.","Iju.","Jumam."], + namesShort: ["P","T","N","T","A","I","M"] + }, + months: { + names: ["Januari","Februari","Machi","Aprili","Mei","Juni","Julai","Agosti","Septemba","Oktoba","Novemba","Decemba",""], + namesAbbr: ["Jan","Feb","Mac","Apr","Mei","Jun","Jul","Ago","Sep","Okt","Nov","Dec",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "M/d/yyyy", + D: "dddd, MMMM dd, yyyy", + F: "dddd, MMMM dd, yyyy h:mm:ss tt", + g: "M/d/yyyy h:mm tt", + G: "M/d/yyyy h:mm:ss tt", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.sw.js b/src/cultures/kendo.culture.sw.js new file mode 100644 index 00000000000..30a727d4249 --- /dev/null +++ b/src/cultures/kendo.culture.sw.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["sw"] = { + name: "sw", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["($n)","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "S" + } + }, + calendars: { + standard: { + days: { + names: ["Jumapili","Jumatatu","Jumanne","Jumatano","Alhamisi","Ijumaa","Jumamosi"], + namesAbbr: ["Jumap.","Jumat.","Juman.","Jumat.","Alh.","Iju.","Jumam."], + namesShort: ["P","T","N","T","A","I","M"] + }, + months: { + names: ["Januari","Februari","Machi","Aprili","Mei","Juni","Julai","Agosti","Septemba","Oktoba","Novemba","Decemba",""], + namesAbbr: ["Jan","Feb","Mac","Apr","Mei","Jun","Jul","Ago","Sep","Okt","Nov","Dec",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "M/d/yyyy", + D: "dddd, MMMM dd, yyyy", + F: "dddd, MMMM dd, yyyy h:mm:ss tt", + g: "M/d/yyyy h:mm tt", + G: "M/d/yyyy h:mm:ss tt", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.syr-SY.js b/src/cultures/kendo.culture.syr-SY.js new file mode 100644 index 00000000000..375bd45eee8 --- /dev/null +++ b/src/cultures/kendo.culture.syr-SY.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["syr-SY"] = { + name: "syr-SY", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$n-","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "ل.س.‏" + } + }, + calendars: { + standard: { + days: { + names: ["ܚܕ ܒܫܒܐ","ܬܪܝܢ ܒܫܒܐ","ܬܠܬܐ ܒܫܒܐ","ܐܪܒܥܐ ܒܫܒܐ","ܚܡܫܐ ܒܫܒܐ","ܥܪܘܒܬܐ","ܫܒܬܐ"], + namesAbbr: ["܏ܐ ܏ܒܫ","܏ܒ ܏ܒܫ","܏ܓ ܏ܒܫ","܏ܕ ܏ܒܫ","܏ܗ ܏ܒܫ","܏ܥܪܘܒ","܏ܫܒ"], + namesShort: ["ܐ","ܒ","ܓ","ܕ","ܗ","ܥ","ܫ"] + }, + months: { + names: ["ܟܢܘܢ ܐܚܪܝ","ܫܒܛ","ܐܕܪ","ܢܝܣܢ","ܐܝܪ","ܚܙܝܪܢ","ܬܡܘܙ","ܐܒ","ܐܝܠܘܠ","ܬܫܪܝ ܩܕܝܡ","ܬܫܪܝ ܐܚܪܝ","ܟܢܘܢ ܩܕܝܡ",""], + namesAbbr: ["܏ܟܢ ܏ܒ","ܫܒܛ","ܐܕܪ","ܢܝܣܢ","ܐܝܪ","ܚܙܝܪܢ","ܬܡܘܙ","ܐܒ","ܐܝܠܘܠ","܏ܬܫ ܏ܐ","܏ܬܫ ܏ܒ","܏ܟܢ ܏ܐ",""] + }, + AM: ["ܩ.ܛ","ܩ.ܛ","ܩ.ܛ"], + PM: ["ܒ.ܛ","ܒ.ܛ","ܒ.ܛ"], + patterns: { + d: "dd/MM/yyyy", + D: "dd MMMM, yyyy", + F: "dd MMMM, yyyy hh:mm:ss tt", + g: "dd/MM/yyyy hh:mm tt", + G: "dd/MM/yyyy hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 6 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.syr.js b/src/cultures/kendo.culture.syr.js new file mode 100644 index 00000000000..c8d08ed67a1 --- /dev/null +++ b/src/cultures/kendo.culture.syr.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["syr"] = { + name: "syr", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$n-","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "ل.س.‏" + } + }, + calendars: { + standard: { + days: { + names: ["ܚܕ ܒܫܒܐ","ܬܪܝܢ ܒܫܒܐ","ܬܠܬܐ ܒܫܒܐ","ܐܪܒܥܐ ܒܫܒܐ","ܚܡܫܐ ܒܫܒܐ","ܥܪܘܒܬܐ","ܫܒܬܐ"], + namesAbbr: ["܏ܐ ܏ܒܫ","܏ܒ ܏ܒܫ","܏ܓ ܏ܒܫ","܏ܕ ܏ܒܫ","܏ܗ ܏ܒܫ","܏ܥܪܘܒ","܏ܫܒ"], + namesShort: ["ܐ","ܒ","ܓ","ܕ","ܗ","ܥ","ܫ"] + }, + months: { + names: ["ܟܢܘܢ ܐܚܪܝ","ܫܒܛ","ܐܕܪ","ܢܝܣܢ","ܐܝܪ","ܚܙܝܪܢ","ܬܡܘܙ","ܐܒ","ܐܝܠܘܠ","ܬܫܪܝ ܩܕܝܡ","ܬܫܪܝ ܐܚܪܝ","ܟܢܘܢ ܩܕܝܡ",""], + namesAbbr: ["܏ܟܢ ܏ܒ","ܫܒܛ","ܐܕܪ","ܢܝܣܢ","ܐܝܪ","ܚܙܝܪܢ","ܬܡܘܙ","ܐܒ","ܐܝܠܘܠ","܏ܬܫ ܏ܐ","܏ܬܫ ܏ܒ","܏ܟܢ ܏ܐ",""] + }, + AM: ["ܩ.ܛ","ܩ.ܛ","ܩ.ܛ"], + PM: ["ܒ.ܛ","ܒ.ܛ","ܒ.ܛ"], + patterns: { + d: "dd/MM/yyyy", + D: "dd MMMM, yyyy", + F: "dd MMMM, yyyy hh:mm:ss tt", + g: "dd/MM/yyyy hh:mm tt", + G: "dd/MM/yyyy hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 6 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ta-IN.js b/src/cultures/kendo.culture.ta-IN.js new file mode 100644 index 00000000000..0a9d717227c --- /dev/null +++ b/src/cultures/kendo.culture.ta-IN.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ta-IN"] = { + name: "ta-IN", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "ரூ" + } + }, + calendars: { + standard: { + days: { + names: ["ஞாயிற்றுக்கிழமை","திங்கள்கிழமை","செவ்வாய்கிழமை","புதன்கிழமை","வியாழக்கிழமை","வெள்ளிக்கிழமை","சனிக்கிழமை"], + namesAbbr: ["ஞாயிறு","திங்கள்","செவ்வாய்","புதன்","வியாழன்","வெள்ளி","சனி"], + namesShort: ["ஞா","தி","செ","பு","வி","வெ","ச"] + }, + months: { + names: ["ஜனவரி","பிப்ரவரி","மார்ச்","ஏப்ரல்","மே","ஜூன்","ஜூலை","ஆகஸ்ட்","செப்டம்பர்","அக்டோபர்","நவம்பர்","டிசம்பர்",""], + namesAbbr: ["ஜனவரி","பிப்ரவரி","மார்ச்","ஏப்ரல்","மே","ஜூன்","ஜூலை","ஆகஸ்ட்","செப்டம்பர்","அக்டோபர்","நவம்பர்","டிசம்பர்",""] + }, + AM: ["காலை","காலை","காலை"], + PM: ["மாலை","மாலை","மாலை"], + patterns: { + d: "dd-MM-yyyy", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy HH:mm:ss", + g: "dd-MM-yyyy HH:mm", + G: "dd-MM-yyyy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "-", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ta.js b/src/cultures/kendo.culture.ta.js new file mode 100644 index 00000000000..f32b855246c --- /dev/null +++ b/src/cultures/kendo.culture.ta.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ta"] = { + name: "ta", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "ரூ" + } + }, + calendars: { + standard: { + days: { + names: ["ஞாயிற்றுக்கிழமை","திங்கள்கிழமை","செவ்வாய்கிழமை","புதன்கிழமை","வியாழக்கிழமை","வெள்ளிக்கிழமை","சனிக்கிழமை"], + namesAbbr: ["ஞாயிறு","திங்கள்","செவ்வாய்","புதன்","வியாழன்","வெள்ளி","சனி"], + namesShort: ["ஞா","தி","செ","பு","வி","வெ","ச"] + }, + months: { + names: ["ஜனவரி","பிப்ரவரி","மார்ச்","ஏப்ரல்","மே","ஜூன்","ஜூலை","ஆகஸ்ட்","செப்டம்பர்","அக்டோபர்","நவம்பர்","டிசம்பர்",""], + namesAbbr: ["ஜனவரி","பிப்ரவரி","மார்ச்","ஏப்ரல்","மே","ஜூன்","ஜூலை","ஆகஸ்ட்","செப்டம்பர்","அக்டோபர்","நவம்பர்","டிசம்பர்",""] + }, + AM: ["காலை","காலை","காலை"], + PM: ["மாலை","மாலை","மாலை"], + patterns: { + d: "dd-MM-yyyy", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy HH:mm:ss", + g: "dd-MM-yyyy HH:mm", + G: "dd-MM-yyyy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "-", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.te-IN.js b/src/cultures/kendo.culture.te-IN.js new file mode 100644 index 00000000000..8415c6ea816 --- /dev/null +++ b/src/cultures/kendo.culture.te-IN.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["te-IN"] = { + name: "te-IN", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "రూ" + } + }, + calendars: { + standard: { + days: { + names: ["ఆదివారం","సోమవారం","మంగళవారం","బుధవారం","గురువారం","శుక్రవారం","శనివారం"], + namesAbbr: ["ఆది.","సోమ.","మంగళ.","బుధ.","గురు.","శుక్ర.","శని."], + namesShort: ["ఆ","సో","మం","బు","గు","శు","శ"] + }, + months: { + names: ["జనవరి","ఫిబ్రవరి","మార్చి","ఏప్రిల్","మే","జూన్","జూలై","ఆగస్టు","సెప్టెంబర్","అక్టోబర్","నవంబర్","డిసెంబర్",""], + namesAbbr: ["జనవరి","ఫిబ్రవరి","మార్చి","ఏప్రిల్","మే","జూన్","జూలై","ఆగస్టు","సెప్టెంబర్","అక్టోబర్","నవంబర్","డిసెంబర్",""] + }, + AM: ["పూర్వాహ్న","పూర్వాహ్న","పూర్వాహ్న"], + PM: ["అపరాహ్న","అపరాహ్న","అపరాహ్న"], + patterns: { + d: "dd-MM-yy", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy HH:mm:ss", + g: "dd-MM-yy HH:mm", + G: "dd-MM-yy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "-", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.te.js b/src/cultures/kendo.culture.te.js new file mode 100644 index 00000000000..5ea0ac08fd4 --- /dev/null +++ b/src/cultures/kendo.culture.te.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["te"] = { + name: "te", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "%" + }, + currency: { + pattern: ["$ -n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3,2], + symbol: "రూ" + } + }, + calendars: { + standard: { + days: { + names: ["ఆదివారం","సోమవారం","మంగళవారం","బుధవారం","గురువారం","శుక్రవారం","శనివారం"], + namesAbbr: ["ఆది.","సోమ.","మంగళ.","బుధ.","గురు.","శుక్ర.","శని."], + namesShort: ["ఆ","సో","మం","బు","గు","శు","శ"] + }, + months: { + names: ["జనవరి","ఫిబ్రవరి","మార్చి","ఏప్రిల్","మే","జూన్","జూలై","ఆగస్టు","సెప్టెంబర్","అక్టోబర్","నవంబర్","డిసెంబర్",""], + namesAbbr: ["జనవరి","ఫిబ్రవరి","మార్చి","ఏప్రిల్","మే","జూన్","జూలై","ఆగస్టు","సెప్టెంబర్","అక్టోబర్","నవంబర్","డిసెంబర్",""] + }, + AM: ["పూర్వాహ్న","పూర్వాహ్న","పూర్వాహ్న"], + PM: ["అపరాహ్న","అపరాహ్న","అపరాహ్న"], + patterns: { + d: "dd-MM-yy", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy HH:mm:ss", + g: "dd-MM-yy HH:mm", + G: "dd-MM-yy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "-", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.tg-Cyrl-TJ.js b/src/cultures/kendo.culture.tg-Cyrl-TJ.js new file mode 100644 index 00000000000..13718c64323 --- /dev/null +++ b/src/cultures/kendo.culture.tg-Cyrl-TJ.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["tg-Cyrl-TJ"] = { + name: "tg-Cyrl-TJ", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3,0], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3,0], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ";", + groupSize: [3,0], + symbol: "т.р." + } + }, + calendars: { + standard: { + days: { + names: ["Яш","Душанбе","Сешанбе","Чоршанбе","Панҷшанбе","Ҷумъа","Шанбе"], + namesAbbr: ["Яш","Дш","Сш","Чш","Пш","Ҷм","Шн"], + namesShort: ["Яш","Дш","Сш","Чш","Пш","Ҷм","Шн"] + }, + months: { + names: ["Январ","Феврал","Март","Апрел","Май","Июн","Июл","Август","Сентябр","Октябр","Ноябр","Декабр",""], + namesAbbr: ["Янв","Фев","Мар","Апр","Май","Июн","Июл","Авг","Сен","Окт","Ноя","Дек",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yy", + D: "d MMMM yyyy", + F: "d MMMM yyyy H:mm:ss", + g: "dd.MM.yy H:mm", + G: "dd.MM.yy H:mm:ss", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.tg-Cyrl.js b/src/cultures/kendo.culture.tg-Cyrl.js new file mode 100644 index 00000000000..261cf233a82 --- /dev/null +++ b/src/cultures/kendo.culture.tg-Cyrl.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["tg-Cyrl"] = { + name: "tg-Cyrl", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3,0], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3,0], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ";", + groupSize: [3,0], + symbol: "т.р." + } + }, + calendars: { + standard: { + days: { + names: ["Яш","Душанбе","Сешанбе","Чоршанбе","Панҷшанбе","Ҷумъа","Шанбе"], + namesAbbr: ["Яш","Дш","Сш","Чш","Пш","Ҷм","Шн"], + namesShort: ["Яш","Дш","Сш","Чш","Пш","Ҷм","Шн"] + }, + months: { + names: ["Январ","Феврал","Март","Апрел","Май","Июн","Июл","Август","Сентябр","Октябр","Ноябр","Декабр",""], + namesAbbr: ["Янв","Фев","Мар","Апр","Май","Июн","Июл","Авг","Сен","Окт","Ноя","Дек",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yy", + D: "d MMMM yyyy", + F: "d MMMM yyyy H:mm:ss", + g: "dd.MM.yy H:mm", + G: "dd.MM.yy H:mm:ss", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.tg.js b/src/cultures/kendo.culture.tg.js new file mode 100644 index 00000000000..93eda02ba67 --- /dev/null +++ b/src/cultures/kendo.culture.tg.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["tg"] = { + name: "tg", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3,0], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3,0], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ";", + groupSize: [3,0], + symbol: "т.р." + } + }, + calendars: { + standard: { + days: { + names: ["Яш","Душанбе","Сешанбе","Чоршанбе","Панҷшанбе","Ҷумъа","Шанбе"], + namesAbbr: ["Яш","Дш","Сш","Чш","Пш","Ҷм","Шн"], + namesShort: ["Яш","Дш","Сш","Чш","Пш","Ҷм","Шн"] + }, + months: { + names: ["Январ","Феврал","Март","Апрел","Май","Июн","Июл","Август","Сентябр","Октябр","Ноябр","Декабр",""], + namesAbbr: ["Янв","Фев","Мар","Апр","Май","Июн","Июл","Авг","Сен","Окт","Ноя","Дек",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yy", + D: "d MMMM yyyy", + F: "d MMMM yyyy H:mm:ss", + g: "dd.MM.yy H:mm", + G: "dd.MM.yy H:mm:ss", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.th-TH.js b/src/cultures/kendo.culture.th-TH.js new file mode 100644 index 00000000000..d0eb4c2b039 --- /dev/null +++ b/src/cultures/kendo.culture.th-TH.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["th-TH"] = { + name: "th-TH", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-$n","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "฿" + } + }, + calendars: { + standard: { + days: { + names: ["อาทิตย์","จันทร์","อังคาร","พุธ","พฤหัสบดี","ศุกร์","เสาร์"], + namesAbbr: ["อา.","จ.","อ.","พ.","พฤ.","ศ.","ส."], + namesShort: ["อ","จ","อ","พ","พ","ศ","ส"] + }, + months: { + names: ["มกราคม","กุมภาพันธ์","มีนาคม","เมษายน","พฤษภาคม","มิถุนายน","กรกฎาคม","สิงหาคม","กันยายน","ตุลาคม","พฤศจิกายน","ธันวาคม",""], + namesAbbr: ["ม.ค.","ก.พ.","มี.ค.","เม.ย.","พ.ค.","มิ.ย.","ก.ค.","ส.ค.","ก.ย.","ต.ค.","พ.ย.","ธ.ค.",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "d/M/yyyy", + D: "d MMMM yyyy", + F: "d MMMM yyyy H:mm:ss", + g: "d/M/yyyy H:mm", + G: "d/M/yyyy H:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.th.js b/src/cultures/kendo.culture.th.js new file mode 100644 index 00000000000..b87b91f7794 --- /dev/null +++ b/src/cultures/kendo.culture.th.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["th"] = { + name: "th", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-$n","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "฿" + } + }, + calendars: { + standard: { + days: { + names: ["อาทิตย์","จันทร์","อังคาร","พุธ","พฤหัสบดี","ศุกร์","เสาร์"], + namesAbbr: ["อา.","จ.","อ.","พ.","พฤ.","ศ.","ส."], + namesShort: ["อ","จ","อ","พ","พ","ศ","ส"] + }, + months: { + names: ["มกราคม","กุมภาพันธ์","มีนาคม","เมษายน","พฤษภาคม","มิถุนายน","กรกฎาคม","สิงหาคม","กันยายน","ตุลาคม","พฤศจิกายน","ธันวาคม",""], + namesAbbr: ["ม.ค.","ก.พ.","มี.ค.","เม.ย.","พ.ค.","มิ.ย.","ก.ค.","ส.ค.","ก.ย.","ต.ค.","พ.ย.","ธ.ค.",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "d/M/yyyy", + D: "d MMMM yyyy", + F: "d MMMM yyyy H:mm:ss", + g: "d/M/yyyy H:mm", + G: "d/M/yyyy H:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.tk-TM.js b/src/cultures/kendo.culture.tk-TM.js new file mode 100644 index 00000000000..3cd16554d0f --- /dev/null +++ b/src/cultures/kendo.culture.tk-TM.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["tk-TM"] = { + name: "tk-TM", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n$","n$"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "m." + } + }, + calendars: { + standard: { + days: { + names: ["Duşenbe","Sişenbe","Çarşenbe","Penşenbe","Anna","Şenbe","Ýekşenbe"], + namesAbbr: ["Db","Sb","Çb","Pb","An","Şb","Ýb"], + namesShort: ["D","S","Ç","P","A","Ş","Ý"] + }, + months: { + names: ["Ýanwar","Fewral","Mart","Aprel","Maý","lýun","lýul","Awgust","Sentýabr","Oktýabr","Noýabr","Dekabr",""], + namesAbbr: ["Ýan","Few","Mart","Apr","Maý","lýun","lýul","Awg","Sen","Okt","Not","Dek",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yy", + D: "yyyy 'ý.' MMMM d", + F: "yyyy 'ý.' MMMM d H:mm:ss", + g: "dd.MM.yy H:mm", + G: "dd.MM.yy H:mm:ss", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "yyyy 'ý.' MMMM", + Y: "yyyy 'ý.' MMMM" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.tk.js b/src/cultures/kendo.culture.tk.js new file mode 100644 index 00000000000..2594db6a945 --- /dev/null +++ b/src/cultures/kendo.culture.tk.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["tk"] = { + name: "tk", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n$","n$"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "m." + } + }, + calendars: { + standard: { + days: { + names: ["Duşenbe","Sişenbe","Çarşenbe","Penşenbe","Anna","Şenbe","Ýekşenbe"], + namesAbbr: ["Db","Sb","Çb","Pb","An","Şb","Ýb"], + namesShort: ["D","S","Ç","P","A","Ş","Ý"] + }, + months: { + names: ["Ýanwar","Fewral","Mart","Aprel","Maý","lýun","lýul","Awgust","Sentýabr","Oktýabr","Noýabr","Dekabr",""], + namesAbbr: ["Ýan","Few","Mart","Apr","Maý","lýun","lýul","Awg","Sen","Okt","Not","Dek",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yy", + D: "yyyy 'ý.' MMMM d", + F: "yyyy 'ý.' MMMM d H:mm:ss", + g: "dd.MM.yy H:mm", + G: "dd.MM.yy H:mm:ss", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "yyyy 'ý.' MMMM", + Y: "yyyy 'ý.' MMMM" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.tn-ZA.js b/src/cultures/kendo.culture.tn-ZA.js new file mode 100644 index 00000000000..1aa0c9f9545 --- /dev/null +++ b/src/cultures/kendo.culture.tn-ZA.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["tn-ZA"] = { + name: "tn-ZA", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-%n","%n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$-n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "R" + } + }, + calendars: { + standard: { + days: { + names: ["Latshipi","Mosupologo","Labobedi","Laboraro","Labone","Labotlhano","Lamatlhatso"], + namesAbbr: ["Ltp.","Mos.","Lbd.","Lbr.","Lbn.","Lbt.","Lmt."], + namesShort: ["Lp","Ms","Lb","Lr","Ln","Lt","Lm"] + }, + months: { + names: ["Ferikgong","Tlhakole","Mopitloe","Moranang","Motsheganong","Seetebosigo","Phukwi","Phatwe","Lwetse","Diphalane","Ngwanatsele","Sedimothole",""], + namesAbbr: ["Fer.","Tlhak.","Mop.","Mor.","Motsh.","Seet.","Phukw.","Phatw.","Lwets.","Diph.","Ngwan.","Sed.",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "yyyy/MM/dd", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy hh:mm:ss tt", + g: "yyyy/MM/dd hh:mm tt", + G: "yyyy/MM/dd hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.tn.js b/src/cultures/kendo.culture.tn.js new file mode 100644 index 00000000000..59527ff514e --- /dev/null +++ b/src/cultures/kendo.culture.tn.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["tn"] = { + name: "tn", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-%n","%n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$-n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "R" + } + }, + calendars: { + standard: { + days: { + names: ["Latshipi","Mosupologo","Labobedi","Laboraro","Labone","Labotlhano","Lamatlhatso"], + namesAbbr: ["Ltp.","Mos.","Lbd.","Lbr.","Lbn.","Lbt.","Lmt."], + namesShort: ["Lp","Ms","Lb","Lr","Ln","Lt","Lm"] + }, + months: { + names: ["Ferikgong","Tlhakole","Mopitloe","Moranang","Motsheganong","Seetebosigo","Phukwi","Phatwe","Lwetse","Diphalane","Ngwanatsele","Sedimothole",""], + namesAbbr: ["Fer.","Tlhak.","Mop.","Mor.","Motsh.","Seet.","Phukw.","Phatw.","Lwets.","Diph.","Ngwan.","Sed.",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "yyyy/MM/dd", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy hh:mm:ss tt", + g: "yyyy/MM/dd hh:mm tt", + G: "yyyy/MM/dd hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.tr-TR.js b/src/cultures/kendo.culture.tr-TR.js new file mode 100644 index 00000000000..2c7628de4a7 --- /dev/null +++ b/src/cultures/kendo.culture.tr-TR.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["tr-TR"] = { + name: "tr-TR", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-%n","%n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "TL" + } + }, + calendars: { + standard: { + days: { + names: ["Pazar","Pazartesi","Salı","Çarşamba","Perşembe","Cuma","Cumartesi"], + namesAbbr: ["Paz","Pzt","Sal","Çar","Per","Cum","Cmt"], + namesShort: ["Pz","Pt","Sa","Ça","Pe","Cu","Ct"] + }, + months: { + names: ["Ocak","Şubat","Mart","Nisan","Mayıs","Haziran","Temmuz","Ağustos","Eylül","Ekim","Kasım","Aralık",""], + namesAbbr: ["Oca","Şub","Mar","Nis","May","Haz","Tem","Ağu","Eyl","Eki","Kas","Ara",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yyyy", + D: "dd MMMM yyyy dddd", + F: "dd MMMM yyyy dddd HH:mm:ss", + g: "dd.MM.yyyy HH:mm", + G: "dd.MM.yyyy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.tr.js b/src/cultures/kendo.culture.tr.js new file mode 100644 index 00000000000..8d096cfe0a5 --- /dev/null +++ b/src/cultures/kendo.culture.tr.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["tr"] = { + name: "tr", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-%n","%n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "TL" + } + }, + calendars: { + standard: { + days: { + names: ["Pazar","Pazartesi","Salı","Çarşamba","Perşembe","Cuma","Cumartesi"], + namesAbbr: ["Paz","Pzt","Sal","Çar","Per","Cum","Cmt"], + namesShort: ["Pz","Pt","Sa","Ça","Pe","Cu","Ct"] + }, + months: { + names: ["Ocak","Şubat","Mart","Nisan","Mayıs","Haziran","Temmuz","Ağustos","Eylül","Ekim","Kasım","Aralık",""], + namesAbbr: ["Oca","Şub","Mar","Nis","May","Haz","Tem","Ağu","Eyl","Eki","Kas","Ara",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yyyy", + D: "dd MMMM yyyy dddd", + F: "dd MMMM yyyy dddd HH:mm:ss", + g: "dd.MM.yyyy HH:mm", + G: "dd.MM.yyyy HH:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.tt-RU.js b/src/cultures/kendo.culture.tt-RU.js new file mode 100644 index 00000000000..702ac8331fa --- /dev/null +++ b/src/cultures/kendo.culture.tt-RU.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["tt-RU"] = { + name: "tt-RU", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "р." + } + }, + calendars: { + standard: { + days: { + names: ["Якшәмбе","Дүшәмбе","Сишәмбе","Чәршәмбе","Пәнҗешәмбе","Җомга","Шимбә"], + namesAbbr: ["Якш","Дүш","Сиш","Чәрш","Пәнҗ","Җом","Шим"], + namesShort: ["Я","Д","С","Ч","П","Җ","Ш"] + }, + months: { + names: ["Гыйнвар","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь",""], + namesAbbr: ["Гыйн.","Фев.","Мар.","Апр.","Май","Июнь","Июль","Авг.","Сен.","Окт.","Нояб.","Дек.",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yyyy", + D: "d MMMM yyyy", + F: "d MMMM yyyy H:mm:ss", + g: "dd.MM.yyyy H:mm", + G: "dd.MM.yyyy H:mm:ss", + m: "d MMMM", + M: "d MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.tt.js b/src/cultures/kendo.culture.tt.js new file mode 100644 index 00000000000..25e2d72f676 --- /dev/null +++ b/src/cultures/kendo.culture.tt.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["tt"] = { + name: "tt", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "р." + } + }, + calendars: { + standard: { + days: { + names: ["Якшәмбе","Дүшәмбе","Сишәмбе","Чәршәмбе","Пәнҗешәмбе","Җомга","Шимбә"], + namesAbbr: ["Якш","Дүш","Сиш","Чәрш","Пәнҗ","Җом","Шим"], + namesShort: ["Я","Д","С","Ч","П","Җ","Ш"] + }, + months: { + names: ["Гыйнвар","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь",""], + namesAbbr: ["Гыйн.","Фев.","Мар.","Апр.","Май","Июнь","Июль","Авг.","Сен.","Окт.","Нояб.","Дек.",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yyyy", + D: "d MMMM yyyy", + F: "d MMMM yyyy H:mm:ss", + g: "dd.MM.yyyy H:mm", + G: "dd.MM.yyyy H:mm:ss", + m: "d MMMM", + M: "d MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.tzm-Latn-DZ.js b/src/cultures/kendo.culture.tzm-Latn-DZ.js new file mode 100644 index 00000000000..a2c1fc3a794 --- /dev/null +++ b/src/cultures/kendo.culture.tzm-Latn-DZ.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["tzm-Latn-DZ"] = { + name: "tzm-Latn-DZ", + numberFormat: { + pattern: ["n-"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "DZD" + } + }, + calendars: { + standard: { + days: { + names: ["Acer","Arime","Aram","Ahad","Amhadh","Sem","Sedh"], + namesAbbr: ["Ace","Ari","Ara","Aha","Amh","Sem","Sed"], + namesShort: ["Ac","Ar","Ar","Ah","Am","Se","Se"] + }, + months: { + names: ["Yenayer","Furar","Maghres","Yebrir","Mayu","Yunyu","Yulyu","Ghuct","Cutenber","Ktuber","Wambir","Dujanbir",""], + namesAbbr: ["Yen","Fur","Mag","Yeb","May","Yun","Yul","Ghu","Cut","Ktu","Wam","Duj",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd-MM-yyyy", + D: "dd MMMM, yyyy", + F: "dd MMMM, yyyy H:mm:ss", + g: "dd-MM-yyyy H:mm", + G: "dd-MM-yyyy H:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "-", + ":": ":", + firstDay: 6 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.tzm-Latn.js b/src/cultures/kendo.culture.tzm-Latn.js new file mode 100644 index 00000000000..823662bd9ba --- /dev/null +++ b/src/cultures/kendo.culture.tzm-Latn.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["tzm-Latn"] = { + name: "tzm-Latn", + numberFormat: { + pattern: ["n-"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "DZD" + } + }, + calendars: { + standard: { + days: { + names: ["Acer","Arime","Aram","Ahad","Amhadh","Sem","Sedh"], + namesAbbr: ["Ace","Ari","Ara","Aha","Amh","Sem","Sed"], + namesShort: ["Ac","Ar","Ar","Ah","Am","Se","Se"] + }, + months: { + names: ["Yenayer","Furar","Maghres","Yebrir","Mayu","Yunyu","Yulyu","Ghuct","Cutenber","Ktuber","Wambir","Dujanbir",""], + namesAbbr: ["Yen","Fur","Mag","Yeb","May","Yun","Yul","Ghu","Cut","Ktu","Wam","Duj",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd-MM-yyyy", + D: "dd MMMM, yyyy", + F: "dd MMMM, yyyy H:mm:ss", + g: "dd-MM-yyyy H:mm", + G: "dd-MM-yyyy H:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "-", + ":": ":", + firstDay: 6 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.tzm.js b/src/cultures/kendo.culture.tzm.js new file mode 100644 index 00000000000..4ae1e2147f7 --- /dev/null +++ b/src/cultures/kendo.culture.tzm.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["tzm"] = { + name: "tzm", + numberFormat: { + pattern: ["n-"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "DZD" + } + }, + calendars: { + standard: { + days: { + names: ["Acer","Arime","Aram","Ahad","Amhadh","Sem","Sedh"], + namesAbbr: ["Ace","Ari","Ara","Aha","Amh","Sem","Sed"], + namesShort: ["Ac","Ar","Ar","Ah","Am","Se","Se"] + }, + months: { + names: ["Yenayer","Furar","Maghres","Yebrir","Mayu","Yunyu","Yulyu","Ghuct","Cutenber","Ktuber","Wambir","Dujanbir",""], + namesAbbr: ["Yen","Fur","Mag","Yeb","May","Yun","Yul","Ghu","Cut","Ktu","Wam","Duj",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd-MM-yyyy", + D: "dd MMMM, yyyy", + F: "dd MMMM, yyyy H:mm:ss", + g: "dd-MM-yyyy H:mm", + G: "dd-MM-yyyy H:mm:ss", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "-", + ":": ":", + firstDay: 6 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ug-CN.js b/src/cultures/kendo.culture.ug-CN.js new file mode 100644 index 00000000000..c3e317c9fcb --- /dev/null +++ b/src/cultures/kendo.culture.ug-CN.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ug-CN"] = { + name: "ug-CN", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$-n","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "¥" + } + }, + calendars: { + standard: { + days: { + names: ["يەكشەنبە","دۈشەنبە","سەيشەنبە","چارشەنبە","پەيشەنبە","جۈمە","شەنبە"], + namesAbbr: ["يە","دۈ","سە","چا","پە","جۈ","شە"], + namesShort: ["ي","د","س","چ","پ","ج","ش"] + }, + months: { + names: ["1-ئاي","2-ئاي","3-ئاي","4-ئاي","5-ئاي","6-ئاي","7-ئاي","8-ئاي","9-ئاي","10-ئاي","11-ئاي","12-ئاي",""], + namesAbbr: ["1-ئاي","2-ئاي","3-ئاي","4-ئاي","5-ئاي","6-ئاي","7-ئاي","8-ئاي","9-ئاي","10-ئاي","11-ئاي","12-ئاي",""] + }, + AM: ["چۈشتىن بۇرۇن","چۈشتىن بۇرۇن","چۈشتىن بۇرۇن"], + PM: ["چۈشتىن كېيىن","چۈشتىن كېيىن","چۈشتىن كېيىن"], + patterns: { + d: "yyyy-M-d", + D: "yyyy-'يىلى' MMMM d-'كۈنى،'", + F: "yyyy-'يىلى' MMMM d-'كۈنى،' H:mm:ss", + g: "yyyy-M-d H:mm", + G: "yyyy-M-d H:mm:ss", + m: "MMMM d'-كۈنى'", + M: "MMMM d'-كۈنى'", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "yyyy-'يىلى' MMMM", + Y: "yyyy-'يىلى' MMMM" + }, + "/": "-", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ug.js b/src/cultures/kendo.culture.ug.js new file mode 100644 index 00000000000..8f2b1668831 --- /dev/null +++ b/src/cultures/kendo.culture.ug.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ug"] = { + name: "ug", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$-n","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "¥" + } + }, + calendars: { + standard: { + days: { + names: ["يەكشەنبە","دۈشەنبە","سەيشەنبە","چارشەنبە","پەيشەنبە","جۈمە","شەنبە"], + namesAbbr: ["يە","دۈ","سە","چا","پە","جۈ","شە"], + namesShort: ["ي","د","س","چ","پ","ج","ش"] + }, + months: { + names: ["1-ئاي","2-ئاي","3-ئاي","4-ئاي","5-ئاي","6-ئاي","7-ئاي","8-ئاي","9-ئاي","10-ئاي","11-ئاي","12-ئاي",""], + namesAbbr: ["1-ئاي","2-ئاي","3-ئاي","4-ئاي","5-ئاي","6-ئاي","7-ئاي","8-ئاي","9-ئاي","10-ئاي","11-ئاي","12-ئاي",""] + }, + AM: ["چۈشتىن بۇرۇن","چۈشتىن بۇرۇن","چۈشتىن بۇرۇن"], + PM: ["چۈشتىن كېيىن","چۈشتىن كېيىن","چۈشتىن كېيىن"], + patterns: { + d: "yyyy-M-d", + D: "yyyy-'يىلى' MMMM d-'كۈنى،'", + F: "yyyy-'يىلى' MMMM d-'كۈنى،' H:mm:ss", + g: "yyyy-M-d H:mm", + G: "yyyy-M-d H:mm:ss", + m: "MMMM d'-كۈنى'", + M: "MMMM d'-كۈنى'", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "yyyy-'يىلى' MMMM", + Y: "yyyy-'يىلى' MMMM" + }, + "/": "-", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.uk-UA.js b/src/cultures/kendo.culture.uk-UA.js new file mode 100644 index 00000000000..a0cccc71709 --- /dev/null +++ b/src/cultures/kendo.culture.uk-UA.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["uk-UA"] = { + name: "uk-UA", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n$","n$"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "₴" + } + }, + calendars: { + standard: { + days: { + names: ["неділя","понеділок","вівторок","середа","четвер","п\u0027ятниця","субота"], + namesAbbr: ["Нд","Пн","Вт","Ср","Чт","Пт","Сб"], + namesShort: ["Нд","Пн","Вт","Ср","Чт","Пт","Сб"] + }, + months: { + names: ["Січень","Лютий","Березень","Квітень","Травень","Червень","Липень","Серпень","Вересень","Жовтень","Листопад","Грудень",""], + namesAbbr: ["Січ","Лют","Бер","Кві","Тра","Чер","Лип","Сер","Вер","Жов","Лис","Гру",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yyyy", + D: "d MMMM yyyy' р.'", + F: "d MMMM yyyy' р.' H:mm:ss", + g: "dd.MM.yyyy H:mm", + G: "dd.MM.yyyy H:mm:ss", + m: "d MMMM", + M: "d MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy' р.'", + Y: "MMMM yyyy' р.'" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.uk.js b/src/cultures/kendo.culture.uk.js new file mode 100644 index 00000000000..4f9774825cf --- /dev/null +++ b/src/cultures/kendo.culture.uk.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["uk"] = { + name: "uk", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n$","n$"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "₴" + } + }, + calendars: { + standard: { + days: { + names: ["неділя","понеділок","вівторок","середа","четвер","п\u0027ятниця","субота"], + namesAbbr: ["Нд","Пн","Вт","Ср","Чт","Пт","Сб"], + namesShort: ["Нд","Пн","Вт","Ср","Чт","Пт","Сб"] + }, + months: { + names: ["Січень","Лютий","Березень","Квітень","Травень","Червень","Липень","Серпень","Вересень","Жовтень","Листопад","Грудень",""], + namesAbbr: ["Січ","Лют","Бер","Кві","Тра","Чер","Лип","Сер","Вер","Жов","Лис","Гру",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yyyy", + D: "d MMMM yyyy' р.'", + F: "d MMMM yyyy' р.' H:mm:ss", + g: "dd.MM.yyyy H:mm", + G: "dd.MM.yyyy H:mm:ss", + m: "d MMMM", + M: "d MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy' р.'", + Y: "MMMM yyyy' р.'" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ur-PK.js b/src/cultures/kendo.culture.ur-PK.js new file mode 100644 index 00000000000..fedcfe6438c --- /dev/null +++ b/src/cultures/kendo.culture.ur-PK.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ur-PK"] = { + name: "ur-PK", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$n-","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "Rs" + } + }, + calendars: { + standard: { + days: { + names: ["اتوار","پير","منگل","بدھ","جمعرات","جمعه","هفته"], + namesAbbr: ["اتوار","پير","منگل","بدھ","جمعرات","جمعه","هفته"], + namesShort: ["ا","پ","م","ب","ج","ج","ه"] + }, + months: { + names: ["جنوری","فروری","مارچ","اپریل","مئی","جون","جولائی","اگست","ستمبر","اکتوبر","نومبر","دسمبر",""], + namesAbbr: ["جنوری","فروری","مارچ","اپریل","مئی","جون","جولائی","اگست","ستمبر","اکتوبر","نومبر","دسمبر",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "dd/MM/yyyy", + D: "dd MMMM, yyyy", + F: "dd MMMM, yyyy h:mm:ss tt", + g: "dd/MM/yyyy h:mm tt", + G: "dd/MM/yyyy h:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.ur.js b/src/cultures/kendo.culture.ur.js new file mode 100644 index 00000000000..880985c0d2c --- /dev/null +++ b/src/cultures/kendo.culture.ur.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["ur"] = { + name: "ur", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$n-","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "Rs" + } + }, + calendars: { + standard: { + days: { + names: ["اتوار","پير","منگل","بدھ","جمعرات","جمعه","هفته"], + namesAbbr: ["اتوار","پير","منگل","بدھ","جمعرات","جمعه","هفته"], + namesShort: ["ا","پ","م","ب","ج","ج","ه"] + }, + months: { + names: ["جنوری","فروری","مارچ","اپریل","مئی","جون","جولائی","اگست","ستمبر","اکتوبر","نومبر","دسمبر",""], + namesAbbr: ["جنوری","فروری","مارچ","اپریل","مئی","جون","جولائی","اگست","ستمبر","اکتوبر","نومبر","دسمبر",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "dd/MM/yyyy", + D: "dd MMMM, yyyy", + F: "dd MMMM, yyyy h:mm:ss tt", + g: "dd/MM/yyyy h:mm tt", + G: "dd/MM/yyyy h:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.uz-Cyrl-UZ.js b/src/cultures/kendo.culture.uz-Cyrl-UZ.js new file mode 100644 index 00000000000..e0baa277952 --- /dev/null +++ b/src/cultures/kendo.culture.uz-Cyrl-UZ.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["uz-Cyrl-UZ"] = { + name: "uz-Cyrl-UZ", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "сўм" + } + }, + calendars: { + standard: { + days: { + names: ["якшанба","душанба","сешанба","чоршанба","пайшанба","жума","шанба"], + namesAbbr: ["якш","дш","сш","чш","пш","ж","ш"], + namesShort: ["я","д","с","ч","п","ж","ш"] + }, + months: { + names: ["Январ","Феврал","Март","Апрел","Май","Июн","Июл","Август","Сентябр","Октябр","Ноябр","Декабр",""], + namesAbbr: ["Янв","Фев","Мар","Апр","Май","Июн","Июл","Авг","Сен","Окт","Ноя","Дек",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yyyy", + D: "yyyy 'йил' d-MMMM", + F: "yyyy 'йил' d-MMMM HH:mm:ss", + g: "dd.MM.yyyy HH:mm", + G: "dd.MM.yyyy HH:mm:ss", + m: "d-MMMM", + M: "d-MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.uz-Cyrl.js b/src/cultures/kendo.culture.uz-Cyrl.js new file mode 100644 index 00000000000..46f5f413cc6 --- /dev/null +++ b/src/cultures/kendo.culture.uz-Cyrl.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["uz-Cyrl"] = { + name: "uz-Cyrl", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "сўм" + } + }, + calendars: { + standard: { + days: { + names: ["якшанба","душанба","сешанба","чоршанба","пайшанба","жума","шанба"], + namesAbbr: ["якш","дш","сш","чш","пш","ж","ш"], + namesShort: ["я","д","с","ч","п","ж","ш"] + }, + months: { + names: ["Январ","Феврал","Март","Апрел","Май","Июн","Июл","Август","Сентябр","Октябр","Ноябр","Декабр",""], + namesAbbr: ["Янв","Фев","Мар","Апр","Май","Июн","Июл","Авг","Сен","Окт","Ноя","Дек",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd.MM.yyyy", + D: "yyyy 'йил' d-MMMM", + F: "yyyy 'йил' d-MMMM HH:mm:ss", + g: "dd.MM.yyyy HH:mm", + G: "dd.MM.yyyy HH:mm:ss", + m: "d-MMMM", + M: "d-MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": ".", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.uz-Latn-UZ.js b/src/cultures/kendo.culture.uz-Latn-UZ.js new file mode 100644 index 00000000000..63883f117f4 --- /dev/null +++ b/src/cultures/kendo.culture.uz-Latn-UZ.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["uz-Latn-UZ"] = { + name: "uz-Latn-UZ", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 0, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "so'm" + } + }, + calendars: { + standard: { + days: { + names: ["yakshanba","dushanba","seshanba","chorshanba","payshanba","juma","shanba"], + namesAbbr: ["yak.","dsh.","sesh.","chr.","psh.","jm.","sh."], + namesShort: ["ya","d","s","ch","p","j","sh"] + }, + months: { + names: ["yanvar","fevral","mart","aprel","may","iyun","iyul","avgust","sentyabr","oktyabr","noyabr","dekabr",""], + namesAbbr: ["yanvar","fevral","mart","aprel","may","iyun","iyul","avgust","sentyabr","oktyabr","noyabr","dekabr",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd/MM yyyy", + D: "yyyy 'yil' d-MMMM", + F: "yyyy 'yil' d-MMMM HH:mm:ss", + g: "dd/MM yyyy HH:mm", + G: "dd/MM yyyy HH:mm:ss", + m: "d-MMMM", + M: "d-MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.uz-Latn.js b/src/cultures/kendo.culture.uz-Latn.js new file mode 100644 index 00000000000..d2ddd301531 --- /dev/null +++ b/src/cultures/kendo.culture.uz-Latn.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["uz-Latn"] = { + name: "uz-Latn", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 0, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "so'm" + } + }, + calendars: { + standard: { + days: { + names: ["yakshanba","dushanba","seshanba","chorshanba","payshanba","juma","shanba"], + namesAbbr: ["yak.","dsh.","sesh.","chr.","psh.","jm.","sh."], + namesShort: ["ya","d","s","ch","p","j","sh"] + }, + months: { + names: ["yanvar","fevral","mart","aprel","may","iyun","iyul","avgust","sentyabr","oktyabr","noyabr","dekabr",""], + namesAbbr: ["yanvar","fevral","mart","aprel","may","iyun","iyul","avgust","sentyabr","oktyabr","noyabr","dekabr",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd/MM yyyy", + D: "yyyy 'yil' d-MMMM", + F: "yyyy 'yil' d-MMMM HH:mm:ss", + g: "dd/MM yyyy HH:mm", + G: "dd/MM yyyy HH:mm:ss", + m: "d-MMMM", + M: "d-MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.uz.js b/src/cultures/kendo.culture.uz.js new file mode 100644 index 00000000000..f00de3e4525 --- /dev/null +++ b/src/cultures/kendo.culture.uz.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["uz"] = { + name: "uz", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 0, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "so'm" + } + }, + calendars: { + standard: { + days: { + names: ["yakshanba","dushanba","seshanba","chorshanba","payshanba","juma","shanba"], + namesAbbr: ["yak.","dsh.","sesh.","chr.","psh.","jm.","sh."], + namesShort: ["ya","d","s","ch","p","j","sh"] + }, + months: { + names: ["yanvar","fevral","mart","aprel","may","iyun","iyul","avgust","sentyabr","oktyabr","noyabr","dekabr",""], + namesAbbr: ["yanvar","fevral","mart","aprel","may","iyun","iyul","avgust","sentyabr","oktyabr","noyabr","dekabr",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd/MM yyyy", + D: "yyyy 'yil' d-MMMM", + F: "yyyy 'yil' d-MMMM HH:mm:ss", + g: "dd/MM yyyy HH:mm", + G: "dd/MM yyyy HH:mm:ss", + m: "d-MMMM", + M: "d-MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.vi-VN.js b/src/cultures/kendo.culture.vi-VN.js new file mode 100644 index 00000000000..182a0b00589 --- /dev/null +++ b/src/cultures/kendo.culture.vi-VN.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["vi-VN"] = { + name: "vi-VN", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "₫" + } + }, + calendars: { + standard: { + days: { + names: ["Chủ Nhật","Thứ Hai","Thứ Ba","Thứ Tư","Thứ Năm","Thứ Sáu","Thứ Bảy"], + namesAbbr: ["CN","Hai","Ba","Tư","Năm","Sáu","Bảy"], + namesShort: ["C","H","B","T","N","S","B"] + }, + months: { + names: ["Tháng Giêng","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",""], + namesAbbr: ["Thg1","Thg2","Thg3","Thg4","Thg5","Thg6","Thg7","Thg8","Thg9","Thg10","Thg11","Thg12",""] + }, + AM: ["SA","sa","SA"], + PM: ["CH","ch","CH"], + patterns: { + d: "dd/MM/yyyy", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy h:mm:ss tt", + g: "dd/MM/yyyy h:mm tt", + G: "dd/MM/yyyy h:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.vi.js b/src/cultures/kendo.culture.vi.js new file mode 100644 index 00000000000..347ebb482c1 --- /dev/null +++ b/src/cultures/kendo.culture.vi.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["vi"] = { + name: "vi", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": ".", + ".": ",", + groupSize: [3], + symbol: "₫" + } + }, + calendars: { + standard: { + days: { + names: ["Chủ Nhật","Thứ Hai","Thứ Ba","Thứ Tư","Thứ Năm","Thứ Sáu","Thứ Bảy"], + namesAbbr: ["CN","Hai","Ba","Tư","Năm","Sáu","Bảy"], + namesShort: ["C","H","B","T","N","S","B"] + }, + months: { + names: ["Tháng Giêng","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",""], + namesAbbr: ["Thg1","Thg2","Thg3","Thg4","Thg5","Thg6","Thg7","Thg8","Thg9","Thg10","Thg11","Thg12",""] + }, + AM: ["SA","sa","SA"], + PM: ["CH","ch","CH"], + patterns: { + d: "dd/MM/yyyy", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy h:mm:ss tt", + g: "dd/MM/yyyy h:mm tt", + G: "dd/MM/yyyy h:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.wo-SN.js b/src/cultures/kendo.culture.wo-SN.js new file mode 100644 index 00000000000..7a8f257b8f6 --- /dev/null +++ b/src/cultures/kendo.culture.wo-SN.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["wo-SN"] = { + name: "wo-SN", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "XOF" + } + }, + calendars: { + standard: { + days: { + names: ["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"], + namesAbbr: ["dim.","lun.","mar.","mer.","jeu.","ven.","sam."], + namesShort: ["di","lu","ma","me","je","ve","sa"] + }, + months: { + names: ["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre",""], + namesAbbr: ["janv.","févr.","mars","avr.","mai","juin","juil.","août","sept.","oct.","nov.","déc.",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd/MM/yyyy", + D: "dddd d MMMM yyyy", + F: "dddd d MMMM yyyy HH:mm:ss", + g: "dd/MM/yyyy HH:mm", + G: "dd/MM/yyyy HH:mm:ss", + m: "d MMMM", + M: "d MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.wo.js b/src/cultures/kendo.culture.wo.js new file mode 100644 index 00000000000..e329e77eb9b --- /dev/null +++ b/src/cultures/kendo.culture.wo.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["wo"] = { + name: "wo", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-n $","n $"], + decimals: 2, + ",": " ", + ".": ",", + groupSize: [3], + symbol: "XOF" + } + }, + calendars: { + standard: { + days: { + names: ["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"], + namesAbbr: ["dim.","lun.","mar.","mer.","jeu.","ven.","sam."], + namesShort: ["di","lu","ma","me","je","ve","sa"] + }, + months: { + names: ["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre",""], + namesAbbr: ["janv.","févr.","mars","avr.","mai","juin","juil.","août","sept.","oct.","nov.","déc.",""] + }, + AM: [""], + PM: [""], + patterns: { + d: "dd/MM/yyyy", + D: "dddd d MMMM yyyy", + F: "dddd d MMMM yyyy HH:mm:ss", + g: "dd/MM/yyyy HH:mm", + G: "dd/MM/yyyy HH:mm:ss", + m: "d MMMM", + M: "d MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "HH:mm", + T: "HH:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 1 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.xh-ZA.js b/src/cultures/kendo.culture.xh-ZA.js new file mode 100644 index 00000000000..5aae19885c1 --- /dev/null +++ b/src/cultures/kendo.culture.xh-ZA.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["xh-ZA"] = { + name: "xh-ZA", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-%n","%n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$-n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "R" + } + }, + calendars: { + standard: { + days: { + names: ["iCawa","uMvulo","uLwesibini","uLwesithathu","uLwesine","uLwesihlanu","uMgqibelo"], + namesAbbr: ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"], + namesShort: ["Ca","Mv","Lb","Lt","Ln","Lh","Mg"] + }, + months: { + names: ["Mqungu","Mdumba","Kwindla","Tshazimpuzi","Canzibe","Silimela","Khala","Thupha","Msintsi","Dwarha","Nkanga","Mnga",""], + namesAbbr: ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "yyyy/MM/dd", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy hh:mm:ss tt", + g: "yyyy/MM/dd hh:mm tt", + G: "yyyy/MM/dd hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.xh.js b/src/cultures/kendo.culture.xh.js new file mode 100644 index 00000000000..cfd6a206dae --- /dev/null +++ b/src/cultures/kendo.culture.xh.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["xh"] = { + name: "xh", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-%n","%n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$-n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "R" + } + }, + calendars: { + standard: { + days: { + names: ["iCawa","uMvulo","uLwesibini","uLwesithathu","uLwesine","uLwesihlanu","uMgqibelo"], + namesAbbr: ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"], + namesShort: ["Ca","Mv","Lb","Lt","Ln","Lh","Mg"] + }, + months: { + names: ["Mqungu","Mdumba","Kwindla","Tshazimpuzi","Canzibe","Silimela","Khala","Thupha","Msintsi","Dwarha","Nkanga","Mnga",""], + namesAbbr: ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "yyyy/MM/dd", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy hh:mm:ss tt", + g: "yyyy/MM/dd hh:mm tt", + G: "yyyy/MM/dd hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.yo-NG.js b/src/cultures/kendo.culture.yo-NG.js new file mode 100644 index 00000000000..0e832f2e100 --- /dev/null +++ b/src/cultures/kendo.culture.yo-NG.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["yo-NG"] = { + name: "yo-NG", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$-n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "N" + } + }, + calendars: { + standard: { + days: { + names: ["Aiku","Aje","Isegun","Ojo\u0027ru","Ojo\u0027bo","Eti","Abameta"], + namesAbbr: ["Aik","Aje","Ise","Ojo","Ojo","Eti","Aba"], + namesShort: ["A","A","I","O","O","E","A"] + }, + months: { + names: ["Osu kinni","Osu keji","Osu keta","Osu kerin","Osu karun","Osu kefa","Osu keje","Osu kejo","Osu kesan","Osu kewa","Osu kokanla","Osu keresi",""], + namesAbbr: ["kin.","kej.","ket.","ker.","kar.","kef.","kej.","kej.","kes.","kew.","kok.","ker.",""] + }, + AM: ["Owuro","owuro","OWURO"], + PM: ["Ale","ale","ALE"], + patterns: { + d: "d/M/yyyy", + D: "dddd, MMMM dd, yyyy", + F: "dddd, MMMM dd, yyyy h:mm:ss tt", + g: "d/M/yyyy h:mm tt", + G: "d/M/yyyy h:mm:ss tt", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.yo.js b/src/cultures/kendo.culture.yo.js new file mode 100644 index 00000000000..857f53abc2d --- /dev/null +++ b/src/cultures/kendo.culture.yo.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["yo"] = { + name: "yo", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n %","n %"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$-n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "N" + } + }, + calendars: { + standard: { + days: { + names: ["Aiku","Aje","Isegun","Ojo\u0027ru","Ojo\u0027bo","Eti","Abameta"], + namesAbbr: ["Aik","Aje","Ise","Ojo","Ojo","Eti","Aba"], + namesShort: ["A","A","I","O","O","E","A"] + }, + months: { + names: ["Osu kinni","Osu keji","Osu keta","Osu kerin","Osu karun","Osu kefa","Osu keje","Osu kejo","Osu kesan","Osu kewa","Osu kokanla","Osu keresi",""], + namesAbbr: ["kin.","kej.","ket.","ker.","kar.","kef.","kej.","kej.","kes.","kew.","kok.","ker.",""] + }, + AM: ["Owuro","owuro","OWURO"], + PM: ["Ale","ale","ALE"], + patterns: { + d: "d/M/yyyy", + D: "dddd, MMMM dd, yyyy", + F: "dddd, MMMM dd, yyyy h:mm:ss tt", + g: "d/M/yyyy h:mm tt", + G: "d/M/yyyy h:mm:ss tt", + m: "MMMM dd", + M: "MMMM dd", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "h:mm tt", + T: "h:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM, yyyy", + Y: "MMMM, yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.zh-CHS.js b/src/cultures/kendo.culture.zh-CHS.js new file mode 100644 index 00000000000..ed89791693d --- /dev/null +++ b/src/cultures/kendo.culture.zh-CHS.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["zh-CHS"] = { + name: "zh-CHS", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$-n","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "¥" + } + }, + calendars: { + standard: { + days: { + names: ["星期日","星期一","星期二","星期三","星期四","星期五","星期六"], + namesAbbr: ["周日","周一","周二","周三","周四","周五","周六"], + namesShort: ["日","一","二","三","四","五","六"] + }, + months: { + names: ["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月",""], + namesAbbr: ["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月",""] + }, + AM: ["上午","上午","上午"], + PM: ["下午","下午","下午"], + patterns: { + d: "yyyy/M/d", + D: "yyyy'年'M'月'd'日'", + F: "yyyy'年'M'月'd'日' H:mm:ss", + g: "yyyy/M/d H:mm", + G: "yyyy/M/d H:mm:ss", + m: "M'月'd'日'", + M: "M'月'd'日'", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "yyyy'年'M'月'", + Y: "yyyy'年'M'月'" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.zh-CHT.js b/src/cultures/kendo.culture.zh-CHT.js new file mode 100644 index 00000000000..83a84de880c --- /dev/null +++ b/src/cultures/kendo.culture.zh-CHT.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["zh-CHT"] = { + name: "zh-CHT", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["($n)","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "HK$" + } + }, + calendars: { + standard: { + days: { + names: ["星期日","星期一","星期二","星期三","星期四","星期五","星期六"], + namesAbbr: ["週日","週一","週二","週三","週四","週五","週六"], + namesShort: ["日","一","二","三","四","五","六"] + }, + months: { + names: ["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月",""], + namesAbbr: ["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月",""] + }, + AM: ["上午","上午","上午"], + PM: ["下午","下午","下午"], + patterns: { + d: "d/M/yyyy", + D: "yyyy'年'M'月'd'日'", + F: "yyyy'年'M'月'd'日' H:mm:ss", + g: "d/M/yyyy H:mm", + G: "d/M/yyyy H:mm:ss", + m: "M'月'd'日'", + M: "M'月'd'日'", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "yyyy'年'M'月'", + Y: "yyyy'年'M'月'" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.zh-CN.js b/src/cultures/kendo.culture.zh-CN.js new file mode 100644 index 00000000000..ef7d11322d0 --- /dev/null +++ b/src/cultures/kendo.culture.zh-CN.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["zh-CN"] = { + name: "zh-CN", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$-n","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "¥" + } + }, + calendars: { + standard: { + days: { + names: ["星期日","星期一","星期二","星期三","星期四","星期五","星期六"], + namesAbbr: ["周日","周一","周二","周三","周四","周五","周六"], + namesShort: ["日","一","二","三","四","五","六"] + }, + months: { + names: ["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月",""], + namesAbbr: ["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月",""] + }, + AM: ["上午","上午","上午"], + PM: ["下午","下午","下午"], + patterns: { + d: "yyyy/M/d", + D: "yyyy'年'M'月'd'日'", + F: "yyyy'年'M'月'd'日' H:mm:ss", + g: "yyyy/M/d H:mm", + G: "yyyy/M/d H:mm:ss", + m: "M'月'd'日'", + M: "M'月'd'日'", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "yyyy'年'M'月'", + Y: "yyyy'年'M'月'" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.zh-HK.js b/src/cultures/kendo.culture.zh-HK.js new file mode 100644 index 00000000000..8d6f4f8fff7 --- /dev/null +++ b/src/cultures/kendo.culture.zh-HK.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["zh-HK"] = { + name: "zh-HK", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["($n)","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "HK$" + } + }, + calendars: { + standard: { + days: { + names: ["星期日","星期一","星期二","星期三","星期四","星期五","星期六"], + namesAbbr: ["週日","週一","週二","週三","週四","週五","週六"], + namesShort: ["日","一","二","三","四","五","六"] + }, + months: { + names: ["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月",""], + namesAbbr: ["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月",""] + }, + AM: ["上午","上午","上午"], + PM: ["下午","下午","下午"], + patterns: { + d: "d/M/yyyy", + D: "yyyy'年'M'月'd'日'", + F: "yyyy'年'M'月'd'日' H:mm:ss", + g: "d/M/yyyy H:mm", + G: "d/M/yyyy H:mm:ss", + m: "M'月'd'日'", + M: "M'月'd'日'", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "yyyy'年'M'月'", + Y: "yyyy'年'M'月'" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.zh-Hans.js b/src/cultures/kendo.culture.zh-Hans.js new file mode 100644 index 00000000000..be2af417056 --- /dev/null +++ b/src/cultures/kendo.culture.zh-Hans.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["zh-Hans"] = { + name: "zh-Hans", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$-n","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "¥" + } + }, + calendars: { + standard: { + days: { + names: ["星期日","星期一","星期二","星期三","星期四","星期五","星期六"], + namesAbbr: ["周日","周一","周二","周三","周四","周五","周六"], + namesShort: ["日","一","二","三","四","五","六"] + }, + months: { + names: ["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月",""], + namesAbbr: ["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月",""] + }, + AM: ["上午","上午","上午"], + PM: ["下午","下午","下午"], + patterns: { + d: "yyyy/M/d", + D: "yyyy'年'M'月'd'日'", + F: "yyyy'年'M'月'd'日' H:mm:ss", + g: "yyyy/M/d H:mm", + G: "yyyy/M/d H:mm:ss", + m: "M'月'd'日'", + M: "M'月'd'日'", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "yyyy'年'M'月'", + Y: "yyyy'年'M'月'" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.zh-Hant.js b/src/cultures/kendo.culture.zh-Hant.js new file mode 100644 index 00000000000..81f0e803f41 --- /dev/null +++ b/src/cultures/kendo.culture.zh-Hant.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["zh-Hant"] = { + name: "zh-Hant", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["($n)","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "HK$" + } + }, + calendars: { + standard: { + days: { + names: ["星期日","星期一","星期二","星期三","星期四","星期五","星期六"], + namesAbbr: ["週日","週一","週二","週三","週四","週五","週六"], + namesShort: ["日","一","二","三","四","五","六"] + }, + months: { + names: ["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月",""], + namesAbbr: ["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月",""] + }, + AM: ["上午","上午","上午"], + PM: ["下午","下午","下午"], + patterns: { + d: "d/M/yyyy", + D: "yyyy'年'M'月'd'日'", + F: "yyyy'年'M'月'd'日' H:mm:ss", + g: "d/M/yyyy H:mm", + G: "d/M/yyyy H:mm:ss", + m: "M'月'd'日'", + M: "M'月'd'日'", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "yyyy'年'M'月'", + Y: "yyyy'年'M'月'" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.zh-MO.js b/src/cultures/kendo.culture.zh-MO.js new file mode 100644 index 00000000000..9353ef1bcfd --- /dev/null +++ b/src/cultures/kendo.culture.zh-MO.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["zh-MO"] = { + name: "zh-MO", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["($n)","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "MOP" + } + }, + calendars: { + standard: { + days: { + names: ["星期日","星期一","星期二","星期三","星期四","星期五","星期六"], + namesAbbr: ["週日","週一","週二","週三","週四","週五","週六"], + namesShort: ["日","一","二","三","四","五","六"] + }, + months: { + names: ["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月",""], + namesAbbr: ["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月",""] + }, + AM: ["上午","上午","上午"], + PM: ["下午","下午","下午"], + patterns: { + d: "d/M/yyyy", + D: "yyyy'年'M'月'd'日'", + F: "yyyy'年'M'月'd'日' H:mm:ss", + g: "d/M/yyyy H:mm", + G: "d/M/yyyy H:mm:ss", + m: "M'月'd'日'", + M: "M'月'd'日'", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "yyyy'年'M'月'", + Y: "yyyy'年'M'月'" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.zh-SG.js b/src/cultures/kendo.culture.zh-SG.js new file mode 100644 index 00000000000..9c06ee55d81 --- /dev/null +++ b/src/cultures/kendo.culture.zh-SG.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["zh-SG"] = { + name: "zh-SG", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["($n)","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "$" + } + }, + calendars: { + standard: { + days: { + names: ["星期日","星期一","星期二","星期三","星期四","星期五","星期六"], + namesAbbr: ["周日","周一","周二","周三","周四","周五","周六"], + namesShort: ["日","一","二","三","四","五","六"] + }, + months: { + names: ["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月",""], + namesAbbr: ["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "d/M/yyyy", + D: "yyyy'年'M'月'd'日'", + F: "yyyy'年'M'月'd'日' tt h:mm:ss", + g: "d/M/yyyy tt h:mm", + G: "d/M/yyyy tt h:mm:ss", + m: "M'月'd'日'", + M: "M'月'd'日'", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "tt h:mm", + T: "tt h:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "yyyy'年'M'月'", + Y: "yyyy'年'M'月'" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.zh-TW.js b/src/cultures/kendo.culture.zh-TW.js new file mode 100644 index 00000000000..e442ff35ded --- /dev/null +++ b/src/cultures/kendo.culture.zh-TW.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["zh-TW"] = { + name: "zh-TW", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["-$n","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "NT$" + } + }, + calendars: { + standard: { + days: { + names: ["星期日","星期一","星期二","星期三","星期四","星期五","星期六"], + namesAbbr: ["週日","週一","週二","週三","週四","週五","週六"], + namesShort: ["日","一","二","三","四","五","六"] + }, + months: { + names: ["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月",""], + namesAbbr: ["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月",""] + }, + AM: ["上午","上午","上午"], + PM: ["下午","下午","下午"], + patterns: { + d: "yyyy/M/d", + D: "yyyy'年'M'月'd'日'", + F: "yyyy'年'M'月'd'日' tt hh:mm:ss", + g: "yyyy/M/d tt hh:mm", + G: "yyyy/M/d tt hh:mm:ss", + m: "M'月'd'日'", + M: "M'月'd'日'", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "tt hh:mm", + T: "tt hh:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "yyyy'年'M'月'", + Y: "yyyy'年'M'月'" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.zh.js b/src/cultures/kendo.culture.zh.js new file mode 100644 index 00000000000..3e817901033 --- /dev/null +++ b/src/cultures/kendo.culture.zh.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["zh"] = { + name: "zh", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-n%","n%"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$-n","$n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "¥" + } + }, + calendars: { + standard: { + days: { + names: ["星期日","星期一","星期二","星期三","星期四","星期五","星期六"], + namesAbbr: ["周日","周一","周二","周三","周四","周五","周六"], + namesShort: ["日","一","二","三","四","五","六"] + }, + months: { + names: ["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月",""], + namesAbbr: ["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月",""] + }, + AM: ["上午","上午","上午"], + PM: ["下午","下午","下午"], + patterns: { + d: "yyyy/M/d", + D: "yyyy'年'M'月'd'日'", + F: "yyyy'年'M'月'd'日' H:mm:ss", + g: "yyyy/M/d H:mm", + G: "yyyy/M/d H:mm:ss", + m: "M'月'd'日'", + M: "M'月'd'日'", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "H:mm", + T: "H:mm:ss", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "yyyy'年'M'月'", + Y: "yyyy'年'M'月'" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.zu-ZA.js b/src/cultures/kendo.culture.zu-ZA.js new file mode 100644 index 00000000000..5e3dcdbca41 --- /dev/null +++ b/src/cultures/kendo.culture.zu-ZA.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["zu-ZA"] = { + name: "zu-ZA", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-%n","%n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$-n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "R" + } + }, + calendars: { + standard: { + days: { + names: ["iSonto","uMsombuluko","uLwesibili","uLwesithathu","uLwesine","uLwesihlanu","uMgqibelo"], + namesAbbr: ["Son.","Mso.","Bi.","Tha.","Ne.","Hla.","Mgq."], + namesShort: ["Su","Mo","Tu","We","Th","Fr","Sa"] + }, + months: { + names: ["uMasingana","uNhlolanja","uNdasa","uMbaso","uNhlaba","uNhlangulana","uNtulikazi","uNcwaba","uMandulo","uMfumfu","uLwezi","uZibandlela",""], + namesAbbr: ["Mas.","Nhlo.","Nda.","Mba.","Nhla.","Nhlang.","Ntu.","Ncwa.","Man.","Mfu.","Lwe.","Zib.",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "yyyy/MM/dd", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy hh:mm:ss tt", + g: "yyyy/MM/dd hh:mm tt", + G: "yyyy/MM/dd hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/cultures/kendo.culture.zu.js b/src/cultures/kendo.culture.zu.js new file mode 100644 index 00000000000..71c9e1dd1e2 --- /dev/null +++ b/src/cultures/kendo.culture.zu.js @@ -0,0 +1,61 @@ +(function( window, undefined ) { + kendo.cultures["zu"] = { + name: "zu", + numberFormat: { + pattern: ["-n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + percent: { + pattern: ["-%n","%n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "%" + }, + currency: { + pattern: ["$-n","$ n"], + decimals: 2, + ",": ",", + ".": ".", + groupSize: [3], + symbol: "R" + } + }, + calendars: { + standard: { + days: { + names: ["iSonto","uMsombuluko","uLwesibili","uLwesithathu","uLwesine","uLwesihlanu","uMgqibelo"], + namesAbbr: ["Son.","Mso.","Bi.","Tha.","Ne.","Hla.","Mgq."], + namesShort: ["Su","Mo","Tu","We","Th","Fr","Sa"] + }, + months: { + names: ["uMasingana","uNhlolanja","uNdasa","uMbaso","uNhlaba","uNhlangulana","uNtulikazi","uNcwaba","uMandulo","uMfumfu","uLwezi","uZibandlela",""], + namesAbbr: ["Mas.","Nhlo.","Nda.","Mba.","Nhla.","Nhlang.","Ntu.","Ncwa.","Man.","Mfu.","Lwe.","Zib.",""] + }, + AM: ["AM","am","AM"], + PM: ["PM","pm","PM"], + patterns: { + d: "yyyy/MM/dd", + D: "dd MMMM yyyy", + F: "dd MMMM yyyy hh:mm:ss tt", + g: "yyyy/MM/dd hh:mm tt", + G: "yyyy/MM/dd hh:mm:ss tt", + m: "dd MMMM", + M: "dd MMMM", + s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", + t: "hh:mm tt", + T: "hh:mm:ss tt", + u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", + y: "MMMM yyyy", + Y: "MMMM yyyy" + }, + "/": "/", + ":": ":", + firstDay: 0 + } + } + } +})(this); diff --git a/src/jquery.js b/src/jquery.js new file mode 100644 index 00000000000..e2c203fe978 --- /dev/null +++ b/src/jquery.js @@ -0,0 +1,9597 @@ +/*! + * jQuery JavaScript Library v1.9.1 + * http://jquery.com/ + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * + * Copyright 2005, 2012 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2013-2-4 + */ +(function( window, undefined ) { + +// Can't do this because several apps including ASP.NET trace +// the stack via arguments.caller.callee and Firefox dies if +// you try to trace through "use strict" call chains. (#13335) +// Support: Firefox 18+ +//"use strict"; +var + // The deferred used on DOM ready + readyList, + + // A central reference to the root jQuery(document) + rootjQuery, + + // Support: IE<9 + // For `typeof node.method` instead of `node.method !== undefined` + core_strundefined = typeof undefined, + + // Use the correct document accordingly with window argument (sandbox) + document = window.document, + location = window.location, + + // Map over jQuery in case of overwrite + _jQuery = window.jQuery, + + // Map over the $ in case of overwrite + _$ = window.$, + + // [[Class]] -> type pairs + class2type = {}, + + // List of deleted data cache ids, so we can reuse them + core_deletedIds = [], + + core_version = "1.9.1", + + // Save a reference to some core methods + core_concat = core_deletedIds.concat, + core_push = core_deletedIds.push, + core_slice = core_deletedIds.slice, + core_indexOf = core_deletedIds.indexOf, + core_toString = class2type.toString, + core_hasOwn = class2type.hasOwnProperty, + core_trim = core_version.trim, + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + return new jQuery.fn.init( selector, context, rootjQuery ); + }, + + // Used for matching numbers + core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source, + + // Used for splitting on whitespace + core_rnotwhite = /\S+/g, + + // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE) + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + rquickExpr = /^(?:(<[\w\W]+>)[^>]*|#([\w-]*))$/, + + // Match a standalone tag + rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, + + // JSON RegExp + rvalidchars = /^[\],:{}\s]*$/, + rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, + rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g, + rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g, + + // Matches dashed string for camelizing + rmsPrefix = /^-ms-/, + rdashAlpha = /-([\da-z])/gi, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return letter.toUpperCase(); + }, + + // The ready event handler + completed = function( event ) { + + // readyState === "complete" is good enough for us to call the dom ready in oldIE + if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) { + detach(); + jQuery.ready(); + } + }, + // Clean-up method for dom ready events + detach = function() { + if ( document.addEventListener ) { + document.removeEventListener( "DOMContentLoaded", completed, false ); + window.removeEventListener( "load", completed, false ); + + } else { + document.detachEvent( "onreadystatechange", completed ); + window.detachEvent( "onload", completed ); + } + }; + +jQuery.fn = jQuery.prototype = { + // The current version of jQuery being used + jquery: core_version, + + constructor: jQuery, + init: function( selector, context, rootjQuery ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + + // scripts is true for back-compat + jQuery.merge( this, jQuery.parseHTML( + match[1], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + // Properties of context are called as methods if possible + if ( jQuery.isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[2] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id !== match[2] ) { + return rootjQuery.find( selector ); + } + + // Otherwise, we inject the element directly into the jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || rootjQuery ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return rootjQuery.ready( selector ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }, + + // Start with an empty selector + selector: "", + + // The default length of a jQuery object is 0 + length: 0, + + // The number of elements contained in the matched element set + size: function() { + return this.length; + }, + + toArray: function() { + return core_slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num == null ? + + // Return a 'clean' array + this.toArray() : + + // Return just the object + ( num < 0 ? this[ this.length + num ] : this[ num ] ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + ret.context = this.context; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + ready: function( fn ) { + // Add the callback + jQuery.ready.promise().done( fn ); + + return this; + }, + + slice: function() { + return this.pushStack( core_slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function( elem, i ) { + return callback.call( elem, i, elem ); + })); + }, + + end: function() { + return this.prevObject || this.constructor(null); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: core_push, + sort: [].sort, + splice: [].splice +}; + +// Give the init function the jQuery prototype for later instantiation +jQuery.fn.init.prototype = jQuery.fn; + +jQuery.extend = jQuery.fn.extend = function() { + var src, copyIsArray, copy, name, options, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction(target) ) { + target = {}; + } + + // extend jQuery itself if only one argument is passed + if ( length === i ) { + target = this; + --i; + } + + for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) { + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray(src) ? src : []; + + } else { + clone = src && jQuery.isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend({ + noConflict: function( deep ) { + if ( window.$ === jQuery ) { + window.$ = _$; + } + + if ( deep && window.jQuery === jQuery ) { + window.jQuery = _jQuery; + } + + return jQuery; + }, + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( !document.body ) { + return setTimeout( jQuery.ready ); + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.trigger ) { + jQuery( document ).trigger("ready").off("ready"); + } + }, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return jQuery.type(obj) === "function"; + }, + + isArray: Array.isArray || function( obj ) { + return jQuery.type(obj) === "array"; + }, + + isWindow: function( obj ) { + return obj != null && obj == obj.window; + }, + + isNumeric: function( obj ) { + return !isNaN( parseFloat(obj) ) && isFinite( obj ); + }, + + type: function( obj ) { + if ( obj == null ) { + return String( obj ); + } + return typeof obj === "object" || typeof obj === "function" ? + class2type[ core_toString.call(obj) ] || "object" : + typeof obj; + }, + + isPlainObject: function( obj ) { + // Must be an Object. + // Because of IE, we also have to check the presence of the constructor property. + // Make sure that DOM nodes and window objects don't pass through, as well + if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + try { + // Not own constructor property must be Object + if ( obj.constructor && + !core_hasOwn.call(obj, "constructor") && + !core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { + return false; + } + } catch ( e ) { + // IE8,9 Will throw exceptions on certain host objects #9897 + return false; + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + + var key; + for ( key in obj ) {} + + return key === undefined || core_hasOwn.call( obj, key ); + }, + + isEmptyObject: function( obj ) { + var name; + for ( name in obj ) { + return false; + } + return true; + }, + + error: function( msg ) { + throw new Error( msg ); + }, + + // data: string of html + // context (optional): If specified, the fragment will be created in this context, defaults to document + // keepScripts (optional): If true, will include scripts passed in the html string + parseHTML: function( data, context, keepScripts ) { + if ( !data || typeof data !== "string" ) { + return null; + } + if ( typeof context === "boolean" ) { + keepScripts = context; + context = false; + } + context = context || document; + + var parsed = rsingleTag.exec( data ), + scripts = !keepScripts && []; + + // Single tag + if ( parsed ) { + return [ context.createElement( parsed[1] ) ]; + } + + parsed = jQuery.buildFragment( [ data ], context, scripts ); + if ( scripts ) { + jQuery( scripts ).remove(); + } + return jQuery.merge( [], parsed.childNodes ); + }, + + parseJSON: function( data ) { + // Attempt to parse using the native JSON parser first + if ( window.JSON && window.JSON.parse ) { + return window.JSON.parse( data ); + } + + if ( data === null ) { + return data; + } + + if ( typeof data === "string" ) { + + // Make sure leading/trailing whitespace is removed (IE can't handle it) + data = jQuery.trim( data ); + + if ( data ) { + // Make sure the incoming data is actual JSON + // Logic borrowed from http://json.org/json2.js + if ( rvalidchars.test( data.replace( rvalidescape, "@" ) + .replace( rvalidtokens, "]" ) + .replace( rvalidbraces, "")) ) { + + return ( new Function( "return " + data ) )(); + } + } + } + + jQuery.error( "Invalid JSON: " + data ); + }, + + // Cross-browser xml parsing + parseXML: function( data ) { + var xml, tmp; + if ( !data || typeof data !== "string" ) { + return null; + } + try { + if ( window.DOMParser ) { // Standard + tmp = new DOMParser(); + xml = tmp.parseFromString( data , "text/xml" ); + } else { // IE + xml = new ActiveXObject( "Microsoft.XMLDOM" ); + xml.async = "false"; + xml.loadXML( data ); + } + } catch( e ) { + xml = undefined; + } + if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; + }, + + noop: function() {}, + + // Evaluates a script in a global context + // Workarounds based on findings by Jim Driscoll + // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context + globalEval: function( data ) { + if ( data && jQuery.trim( data ) ) { + // We use execScript on Internet Explorer + // We use an anonymous function so that context is window + // rather than jQuery in Firefox + ( window.execScript || function( data ) { + window[ "eval" ].call( window, data ); + } )( data ); + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + }, + + // args is for internal usage only + each: function( obj, callback, args ) { + var value, + i = 0, + length = obj.length, + isArray = isArraylike( obj ); + + if ( args ) { + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback.apply( obj[ i ], args ); + + if ( value === false ) { + break; + } + } + } else { + for ( i in obj ) { + value = callback.apply( obj[ i ], args ); + + if ( value === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback.call( obj[ i ], i, obj[ i ] ); + + if ( value === false ) { + break; + } + } + } else { + for ( i in obj ) { + value = callback.call( obj[ i ], i, obj[ i ] ); + + if ( value === false ) { + break; + } + } + } + } + + return obj; + }, + + // Use native String.trim function wherever possible + trim: core_trim && !core_trim.call("\uFEFF\xA0") ? + function( text ) { + return text == null ? + "" : + core_trim.call( text ); + } : + + // Otherwise use our own trimming functionality + function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArraylike( Object(arr) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + core_push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + var len; + + if ( arr ) { + if ( core_indexOf ) { + return core_indexOf.call( arr, elem, i ); + } + + len = arr.length; + i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; + + for ( ; i < len; i++ ) { + // Skip accessing in sparse arrays + if ( i in arr && arr[ i ] === elem ) { + return i; + } + } + } + + return -1; + }, + + merge: function( first, second ) { + var l = second.length, + i = first.length, + j = 0; + + if ( typeof l === "number" ) { + for ( ; j < l; j++ ) { + first[ i++ ] = second[ j ]; + } + } else { + while ( second[j] !== undefined ) { + first[ i++ ] = second[ j++ ]; + } + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, inv ) { + var retVal, + ret = [], + i = 0, + length = elems.length; + inv = !!inv; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + retVal = !!callback( elems[ i ], i ); + if ( inv !== retVal ) { + ret.push( elems[ i ] ); + } + } + + return ret; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var value, + i = 0, + length = elems.length, + isArray = isArraylike( elems ), + ret = []; + + // Go through the array, translating each of the items to their + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + } + + // Flatten any nested arrays + return core_concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + var args, proxy, tmp; + + if ( typeof context === "string" ) { + tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + args = core_slice.call( arguments, 2 ); + proxy = function() { + return fn.apply( context || this, args.concat( core_slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || jQuery.guid++; + + return proxy; + }, + + // Multifunctional method to get and set values of a collection + // The value/s can optionally be executed if it's a function + access: function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + length = elems.length, + bulk = key == null; + + // Sets many values + if ( jQuery.type( key ) === "object" ) { + chainable = true; + for ( i in key ) { + jQuery.access( elems, fn, i, key[i], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !jQuery.isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < length; i++ ) { + fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) ); + } + } + } + + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + length ? fn( elems[0], key ) : emptyGet; + }, + + now: function() { + return ( new Date() ).getTime(); + } +}); + +jQuery.ready.promise = function( obj ) { + if ( !readyList ) { + + readyList = jQuery.Deferred(); + + // Catch cases where $(document).ready() is called after the browser event has already occurred. + // we once tried to use readyState "interactive" here, but it caused issues like the one + // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + setTimeout( jQuery.ready ); + + // Standards-based browsers support DOMContentLoaded + } else if ( document.addEventListener ) { + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed, false ); + + // If IE event model is used + } else { + // Ensure firing before onload, maybe late but safe also for iframes + document.attachEvent( "onreadystatechange", completed ); + + // A fallback to window.onload, that will always work + window.attachEvent( "onload", completed ); + + // If IE and not a frame + // continually check to see if the document is ready + var top = false; + + try { + top = window.frameElement == null && document.documentElement; + } catch(e) {} + + if ( top && top.doScroll ) { + (function doScrollCheck() { + if ( !jQuery.isReady ) { + + try { + // Use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + top.doScroll("left"); + } catch(e) { + return setTimeout( doScrollCheck, 50 ); + } + + // detach all dom ready events + detach(); + + // and execute any waiting functions + jQuery.ready(); + } + })(); + } + } + } + return readyList.promise( obj ); +}; + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +function isArraylike( obj ) { + var length = obj.length, + type = jQuery.type( obj ); + + if ( jQuery.isWindow( obj ) ) { + return false; + } + + if ( obj.nodeType === 1 && length ) { + return true; + } + + return type === "array" || type !== "function" && + ( length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj ); +} + +// All jQuery objects should point back to these +rootjQuery = jQuery(document); +// String to Object options format cache +var optionsCache = {}; + +// Convert String-formatted options into Object-formatted ones and store in cache +function createOptions( options ) { + var object = optionsCache[ options ] = {}; + jQuery.each( options.match( core_rnotwhite ) || [], function( _, flag ) { + object[ flag ] = true; + }); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + ( optionsCache[ options ] || createOptions( options ) ) : + jQuery.extend( {}, options ); + + var // Flag to know if list is currently firing + firing, + // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list was already fired + fired, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // First callback to fire (used internally by add and fireWith) + firingStart, + // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = !options.once && [], + // Fire callbacks + fire = function( data ) { + memory = options.memory && data; + fired = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + firing = true; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { + memory = false; // To prevent further calls using add + break; + } + } + firing = false; + if ( list ) { + if ( stack ) { + if ( stack.length ) { + fire( stack.shift() ); + } + } else if ( memory ) { + list = []; + } else { + self.disable(); + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + // First, we save the current length + var start = list.length; + (function add( args ) { + jQuery.each( args, function( _, arg ) { + var type = jQuery.type( arg ); + if ( type === "function" ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && type !== "string" ) { + // Inspect recursively + add( arg ); + } + }); + })( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away + } else if ( memory ) { + firingStart = start; + fire( memory ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + jQuery.each( arguments, function( _, arg ) { + var index; + while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + // Handle firing indexes + if ( firing ) { + if ( index <= firingLength ) { + firingLength--; + } + if ( index <= firingIndex ) { + firingIndex--; + } + } + } + }); + } + return this; + }, + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length ); + }, + // Remove all callbacks from the list + empty: function() { + list = []; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + if ( list && ( !fired || stack ) ) { + if ( firing ) { + stack.push( args ); + } else { + fire( args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; +jQuery.extend({ + + Deferred: function( func ) { + var tuples = [ + // action, add listener, listener list, final state + [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], + [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], + [ "notify", "progress", jQuery.Callbacks("memory") ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + then: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + return jQuery.Deferred(function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + var action = tuple[ 0 ], + fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; + // deferred[ done | fail | progress ] for forwarding actions to newDefer + deferred[ tuple[1] ](function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .done( newDefer.resolve ) + .fail( newDefer.reject ) + .progress( newDefer.notify ); + } else { + newDefer[ action + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); + } + }); + }); + fns = null; + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Keep pipe for back-compat + promise.pipe = promise.then; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 3 ]; + + // promise[ done | fail | progress ] = list.add + promise[ tuple[1] ] = list.add; + + // Handle state + if ( stateString ) { + list.add(function() { + // state = [ resolved | rejected ] + state = stateString; + + // [ reject_list | resolve_list ].disable; progress_list.lock + }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); + } + + // deferred[ resolve | reject | notify ] + deferred[ tuple[0] ] = function() { + deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments ); + return this; + }; + deferred[ tuple[0] + "With" ] = list.fireWith; + }); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( subordinate /* , ..., subordinateN */ ) { + var i = 0, + resolveValues = core_slice.call( arguments ), + length = resolveValues.length, + + // the count of uncompleted subordinates + remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, + + // the master Deferred. If resolveValues consist of only a single Deferred, just use that. + deferred = remaining === 1 ? subordinate : jQuery.Deferred(), + + // Update function for both resolve and progress values + updateFunc = function( i, contexts, values ) { + return function( value ) { + contexts[ i ] = this; + values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value; + if( values === progressValues ) { + deferred.notifyWith( contexts, values ); + } else if ( !( --remaining ) ) { + deferred.resolveWith( contexts, values ); + } + }; + }, + + progressValues, progressContexts, resolveContexts; + + // add listeners to Deferred subordinates; treat others as resolved + if ( length > 1 ) { + progressValues = new Array( length ); + progressContexts = new Array( length ); + resolveContexts = new Array( length ); + for ( ; i < length; i++ ) { + if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { + resolveValues[ i ].promise() + .done( updateFunc( i, resolveContexts, resolveValues ) ) + .fail( deferred.reject ) + .progress( updateFunc( i, progressContexts, progressValues ) ); + } else { + --remaining; + } + } + } + + // if we're not waiting on anything, resolve the master + if ( !remaining ) { + deferred.resolveWith( resolveContexts, resolveValues ); + } + + return deferred.promise(); + } +}); +jQuery.support = (function() { + + var support, all, a, + input, select, fragment, + opt, eventName, isSupported, i, + div = document.createElement("div"); + + // Setup + div.setAttribute( "className", "t" ); + div.innerHTML = "
a"; + + // Support tests won't run in some limited or non-browser environments + all = div.getElementsByTagName("*"); + a = div.getElementsByTagName("a")[ 0 ]; + if ( !all || !a || !all.length ) { + return {}; + } + + // First batch of tests + select = document.createElement("select"); + opt = select.appendChild( document.createElement("option") ); + input = div.getElementsByTagName("input")[ 0 ]; + + a.style.cssText = "top:1px;float:left;opacity:.5"; + support = { + // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) + getSetAttribute: div.className !== "t", + + // IE strips leading whitespace when .innerHTML is used + leadingWhitespace: div.firstChild.nodeType === 3, + + // Make sure that tbody elements aren't automatically inserted + // IE will insert them into empty tables + tbody: !div.getElementsByTagName("tbody").length, + + // Make sure that link elements get serialized correctly by innerHTML + // This requires a wrapper element in IE + htmlSerialize: !!div.getElementsByTagName("link").length, + + // Get the style information from getAttribute + // (IE uses .cssText instead) + style: /top/.test( a.getAttribute("style") ), + + // Make sure that URLs aren't manipulated + // (IE normalizes it by default) + hrefNormalized: a.getAttribute("href") === "/a", + + // Make sure that element opacity exists + // (IE uses filter instead) + // Use a regex to work around a WebKit issue. See #5145 + opacity: /^0.5/.test( a.style.opacity ), + + // Verify style float existence + // (IE uses styleFloat instead of cssFloat) + cssFloat: !!a.style.cssFloat, + + // Check the default checkbox/radio value ("" on WebKit; "on" elsewhere) + checkOn: !!input.value, + + // Make sure that a selected-by-default option has a working selected property. + // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) + optSelected: opt.selected, + + // Tests for enctype support on a form (#6743) + enctype: !!document.createElement("form").enctype, + + // Makes sure cloning an html5 element does not cause problems + // Where outerHTML is undefined, this still works + html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav>", + + // jQuery.support.boxModel DEPRECATED in 1.8 since we don't support Quirks Mode + boxModel: document.compatMode === "CSS1Compat", + + // Will be defined later + deleteExpando: true, + noCloneEvent: true, + inlineBlockNeedsLayout: false, + shrinkWrapBlocks: false, + reliableMarginRight: true, + boxSizingReliable: true, + pixelPosition: false + }; + + // Make sure checked status is properly cloned + input.checked = true; + support.noCloneChecked = input.cloneNode( true ).checked; + + // Make sure that the options inside disabled selects aren't marked as disabled + // (WebKit marks them as disabled) + select.disabled = true; + support.optDisabled = !opt.disabled; + + // Support: IE<9 + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + + // Check if we can trust getAttribute("value") + input = document.createElement("input"); + input.setAttribute( "value", "" ); + support.input = input.getAttribute( "value" ) === ""; + + // Check if an input maintains its value after becoming a radio + input.value = "t"; + input.setAttribute( "type", "radio" ); + support.radioValue = input.value === "t"; + + // #11217 - WebKit loses check when the name is after the checked attribute + input.setAttribute( "checked", "t" ); + input.setAttribute( "name", "t" ); + + fragment = document.createDocumentFragment(); + fragment.appendChild( input ); + + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + support.appendChecked = input.checked; + + // WebKit doesn't clone checked state correctly in fragments + support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE<9 + // Opera does not clone events (and typeof div.attachEvent === undefined). + // IE9-10 clones events bound via attachEvent, but they don't trigger with .click() + if ( div.attachEvent ) { + div.attachEvent( "onclick", function() { + support.noCloneEvent = false; + }); + + div.cloneNode( true ).click(); + } + + // Support: IE<9 (lack submit/change bubble), Firefox 17+ (lack focusin event) + // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP), test/csp.php + for ( i in { submit: true, change: true, focusin: true }) { + div.setAttribute( eventName = "on" + i, "t" ); + + support[ i + "Bubbles" ] = eventName in window || div.attributes[ eventName ].expando === false; + } + + div.style.backgroundClip = "content-box"; + div.cloneNode( true ).style.backgroundClip = ""; + support.clearCloneStyle = div.style.backgroundClip === "content-box"; + + // Run tests that need a body at doc ready + jQuery(function() { + var container, marginDiv, tds, + divReset = "padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;", + body = document.getElementsByTagName("body")[0]; + + if ( !body ) { + // Return for frameset docs that don't have a body + return; + } + + container = document.createElement("div"); + container.style.cssText = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px"; + + body.appendChild( container ).appendChild( div ); + + // Support: IE8 + // Check if table cells still have offsetWidth/Height when they are set + // to display:none and there are still other visible table cells in a + // table row; if so, offsetWidth/Height are not reliable for use when + // determining if an element has been hidden directly using + // display:none (it is still safe to use offsets if a parent element is + // hidden; don safety goggles and see bug #4512 for more information). + div.innerHTML = "
t
"; + tds = div.getElementsByTagName("td"); + tds[ 0 ].style.cssText = "padding:0;margin:0;border:0;display:none"; + isSupported = ( tds[ 0 ].offsetHeight === 0 ); + + tds[ 0 ].style.display = ""; + tds[ 1 ].style.display = "none"; + + // Support: IE8 + // Check if empty table cells still have offsetWidth/Height + support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); + + // Check box-sizing and margin behavior + div.innerHTML = ""; + div.style.cssText = "box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;"; + support.boxSizing = ( div.offsetWidth === 4 ); + support.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== 1 ); + + // Use window.getComputedStyle because jsdom on node.js will break without it. + if ( window.getComputedStyle ) { + support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%"; + support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px"; + + // Check if div with explicit width and no margin-right incorrectly + // gets computed margin-right based on width of container. (#3333) + // Fails in WebKit before Feb 2011 nightlies + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + marginDiv = div.appendChild( document.createElement("div") ); + marginDiv.style.cssText = div.style.cssText = divReset; + marginDiv.style.marginRight = marginDiv.style.width = "0"; + div.style.width = "1px"; + + support.reliableMarginRight = + !parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight ); + } + + if ( typeof div.style.zoom !== core_strundefined ) { + // Support: IE<8 + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + div.innerHTML = ""; + div.style.cssText = divReset + "width:1px;padding:1px;display:inline;zoom:1"; + support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 ); + + // Support: IE6 + // Check if elements with layout shrink-wrap their children + div.style.display = "block"; + div.innerHTML = "
"; + div.firstChild.style.width = "5px"; + support.shrinkWrapBlocks = ( div.offsetWidth !== 3 ); + + if ( support.inlineBlockNeedsLayout ) { + // Prevent IE 6 from affecting layout for positioned elements #11048 + // Prevent IE from shrinking the body in IE 7 mode #12869 + // Support: IE<8 + body.style.zoom = 1; + } + } + + body.removeChild( container ); + + // Null elements to avoid leaks in IE + container = div = tds = marginDiv = null; + }); + + // Null elements to avoid leaks in IE + all = select = fragment = opt = a = input = null; + + return support; +})(); + +var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/, + rmultiDash = /([A-Z])/g; + +function internalData( elem, name, data, pvt /* Internal Use Only */ ){ + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, ret, + internalKey = jQuery.expando, + getByName = typeof name === "string", + + // We have to handle DOM nodes and JS objects differently because IE6-7 + // can't GC object references properly across the DOM-JS boundary + isNode = elem.nodeType, + + // Only DOM nodes need the global jQuery cache; JS object data is + // attached directly to the object so GC can occur automatically + cache = isNode ? jQuery.cache : elem, + + // Only defining an ID for JS objects if its cache already exists allows + // the code to shortcut on the same path as a DOM node with no cache + id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey; + + // Avoid doing any more work than we need to when trying to get data on an + // object that has no data at all + if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && getByName && data === undefined ) { + return; + } + + if ( !id ) { + // Only DOM nodes need a new unique ID for each element since their data + // ends up in the global cache + if ( isNode ) { + elem[ internalKey ] = id = core_deletedIds.pop() || jQuery.guid++; + } else { + id = internalKey; + } + } + + if ( !cache[ id ] ) { + cache[ id ] = {}; + + // Avoids exposing jQuery metadata on plain JS objects when the object + // is serialized using JSON.stringify + if ( !isNode ) { + cache[ id ].toJSON = jQuery.noop; + } + } + + // An object can be passed to jQuery.data instead of a key/value pair; this gets + // shallow copied over onto the existing cache + if ( typeof name === "object" || typeof name === "function" ) { + if ( pvt ) { + cache[ id ] = jQuery.extend( cache[ id ], name ); + } else { + cache[ id ].data = jQuery.extend( cache[ id ].data, name ); + } + } + + thisCache = cache[ id ]; + + // jQuery data() is stored in a separate object inside the object's internal data + // cache in order to avoid key collisions between internal data and user-defined + // data. + if ( !pvt ) { + if ( !thisCache.data ) { + thisCache.data = {}; + } + + thisCache = thisCache.data; + } + + if ( data !== undefined ) { + thisCache[ jQuery.camelCase( name ) ] = data; + } + + // Check for both converted-to-camel and non-converted data property names + // If a data property was specified + if ( getByName ) { + + // First Try to find as-is property data + ret = thisCache[ name ]; + + // Test for null|undefined property data + if ( ret == null ) { + + // Try to find the camelCased property + ret = thisCache[ jQuery.camelCase( name ) ]; + } + } else { + ret = thisCache; + } + + return ret; +} + +function internalRemoveData( elem, name, pvt ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var i, l, thisCache, + isNode = elem.nodeType, + + // See jQuery.data for more information + cache = isNode ? jQuery.cache : elem, + id = isNode ? elem[ jQuery.expando ] : jQuery.expando; + + // If there is already no cache entry for this object, there is no + // purpose in continuing + if ( !cache[ id ] ) { + return; + } + + if ( name ) { + + thisCache = pvt ? cache[ id ] : cache[ id ].data; + + if ( thisCache ) { + + // Support array or space separated string names for data keys + if ( !jQuery.isArray( name ) ) { + + // try the string as a key before any manipulation + if ( name in thisCache ) { + name = [ name ]; + } else { + + // split the camel cased version by spaces unless a key with the spaces exists + name = jQuery.camelCase( name ); + if ( name in thisCache ) { + name = [ name ]; + } else { + name = name.split(" "); + } + } + } else { + // If "name" is an array of keys... + // When data is initially created, via ("key", "val") signature, + // keys will be converted to camelCase. + // Since there is no way to tell _how_ a key was added, remove + // both plain key and camelCase key. #12786 + // This will only penalize the array argument path. + name = name.concat( jQuery.map( name, jQuery.camelCase ) ); + } + + for ( i = 0, l = name.length; i < l; i++ ) { + delete thisCache[ name[i] ]; + } + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) { + return; + } + } + } + + // See jQuery.data for more information + if ( !pvt ) { + delete cache[ id ].data; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject( cache[ id ] ) ) { + return; + } + } + + // Destroy the cache + if ( isNode ) { + jQuery.cleanData( [ elem ], true ); + + // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080) + } else if ( jQuery.support.deleteExpando || cache != cache.window ) { + delete cache[ id ]; + + // When all else fails, null + } else { + cache[ id ] = null; + } +} + +jQuery.extend({ + cache: {}, + + // Unique for each copy of jQuery on the page + // Non-digits removed to match rinlinejQuery + expando: "jQuery" + ( core_version + Math.random() ).replace( /\D/g, "" ), + + // The following elements throw uncatchable exceptions if you + // attempt to add expando properties to them. + noData: { + "embed": true, + // Ban all objects except for Flash (which handle expandos) + "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", + "applet": true + }, + + hasData: function( elem ) { + elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; + return !!elem && !isEmptyDataObject( elem ); + }, + + data: function( elem, name, data ) { + return internalData( elem, name, data ); + }, + + removeData: function( elem, name ) { + return internalRemoveData( elem, name ); + }, + + // For internal use only. + _data: function( elem, name, data ) { + return internalData( elem, name, data, true ); + }, + + _removeData: function( elem, name ) { + return internalRemoveData( elem, name, true ); + }, + + // A method for determining if a DOM node can handle the data expando + acceptData: function( elem ) { + // Do not set data on non-element because it will not be cleared (#8335). + if ( elem.nodeType && elem.nodeType !== 1 && elem.nodeType !== 9 ) { + return false; + } + + var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ]; + + // nodes accept data unless otherwise specified; rejection can be conditional + return !noData || noData !== true && elem.getAttribute("classid") === noData; + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var attrs, name, + elem = this[0], + i = 0, + data = null; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = jQuery.data( elem ); + + if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { + attrs = elem.attributes; + for ( ; i < attrs.length; i++ ) { + name = attrs[i].name; + + if ( !name.indexOf( "data-" ) ) { + name = jQuery.camelCase( name.slice(5) ); + + dataAttr( elem, name, data[ name ] ); + } + } + jQuery._data( elem, "parsedAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each(function() { + jQuery.data( this, key ); + }); + } + + return jQuery.access( this, function( value ) { + + if ( value === undefined ) { + // Try to fetch any internally stored data first + return elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : null; + } + + this.each(function() { + jQuery.data( this, key, value ); + }); + }, null, value, arguments.length > 1, null, true ); + }, + + removeData: function( key ) { + return this.each(function() { + jQuery.removeData( this, key ); + }); + } +}); + +function dataAttr( elem, key, data ) { + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + + var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + // Only convert to a number if it doesn't change the string + +data + "" === data ? +data : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + jQuery.data( elem, key, data ); + + } else { + data = undefined; + } + } + + return data; +} + +// checks a cache object for emptiness +function isEmptyDataObject( obj ) { + var name; + for ( name in obj ) { + + // if the public data object is empty, the private is still empty + if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { + continue; + } + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} +jQuery.extend({ + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = jQuery._data( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || jQuery.isArray(data) ) { + queue = jQuery._data( elem, type, jQuery.makeArray(data) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + hooks.cur = fn; + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // not intended for public consumption - generates a queueHooks object, or returns the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return jQuery._data( elem, key ) || jQuery._data( elem, key, { + empty: jQuery.Callbacks("once memory").add(function() { + jQuery._removeData( elem, type + "queue" ); + jQuery._removeData( elem, key ); + }) + }); + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[0], type ); + } + + return data === undefined ? + this : + this.each(function() { + var queue = jQuery.queue( this, type, data ); + + // ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + }); + }, + dequeue: function( type ) { + return this.each(function() { + jQuery.dequeue( this, type ); + }); + }, + // Based off of the plugin by Clint Helfers, with permission. + // http://blindsignals.com/index.php/2009/07/jquery-delay/ + delay: function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = setTimeout( next, time ); + hooks.stop = function() { + clearTimeout( timeout ); + }; + }); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while( i-- ) { + tmp = jQuery._data( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +}); +var nodeHook, boolHook, + rclass = /[\t\r\n]/g, + rreturn = /\r/g, + rfocusable = /^(?:input|select|textarea|button|object)$/i, + rclickable = /^(?:a|area)$/i, + rboolean = /^(?:checked|selected|autofocus|autoplay|async|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped)$/i, + ruseDefault = /^(?:checked|selected)$/i, + getSetAttribute = jQuery.support.getSetAttribute, + getSetInput = jQuery.support.input; + +jQuery.fn.extend({ + attr: function( name, value ) { + return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each(function() { + jQuery.removeAttr( this, name ); + }); + }, + + prop: function( name, value ) { + return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + name = jQuery.propFix[ name ] || name; + return this.each(function() { + // try/catch handles cases where IE balks (such as removing a property on window) + try { + this[ name ] = undefined; + delete this[ name ]; + } catch( e ) {} + }); + }, + + addClass: function( value ) { + var classes, elem, cur, clazz, j, + i = 0, + len = this.length, + proceed = typeof value === "string" && value; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).addClass( value.call( this, j, this.className ) ); + }); + } + + if ( proceed ) { + // The disjunction here is for better compressibility (see removeClass) + classes = ( value || "" ).match( core_rnotwhite ) || []; + + for ( ; i < len; i++ ) { + elem = this[ i ]; + cur = elem.nodeType === 1 && ( elem.className ? + ( " " + elem.className + " " ).replace( rclass, " " ) : + " " + ); + + if ( cur ) { + j = 0; + while ( (clazz = classes[j++]) ) { + if ( cur.indexOf( " " + clazz + " " ) < 0 ) { + cur += clazz + " "; + } + } + elem.className = jQuery.trim( cur ); + + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classes, elem, cur, clazz, j, + i = 0, + len = this.length, + proceed = arguments.length === 0 || typeof value === "string" && value; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).removeClass( value.call( this, j, this.className ) ); + }); + } + if ( proceed ) { + classes = ( value || "" ).match( core_rnotwhite ) || []; + + for ( ; i < len; i++ ) { + elem = this[ i ]; + // This expression is here for better compressibility (see addClass) + cur = elem.nodeType === 1 && ( elem.className ? + ( " " + elem.className + " " ).replace( rclass, " " ) : + "" + ); + + if ( cur ) { + j = 0; + while ( (clazz = classes[j++]) ) { + // Remove *all* instances + while ( cur.indexOf( " " + clazz + " " ) >= 0 ) { + cur = cur.replace( " " + clazz + " ", " " ); + } + } + elem.className = value ? jQuery.trim( cur ) : ""; + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isBool = typeof stateVal === "boolean"; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( i ) { + jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); + }); + } + + return this.each(function() { + if ( type === "string" ) { + // toggle individual class names + var className, + i = 0, + self = jQuery( this ), + state = stateVal, + classNames = value.match( core_rnotwhite ) || []; + + while ( (className = classNames[ i++ ]) ) { + // check each className given, space separated list + state = isBool ? state : !self.hasClass( className ); + self[ state ? "addClass" : "removeClass" ]( className ); + } + + // Toggle whole class name + } else if ( type === core_strundefined || type === "boolean" ) { + if ( this.className ) { + // store className if set + jQuery._data( this, "__className__", this.className ); + } + + // If the element has a class name or if we're passed "false", + // then remove the whole classname (if there was one, the above saved it). + // Otherwise bring back whatever was previously saved (if anything), + // falling back to the empty string if nothing was stored. + this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; + } + }); + }, + + hasClass: function( selector ) { + var className = " " + selector + " ", + i = 0, + l = this.length; + for ( ; i < l; i++ ) { + if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) { + return true; + } + } + + return false; + }, + + val: function( value ) { + var ret, hooks, isFunction, + elem = this[0]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { + return ret; + } + + ret = elem.value; + + return typeof ret === "string" ? + // handle most common string cases + ret.replace(rreturn, "") : + // handle cases where value is null/undef or number + ret == null ? "" : ret; + } + + return; + } + + isFunction = jQuery.isFunction( value ); + + return this.each(function( i ) { + var val, + self = jQuery(this); + + if ( this.nodeType !== 1 ) { + return; + } + + if ( isFunction ) { + val = value.call( this, i, self.val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + } else if ( typeof val === "number" ) { + val += ""; + } else if ( jQuery.isArray( val ) ) { + val = jQuery.map(val, function ( value ) { + return value == null ? "" : value + ""; + }); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + }); + } +}); + +jQuery.extend({ + valHooks: { + option: { + get: function( elem ) { + // attributes.value is undefined in Blackberry 4.7 but + // uses .value. See #6932 + var val = elem.attributes.value; + return !val || val.specified ? elem.value : elem.text; + } + }, + select: { + get: function( elem ) { + var value, option, + options = elem.options, + index = elem.selectedIndex, + one = elem.type === "select-one" || index < 0, + values = one ? null : [], + max = one ? index + 1 : options.length, + i = index < 0 ? + max : + one ? index : 0; + + // Loop through all the selected options + for ( ; i < max; i++ ) { + option = options[ i ]; + + // oldIE doesn't update selected after form reset (#2551) + if ( ( option.selected || i === index ) && + // Don't return options that are disabled or in a disabled optgroup + ( jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) && + ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + }, + + set: function( elem, value ) { + var values = jQuery.makeArray( value ); + + jQuery(elem).find("option").each(function() { + this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; + }); + + if ( !values.length ) { + elem.selectedIndex = -1; + } + return values; + } + } + }, + + attr: function( elem, name, value ) { + var hooks, notxml, ret, + nType = elem.nodeType; + + // don't get/set attributes on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === core_strundefined ) { + return jQuery.prop( elem, name, value ); + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + // All attributes are lowercase + // Grab necessary hook if one is defined + if ( notxml ) { + name = name.toLowerCase(); + hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); + } + + if ( value !== undefined ) { + + if ( value === null ) { + jQuery.removeAttr( elem, name ); + + } else if ( hooks && notxml && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + elem.setAttribute( name, value + "" ); + return value; + } + + } else if ( hooks && notxml && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + + // In IE9+, Flash objects don't have .getAttribute (#12945) + // Support: IE9+ + if ( typeof elem.getAttribute !== core_strundefined ) { + ret = elem.getAttribute( name ); + } + + // Non-existent attributes return null, we normalize to undefined + return ret == null ? + undefined : + ret; + } + }, + + removeAttr: function( elem, value ) { + var name, propName, + i = 0, + attrNames = value && value.match( core_rnotwhite ); + + if ( attrNames && elem.nodeType === 1 ) { + while ( (name = attrNames[i++]) ) { + propName = jQuery.propFix[ name ] || name; + + // Boolean attributes get special treatment (#10870) + if ( rboolean.test( name ) ) { + // Set corresponding property to false for boolean attributes + // Also clear defaultChecked/defaultSelected (if appropriate) for IE<8 + if ( !getSetAttribute && ruseDefault.test( name ) ) { + elem[ jQuery.camelCase( "default-" + name ) ] = + elem[ propName ] = false; + } else { + elem[ propName ] = false; + } + + // See #9699 for explanation of this approach (setting first, then removal) + } else { + jQuery.attr( elem, name, "" ); + } + + elem.removeAttribute( getSetAttribute ? name : propName ); + } + } + }, + + attrHooks: { + type: { + set: function( elem, value ) { + if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { + // Setting the type on a radio button after the value resets the value in IE6-9 + // Reset value to default in case type is set after value during creation + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + } + }, + + propFix: { + tabindex: "tabIndex", + readonly: "readOnly", + "for": "htmlFor", + "class": "className", + maxlength: "maxLength", + cellspacing: "cellSpacing", + cellpadding: "cellPadding", + rowspan: "rowSpan", + colspan: "colSpan", + usemap: "useMap", + frameborder: "frameBorder", + contenteditable: "contentEditable" + }, + + prop: function( elem, name, value ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set properties on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + if ( notxml ) { + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + return ( elem[ name ] = value ); + } + + } else { + if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + return elem[ name ]; + } + } + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set + // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + var attributeNode = elem.getAttributeNode("tabindex"); + + return attributeNode && attributeNode.specified ? + parseInt( attributeNode.value, 10 ) : + rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? + 0 : + undefined; + } + } + } +}); + +// Hook for boolean attributes +boolHook = { + get: function( elem, name ) { + var + // Use .prop to determine if this attribute is understood as boolean + prop = jQuery.prop( elem, name ), + + // Fetch it accordingly + attr = typeof prop === "boolean" && elem.getAttribute( name ), + detail = typeof prop === "boolean" ? + + getSetInput && getSetAttribute ? + attr != null : + // oldIE fabricates an empty string for missing boolean attributes + // and conflates checked/selected into attroperties + ruseDefault.test( name ) ? + elem[ jQuery.camelCase( "default-" + name ) ] : + !!attr : + + // fetch an attribute node for properties not recognized as boolean + elem.getAttributeNode( name ); + + return detail && detail.value !== false ? + name.toLowerCase() : + undefined; + }, + set: function( elem, value, name ) { + if ( value === false ) { + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) { + // IE<8 needs the *property* name + elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name ); + + // Use defaultChecked and defaultSelected for oldIE + } else { + elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true; + } + + return name; + } +}; + +// fix oldIE value attroperty +if ( !getSetInput || !getSetAttribute ) { + jQuery.attrHooks.value = { + get: function( elem, name ) { + var ret = elem.getAttributeNode( name ); + return jQuery.nodeName( elem, "input" ) ? + + // Ignore the value *property* by using defaultValue + elem.defaultValue : + + ret && ret.specified ? ret.value : undefined; + }, + set: function( elem, value, name ) { + if ( jQuery.nodeName( elem, "input" ) ) { + // Does not return so that setAttribute is also used + elem.defaultValue = value; + } else { + // Use nodeHook if defined (#1954); otherwise setAttribute is fine + return nodeHook && nodeHook.set( elem, value, name ); + } + } + }; +} + +// IE6/7 do not support getting/setting some attributes with get/setAttribute +if ( !getSetAttribute ) { + + // Use this for any attribute in IE6/7 + // This fixes almost every IE6/7 issue + nodeHook = jQuery.valHooks.button = { + get: function( elem, name ) { + var ret = elem.getAttributeNode( name ); + return ret && ( name === "id" || name === "name" || name === "coords" ? ret.value !== "" : ret.specified ) ? + ret.value : + undefined; + }, + set: function( elem, value, name ) { + // Set the existing or create a new attribute node + var ret = elem.getAttributeNode( name ); + if ( !ret ) { + elem.setAttributeNode( + (ret = elem.ownerDocument.createAttribute( name )) + ); + } + + ret.value = value += ""; + + // Break association with cloned elements by also using setAttribute (#9646) + return name === "value" || value === elem.getAttribute( name ) ? + value : + undefined; + } + }; + + // Set contenteditable to false on removals(#10429) + // Setting to empty string throws an error as an invalid value + jQuery.attrHooks.contenteditable = { + get: nodeHook.get, + set: function( elem, value, name ) { + nodeHook.set( elem, value === "" ? false : value, name ); + } + }; + + // Set width and height to auto instead of 0 on empty string( Bug #8150 ) + // This is for removals + jQuery.each([ "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + set: function( elem, value ) { + if ( value === "" ) { + elem.setAttribute( name, "auto" ); + return value; + } + } + }); + }); +} + + +// Some attributes require a special call on IE +// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !jQuery.support.hrefNormalized ) { + jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + get: function( elem ) { + var ret = elem.getAttribute( name, 2 ); + return ret == null ? undefined : ret; + } + }); + }); + + // href/src property should get the full normalized URL (#10299/#12915) + jQuery.each([ "href", "src" ], function( i, name ) { + jQuery.propHooks[ name ] = { + get: function( elem ) { + return elem.getAttribute( name, 4 ); + } + }; + }); +} + +if ( !jQuery.support.style ) { + jQuery.attrHooks.style = { + get: function( elem ) { + // Return undefined in the case of empty string + // Note: IE uppercases css property names, but if we were to .toLowerCase() + // .cssText, that would destroy case senstitivity in URL's, like in "background" + return elem.style.cssText || undefined; + }, + set: function( elem, value ) { + return ( elem.style.cssText = value + "" ); + } + }; +} + +// Safari mis-reports the default selected property of an option +// Accessing the parent's selectedIndex property fixes it +if ( !jQuery.support.optSelected ) { + jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, { + get: function( elem ) { + var parent = elem.parentNode; + + if ( parent ) { + parent.selectedIndex; + + // Make sure that it also works with optgroups, see #5701 + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + return null; + } + }); +} + +// IE6/7 call enctype encoding +if ( !jQuery.support.enctype ) { + jQuery.propFix.enctype = "encoding"; +} + +// Radios and checkboxes getter/setter +if ( !jQuery.support.checkOn ) { + jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + get: function( elem ) { + // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified + return elem.getAttribute("value") === null ? "on" : elem.value; + } + }; + }); +} +jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], { + set: function( elem, value ) { + if ( jQuery.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); + } + } + }); +}); +var rformElems = /^(?:input|select|textarea)$/i, + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)$/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + var tmp, events, t, handleObjIn, + special, eventHandle, handleObj, + handlers, type, namespaces, origType, + elemData = jQuery._data( elem ); + + // Don't attach events to noData or text/comment nodes (but allow plain objects) + if ( !elemData ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !(events = elemData.events) ) { + events = elemData.events = {}; + } + if ( !(eventHandle = elemData.handle) ) { + eventHandle = elemData.handle = function( e ) { + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== core_strundefined && (!e || jQuery.event.triggered !== e.type) ? + jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : + undefined; + }; + // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events + eventHandle.elem = elem; + } + + // Handle multiple events separated by a space + // jQuery(...).bind("mouseover mouseout", fn); + types = ( types || "" ).match( core_rnotwhite ) || [""]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend({ + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join(".") + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !(handlers = events[ type ]) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener/attachEvent if the special events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + // Bind the global event handler to the element + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + // Nullify elem to prevent memory leaks in IE + elem = null; + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + var j, handleObj, tmp, + origCount, t, events, + special, handlers, type, + namespaces, origType, + elemData = jQuery.hasData( elem ) && jQuery._data( elem ); + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( core_rnotwhite ) || [""]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + delete elemData.handle; + + // removeData also checks for emptiness and clears the expando if empty + // so use it instead of delete + jQuery._removeData( elem, "events" ); + } + }, + + trigger: function( event, data, elem, onlyHandlers ) { + var handle, ontype, cur, + bubbleType, special, tmp, i, + eventPath = [ elem || document ], + type = core_hasOwn.call( event, "type" ) ? event.type : event, + namespaces = core_hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : []; + + cur = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf(".") >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf(":") < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + event.isTrigger = true; + event.namespace = namespaces.join("."); + event.namespace_re = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === (elem.ownerDocument || document) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) { + + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) { + event.preventDefault(); + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) && + !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Can't use an .isFunction() check here because IE6/7 fails that test. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + try { + elem[ type ](); + } catch ( e ) { + // IE<9 dies on focus/blur to hidden element (#1486,#12518) + // only reproducible on winXP IE8 native, not IE9 in IE8 mode + } + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event ); + + var i, ret, handleObj, matched, j, + handlerQueue = [], + args = core_slice.call( arguments ), + handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) { + + // Triggered event must either 1) have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). + if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) + .apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( (event.result = ret) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var sel, handleObj, matches, i, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + // Black-hole SVG instance trees (#13180) + // Avoid non-left-click bubbling in Firefox (#3861) + if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) { + + for ( ; cur != this; cur = cur.parentNode || this ) { + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== "click") ) { + matches = []; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matches[ sel ] === undefined ) { + matches[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) >= 0 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matches[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, handlers: matches }); + } + } + } + } + + // Add the remaining (directly-bound) handlers + if ( delegateCount < handlers.length ) { + handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) }); + } + + return handlerQueue; + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, copy, + type = event.type, + originalEvent = event, + fixHook = this.fixHooks[ type ]; + + if ( !fixHook ) { + this.fixHooks[ type ] = fixHook = + rmouseEvent.test( type ) ? this.mouseHooks : + rkeyEvent.test( type ) ? this.keyHooks : + {}; + } + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = new jQuery.Event( originalEvent ); + + i = copy.length; + while ( i-- ) { + prop = copy[ i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Support: IE<9 + // Fix target property (#1925) + if ( !event.target ) { + event.target = originalEvent.srcElement || document; + } + + // Support: Chrome 23+, Safari? + // Target should not be a text node (#504, #13143) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // Support: IE<9 + // For mouse/key events, metaKey==false if it's undefined (#3368, #11328) + event.metaKey = !!event.metaKey; + + return fixHook.filter ? fixHook.filter( event, originalEvent ) : event; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split(" "), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var body, eventDoc, doc, + button = original.button, + fromElement = original.fromElement; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && fromElement ) { + event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + special: { + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + click: { + // For checkbox, fire native event so checked state will be right + trigger: function() { + if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) { + this.click(); + return false; + } + } + }, + focus: { + // Fire native event if possible so blur/focus sequence is correct + trigger: function() { + if ( this !== document.activeElement && this.focus ) { + try { + this.focus(); + return false; + } catch ( e ) { + // Support: IE<9 + // If we error on focus to hidden element (#1486, #12518), + // let .trigger() run the handlers + } + } + }, + delegateType: "focusin" + }, + blur: { + trigger: function() { + if ( this === document.activeElement && this.blur ) { + this.blur(); + return false; + } + }, + delegateType: "focusout" + }, + + beforeunload: { + postDispatch: function( event ) { + + // Even when returnValue equals to undefined Firefox will still show alert + if ( event.result !== undefined ) { + event.originalEvent.returnValue = event.result; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // Piggyback on a donor event to simulate a different one. + // Fake originalEvent to avoid donor's stopPropagation, but if the + // simulated event prevents default then we do the same on the donor. + var e = jQuery.extend( + new jQuery.Event(), + event, + { type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + jQuery.event.trigger( e, null, elem ); + } else { + jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +jQuery.removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } + } : + function( elem, type, handle ) { + var name = "on" + type; + + if ( elem.detachEvent ) { + + // #8545, #7054, preventing memory leaks for custom events in IE6-8 + // detachEvent needed property on element, by name of that event, to properly expose it to GC + if ( typeof elem[ name ] === core_strundefined ) { + elem[ name ] = null; + } + + elem.detachEvent( name, handle ); + } + }; + +jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof jQuery.Event) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false || + src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + if ( !e ) { + return; + } + + // If preventDefault exists, run it on the original event + if ( e.preventDefault ) { + e.preventDefault(); + + // Support: IE + // Otherwise set the returnValue property of the original event to false + } else { + e.returnValue = false; + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + if ( !e ) { + return; + } + // If stopPropagation exists, run it on the original event + if ( e.stopPropagation ) { + e.stopPropagation(); + } + + // Support: IE + // Set the cancelBubble property of the original event to true + e.cancelBubble = true; + }, + stopImmediatePropagation: function() { + this.isImmediatePropagationStopped = returnTrue; + this.stopPropagation(); + } +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !jQuery.contains( target, related )) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +}); + +// IE submit delegation +if ( !jQuery.support.submitBubbles ) { + + jQuery.event.special.submit = { + setup: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Lazy-add a submit handler when a descendant form may potentially be submitted + jQuery.event.add( this, "click._submit keypress._submit", function( e ) { + // Node name check avoids a VML-related crash in IE (#9807) + var elem = e.target, + form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; + if ( form && !jQuery._data( form, "submitBubbles" ) ) { + jQuery.event.add( form, "submit._submit", function( event ) { + event._submit_bubble = true; + }); + jQuery._data( form, "submitBubbles", true ); + } + }); + // return undefined since we don't need an event listener + }, + + postDispatch: function( event ) { + // If form was submitted by the user, bubble the event up the tree + if ( event._submit_bubble ) { + delete event._submit_bubble; + if ( this.parentNode && !event.isTrigger ) { + jQuery.event.simulate( "submit", this.parentNode, event, true ); + } + } + }, + + teardown: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Remove delegated handlers; cleanData eventually reaps submit handlers attached above + jQuery.event.remove( this, "._submit" ); + } + }; +} + +// IE change delegation and checkbox/radio fix +if ( !jQuery.support.changeBubbles ) { + + jQuery.event.special.change = { + + setup: function() { + + if ( rformElems.test( this.nodeName ) ) { + // IE doesn't fire change on a check/radio until blur; trigger it on click + // after a propertychange. Eat the blur-change in special.change.handle. + // This still fires onchange a second time for check/radio after blur. + if ( this.type === "checkbox" || this.type === "radio" ) { + jQuery.event.add( this, "propertychange._change", function( event ) { + if ( event.originalEvent.propertyName === "checked" ) { + this._just_changed = true; + } + }); + jQuery.event.add( this, "click._change", function( event ) { + if ( this._just_changed && !event.isTrigger ) { + this._just_changed = false; + } + // Allow triggered, simulated change events (#11500) + jQuery.event.simulate( "change", this, event, true ); + }); + } + return false; + } + // Delegated event; lazy-add a change handler on descendant inputs + jQuery.event.add( this, "beforeactivate._change", function( e ) { + var elem = e.target; + + if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "changeBubbles" ) ) { + jQuery.event.add( elem, "change._change", function( event ) { + if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { + jQuery.event.simulate( "change", this.parentNode, event, true ); + } + }); + jQuery._data( elem, "changeBubbles", true ); + } + }); + }, + + handle: function( event ) { + var elem = event.target; + + // Swallow native change events from checkbox/radio, we already triggered them above + if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { + return event.handleObj.handler.apply( this, arguments ); + } + }, + + teardown: function() { + jQuery.event.remove( this, "._change" ); + + return !rformElems.test( this.nodeName ); + } + }; +} + +// Create "bubbling" focus and blur events +if ( !jQuery.support.focusinBubbles ) { + jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler while someone wants focusin/focusout + var attaches = 0, + handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + if ( attaches++ === 0 ) { + document.addEventListener( orig, handler, true ); + } + }, + teardown: function() { + if ( --attaches === 0 ) { + document.removeEventListener( orig, handler, true ); + } + } + }; + }); +} + +jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var type, origFn; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return this.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on( types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + jQuery.event.remove( this, types, fn, selector ); + }); + }, + + bind: function( types, data, fn ) { + return this.on( types, null, data, fn ); + }, + unbind: function( types, fn ) { + return this.off( types, null, fn ); + }, + + delegate: function( selector, types, data, fn ) { + return this.on( types, selector, data, fn ); + }, + undelegate: function( selector, types, fn ) { + // ( namespace ) or ( selector, types [, fn] ) + return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn ); + }, + + trigger: function( type, data ) { + return this.each(function() { + jQuery.event.trigger( type, data, this ); + }); + }, + triggerHandler: function( type, data ) { + var elem = this[0]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +}); +/*! + * Sizzle CSS Selector Engine + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license + * http://sizzlejs.com/ + */ +(function( window, undefined ) { + +var i, + cachedruns, + Expr, + getText, + isXML, + compile, + hasDuplicate, + outermostContext, + + // Local document vars + setDocument, + document, + docElem, + documentIsXML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + sortOrder, + + // Instance-specific data + expando = "sizzle" + -(new Date()), + preferredDoc = window.document, + support = {}, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + + // General-purpose constants + strundefined = typeof undefined, + MAX_NEGATIVE = 1 << 31, + + // Array methods + arr = [], + pop = arr.pop, + push = arr.push, + slice = arr.slice, + // Use a stripped-down indexOf if we can't use a native one + indexOf = arr.indexOf || function( elem ) { + var i = 0, + len = this.length; + for ( ; i < len; i++ ) { + if ( this[i] === elem ) { + return i; + } + } + return -1; + }, + + + // Regular expressions + + // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + // http://www.w3.org/TR/css3-syntax/#characters + characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", + + // Loosely modeled on CSS identifier characters + // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors + // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = characterEncoding.replace( "w", "w#" ), + + // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors + operators = "([*^$|!~]?=)", + attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace + + "*(?:" + operators + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]", + + // Prefer arguments quoted, + // then not containing pseudos/brackets, + // then attribute selectors/non-parenthetical expressions, + // then anything else + // These preferences are here to reduce the number of selectors + // needing tokenize in the PSEUDO preFilter + pseudos = ":(" + characterEncoding + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + attributes.replace( 3, 8 ) + ")*)|.*)\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace + "*" ), + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + characterEncoding + ")" ), + "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), + "NAME": new RegExp( "^\\[name=['\"]?(" + characterEncoding + ")['\"]?\\]" ), + "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rsibling = /[\x20\t\r\n\f]*[+~]/, + + rnative = /^[^{]+\{\s*\[native code/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rescape = /'|\\/g, + rattributeQuotes = /\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g, + + // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = /\\([\da-fA-F]{1,6}[\x20\t\r\n\f]?|.)/g, + funescape = function( _, escaped ) { + var high = "0x" + escaped - 0x10000; + // NaN means non-codepoint + return high !== high ? + escaped : + // BMP codepoint + high < 0 ? + String.fromCharCode( high + 0x10000 ) : + // Supplemental Plane codepoint (surrogate pair) + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }; + +// Use a stripped-down slice if we can't use a native one +try { + slice.call( preferredDoc.documentElement.childNodes, 0 )[0].nodeType; +} catch ( e ) { + slice = function( i ) { + var elem, + results = []; + while ( (elem = this[i++]) ) { + results.push( elem ); + } + return results; + }; +} + +/** + * For feature detection + * @param {Function} fn The function to test for native support + */ +function isNative( fn ) { + return rnative.test( fn + "" ); +} + +/** + * Create key-value caches of limited size + * @returns {Function(string, Object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var cache, + keys = []; + + return (cache = function( key, value ) { + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key += " " ) > Expr.cacheLength ) { + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return (cache[ key ] = value); + }); +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created div and expects a boolean result + */ +function assert( fn ) { + var div = document.createElement("div"); + + try { + return fn( div ); + } catch (e) { + return false; + } finally { + // release memory in IE + div = null; + } +} + +function Sizzle( selector, context, results, seed ) { + var match, elem, m, nodeType, + // QSA vars + i, groups, old, nid, newContext, newSelector; + + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { + setDocument( context ); + } + + context = context || document; + results = results || []; + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) { + return []; + } + + if ( !documentIsXML && !seed ) { + + // Shortcuts + if ( (match = rquickExpr.exec( selector )) ) { + // Speed-up: Sizzle("#ID") + if ( (m = match[1]) ) { + if ( nodeType === 9 ) { + elem = context.getElementById( m ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE, Opera, and Webkit return items + // by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + } else { + // Context is not a document + if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && + contains( context, elem ) && elem.id === m ) { + results.push( elem ); + return results; + } + } + + // Speed-up: Sizzle("TAG") + } else if ( match[2] ) { + push.apply( results, slice.call(context.getElementsByTagName( selector ), 0) ); + return results; + + // Speed-up: Sizzle(".CLASS") + } else if ( (m = match[3]) && support.getByClassName && context.getElementsByClassName ) { + push.apply( results, slice.call(context.getElementsByClassName( m ), 0) ); + return results; + } + } + + // QSA path + if ( support.qsa && !rbuggyQSA.test(selector) ) { + old = true; + nid = expando; + newContext = context; + newSelector = nodeType === 9 && selector; + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + groups = tokenize( selector ); + + if ( (old = context.getAttribute("id")) ) { + nid = old.replace( rescape, "\\$&" ); + } else { + context.setAttribute( "id", nid ); + } + nid = "[id='" + nid + "'] "; + + i = groups.length; + while ( i-- ) { + groups[i] = nid + toSelector( groups[i] ); + } + newContext = rsibling.test( selector ) && context.parentNode || context; + newSelector = groups.join(","); + } + + if ( newSelector ) { + try { + push.apply( results, slice.call( newContext.querySelectorAll( + newSelector + ), 0 ) ); + return results; + } catch(qsaError) { + } finally { + if ( !old ) { + context.removeAttribute("id"); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Detect xml + * @param {Element|Object} elem An element or a document + */ +isXML = Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = elem && (elem.ownerDocument || elem).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var doc = node ? node.ownerDocument || node : preferredDoc; + + // If no document and documentElement is available, return + if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Set our document + document = doc; + docElem = doc.documentElement; + + // Support tests + documentIsXML = isXML( doc ); + + // Check if getElementsByTagName("*") returns only elements + support.tagNameNoComments = assert(function( div ) { + div.appendChild( doc.createComment("") ); + return !div.getElementsByTagName("*").length; + }); + + // Check if attributes should be retrieved by attribute nodes + support.attributes = assert(function( div ) { + div.innerHTML = ""; + var type = typeof div.lastChild.getAttribute("multiple"); + // IE8 returns a string for some attributes even when not present + return type !== "boolean" && type !== "string"; + }); + + // Check if getElementsByClassName can be trusted + support.getByClassName = assert(function( div ) { + // Opera can't find a second classname (in 9.6) + div.innerHTML = ""; + if ( !div.getElementsByClassName || !div.getElementsByClassName("e").length ) { + return false; + } + + // Safari 3.2 caches class attributes and doesn't catch changes + div.lastChild.className = "e"; + return div.getElementsByClassName("e").length === 2; + }); + + // Check if getElementById returns elements by name + // Check if getElementsByName privileges form controls or returns elements by ID + support.getByName = assert(function( div ) { + // Inject content + div.id = expando + 0; + div.innerHTML = "
"; + docElem.insertBefore( div, docElem.firstChild ); + + // Test + var pass = doc.getElementsByName && + // buggy browsers will return fewer than the correct 2 + doc.getElementsByName( expando ).length === 2 + + // buggy browsers will return more than the correct 0 + doc.getElementsByName( expando + 0 ).length; + support.getIdNotName = !doc.getElementById( expando ); + + // Cleanup + docElem.removeChild( div ); + + return pass; + }); + + // IE6/7 return modified attributes + Expr.attrHandle = assert(function( div ) { + div.innerHTML = ""; + return div.firstChild && typeof div.firstChild.getAttribute !== strundefined && + div.firstChild.getAttribute("href") === "#"; + }) ? + {} : + { + "href": function( elem ) { + return elem.getAttribute( "href", 2 ); + }, + "type": function( elem ) { + return elem.getAttribute("type"); + } + }; + + // ID find and filter + if ( support.getIdNotName ) { + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== strundefined && !documentIsXML ) { + var m = context.getElementById( id ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [m] : []; + } + }; + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute("id") === attrId; + }; + }; + } else { + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== strundefined && !documentIsXML ) { + var m = context.getElementById( id ); + + return m ? + m.id === id || typeof m.getAttributeNode !== strundefined && m.getAttributeNode("id").value === id ? + [m] : + undefined : + []; + } + }; + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id"); + return node && node.value === attrId; + }; + }; + } + + // Tag + Expr.find["TAG"] = support.tagNameNoComments ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== strundefined ) { + return context.getElementsByTagName( tag ); + } + } : + function( tag, context ) { + var elem, + tmp = [], + i = 0, + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( (elem = results[i++]) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Name + Expr.find["NAME"] = support.getByName && function( tag, context ) { + if ( typeof context.getElementsByName !== strundefined ) { + return context.getElementsByName( name ); + } + }; + + // Class + Expr.find["CLASS"] = support.getByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== strundefined && !documentIsXML ) { + return context.getElementsByClassName( className ); + } + }; + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21), + // no need to also add to buggyMatches since matches checks buggyQSA + // A support test would require too much code (would include document ready) + rbuggyQSA = [ ":focus" ]; + + if ( (support.qsa = isNative(doc.querySelectorAll)) ) { + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( div ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explictly + // setting a boolean content attribute, + // since its presence should be enough + // http://bugs.jquery.com/ticket/12359 + div.innerHTML = ""; + + // IE8 - Some boolean attributes are not treated correctly + if ( !div.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:checked|disabled|ismap|multiple|readonly|selected|value)" ); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + }); + + assert(function( div ) { + + // Opera 10-12/IE8 - ^= $= *= and empty values + // Should not select anything + div.innerHTML = ""; + if ( div.querySelectorAll("[i^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:\"\"|'')" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":enabled").length ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Opera 10-11 does not throw on post-comma invalid pseudos + div.querySelectorAll("*,:x"); + rbuggyQSA.push(",.*:"); + }); + } + + if ( (support.matchesSelector = isNative( (matches = docElem.matchesSelector || + docElem.mozMatchesSelector || + docElem.webkitMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector) )) ) { + + assert(function( div ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( div, "div" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( div, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + }); + } + + rbuggyQSA = new RegExp( rbuggyQSA.join("|") ); + rbuggyMatches = new RegExp( rbuggyMatches.join("|") ); + + // Element contains another + // Purposefully does not implement inclusive descendent + // As in, an element does not contain itself + contains = isNative(docElem.contains) || docElem.compareDocumentPosition ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + )); + } : + function( a, b ) { + if ( b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + // Document order sorting + sortOrder = docElem.compareDocumentPosition ? + function( a, b ) { + var compare; + + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + if ( (compare = b.compareDocumentPosition && a.compareDocumentPosition && a.compareDocumentPosition( b )) ) { + if ( compare & 1 || a.parentNode && a.parentNode.nodeType === 11 ) { + if ( a === doc || contains( preferredDoc, a ) ) { + return -1; + } + if ( b === doc || contains( preferredDoc, b ) ) { + return 1; + } + return 0; + } + return compare & 4 ? -1 : 1; + } + + return a.compareDocumentPosition ? -1 : 1; + } : + function( a, b ) { + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + + // Parentless nodes are either documents or disconnected + } else if ( !aup || !bup ) { + return a === doc ? -1 : + b === doc ? 1 : + aup ? -1 : + bup ? 1 : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( (cur = cur.parentNode) ) { + ap.unshift( cur ); + } + cur = b; + while ( (cur = cur.parentNode) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[i] === bp[i] ) { + i++; + } + + return i ? + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[i], bp[i] ) : + + // Otherwise nodes in our document sort first + ap[i] === preferredDoc ? -1 : + bp[i] === preferredDoc ? 1 : + 0; + }; + + // Always assume the presence of duplicates if sort doesn't + // pass them to our comparison function (as in Google Chrome). + hasDuplicate = false; + [0, 0].sort( sortOrder ); + support.detectDuplicates = hasDuplicate; + + return document; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + // Make sure that attribute selectors are quoted + expr = expr.replace( rattributeQuotes, "='$1']" ); + + // rbuggyQSA always contains :focus, so no need for an existence check + if ( support.matchesSelector && !documentIsXML && (!rbuggyMatches || !rbuggyMatches.test(expr)) && !rbuggyQSA.test(expr) ) { + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch(e) {} + } + + return Sizzle( expr, document, null, [elem] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + // Set document vars if needed + if ( ( context.ownerDocument || context ) !== document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + var val; + + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + if ( !documentIsXML ) { + name = name.toLowerCase(); + } + if ( (val = Expr.attrHandle[ name ]) ) { + return val( elem ); + } + if ( documentIsXML || support.attributes ) { + return elem.getAttribute( name ); + } + return ( (val = elem.getAttributeNode( name )) || elem.getAttribute( name ) ) && elem[ name ] === true ? + name : + val && val.specified ? val.value : null; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +// Document sorting and removing duplicates +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + i = 1, + j = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + results.sort( sortOrder ); + + if ( hasDuplicate ) { + for ( ; (elem = results[i]); i++ ) { + if ( elem === results[ i - 1 ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + return results; +}; + +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && ( ~b.sourceIndex || MAX_NEGATIVE ) - ( ~a.sourceIndex || MAX_NEGATIVE ); + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( (cur = cur.nextSibling) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +// Returns a function to use in pseudos for input types +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +// Returns a function to use in pseudos for buttons +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +// Returns a function to use in pseudos for positionals +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + // If no nodeType, this is expected to be an array + for ( ; (node = elem[i]); i++ ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (see #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[4] || match[5] || "" ).replace( runescape, funescape ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1].slice( 0, 3 ) === "nth" ) { + // nth-* requires argument + if ( !match[3] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); + match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); + + // other types prohibit arguments + } else if ( match[3] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[5] && match[2]; + + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[4] ) { + match[2] = match[4]; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + match[0] = match[0].slice( 0, excess ); + match[2] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeName ) { + if ( nodeName === "*" ) { + return function() { return true; }; + } + + nodeName = nodeName.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && + classCache( className, function( elem ) { + return pattern.test( elem.className || (typeof elem.getAttribute !== strundefined && elem.getAttribute("class")) || "" ); + }); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + }; + }, + + "CHILD": function( type, what, argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, context, xml ) { + var cache, outerCache, node, diff, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( (node = node[ dir ]) ) { + if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { + return false; + } + } + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + // Seek `elem` from a previously-cached index + outerCache = parent[ expando ] || (parent[ expando ] = {}); + cache = outerCache[ type ] || []; + nodeIndex = cache[0] === dirruns && cache[1]; + diff = cache[0] === dirruns && cache[2]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( (node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + (diff = nodeIndex = 0) || start.pop()) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + outerCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + // Use previously-cached element index if available + } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) { + diff = cache[1]; + + // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...) + } else { + // Use the same loop as above to seek `elem` from the start + while ( (node = ++nodeIndex && node && node[ dir ] || + (diff = nodeIndex = 0) || start.pop()) ) { + + if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { + // Cache the index of each encountered element + if ( useCache ) { + (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf.call( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + // Potentially complex pseudos + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + return function( elem ) { + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + // lang value must be a valid identifider + if ( !ridentifier.test(lang || "") ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( (elemLang = documentIsXML ? + elem.getAttribute("xml:lang") || elem.getAttribute("lang") : + elem.lang) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); + return false; + }; + }), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + + // Boolean properties + "enabled": function( elem ) { + return elem.disabled === false; + }, + + "disabled": function( elem ) { + return elem.disabled === true; + }, + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "selected": function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)), + // not comment, processing instructions, or others + // Thanks to Diego Perini for the nodeName shortcut + // Greater than "@" means alpha characters (specifically not starting with "#" or "?") + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeName > "@" || elem.nodeType === 3 || elem.nodeType === 4 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos["empty"]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) + // use getAttribute instead to test this case + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === elem.type ); + }, + + // Position-in-collection + "first": createPositionalPseudo(function() { + return [ 0 ]; + }), + + "last": createPositionalPseudo(function( matchIndexes, length ) { + return [ length - 1 ]; + }), + + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), + + "even": createPositionalPseudo(function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) + } +}; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +function tokenize( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + // Don't consume trailing commas as valid + soFar = soFar.slice( match[0].length ) || soFar; + } + groups.push( tokens = [] ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + matched = match.shift(); + tokens.push( { + value: matched, + // Cast descendant combinators to space + type: match[0].replace( rtrim, " " ) + } ); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + (match = preFilters[ type ]( match ))) ) { + matched = match.shift(); + tokens.push( { + value: matched, + type: type, + matches: match + } ); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +} + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[i].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + checkNonElements = base && dir === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var data, cache, outerCache, + dirkey = dirruns + " " + doneName; + + // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching + if ( xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || (elem[ expando ] = {}); + if ( (cache = outerCache[ dir ]) && cache[0] === dirkey ) { + if ( (data = cache[1]) === true || data === cachedruns ) { + return data === true; + } + } else { + cache = outerCache[ dir ] = [ dirkey ]; + cache[1] = matcher( elem, context, xml ) || cachedruns; + if ( cache[1] === true ) { + return true; + } + } + } + } + } + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[i]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[0]; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( (elem = unmatched[i]) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction(function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( (elem = temp[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + // Restore matcherIn since elem is not yet a final match + temp.push( (matcherIn[i] = elem) ); + } + } + postFinder( null, (matcherOut = []), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) && + (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) { + + seed[temp] = !(results[temp] = elem); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + }); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[0].type ], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf.call( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + return ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + } ]; + + for ( ; i < len; i++ ) { + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { + matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; + } else { + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( tokens.slice( 0, i - 1 ) ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + // A counter to specify which element is currently being matched + var matcherCachedRuns = 0, + bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, expandContext ) { + var elem, j, matcher, + setMatched = [], + matchedCount = 0, + i = "0", + unmatched = seed && [], + outermost = expandContext != null, + contextBackup = outermostContext, + // We must always have either seed elements or context + elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ), + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1); + + if ( outermost ) { + outermostContext = context !== document && context; + cachedruns = matcherCachedRuns; + } + + // Add elements passing elementMatchers directly to results + // Keep `i` a string if there are no elements so `matchedCount` will be "00" below + for ( ; (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + while ( (matcher = elementMatchers[j++]) ) { + if ( matcher( elem, context, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + cachedruns = ++matcherCachedRuns; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // Apply set filters to unmatched elements + matchedCount += i; + if ( bySet && i !== matchedCount ) { + j = 0; + while ( (matcher = setMatchers[j++]) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !group ) { + group = tokenize( selector ); + } + i = group.length; + while ( i-- ) { + cached = matcherFromTokens( group[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + } + return cached; +}; + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results ); + } + return results; +} + +function select( selector, context, results, seed ) { + var i, tokens, token, type, find, + match = tokenize( selector ); + + if ( !seed ) { + // Try to minimize operations if there is only one group + if ( match.length === 1 ) { + + // Take a shortcut and set the context if the root selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + context.nodeType === 9 && !documentIsXML && + Expr.relative[ tokens[1].type ] ) { + + context = Expr.find["ID"]( token.matches[0].replace( runescape, funescape ), context )[0]; + if ( !context ) { + return results; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( runescape, funescape ), + rsibling.test( tokens[0].type ) && context.parentNode || context + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, slice.call( seed, 0 ) ); + return results; + } + + break; + } + } + } + } + } + + // Compile and execute a filtering function + // Provide `match` to avoid retokenization if we modified the selector above + compile( selector, match )( + seed, + context, + documentIsXML, + results, + rsibling.test( selector ) + ); + return results; +} + +// Deprecated +Expr.pseudos["nth"] = Expr.pseudos["eq"]; + +// Easy API for creating new setFilters +function setFilters() {} +Expr.filters = setFilters.prototype = Expr.pseudos; +Expr.setFilters = new setFilters(); + +// Initialize with the default document +setDocument(); + +// Override sizzle attribute retrieval +Sizzle.attr = jQuery.attr; +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.pseudos; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + +})( window ); +var runtil = /Until$/, + rparentsprev = /^(?:parents|prev(?:Until|All))/, + isSimple = /^.[^:#\[\.,]*$/, + rneedsContext = jQuery.expr.match.needsContext, + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend({ + find: function( selector ) { + var i, ret, self, + len = this.length; + + if ( typeof selector !== "string" ) { + self = this; + return this.pushStack( jQuery( selector ).filter(function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }) ); + } + + ret = []; + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, this[ i ], ret ); + } + + // Needed because $( selector, context ) becomes $( context ).find( selector ) + ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); + ret.selector = ( this.selector ? this.selector + " " : "" ) + selector; + return ret; + }, + + has: function( target ) { + var i, + targets = jQuery( target, this ), + len = targets.length; + + return this.filter(function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + not: function( selector ) { + return this.pushStack( winnow(this, selector, false) ); + }, + + filter: function( selector ) { + return this.pushStack( winnow(this, selector, true) ); + }, + + is: function( selector ) { + return !!selector && ( + typeof selector === "string" ? + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + rneedsContext.test( selector ) ? + jQuery( selector, this.context ).index( this[0] ) >= 0 : + jQuery.filter( selector, this ).length > 0 : + this.filter( selector ).length > 0 ); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + ret = [], + pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( ; i < l; i++ ) { + cur = this[i]; + + while ( cur && cur.ownerDocument && cur !== context && cur.nodeType !== 11 ) { + if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { + ret.push( cur ); + break; + } + cur = cur.parentNode; + } + } + + return this.pushStack( ret.length > 1 ? jQuery.unique( ret ) : ret ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return jQuery.inArray( this[0], jQuery( elem ) ); + } + + // Locate the position of the desired element + return jQuery.inArray( + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[0] : elem, this ); + }, + + add: function( selector, context ) { + var set = typeof selector === "string" ? + jQuery( selector, context ) : + jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), + all = jQuery.merge( this.get(), set ); + + return this.pushStack( jQuery.unique(all) ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter(selector) + ); + } +}); + +jQuery.fn.andSelf = jQuery.fn.addBack; + +function sibling( cur, dir ) { + do { + cur = cur[ dir ]; + } while ( cur && cur.nodeType !== 1 ); + + return cur; +} + +jQuery.each({ + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return jQuery.nodeName( elem, "iframe" ) ? + elem.contentDocument || elem.contentWindow.document : + jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var ret = jQuery.map( this, fn, until ); + + if ( !runtil.test( name ) ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + ret = jQuery.filter( selector, ret ); + } + + ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret; + + if ( this.length > 1 && rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + + return this.pushStack( ret ); + }; +}); + +jQuery.extend({ + filter: function( expr, elems, not ) { + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 ? + jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : + jQuery.find.matches(expr, elems); + }, + + dir: function( elem, dir, until ) { + var matched = [], + cur = elem[ dir ]; + + while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { + if ( cur.nodeType === 1 ) { + matched.push( cur ); + } + cur = cur[dir]; + } + return matched; + }, + + sibling: function( n, elem ) { + var r = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + r.push( n ); + } + } + + return r; + } +}); + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, keep ) { + + // Can't pass null or undefined to indexOf in Firefox 4 + // Set to 0 to skip string check + qualifier = qualifier || 0; + + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep(elements, function( elem, i ) { + var retVal = !!qualifier.call( elem, i, elem ); + return retVal === keep; + }); + + } else if ( qualifier.nodeType ) { + return jQuery.grep(elements, function( elem ) { + return ( elem === qualifier ) === keep; + }); + + } else if ( typeof qualifier === "string" ) { + var filtered = jQuery.grep(elements, function( elem ) { + return elem.nodeType === 1; + }); + + if ( isSimple.test( qualifier ) ) { + return jQuery.filter(qualifier, filtered, !keep); + } else { + qualifier = jQuery.filter( qualifier, filtered ); + } + } + + return jQuery.grep(elements, function( elem ) { + return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep; + }); +} +function createSafeFragment( document ) { + var list = nodeNames.split( "|" ), + safeFrag = document.createDocumentFragment(); + + if ( safeFrag.createElement ) { + while ( list.length ) { + safeFrag.createElement( + list.pop() + ); + } + } + return safeFrag; +} + +var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" + + "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", + rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g, + rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"), + rleadingWhitespace = /^\s+/, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, + rtagName = /<([\w:]+)/, + rtbody = /\s*$/g, + + // We have to close these tags to support XHTML (#13200) + wrapMap = { + option: [ 1, "" ], + legend: [ 1, "
", "
" ], + area: [ 1, "", "" ], + param: [ 1, "", "" ], + thead: [ 1, "", "
" ], + tr: [ 2, "", "
" ], + col: [ 2, "", "
" ], + td: [ 3, "", "
" ], + + // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags, + // unless wrapped in a div with non-breaking characters in front of it. + _default: jQuery.support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X
", "
" ] + }, + safeFragment = createSafeFragment( document ), + fragmentDiv = safeFragment.appendChild( document.createElement("div") ); + +wrapMap.optgroup = wrapMap.option; +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +jQuery.fn.extend({ + text: function( value ) { + return jQuery.access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) ); + }, null, value, arguments.length ); + }, + + wrapAll: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each(function(i) { + jQuery(this).wrapAll( html.call(this, i) ); + }); + } + + if ( this[0] ) { + // The elements to wrap the target around + var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true); + + if ( this[0].parentNode ) { + wrap.insertBefore( this[0] ); + } + + wrap.map(function() { + var elem = this; + + while ( elem.firstChild && elem.firstChild.nodeType === 1 ) { + elem = elem.firstChild; + } + + return elem; + }).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each(function(i) { + jQuery(this).wrapInner( html.call(this, i) ); + }); + } + + return this.each(function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + }); + }, + + wrap: function( html ) { + var isFunction = jQuery.isFunction( html ); + + return this.each(function(i) { + jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html ); + }); + }, + + unwrap: function() { + return this.parent().each(function() { + if ( !jQuery.nodeName( this, "body" ) ) { + jQuery( this ).replaceWith( this.childNodes ); + } + }).end(); + }, + + append: function() { + return this.domManip(arguments, true, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + this.appendChild( elem ); + } + }); + }, + + prepend: function() { + return this.domManip(arguments, true, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + this.insertBefore( elem, this.firstChild ); + } + }); + }, + + before: function() { + return this.domManip( arguments, false, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + }); + }, + + after: function() { + return this.domManip( arguments, false, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + }); + }, + + // keepData is for internal use only--do not document + remove: function( selector, keepData ) { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { + if ( !selector || jQuery.filter( selector, [ elem ] ).length > 0 ) { + if ( !keepData && elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem ) ); + } + + if ( elem.parentNode ) { + if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) { + setGlobalEval( getAll( elem, "script" ) ); + } + elem.parentNode.removeChild( elem ); + } + } + } + + return this; + }, + + empty: function() { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + } + + // Remove any remaining nodes + while ( elem.firstChild ) { + elem.removeChild( elem.firstChild ); + } + + // If this is a select, ensure that it displays empty (#12336) + // Support: IE<9 + if ( elem.options && jQuery.nodeName( elem, "select" ) ) { + elem.options.length = 0; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function () { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + }); + }, + + html: function( value ) { + return jQuery.access( this, function( value ) { + var elem = this[0] || {}, + i = 0, + l = this.length; + + if ( value === undefined ) { + return elem.nodeType === 1 ? + elem.innerHTML.replace( rinlinejQuery, "" ) : + undefined; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + ( jQuery.support.htmlSerialize || !rnoshimcache.test( value ) ) && + ( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && + !wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) { + + value = value.replace( rxhtmlTag, "<$1>" ); + + try { + for (; i < l; i++ ) { + // Remove element nodes and prevent memory leaks + elem = this[i] || {}; + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch(e) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function( value ) { + var isFunc = jQuery.isFunction( value ); + + // Make sure that the elements are removed from the DOM before they are inserted + // this can help fix replacing a parent with child elements + if ( !isFunc && typeof value !== "string" ) { + value = jQuery( value ).not( this ).detach(); + } + + return this.domManip( [ value ], true, function( elem ) { + var next = this.nextSibling, + parent = this.parentNode; + + if ( parent ) { + jQuery( this ).remove(); + parent.insertBefore( elem, next ); + } + }); + }, + + detach: function( selector ) { + return this.remove( selector, true ); + }, + + domManip: function( args, table, callback ) { + + // Flatten any nested arrays + args = core_concat.apply( [], args ); + + var first, node, hasScripts, + scripts, doc, fragment, + i = 0, + l = this.length, + set = this, + iNoClone = l - 1, + value = args[0], + isFunction = jQuery.isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( isFunction || !( l <= 1 || typeof value !== "string" || jQuery.support.checkClone || !rchecked.test( value ) ) ) { + return this.each(function( index ) { + var self = set.eq( index ); + if ( isFunction ) { + args[0] = value.call( this, index, table ? self.html() : undefined ); + } + self.domManip( args, table, callback ); + }); + } + + if ( l ) { + fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + if ( first ) { + table = table && jQuery.nodeName( first, "tr" ); + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( + table && jQuery.nodeName( this[i], "table" ) ? + findOrAppend( this[i], "tbody" ) : + this[i], + node, + i + ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !jQuery._data( node, "globalEval" ) && jQuery.contains( doc, node ) ) { + + if ( node.src ) { + // Hope ajax is available... + jQuery.ajax({ + url: node.src, + type: "GET", + dataType: "script", + async: false, + global: false, + "throws": true + }); + } else { + jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || "" ).replace( rcleanScript, "" ) ); + } + } + } + } + + // Fix #11809: Avoid leaking memory + fragment = first = null; + } + } + + return this; + } +}); + +function findOrAppend( elem, tag ) { + return elem.getElementsByTagName( tag )[0] || elem.appendChild( elem.ownerDocument.createElement( tag ) ); +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + var attr = elem.getAttributeNode("type"); + elem.type = ( attr && attr.specified ) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + var match = rscriptTypeMasked.exec( elem.type ); + if ( match ) { + elem.type = match[1]; + } else { + elem.removeAttribute("type"); + } + return elem; +} + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var elem, + i = 0; + for ( ; (elem = elems[i]) != null; i++ ) { + jQuery._data( elem, "globalEval", !refElements || jQuery._data( refElements[i], "globalEval" ) ); + } +} + +function cloneCopyEvent( src, dest ) { + + if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { + return; + } + + var type, i, l, + oldData = jQuery._data( src ), + curData = jQuery._data( dest, oldData ), + events = oldData.events; + + if ( events ) { + delete curData.handle; + curData.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + + // make the cloned public data object a copy from the original + if ( curData.data ) { + curData.data = jQuery.extend( {}, curData.data ); + } +} + +function fixCloneNodeIssues( src, dest ) { + var nodeName, e, data; + + // We do not need to do anything for non-Elements + if ( dest.nodeType !== 1 ) { + return; + } + + nodeName = dest.nodeName.toLowerCase(); + + // IE6-8 copies events bound via attachEvent when using cloneNode. + if ( !jQuery.support.noCloneEvent && dest[ jQuery.expando ] ) { + data = jQuery._data( dest ); + + for ( e in data.events ) { + jQuery.removeEvent( dest, e, data.handle ); + } + + // Event data gets referenced instead of copied if the expando gets copied too + dest.removeAttribute( jQuery.expando ); + } + + // IE blanks contents when cloning scripts, and tries to evaluate newly-set text + if ( nodeName === "script" && dest.text !== src.text ) { + disableScript( dest ).text = src.text; + restoreScript( dest ); + + // IE6-10 improperly clones children of object elements using classid. + // IE10 throws NoModificationAllowedError if parent is null, #12132. + } else if ( nodeName === "object" ) { + if ( dest.parentNode ) { + dest.outerHTML = src.outerHTML; + } + + // This path appears unavoidable for IE9. When cloning an object + // element in IE9, the outerHTML strategy above is not sufficient. + // If the src has innerHTML and the destination does not, + // copy the src.innerHTML into the dest.innerHTML. #10324 + if ( jQuery.support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) { + dest.innerHTML = src.innerHTML; + } + + } else if ( nodeName === "input" && manipulation_rcheckableType.test( src.type ) ) { + // IE6-8 fails to persist the checked state of a cloned checkbox + // or radio button. Worse, IE6-7 fail to give the cloned element + // a checked appearance if the defaultChecked value isn't also set + + dest.defaultChecked = dest.checked = src.checked; + + // IE6-7 get confused and end up setting the value of a cloned + // checkbox/radio button to an empty string instead of "on" + if ( dest.value !== src.value ) { + dest.value = src.value; + } + + // IE6-8 fails to return the selected option to the default selected + // state when cloning options + } else if ( nodeName === "option" ) { + dest.defaultSelected = dest.selected = src.defaultSelected; + + // IE6-8 fails to set the defaultValue to the correct value when + // cloning other types of input fields + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +jQuery.each({ + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + i = 0, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone(true); + jQuery( insert[i] )[ original ]( elems ); + + // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get() + core_push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +}); + +function getAll( context, tag ) { + var elems, elem, + i = 0, + found = typeof context.getElementsByTagName !== core_strundefined ? context.getElementsByTagName( tag || "*" ) : + typeof context.querySelectorAll !== core_strundefined ? context.querySelectorAll( tag || "*" ) : + undefined; + + if ( !found ) { + for ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) { + if ( !tag || jQuery.nodeName( elem, tag ) ) { + found.push( elem ); + } else { + jQuery.merge( found, getAll( elem, tag ) ); + } + } + } + + return tag === undefined || tag && jQuery.nodeName( context, tag ) ? + jQuery.merge( [ context ], found ) : + found; +} + +// Used in buildFragment, fixes the defaultChecked property +function fixDefaultChecked( elem ) { + if ( manipulation_rcheckableType.test( elem.type ) ) { + elem.defaultChecked = elem.checked; + } +} + +jQuery.extend({ + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var destElements, node, clone, i, srcElements, + inPage = jQuery.contains( elem.ownerDocument, elem ); + + if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { + clone = elem.cloneNode( true ); + + // IE<=8 does not properly clone detached, unknown element nodes + } else { + fragmentDiv.innerHTML = elem.outerHTML; + fragmentDiv.removeChild( clone = fragmentDiv.firstChild ); + } + + if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) && + (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { + + // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + // Fix all IE cloning issues + for ( i = 0; (node = srcElements[i]) != null; ++i ) { + // Ensure that the destination node is not null; Fixes #9587 + if ( destElements[i] ) { + fixCloneNodeIssues( node, destElements[i] ); + } + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0; (node = srcElements[i]) != null; i++ ) { + cloneCopyEvent( node, destElements[i] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + destElements = srcElements = node = null; + + // Return the cloned set + return clone; + }, + + buildFragment: function( elems, context, scripts, selection ) { + var j, elem, contains, + tmp, tag, tbody, wrap, + l = elems.length, + + // Ensure a safe fragment + safe = createSafeFragment( context ), + + nodes = [], + i = 0; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( jQuery.type( elem ) === "object" ) { + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || safe.appendChild( context.createElement("div") ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + + tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, "<$1>" ) + wrap[2]; + + // Descend through wrappers to the right content + j = wrap[0]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Manually add leading whitespace removed by IE + if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { + nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) ); + } + + // Remove IE's autoinserted from table fragments + if ( !jQuery.support.tbody ) { + + // String was a , *may* have spurious + elem = tag === "table" && !rtbody.test( elem ) ? + tmp.firstChild : + + // String was a bare or + wrap[1] === "
" && !rtbody.test( elem ) ? + tmp : + 0; + + j = elem && elem.childNodes.length; + while ( j-- ) { + if ( jQuery.nodeName( (tbody = elem.childNodes[j]), "tbody" ) && !tbody.childNodes.length ) { + elem.removeChild( tbody ); + } + } + } + + jQuery.merge( nodes, tmp.childNodes ); + + // Fix #12392 for WebKit and IE > 9 + tmp.textContent = ""; + + // Fix #12392 for oldIE + while ( tmp.firstChild ) { + tmp.removeChild( tmp.firstChild ); + } + + // Remember the top-level container for proper cleanup + tmp = safe.lastChild; + } + } + } + + // Fix #11356: Clear elements from fragment + if ( tmp ) { + safe.removeChild( tmp ); + } + + // Reset defaultChecked for any radios and checkboxes + // about to be appended to the DOM in IE 6/7 (#8060) + if ( !jQuery.support.appendChecked ) { + jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked ); + } + + i = 0; + while ( (elem = nodes[ i++ ]) ) { + + // #4087 - If origin and destination elements are the same, and this is + // that element, do not do anything + if ( selection && jQuery.inArray( elem, selection ) !== -1 ) { + continue; + } + + contains = jQuery.contains( elem.ownerDocument, elem ); + + // Append to fragment + tmp = getAll( safe.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( contains ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( (elem = tmp[ j++ ]) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + tmp = null; + + return safe; + }, + + cleanData: function( elems, /* internal */ acceptData ) { + var elem, type, id, data, + i = 0, + internalKey = jQuery.expando, + cache = jQuery.cache, + deleteExpando = jQuery.support.deleteExpando, + special = jQuery.event.special; + + for ( ; (elem = elems[i]) != null; i++ ) { + + if ( acceptData || jQuery.acceptData( elem ) ) { + + id = elem[ internalKey ]; + data = id && cache[ id ]; + + if ( data ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Remove cache only if it was not already removed by jQuery.event.remove + if ( cache[ id ] ) { + + delete cache[ id ]; + + // IE does not allow us to delete expando properties from nodes, + // nor does it have a removeAttribute function on Document nodes; + // we must handle all of these cases + if ( deleteExpando ) { + delete elem[ internalKey ]; + + } else if ( typeof elem.removeAttribute !== core_strundefined ) { + elem.removeAttribute( internalKey ); + + } else { + elem[ internalKey ] = null; + } + + core_deletedIds.push( id ); + } + } + } + } + } +}); +var iframe, getStyles, curCSS, + ralpha = /alpha\([^)]*\)/i, + ropacity = /opacity\s*=\s*([^)]*)/, + rposition = /^(top|right|bottom|left)$/, + // swappable if display is none or starts with table except "table", "table-cell", or "table-caption" + // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rmargin = /^margin/, + rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ), + rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ), + rrelNum = new RegExp( "^([+-])=(" + core_pnum + ")", "i" ), + elemdisplay = { BODY: "block" }, + + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: 0, + fontWeight: 400 + }, + + cssExpand = [ "Top", "Right", "Bottom", "Left" ], + cssPrefixes = [ "Webkit", "O", "Moz", "ms" ]; + +// return a css property mapped to a potentially vendor prefixed property +function vendorPropName( style, name ) { + + // shortcut for names that are not vendor prefixed + if ( name in style ) { + return name; + } + + // check for vendor prefixed names + var capName = name.charAt(0).toUpperCase() + name.slice(1), + origName = name, + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in style ) { + return name; + } + } + + return origName; +} + +function isHidden( elem, el ) { + // isHidden might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); +} + +function showHide( elements, show ) { + var display, elem, hidden, + values = [], + index = 0, + length = elements.length; + + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + + values[ index ] = jQuery._data( elem, "olddisplay" ); + display = elem.style.display; + if ( show ) { + // Reset the inline display of this element to learn if it is + // being hidden by cascaded rules or not + if ( !values[ index ] && display === "none" ) { + elem.style.display = ""; + } + + // Set elements which have been overridden with display: none + // in a stylesheet to whatever the default browser style is + // for such an element + if ( elem.style.display === "" && isHidden( elem ) ) { + values[ index ] = jQuery._data( elem, "olddisplay", css_defaultDisplay(elem.nodeName) ); + } + } else { + + if ( !values[ index ] ) { + hidden = isHidden( elem ); + + if ( display && display !== "none" || !hidden ) { + jQuery._data( elem, "olddisplay", hidden ? display : jQuery.css( elem, "display" ) ); + } + } + } + } + + // Set the display of most of the elements in a second loop + // to avoid the constant reflow + for ( index = 0; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + if ( !show || elem.style.display === "none" || elem.style.display === "" ) { + elem.style.display = show ? values[ index ] || "" : "none"; + } + } + + return elements; +} + +jQuery.fn.extend({ + css: function( name, value ) { + return jQuery.access( this, function( elem, name, value ) { + var len, styles, + map = {}, + i = 0; + + if ( jQuery.isArray( name ) ) { + styles = getStyles( elem ); + len = name.length; + + for ( ; i < len; i++ ) { + map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); + } + + return map; + } + + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + }, + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state ) { + var bool = typeof state === "boolean"; + + return this.each(function() { + if ( bool ? state : isHidden( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + }); + } +}); + +jQuery.extend({ + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + } + } + } + }, + + // Exclude the following css properties to add px + cssNumber: { + "columnCount": true, + "fillOpacity": true, + "fontWeight": true, + "lineHeight": true, + "opacity": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: { + // normalize float css property + "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat" + }, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = jQuery.camelCase( name ), + style = elem.style; + + name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) ); + + // gets hook for the prefixed version + // followed by the unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // convert relative number strings (+= or -=) to relative numbers. #7345 + if ( type === "string" && (ret = rrelNum.exec( value )) ) { + value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) ); + // Fixes bug #9237 + type = "number"; + } + + // Make sure that NaN and null values aren't set. See: #7116 + if ( value == null || type === "number" && isNaN( value ) ) { + return; + } + + // If a number was passed in, add 'px' to the (except for certain CSS properties) + if ( type === "number" && !jQuery.cssNumber[ origName ] ) { + value += "px"; + } + + // Fixes #8908, it can be done more correctly by specifing setters in cssHooks, + // but it would mean to define eight (for every problematic property) identical functions + if ( !jQuery.support.clearCloneStyle && value === "" && name.indexOf("background") === 0 ) { + style[ name ] = "inherit"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) { + + // Wrapped to prevent IE from throwing errors when 'invalid' values are provided + // Fixes bug #5509 + try { + style[ name ] = value; + } catch(e) {} + } + + } else { + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) { + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, extra, styles ) { + var num, val, hooks, + origName = jQuery.camelCase( name ); + + // Make sure that we're working with the right name + name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) ); + + // gets hook for the prefixed version + // followed by the unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name, styles ); + } + + //convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Return, converting to number if forced or a qualifier was provided and val looks numeric + if ( extra === "" || extra ) { + num = parseFloat( val ); + return extra === true || jQuery.isNumeric( num ) ? num || 0 : val; + } + return val; + }, + + // A method for quickly swapping in/out CSS properties to get correct calculations + swap: function( elem, options, callback, args ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.apply( elem, args || [] ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; + } +}); + +// NOTE: we've included the "window" in window.getComputedStyle +// because jsdom on node.js will break without it. +if ( window.getComputedStyle ) { + getStyles = function( elem ) { + return window.getComputedStyle( elem, null ); + }; + + curCSS = function( elem, name, _computed ) { + var width, minWidth, maxWidth, + computed = _computed || getStyles( elem ), + + // getPropertyValue is only needed for .css('filter') in IE9, see #12537 + ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined, + style = elem.style; + + if ( computed ) { + + if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right + // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels + // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values + if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) { + + // Remember the original values + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + // Put in the new values to get a computed value out + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + // Revert the changed values + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret; + }; +} else if ( document.documentElement.currentStyle ) { + getStyles = function( elem ) { + return elem.currentStyle; + }; + + curCSS = function( elem, name, _computed ) { + var left, rs, rsLeft, + computed = _computed || getStyles( elem ), + ret = computed ? computed[ name ] : undefined, + style = elem.style; + + // Avoid setting ret to empty string here + // so we don't default to auto + if ( ret == null && style && style[ name ] ) { + ret = style[ name ]; + } + + // From the awesome hack by Dean Edwards + // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 + + // If we're not dealing with a regular pixel number + // but a number that has a weird ending, we need to convert it to pixels + // but not position css attributes, as those are proportional to the parent element instead + // and we can't measure the parent instead because it might trigger a "stacking dolls" problem + if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) { + + // Remember the original values + left = style.left; + rs = elem.runtimeStyle; + rsLeft = rs && rs.left; + + // Put in the new values to get a computed value out + if ( rsLeft ) { + rs.left = elem.currentStyle.left; + } + style.left = name === "fontSize" ? "1em" : ret; + ret = style.pixelLeft + "px"; + + // Revert the changed values + style.left = left; + if ( rsLeft ) { + rs.left = rsLeft; + } + } + + return ret === "" ? "auto" : ret; + }; +} + +function setPositiveNumber( elem, value, subtract ) { + var matches = rnumsplit.exec( value ); + return matches ? + // Guard against undefined "subtract", e.g., when used as in cssHooks + Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) : + value; +} + +function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) { + var i = extra === ( isBorderBox ? "border" : "content" ) ? + // If we already have the right measurement, avoid augmentation + 4 : + // Otherwise initialize for horizontal or vertical properties + name === "width" ? 1 : 0, + + val = 0; + + for ( ; i < 4; i += 2 ) { + // both box models exclude margin, so add it if we want it + if ( extra === "margin" ) { + val += jQuery.css( elem, extra + cssExpand[ i ], true, styles ); + } + + if ( isBorderBox ) { + // border-box includes padding, so remove it if we want content + if ( extra === "content" ) { + val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + } + + // at this point, extra isn't border nor margin, so remove border + if ( extra !== "margin" ) { + val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } else { + // at this point, extra isn't content, so add padding + val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + + // at this point, extra isn't content nor padding, so add border + if ( extra !== "padding" ) { + val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } + } + + return val; +} + +function getWidthOrHeight( elem, name, extra ) { + + // Start with offset property, which is equivalent to the border-box value + var valueIsBorderBox = true, + val = name === "width" ? elem.offsetWidth : elem.offsetHeight, + styles = getStyles( elem ), + isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; + + // some non-html elements return undefined for offsetWidth, so check for null/undefined + // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285 + // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668 + if ( val <= 0 || val == null ) { + // Fall back to computed then uncomputed css if necessary + val = curCSS( elem, name, styles ); + if ( val < 0 || val == null ) { + val = elem.style[ name ]; + } + + // Computed unit is not pixels. Stop here and return. + if ( rnumnonpx.test(val) ) { + return val; + } + + // we need the check for style in case a browser which returns unreliable values + // for getComputedStyle silently falls back to the reliable elem.style + valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] ); + + // Normalize "", auto, and prepare for extra + val = parseFloat( val ) || 0; + } + + // use the active box-sizing model to add/subtract irrelevant styles + return ( val + + augmentWidthOrHeight( + elem, + name, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox, + styles + ) + ) + "px"; +} + +// Try to determine the default display value of an element +function css_defaultDisplay( nodeName ) { + var doc = document, + display = elemdisplay[ nodeName ]; + + if ( !display ) { + display = actualDisplay( nodeName, doc ); + + // If the simple way fails, read from inside an iframe + if ( display === "none" || !display ) { + // Use the already-created iframe if possible + iframe = ( iframe || + jQuery(""); + } + } + }, + + _triggerAction: function(type, pane) { + if (!this.trigger(type, { pane: pane[0] })) { + this[type](pane[0]); + } + }, + + _togglePane: function(e) { + var that = this, + target = $(e.target), + arrow; + + if (target.closest(".k-splitter")[0] != that.element[0]) { + return; + } + + arrow = target.children(".k-icon:not(.k-resize-handle)"); + + if (arrow.length !== 1) { + return; + } + + if (arrow.is(".k-collapse-prev")) { + that._triggerAction(COLLAPSE, target.prev()); + } else if (arrow.is(".k-collapse-next")) { + that._triggerAction(COLLAPSE, target.next()); + } else if (arrow.is(".k-expand-prev")) { + that._triggerAction(EXPAND, target.prev()); + } else if (arrow.is(".k-expand-next")) { + that._triggerAction(EXPAND, target.next()); + } + }, + _arrowClick: function (arrowType) { + var that = this; + + return function(e) { + var target = $(e.target), + pane; + + if (target.closest(".k-splitter")[0] != that.element[0]) { + return; + } + + if (target.is(".k-" + arrowType + "-prev")) { + pane = target.parent().prev(); + } else { + pane = target.parent().next(); + } + that._triggerAction(arrowType, pane); + }; + }, + _updateSplitBar: function(splitbar, previousPane, nextPane) { + var catIconIf = function(iconType, condition) { + return condition ? "
" : ""; + }, + orientation = this.orientation, + draggable = (previousPane.resizable !== false) && (nextPane.resizable !== false), + prevCollapsible = previousPane.collapsible, + prevCollapsed = previousPane.collapsed, + nextCollapsible = nextPane.collapsible, + nextCollapsed = nextPane.collapsed; + + splitbar.addClass("k-splitbar k-state-default k-secondary k-splitbar-" + orientation) + .attr("role", "separator") + .attr("aria-expanded", !(prevCollapsed || nextCollapsed)) + .removeClass("k-splitbar-" + orientation + "-hover") + .toggleClass("k-splitbar-draggable-" + orientation, + draggable && !prevCollapsed && !nextCollapsed) + .toggleClass("k-splitbar-static-" + orientation, + !draggable && !prevCollapsible && !nextCollapsible) + .html( + catIconIf("k-collapse-prev", prevCollapsible && !prevCollapsed && !nextCollapsed) + + catIconIf("k-expand-prev", prevCollapsible && prevCollapsed && !nextCollapsed) + + catIconIf("k-resize-handle", draggable) + + catIconIf("k-collapse-next", nextCollapsible && !nextCollapsed && !prevCollapsed) + + catIconIf("k-expand-next", nextCollapsible && nextCollapsed && !prevCollapsed) + ); + }, + _updateSplitBars: function() { + var that = this; + + this.element.children(".k-splitbar").each(function() { + var splitbar = $(this), + previousPane = splitbar.prevAll(PANECLASS).first().data(PANE), + nextPane = splitbar.nextAll(PANECLASS).first().data(PANE); + + if (!nextPane) { + return; + } + + that._updateSplitBar(splitbar, previousPane, nextPane); + }); + }, + _removeSplitBars: function() { + this.element.children(".k-splitbar").remove(); + }, + _panes: function() { + return this.element.children(PANECLASS); + }, + + _resize: function() { + var that = this, + element = that.element, + panes = element.children(PANECLASS), + isHorizontal = that.orientation == HORIZONTAL, + splitBars = element.children(".k-splitbar"), + splitBarsCount = splitBars.length, + sizingProperty = isHorizontal ? "width" : "height", + totalSize = element[sizingProperty](); + + if (splitBarsCount === 0) { + splitBarsCount = panes.length - 1; + panes.slice(0, splitBarsCount) + .after("
"); + + that._updateSplitBars(); + splitBars = element.children(".k-splitbar"); + } else { + that._updateSplitBars(); + } + + // discard splitbar sizes from total size + splitBars.each(function() { + totalSize -= this[isHorizontal ? "offsetWidth" : "offsetHeight"]; + }); + + var sizedPanesWidth = 0, + sizedPanesCount = 0, + freeSizedPanes = $(); + + panes.css({ position: "absolute", top: 0 }) + [sizingProperty](function() { + var config = $(this).data(PANE) || {}, size; + + if (config.collapsed) { + size = 0; + $(this).css("overflow", "hidden"); + } else if (isFluid(config.size)) { + freeSizedPanes = freeSizedPanes.add(this); + return; + } else { // sized in px/%, not collapsed + size = parseInt(config.size, 10); + + if (isPercentageSize(config.size)) { + size = Math.floor(size * totalSize / 100); + } + } + + sizedPanesCount++; + sizedPanesWidth += size; + + return size; + }); + + totalSize -= sizedPanesWidth; + + var freeSizePanesCount = freeSizedPanes.length, + freeSizePaneWidth = Math.floor(totalSize / freeSizePanesCount); + + freeSizedPanes + .slice(0, freeSizePanesCount - 1) + .css(sizingProperty, freeSizePaneWidth) + .end() + .eq(freeSizePanesCount - 1) + .css(sizingProperty, totalSize - (freeSizePanesCount - 1) * freeSizePaneWidth); + + // arrange panes + var sum = 0, + alternateSizingProperty = isHorizontal ? "height" : "width", + positioningProperty = isHorizontal ? "left" : "top", + sizingDomProperty = isHorizontal ? "offsetWidth" : "offsetHeight"; + + if (freeSizePanesCount === 0) { + var lastNonCollapsedPane = panes.filter(function() { + return !(($(this).data(PANE) || {}).collapsed); + }).last(); + + lastNonCollapsedPane[sizingProperty](totalSize + lastNonCollapsedPane[0][sizingDomProperty]); + } + + element.children(":not(script)") + .css(alternateSizingProperty, element[alternateSizingProperty]()) + .each(function (i, child) { + child.style[positioningProperty] = Math.floor(sum) + "px"; + sum += child[sizingDomProperty]; + }); + + that._detachEvents(); + that._attachEvents(); + + kendo.resize(panes); + that.trigger(LAYOUTCHANGE); + }, + + toggle: function(pane, expand) { + var that = this, + paneConfig; + + pane = that.element.find(pane); + paneConfig = pane.data(PANE); + + if (!expand && !paneConfig.collapsible) { + return; + } + + if (arguments.length == 1) { + expand = paneConfig.collapsed === undefined ? false : paneConfig.collapsed; + } + + paneConfig.collapsed = !expand; + + if (paneConfig.collapsed) { + pane.css("overflow", "hidden"); + } else { + pane.css("overflow", ""); + } + + that.resize(true); + }, + + collapse: function(pane) { + this.toggle(pane, false); + }, + + expand: function(pane) { + this.toggle(pane, true); + }, + + _addPane: function(config, idx, paneElement) { + var that = this; + + if (paneElement.length) { + that.options.panes.splice(idx, 0, config); + that._initPane(paneElement, config); + + that._removeSplitBars(); + + that.resize(true); + } + + return paneElement; + }, + + append: function(config) { + config = config || {}; + + var that = this, + paneElement = $("
").appendTo(that.element); + + return that._addPane(config, that.options.panes.length, paneElement); + }, + + insertBefore: function(config, referencePane) { + referencePane = $(referencePane); + config = config || {}; + + var that = this, + idx = that.wrapper.children(".k-pane").index(referencePane), + paneElement = $("
").insertBefore($(referencePane)); + + return that._addPane(config, idx, paneElement); + }, + + insertAfter: function(config, referencePane) { + referencePane = $(referencePane); + config = config || {}; + + var that = this, + idx = that.wrapper.children(".k-pane").index(referencePane), + paneElement = $("
").insertAfter($(referencePane)); + + return that._addPane(config, idx + 1, paneElement); + }, + + remove: function(pane) { + pane = $(pane); + + var that = this; + + if (pane.length) { + kendo.destroy(pane); + pane.each(function(idx, element){ + that.options.panes.splice(that.wrapper.children(".k-pane").index(element), 1); + $(element).remove(); + }); + + that._removeSplitBars(); + + if (that.options.panes.length) { + that.resize(true); + } + } + + return that; + }, + + size: panePropertyAccessor("size", true), + + min: panePropertyAccessor("min"), + + max: panePropertyAccessor("max") + }); + + ui.plugin(Splitter); + + var verticalDefaults = { + sizingProperty: "height", + sizingDomProperty: "offsetHeight", + alternateSizingProperty: "width", + positioningProperty: "top", + mousePositioningProperty: "pageY" + }; + + var horizontalDefaults = { + sizingProperty: "width", + sizingDomProperty: "offsetWidth", + alternateSizingProperty: "height", + positioningProperty: "left", + mousePositioningProperty: "pageX" + }; + + function PaneResizing(splitter) { + var that = this, + orientation = splitter.orientation; + + that.owner = splitter; + that._element = splitter.element; + that.orientation = orientation; + + extend(that, orientation === HORIZONTAL ? horizontalDefaults : verticalDefaults); + + that._resizable = new kendo.ui.Resizable(splitter.element, { + orientation: orientation, + handle: ".k-splitbar-draggable-" + orientation + "[data-marker=" + splitter._marker + "]", + hint: proxy(that._createHint, that), + start: proxy(that._start, that), + max: proxy(that._max, that), + min: proxy(that._min, that), + invalidClass:"k-restricted-size-" + orientation, + resizeend: proxy(that._stop, that) + }); + } + + PaneResizing.prototype = { + press: function(target) { + this._resizable.press(target); + }, + + move: function(delta, target) { + if (!this.pressed) { + this.press(target); + this.pressed = true; + } + + if (!this._resizable.target) { + this._resizable.press(target); + } + + this._resizable.move(delta); + }, + + end: function() { + this._resizable.end(); + this.pressed = false; + }, + + destroy: function() { + this._resizable.destroy(); + }, + + isResizing: function() { + return this._resizable.resizing; + }, + + _createHint: function(handle) { + var that = this; + return $("
") + .css(that.alternateSizingProperty, handle[that.alternateSizingProperty]()); + }, + + _start: function(e) { + var that = this, + splitbar = $(e.currentTarget), + previousPane = splitbar.prev(), + nextPane = splitbar.next(), + previousPaneConfig = previousPane.data(PANE), + nextPaneConfig = nextPane.data(PANE), + prevBoundary = parseInt(previousPane[0].style[that.positioningProperty], 10), + nextBoundary = parseInt(nextPane[0].style[that.positioningProperty], 10) + nextPane[0][that.sizingDomProperty] - splitbar[0][that.sizingDomProperty], + totalSize = parseInt(that._element.css(that.sizingProperty), 10), + toPx = function (value) { + var val = parseInt(value, 10); + return (isPixelSize(value) ? val : (totalSize * val) / 100) || 0; + }, + prevMinSize = toPx(previousPaneConfig.min), + prevMaxSize = toPx(previousPaneConfig.max) || nextBoundary - prevBoundary, + nextMinSize = toPx(nextPaneConfig.min), + nextMaxSize = toPx(nextPaneConfig.max) || nextBoundary - prevBoundary; + + that.previousPane = previousPane; + that.nextPane = nextPane; + that._maxPosition = Math.min(nextBoundary - nextMinSize, prevBoundary + prevMaxSize); + that._minPosition = Math.max(prevBoundary + prevMinSize, nextBoundary - nextMaxSize); + }, + _max: function() { + return this._maxPosition; + }, + _min: function() { + return this._minPosition; + }, + _stop: function(e) { + var that = this, + splitbar = $(e.currentTarget), + owner = that.owner; + + owner._panes().children(".k-splitter-overlay").remove(); + + if (e.keyCode !== kendo.keys.ESC) { + var ghostPosition = e.position, + previousPane = splitbar.prev(), + nextPane = splitbar.next(), + previousPaneConfig = previousPane.data(PANE), + nextPaneConfig = nextPane.data(PANE), + previousPaneNewSize = ghostPosition - parseInt(previousPane[0].style[that.positioningProperty], 10), + nextPaneNewSize = parseInt(nextPane[0].style[that.positioningProperty], 10) + nextPane[0][that.sizingDomProperty] - ghostPosition - splitbar[0][that.sizingDomProperty], + fluidPanesCount = that._element.children(PANECLASS).filter(function() { return isFluid($(this).data(PANE).size); }).length; + + if (!isFluid(previousPaneConfig.size) || fluidPanesCount > 1) { + if (isFluid(previousPaneConfig.size)) { + fluidPanesCount--; + } + + previousPaneConfig.size = previousPaneNewSize + "px"; + } + + if (!isFluid(nextPaneConfig.size) || fluidPanesCount > 1) { + nextPaneConfig.size = nextPaneNewSize + "px"; + } + + owner.resize(true); + } + + return false; + } + }; + +})(window.kendo.jQuery); + +return window.kendo; + +}, typeof define == 'function' && define.amd ? define : function(_, f){ f(); }); diff --git a/src/kendo.tabstrip.js b/src/kendo.tabstrip.js new file mode 100644 index 00000000000..563f2a8ced9 --- /dev/null +++ b/src/kendo.tabstrip.js @@ -0,0 +1,1133 @@ +(function(f, define){ + define([ "./kendo.data" ], f); +})(function(){ + +var __meta__ = { + id: "tabstrip", + name: "TabStrip", + category: "web", + description: "The TabStrip widget displays a collection of tabs with associated tab content.", + depends: [ "data" ] +}; + +(function ($, undefined) { + var kendo = window.kendo, + ui = kendo.ui, + keys = kendo.keys, + map = $.map, + each = $.each, + trim = $.trim, + extend = $.extend, + template = kendo.template, + Widget = ui.Widget, + excludedNodesRegExp = /^(a|div)$/i, + NS = ".kendoTabStrip", + IMG = "img", + HREF = "href", + PREV = "prev", + LINK = "k-link", + LAST = "k-last", + CLICK = "click", + ERROR = "error", + EMPTY = ":empty", + IMAGE = "k-image", + FIRST = "k-first", + SELECT = "select", + ACTIVATE = "activate", + CONTENT = "k-content", + CONTENTURL = "contentUrl", + MOUSEENTER = "mouseenter", + MOUSELEAVE = "mouseleave", + CONTENTLOAD = "contentLoad", + DISABLEDSTATE = "k-state-disabled", + DEFAULTSTATE = "k-state-default", + ACTIVESTATE = "k-state-active", + FOCUSEDSTATE = "k-state-focused", + HOVERSTATE = "k-state-hover", + TABONTOP = "k-tab-on-top", + NAVIGATABLEITEMS = ".k-item:not(." + DISABLEDSTATE + ")", + HOVERABLEITEMS = ".k-tabstrip-items > " + NAVIGATABLEITEMS + ":not(." + ACTIVESTATE + ")", + + templates = { + content: template( + "
#= content(item) #
" + ), + itemWrapper: template( + "<#= tag(item) # class='k-link'#= contentUrl(item) ##= textAttributes(item) #>" + + "#= image(item) ##= sprite(item) ##= text(item) #" + + "" + ), + item: template( + "" + ), + image: template(""), + sprite: template(""), + empty: template("") + }, + + rendering = { + wrapperCssClass: function (group, item) { + var result = "k-item", + index = item.index; + + if (item.enabled === false) { + result += " k-state-disabled"; + } else { + result += " k-state-default"; + } + + if (index === 0) { + result += " k-first"; + } + + if (index == group.length-1) { + result += " k-last"; + } + + return result; + }, + textAttributes: function(item) { + return item.url ? " href='" + item.url + "'" : ""; + }, + text: function(item) { + return item.encoded === false ? item.text : kendo.htmlEncode(item.text); + }, + tag: function(item) { + return item.url ? "a" : "span"; + }, + contentAttributes: function(content) { + return content.active !== true ? " style='display:none' aria-hidden='true' aria-expanded='false'" : ""; + }, + content: function(item) { + return item.content ? item.content : item.contentUrl ? "" : " "; + }, + contentUrl: function(item) { + return item.contentUrl ? kendo.attr("content-url") + '="' + item.contentUrl + '"' : ""; + } + }; + + function updateTabClasses (tabs) { + tabs.children(IMG) + .addClass(IMAGE); + + tabs.children("a") + .addClass(LINK) + .children(IMG) + .addClass(IMAGE); + + tabs.filter(":not([disabled]):not([class*=k-state-disabled])") + .addClass(DEFAULTSTATE); + + tabs.filter("li[disabled]") + .addClass(DISABLEDSTATE) + .removeAttr("disabled"); + + tabs.filter(":not([class*=k-state])") + .children("a") + .filter(":focus") + .parent() + .addClass(ACTIVESTATE + " " + TABONTOP); + + tabs.attr("role", "tab"); + tabs.filter("." + ACTIVESTATE) + .attr("aria-selected", true); + + + tabs.each(function() { + var item = $(this); + + if (!item.children("." + LINK).length) { + item + .contents() // exclude groups, real links, templates and empty text nodes + .filter(function() { return (!this.nodeName.match(excludedNodesRegExp) && !(this.nodeType == 3 && !trim(this.nodeValue))); }) + .wrapAll(""); + } + }); + + } + + function updateFirstLast (tabGroup) { + var tabs = tabGroup.children(".k-item"); + + tabs.filter(".k-first:not(:first-child)").removeClass(FIRST); + tabs.filter(".k-last:not(:last-child)").removeClass(LAST); + tabs.filter(":first-child").addClass(FIRST); + tabs.filter(":last-child").addClass(LAST); + } + + var TabStrip = Widget.extend({ + init: function(element, options) { + var that = this; + + Widget.fn.init.call(that, element, options); + + that._animations(that.options); + + if (that.element.is("ul")) { + that.wrapper = that.element.wrapAll("
").parent(); + } else { + that.wrapper = that.element; + } + + options = that.options; + + that._isRtl = kendo.support.isRtl(that.wrapper); + + that._tabindex(); + + that._updateClasses(); + + that._dataSource(); + + if (options.dataSource) { + that.dataSource.fetch(); + } + + if (that.options.contentUrls) { + that.wrapper.find(".k-tabstrip-items > .k-item") + .each(function(index, item) { + $(item).find(">." + LINK).data(CONTENTURL, that.options.contentUrls[index]); + }); + } + + that.wrapper + .on(MOUSEENTER + NS + " " + MOUSELEAVE + NS, HOVERABLEITEMS, that._toggleHover) + .on("keydown" + NS, $.proxy(that._keydown, that)) + .on("focus" + NS, $.proxy(that._active, that)) + .on("blur" + NS, function() { that._current(null); }); + + that.wrapper.children(".k-tabstrip-items") + .on(CLICK + NS, ".k-state-disabled .k-link", false) + .on(CLICK + NS, " > " + NAVIGATABLEITEMS, function(e) { + if (that.wrapper[0] !== document.activeElement) { + that.wrapper.focus(); + } + + if (that._click($(e.currentTarget))) { + e.preventDefault(); + } + }); + + var selectedItems = that.tabGroup.children("li." + ACTIVESTATE), + content = that.contentHolder(selectedItems.index()); + + if (content.length > 0 && content[0].childNodes.length === 0) { + that.activateTab(selectedItems.eq(0)); + } + + that.element.attr("role", "tablist"); + + if (that.element[0].id) { + that._ariaId = that.element[0].id + "_ts_active"; + } + + kendo.notify(that); + }, + + _active: function() { + var item = this.tabGroup.children().filter("." + ACTIVESTATE); + + item = item[0] ? item : this._endItem("first"); + if (item[0]) { + this._current(item); + } + }, + + _endItem: function(action) { + return this.tabGroup.children(NAVIGATABLEITEMS)[action](); + }, + + _item: function(item, action) { + var endItem; + if (action === PREV) { + endItem = "last"; + } else { + endItem = "first"; + } + + if (!item) { + return this._endItem(endItem); + } + + item = item[action](); + + if (!item[0]) { + item = this._endItem(endItem); + } + + if (item.hasClass(DISABLEDSTATE)) { + item = this._item(item, action); + } + + return item; + }, + + _current: function(candidate) { + var that = this, + focused = that._focused, + id = that._ariaId; + + if (candidate === undefined) { + return focused; + } + + if (focused) { + if (focused[0].id === id) { + focused.removeAttr("id"); + } + focused.removeClass(FOCUSEDSTATE); + } + + if (candidate) { + if (!candidate.hasClass(ACTIVESTATE)) { + candidate.addClass(FOCUSEDSTATE); + } + + that.element.removeAttr("aria-activedescendant"); + + id = candidate[0].id || id; + + if (id) { + candidate.attr("id", id); + that.element.attr("aria-activedescendant", id); + } + } + + that._focused = candidate; + }, + + _keydown: function(e) { + var that = this, + key = e.keyCode, + current = that._current(), + rtl = that._isRtl, + action; + + if (e.target != e.currentTarget) { + return; + } + + if (key == keys.DOWN || key == keys.RIGHT) { + action = rtl ? PREV : "next"; + } else if (key == keys.UP || key == keys.LEFT) { + action = rtl ? "next" : PREV; + } else if (key == keys.ENTER || key == keys.SPACEBAR) { + that._click(current); + e.preventDefault(); + } else if (key == keys.HOME) { + that._click(that._endItem("first")); + e.preventDefault(); + return; + } else if (key == keys.END) { + that._click(that._endItem("last")); + e.preventDefault(); + return; + } + + if (action) { + that._click(that._item(current, action)); + e.preventDefault(); + } + }, + + _dataSource: function() { + var that = this; + + if (that.dataSource && that._refreshHandler) { + that.dataSource.unbind("change", that._refreshHandler); + } else { + that._refreshHandler = $.proxy(that.refresh, that); + } + + that.dataSource = kendo.data.DataSource.create(that.options.dataSource) + .bind("change", that._refreshHandler); + }, + + setDataSource: function(dataSource) { + this.options.dataSource = dataSource; + this._dataSource(); + dataSource.fetch(); + }, + + _animations: function(options) { + if (options && ("animation" in options) && !options.animation) { + options.animation = { open: { effects: {} }, close: { effects: {} } }; // No animation + } + }, + + refresh: function(e) { + var that = this, + options = that.options, + text = kendo.getter(options.dataTextField), + content = kendo.getter(options.dataContentField), + contentUrl = kendo.getter(options.dataContentUrlField), + image = kendo.getter(options.dataImageUrlField), + url = kendo.getter(options.dataUrlField), + sprite = kendo.getter(options.dataSpriteCssClass), + idx, + tabs = [], + tab, + action, + view = that.dataSource.view(), + length; + + + e = e || {}; + action = e.action; + + if (action) { + view = e.items; + } + + for (idx = 0, length = view.length; idx < length; idx ++) { + tab = { + text: text(view[idx]) + }; + + if (options.dataContentField) { + tab.content = content(view[idx]); + } + + if (options.dataContentUrlField) { + tab.contentUrl = contentUrl(view[idx]); + } + + if (options.dataUrlField) { + tab.url = url(view[idx]); + } + + if (options.dataImageUrlField) { + tab.imageUrl = image(view[idx]); + } + + if (options.dataSpriteCssClass) { + tab.spriteCssClass = sprite(view[idx]); + } + + tabs[idx] = tab; + } + + if (e.action == "add") { + if (e.index < that.tabGroup.children().length) { + that.insertBefore(tabs, that.tabGroup.children().eq(e.index)); + } else { + that.append(tabs); + } + } else if (e.action == "remove") { + for (idx = 0; idx < view.length; idx++) { + that.remove(e.index); + } + } else if (e.action == "itemchange") { + idx = that.dataSource.view().indexOf(view[0]); + if (e.field === options.dataTextField) { + that.tabGroup.children().eq(idx).find(".k-link").text(view[0].get(e.field)); + } + } else { + that.trigger("dataBinding"); + that.remove("li"); + that.append(tabs); + that.trigger("dataBound"); + } + }, + + value: function(value) { + var that = this; + + if (value !== undefined) { + if (value != that.value()) { + that.tabGroup.children().each(function() { + if ($.trim($(this).text()) == value) { + that.select(this); + } + }); + } + } else { + return that.select().text(); + } + }, + + items: function() { + return this.tabGroup[0].children; + }, + + setOptions: function(options) { + var animation = this.options.animation; + + this._animations(options); + + options.animation = extend(true, animation, options.animation); + + Widget.fn.setOptions.call(this, options); + }, + + events: [ + SELECT, + ACTIVATE, + ERROR, + CONTENTLOAD, + "change", + "dataBinding", + "dataBound" + ], + + options: { + name: "TabStrip", + dataTextField: "", + dataContentField: "", + dataImageUrlField: "", + dataUrlField: "", + dataSpriteCssClass: "", + dataContentUrlField: "", + animation: { + open: { + effects: "expand:vertical fadeIn", + duration: 200 + }, + close: { // if close animation effects are defined, they will be used instead of open.reverse + duration: 200 + } + }, + collapsible: false + }, + + destroy: function() { + var that = this; + + Widget.fn.destroy.call(that); + + if (that._refreshHandler) { + that.dataSource.unbind("change", that._refreshHandler); + } + + that.wrapper.off(NS); + that.wrapper.children(".k-tabstrip-items").off(NS); + + kendo.destroy(that.wrapper); + }, + + select: function (element) { + var that = this; + + if (arguments.length === 0) { + return that.tabGroup.children("li." + ACTIVESTATE); + } + + if (!isNaN(element)) { + element = that.tabGroup.children().get(element); + } + + element = that.tabGroup.find(element); + $(element).each(function (index, item) { + item = $(item); + if (!item.hasClass(ACTIVESTATE) && !that.trigger(SELECT, { item: item[0], contentElement: that.contentHolder(item.index())[0] })) { + that.activateTab(item); + } + }); + + return that; + }, + + enable: function (element, state) { + this._toggleDisabled(element, state !== false); + + return this; + }, + + disable: function (element) { + this._toggleDisabled(element, false); + + return this; + }, + + reload: function (element) { + element = this.tabGroup.find(element); + var that = this; + + element.each(function () { + var item = $(this), + contentUrl = item.find("." + LINK).data(CONTENTURL), + content = that.contentHolder(item.index()); + + if (contentUrl) { + that.ajaxRequest(item, content, null, contentUrl); + } + }); + + return that; + }, + + append: function (tab) { + var that = this, + inserted = that._create(tab); + + each(inserted.tabs, function (idx) { + that.tabGroup.append(this); + that.wrapper.append(inserted.contents[idx]); + }); + + updateFirstLast(that.tabGroup); + that._updateContentElements(); + + return that; + }, + + insertBefore: function (tab, referenceTab) { + referenceTab = this.tabGroup.find(referenceTab); + + var that = this, + inserted = that._create(tab), + referenceContent = $(that.contentElement(referenceTab.index())); + + each(inserted.tabs, function (idx) { + referenceTab.before(this); + referenceContent.before(inserted.contents[idx]); + }); + + updateFirstLast(that.tabGroup); + that._updateContentElements(); + + return that; + }, + + insertAfter: function (tab, referenceTab) { + referenceTab = this.tabGroup.find(referenceTab); + + var that = this, + inserted = that._create(tab), + referenceContent = $(that.contentElement(referenceTab.index())); + + each(inserted.tabs, function (idx) { + referenceTab.after(this); + referenceContent.after(inserted.contents[idx]); + }); + + updateFirstLast(that.tabGroup); + that._updateContentElements(); + + return that; + }, + + remove: function (elements) { + var that = this, + type = typeof elements, + contents = $(); + + if (type === "string") { + elements = that.tabGroup.find(elements); + } else if (type === "number") { + elements = that.tabGroup.children().eq(elements); + } + + elements.each(function () { + contents.push(that.contentElement($(this).index())); + }); + elements.remove(); + contents.remove(); + + that._updateContentElements(); + + return that; + }, + + _create: function (tab) { + var plain = $.isPlainObject(tab), + that = this, tabs, contents, content; + + if (plain || $.isArray(tab)) { + tab = $.isArray(tab) ? tab : [tab]; + + tabs = map(tab, function (value, idx) { + return $(TabStrip.renderItem({ + group: that.tabGroup, + item: extend(value, { index: idx }) + })); + }); + + contents = map( tab, function (value, idx) { + if (value.content || value.contentUrl) { + return $(TabStrip.renderContent({ + item: extend(value, { index: idx }) + })); + } + }); + } else { + if (typeof tab == "string" && tab[0] != "<") { + tabs = that.element.find(tab); + } else { + tabs = $(tab); + } + contents = $(); + tabs.each(function () { + content = $("
"); + if (/k-tabstrip-items/.test(this.parentNode.className)) { + content = $(that.contentElement($(this).index())); + } + contents = contents.add(content); + }); + + updateTabClasses(tabs); + } + + return { tabs: tabs, contents: contents }; + }, + + _toggleDisabled: function(element, enable) { + element = this.tabGroup.find(element); + element.each(function () { + $(this) + .toggleClass(DEFAULTSTATE, enable) + .toggleClass(DISABLEDSTATE, !enable); + }); + }, + + _updateClasses: function() { + var that = this, + tabs, activeItem, activeTab; + + that.wrapper.addClass("k-widget k-header k-tabstrip"); + + that.tabGroup = that.wrapper.children("ul").addClass("k-tabstrip-items k-reset"); + + if (!that.tabGroup[0]) { + that.tabGroup = $("
foo1bar1
foo2bar2
"), + dataSource = DataSource.create({ + table: table, + fields: [ { field: "foo" }, { field: "bar" } ] + }); + + dataSource.read(); + equal(dataSource.data().length, 2); + equal(dataSource.data()[0].foo, "foo1"); + equal(dataSource.data()[0].bar, "bar1"); + equal(dataSource.data()[1].foo, "foo2"); + equal(dataSource.data()[1].bar, "bar2"); +}); + +test("infer from html table skips th", function() { + var table = $("
foo
"), + dataSource = DataSource.create({ + table: table, + fields: [ { field: "foo" }] + }); + + dataSource.read(); + equal(dataSource.data().length, 0); +}); + +test("infer from html select", function() { + var select = $(""), + dataSource = DataSource.create({ + select: select, + fields: [ { field: "text" }, { field: "value" } ] + }); + + dataSource.read(); + equal(dataSource.data().length, 2); + equal(dataSource.data()[0].text, "foo1"); + equal(dataSource.data()[0].value, "1"); + equal(dataSource.data()[1].text, "foo2"); + equal(dataSource.data()[1].value, "2"); +}); + +test("infer from html select skips disabled options", function() { + var select = $(""), + dataSource = DataSource.create({ + select: select, + fields: [ { field: "text" }, { field: "value" } ] + }); + + dataSource.read(); + equal(dataSource.data().length, 1); + equal(dataSource.data()[0].text, "foo2"); + equal(dataSource.data()[0].value, "2"); +}); + +test("initialize data source from array", function() { + var data = [1, 2], + dataSource = DataSource.create(data); + + dataSource.read(); + ok(dataSource.data().length, 2); + ok(dataSource.data()[0], 1); + ok(dataSource.data()[1], 2); +}); + +test("XmlDataReader is initialized when the type of the schema is xml", function() { + var dataSource = new DataSource({ + schema: { + type: "xml", + model: Model.define() + } + }); + + ok(dataSource.reader instanceof kendo.data.XmlDataReader); +}); + +test("get returns a model instance", function() { + var dataSource = new DataSource({ + schema: { + model: Model.define() + }, + data: [ { id: 1, foo: "bar"}, { id: 2, foo: "baz"}] + }); + dataSource.read(); + var model = dataSource.get(1); + equal(model.get("id"), 1); + equal(model.get("foo"), "bar"); +}); + +test("get returns data record if original data is grouped", function() { + var dataSource = new DataSource({ + schema: { + model: Model.define() + }, + serverGrouping: true, + group: [ { field: "foo", value: "bar" } ], + data: [ { field: "foo", value: "bar", items: [{ id: 1, foo: "bar"}, { id: 2, foo: "bar"}]}] + }); + dataSource.read(); + var model = dataSource.get(1); + equal(model.get("id"), 1); + equal(model.get("foo"), "bar"); +}); + +test("get data record is same as the original if original data is grouped", function() { + var dataSource = new DataSource({ + schema: { + model: Model.define() + }, + serverGrouping: true, + group: [ { field: "foo", value: "bar" } ], + data: [ { field: "foo", value: "bar", items: [{ id: 1, foo: "bar"}, { id: 2, foo: "bar"}]}] + }); + dataSource.read(); + var original = dataSource.data()[0].items[0]; + + var model = dataSource.get(1); + equal(model, original); +}); + +test("getByUid returns data record if data is grouped", function() { + var dataSource = new DataSource({ + serverGrouping: true, + group: [ { field: "foo", value: "bar" } ], + data: [ { field: "foo", value: "bar", items: [{ id: 1, foo: "bar"}, { id: 2, foo: "bar"}]}] + }); + dataSource.read(); + var uid = dataSource.data()[0].items[0].uid; + var model = dataSource.getByUid(uid); + + equal(model.get("id"), 1); + equal(model.get("foo"), "bar"); +}); + +test("getByUid returns data record if data is grouped with multiple group levels", function() { + var dataSource = new DataSource({ + serverGrouping: true, + group: [ { field: "foo", value: "bar" } ], + data: [ { field: "foo", value: "bar", hasSubgroups: true, items: [ + { field: "id", value: 1, items: [{ id: 1, foo: "bar"}]}, + { field: "id", value: 2, items: [{ id: 2, foo: "bar"}]} + ]}] + }); + dataSource.read(); + var uid = dataSource.data()[0].items[0].items[0].uid; + var model = dataSource.getByUid(uid); + + equal(model.get("id"), 1); + equal(model.get("foo"), "bar"); +}); + +test("model use model metadata", function() { + var dataSource = new DataSource({ + schema: { + model: Model.define( { id: "foo" }) + }, + data: [ { foo: "1", bar: "bar1"}, { foo: "2", bar: "bar2"}] + }); + dataSource.read(); + var model = dataSource.get("2"); + equal(model.get("foo"), "2"); + equal(model.get("bar"), "bar2"); +}); + +test("model method uses specified model from the configuration", function() { + var dataSource = new DataSource({ + schema: { + model: { id: "foo" } + }, + data: [ { foo: "1", bar: "bar1"}, { foo: "2", bar: "bar2"}] + }); + dataSource.read(); + + var model = dataSource.get("2"); + equal(model.get("foo"), "2"); + equal(model.get("bar"), "bar2"); +}); + +test("sort as object is expanded to array", function() { + var dataSource = new DataSource({ + data: [], + sort: { field: "foo", dir: "asc" } + }); + + ok($.isArray(dataSource._sort)); + equal(dataSource._sort[0].field, "foo"); + equal(dataSource._sort[0].dir, "asc"); +}); + +test("Data is converted to ObservableArray", function() { + var dataSource = new DataSource({ + data: [{ foo: 1 }] + }); + dataSource.read(); + ok(dataSource.data() instanceof kendo.data.ObservableArray); + ok(dataSource.view() instanceof kendo.data.ObservableArray); +}); + +test("Data initial value is ObservableArray", function() { + var dataSource = new DataSource({ + data: [{ foo: 1 }] + }); + ok(dataSource.data() instanceof kendo.data.ObservableArray); +}); + +test("Group items are converted to the model type when server grouping is enabled", function() { + var MyModel = Model.define({}), + dataSource = new DataSource({ + schema: { + model: MyModel, + groups: function(data) { + return [{ + items: [{ foo: 1 },{ foo: 2 }], + field: "foo", + value: "bar" + }]; + }, + total: function() { + return 1; + } + }, + serverGrouping: true, + group: { field: "foo" } + }); + + dataSource.read(); + + ok(dataSource.data()[0].items[0] instanceof MyModel); + ok(dataSource.data()[0].items[1] instanceof MyModel); +}); + +test("Nested group items are converted to the model type when server grouping is enabled", function() { + var MyModel = Model.define({}), + dataSource = new DataSource({ + schema: { + model: MyModel, + groups: function(data) { + return [{ + items: [{ + items: [{ bar: "bar", foo: 1, id: 0}, { bar: "bar", foo: 1, id: 1}], + field: "bar", + value: "bar" + }], + field: "foo", + value: 1, + hasSubgroups: true + }]; + }, + total: function() { + return 1; + } + }, + serverGrouping: true, + group: { field: "foo" } + }); + + dataSource.read(); + + ok(dataSource.data()[0].items[0].items[0] instanceof MyModel); +}); + +test("reseting data unbind change from the previous data", 1, function() { + var dataSource = new DataSource({ + data: [] + }); + var originalData = dataSource.data(); + + dataSource.bind("change", function() { + ok(true); + }); + + dataSource.data([{}]); + + originalData.push({}); +}); + +}()); diff --git a/tests/data/datasource/model.js b/tests/data/datasource/model.js new file mode 100644 index 00000000000..ffcef0cccbc --- /dev/null +++ b/tests/data/datasource/model.js @@ -0,0 +1,366 @@ +(function(){ + +var dataSource; + +function setup(source) { + dataSource = new kendo.data.DataSource( { + data: source || [{ id:1, foo: "foo" },{ id: 2, foo: "foo" }], + schema: { + model: { + id: "id" + } + } + }); + + dataSource.read(); +} + +module("DataSource", { + setup: function() { + setup(); + } +}); + +test("get returns undefined if no model exist with the specified id", function() { + equal(dataSource.get(3), undefined, "result is undefined"); +}); + +test("get returns the model instance with the specified id", function() { + var model = dataSource.get(1); + ok(model); + ok(model instanceof kendo.data.Model); +}); + +test("get returns the model instance with the specified id as string", function() { + var model = dataSource.get(1); + equal(model.id, 1); +}); + +test("add appends the specified values", function() { + dataSource.add( { foo: "bar" } ); + + equal(dataSource.data().length, 3); + equal(dataSource.data()[2].foo, "bar"); +}); + +test("add returns the new model istance", function() { + var model = dataSource.add( { foo: "bar" } ); + + ok(model instanceof kendo.data.Model); + ok(model.isNew()); + equal(model.foo, "bar"); +}); + +test("add appends specified model instance", function() { + var model = new kendo.data.Model({ foo: "bar" }); + + equal(dataSource.add(model), model); +}); + +test("inserts specified values at specified position", function() { + dataSource.insert(0, { foo: "bar" } ); + + equal(dataSource.data().length, 3); + equal(dataSource.data()[0].foo, "bar"); +}); + +test("inserts the specified values at first position if index is not specified", function() { + dataSource.insert({ foo: "bar" } ); + + equal(dataSource.data()[0].foo, "bar"); +}); + +test("insert returns the new model istance", function() { + var model = dataSource.insert({ foo: "bar" }); + + ok(model instanceof kendo.data.Model); + ok(model.isNew()); +}); + +test("removes the specified model", function() { + var model = dataSource.get(1); + dataSource.remove(model); + + equal(dataSource.data().length, 1); +}); + +test("remove returns the removed model", function() { + var model = dataSource.get(1); + + equal(dataSource.remove(model), model); +}); + +test("cancelChanges restores removed model", function() { + dataSource.remove(dataSource.get(1)); + + dataSource.cancelChanges(); + + equal(dataSource.data().length, 2); + + equal(dataSource.data()[0].id, 1); + ok(dataSource.data()[0] instanceof kendo.data.Model, "First item is a model"); +}); + +test("cancelChanges restores removed model to its original state", function() { + var model = dataSource.get(1); + + model.set("foo", "bar"); + + dataSource.remove(model); + + dataSource.cancelChanges(); + + equal(dataSource.get(1).foo, "foo"); +}); + +test("cancelChanges removes inserted model", function() { + dataSource.insert({ foo: "baz" }); + + dataSource.cancelChanges(); + + equal(dataSource.data().length, 2); +}); + +test("cancelChanges restores updated model to its original state", function() { + var model = dataSource.get(1); + model.set("foo", "baz"); + + dataSource.cancelChanges(model); + + equal(dataSource.get(1).foo, "foo"); + ok(dataSource.get(1) instanceof kendo.data.ObservableObject); +}); + +test("cancelChanges restores updated complex model to its original state", function() { + setup([ { id: 1, foo: { bar: "baz" } } ]); + + var model = dataSource.get(1); + model.set("foo", { bar: "moo" }); + + dataSource.cancelChanges(model); + + equal(dataSource.get(1).foo.bar, "baz"); + ok(dataSource.get(1).foo instanceof kendo.data.ObservableObject); +}); + +test("cancelChanges restores updated model to its original state only for povided model", function() { + var model1 = dataSource.get(1), + model2 = dataSource.get(2); + + model1.set("foo", "baz"); + model2.set("foo", "bar"); + + dataSource.cancelChanges(model1); + + equal(dataSource.get(1).foo, "foo"); + equal(dataSource.get(2).foo, "bar"); +}); + +test("cancelChanges removes inserted model passed as parameter", function() { + var model; + + dataSource.get(1).set("foo", "bar"); + model = dataSource.insert({ foo: "baz" }); + + dataSource.cancelChanges(model); + + equal(dataSource.get(1).foo, "bar"); + equal(dataSource.data().length, 2); +}); + +test("cancelChanges does not revert it passed model is removed", function() { + var model = dataSource.get(1); + + dataSource.get(2).set("foo", "bar"); + dataSource.remove(model); + + dataSource.cancelChanges(model); + + equal(dataSource.get(2).foo, "bar"); + equal(dataSource.data().length, 1); +}); + +test("indexOf returns the index of model", function() { + var model = dataSource.get(1); + + equal(dataSource.indexOf(model), 0); +}); +test("indexOf returns -1 if model is undefined", function() { + var model = dataSource.get(); + + equal(dataSource.indexOf(model), -1); +}); + + +test("indexOf returns -1 if model does is not contained in the data source", function() { + equal(dataSource.indexOf(new kendo.data.Model()), -1); +}); + +test("removes model from grouped data", function() { + var dataSource = new kendo.data.DataSource({ + schema: { + model: { id: "id" }, + groups: function(data) { + return [{ + items: [{ foo: 1, id: 0}, { foo: 1, id: 1}], + field: "foo", + value: 1 + }]; + }, + total: function() { + return 1; + } + }, + serverGrouping: true, + group: { field: "foo" } + }); + + dataSource.read(); + var model = dataSource.get(0); + var removedModel = dataSource.remove(model); + + deepEqual(removedModel, model); + equal(removedModel.foo, 1); + equal(removedModel.id, 0); + equal(dataSource.data()[0].items.length, 1); +}); + +test("removes model from nested grouped data", function() { + var dataSource = new kendo.data.DataSource({ + schema: { + model: { id: "id" }, + groups: function(data) { + return [{ + items: [{ + items: [{ bar: "bar", foo: 1, id: 0}, { bar: "bar", foo: 1, id: 1}], + field: "bar", + value: "bar" + }], + field: "foo", + value: 1, + hasSubgroups: true + }]; + }, + total: function() { + return 1; + } + }, + serverGrouping: true, + group: [{ field: "foo" }, { field: "bar" }] + }); + + dataSource.read(); + var model = dataSource.get(1); + var removedModel = dataSource.remove(model); + + deepEqual(removedModel, model); + equal(removedModel.foo, 1); + equal(removedModel.id, 1); + equal(dataSource.data()[0].items[0].items.length, 1); +}); + +test("cancelChanges does revert changes if server grouping is enabled", function() { + var dataSource = new kendo.data.DataSource({ + schema: { + model: { id: "id" }, + parse: function(data) { + return [{ + items: [{ + items: [{ bar: "bar", foo: 1, id: 0}, { bar: "bar", foo: 1, id: 1}], + field: "bar", + value: "bar" + }], + field: "foo", + value: 1, + hasSubgroups: true + }]; + }, + total: function() { + return 1; + } + }, + serverGrouping: true, + group: [{ field: "foo" }, { field: "bar" }] + }); + + dataSource.read(); + + var model = dataSource.get(1); + + dataSource.remove(model); + + dataSource.cancelChanges(); + + ok(dataSource.get(1)); + equal(dataSource.data()[0].items[0].items.length, 2); +}); + +test("cancelChanges does revert changes for given model if server grouping is enabled", function() { + var dataSource = new kendo.data.DataSource({ + schema: { + model: { id: "id" }, + parse: function(data) { + return [{ + items: [{ + items: [{ bar: "bar", foo: 1, id: 0}, { bar: "bar", foo: 1, id: 1}], + field: "bar", + value: "bar" + }], + field: "foo", + value: 1, + hasSubgroups: true + }]; + }, + total: function() { + return 1; + } + }, + serverGrouping: true, + group: [{ field: "foo" }, { field: "bar" }] + }); + + dataSource.read(); + + var model = dataSource.get(1); + + model.set("bar", "boo"); + + dataSource.cancelChanges(model); + + equal(dataSource.get(1).get("bar"), "bar"); + equal(dataSource.data()[0].items[0].items.length, 2); +}); + +test("adding items to array field sets the dirty flag to true", function() { + var model = new kendo.data.Model({ + foo: [] + }); + + model.foo.push("foo"); + + equal(model.dirty, true); +}); + +test("removing items from array field sets the dirty flag to true", function() { + var model = new kendo.data.Model({ + foo: ["foo"] + }); + + model.foo.pop(); + + equal(model.dirty, true); +}); + +test("accept does not wrap field with underscore", function() { + var model = new kendo.data.Model({ + _foo: {}, + bar: "bar" + }); + + model.accept({ _foo: { foo: "foo1" }, bar: "bar1" }); + + ok(!(model._foo instanceof kendo.data.ObservableObject)); + equal(model._foo.foo, "foo1"); +}); + +}()); diff --git a/tests/data/datasource/observable-array.js b/tests/data/datasource/observable-array.js new file mode 100644 index 00000000000..67d93271a02 --- /dev/null +++ b/tests/data/datasource/observable-array.js @@ -0,0 +1,96 @@ +(function() { + +module("data source observable array"); + +test("triggers change when observable array changes", 1, function() { + var dataSource = kendo.data.DataSource.create([1,2,3]); + + dataSource.read(); + + dataSource.bind("change", function(){ + ok("change is triggered"); + }); + + dataSource.data().push(4); +}); + +test("passes added items in the event parameter", 1, function() { + var dataSource = kendo.data.DataSource.create([1,2,3]); + + dataSource.read(); + + dataSource.bind("change", function(e){ + equal(e.items[0], 4); + }); + + dataSource.data().push(4); +}); + +test("creates observale array which contains model instances if model is specified", 1, function() { + + var dataSource = new kendo.data.DataSource( { + data: [{ id: 1}], + schema: { + model: { + id: "id" + } + } + }); + + dataSource.read(); + + ok(dataSource.data()[0] instanceof kendo.data.Model); +}); + +test("ObservableObject are converted to Model if such is set", function() { + var data = new kendo.data.ObservableArray([ {foo: 1 }]), + ModelType = kendo.data.Model.define({ + fields: { + foo: "foo" + } + }), + dataSource = new kendo.data.DataSource({ + data: data, + schema: { + model: ModelType + } + }); + + dataSource.read(); + + ok(dataSource.at(0) instanceof ModelType); + strictEqual(dataSource.data(), data); +}); + + +test("field is not assigned if is undefined", function() { + var data = new kendo.data.ObservableObject({foo: 1, bar: undefined }); + + strictEqual(data.foo, 1); + strictEqual(data.bar, undefined); +}); + +test("data parent field is assign if observable array is assign", function() { + var viewModel = kendo.observable({ + data: [{foo: 1 }], + dataSource: new kendo.data.DataSource({ + }) + }); + + viewModel.dataSource.data(viewModel.data); + + equal(viewModel.dataSource.data().parent(), viewModel); +}); + +test("data parent field is assign if array is assign", function() { + var viewModel = kendo.observable({ + data: [{foo: 1 }], + dataSource: new kendo.data.DataSource({ + data: [1,2,3,4,5] + }) + }); + + equal(viewModel.dataSource.data().parent(), viewModel); +}); + +}()); diff --git a/tests/data/datasource/push.js b/tests/data/datasource/push.js new file mode 100644 index 00000000000..72aa1103734 --- /dev/null +++ b/tests/data/datasource/push.js @@ -0,0 +1,494 @@ +(function(){ + +var DataSource = kendo.data.DataSource; + +module("data source push"); + +test("push is invoked when the data source is initialized", function(){ + var transport = stub({}, "push"); + + new DataSource({ transport: transport }) + + equal(transport.calls("push"), 1); +}); + +test("push of custom transport is invoked", function(){ + var transport = stub({ read: function() {} }, "push"); + + new DataSource({ transport: transport }) + + equal(transport.calls("push"), 1); +}); + +test("pushCreate option is passed to the push method", 1, function() { + var transport = { + push: function(options) { + ok($.isFunction(options.pushCreate)); + } + }; + + new DataSource( { transport : transport }); +}); + +test("pushUpdate option is passed to the push method", 1, function() { + var transport = { + push: function(options) { + ok($.isFunction(options.pushUpdate)); + } + }; + + new DataSource( { transport : transport }); +}); + +test("pushDestroy option is passed to the push method", 1, function() { + var transport = { + push: function(options) { + ok($.isFunction(options.pushDestroy)); + } + }; + + new DataSource( { transport : transport }); +}); + +test("pushCreate option calls _pushCreate of the data source", function() { + var transportPushCreate; + + var transport = { + push: function(options) { + transportPushCreate = options.pushCreate; + } + }; + + var _pushCreate; + + try { + _pushCreate = DataSource.fn._pushCreate; + + stub(DataSource.fn, "_pushCreate"); + + var dataSource = new DataSource({ transport : transport }); + + transportPushCreate(); + + equal(dataSource.calls("_pushCreate"), 1); + + } finally { + DataSource.fn._pushCreate = _pushCreate; + } +}); + +test("pushUpdate option calls _pushUpdate of the data source", function() { + var transportPushUpdate; + + var transport = { + push: function(options) { + transportPushUpdate = options.pushUpdate; + } + }; + + var _pushUpdate; + + try { + _pushUpdate = DataSource.fn._pushUpdate; + + stub(DataSource.fn, "_pushUpdate"); + + var dataSource = new DataSource({ transport : transport }); + + transportPushUpdate(); + + equal(dataSource.calls("_pushUpdate"), 1); + + } finally { + DataSource.fn._pushUpdate = _pushUpdate; + } +}); + +test("pushDestroy option calls _pushDestroy of the data source", function() { + var transportPushDestroy; + + var transport = { + push: function(options) { + transportPushDestroy = options.pushDestroy; + } + }; + + var _pushDestroy; + + try { + _pushDestroy = DataSource.fn._pushDestroy; + + stub(DataSource.fn, "_pushDestroy"); + + var dataSource = new DataSource({ transport : transport }); + + transportPushDestroy(); + + equal(dataSource.calls("_pushDestroy"), 1); + + } finally { + DataSource.fn._pushDestroy = _pushDestroy; + } +}); + +test("pushCreate inserts a new item in the data source", function() { + var dataSource = new DataSource(); + + dataSource.pushCreate({ foo: "foo" }); + + equal(dataSource.at(0).foo, "foo"); +}); + +test("hasChanges returns false after pushCreate", function() { + var dataSource = new DataSource({ + schema: { model: { id: "id" } } + }); + + dataSource.pushCreate({ id: 1, foo: "foo" }); + + equal(dataSource.hasChanges(), false); +}); + +test("isNew returns false after pushCreate", function() { + var dataSource = new DataSource({ + schema: { model: { id: "id" } } + }); + + dataSource.pushCreate({ id: 1, foo: "foo" }); + + equal(dataSource.at(0).isNew(), false); +}); + +test("pushCreate raises the change event", 2, function() { + var dataSource = new DataSource({ + change: function(e) { + equal(e.action, "add"); + equal(e.items[0].foo, "foo"); + } + }); + + dataSource.pushCreate({ id: 1, foo: "foo" }); +}); + +test("pushCreate inserts an array of items in the data source", function() { + var dataSource = new DataSource(); + + dataSource.pushCreate([ + { foo: "foo" }, + { foo: "bar" } + ]); + + equal(dataSource.at(1).foo, "bar"); +}); + +test("pushUpdate updates an existing item", function() { + var dataSource = new DataSource({ + schema: { model: { id: "id" } }, + data: [ { id: 1, foo: "foo" }] + }); + + dataSource.read(); + + dataSource.pushUpdate({ id: 1, foo: "bar" }); + + equal(dataSource.at(0).foo, "bar"); +}); + +test("hasChanges returns false after pushUpdate", function() { + var dataSource = new DataSource({ + schema: { model: { id: "id" } }, + data: [ { id: 1, foo: "foo" }] + }); + + dataSource.read(); + + dataSource.pushUpdate({ id: 1, foo: "bar" }); + + equal(dataSource.hasChanges(), false); +}); + +test("pushUpdate raises the change event", 2, function() { + var dataSource = new DataSource({ + schema: { model: { id: "id" } }, + data: [ { id: 1, foo: "foo" }] + }); + + dataSource.read(); + + dataSource.bind("change", function(e){ + equal(e.action, "itemchange"); + equal(e.items[0].foo, "bar"); + }); + + dataSource.pushUpdate({ id: 1, foo: "bar" }); +}); + +test("pushUpdate updates an array of existing items", function() { + var dataSource = new DataSource({ + schema: { model: { id: "id" } }, + data: [ + { id: 1, foo: "foo" }, + { id: 2, foo: "foo" } + ] + }); + + dataSource.read(); + + dataSource.pushUpdate([ + { id: 1, foo: "bar" }, + { id: 2, foo: "bar" } + ]); + + equal(dataSource.at(1).foo, "bar"); +}); + +test("pushDestroy removes an existing item", function() { + var dataSource = new DataSource({ + schema: { model: { id: "id" } }, + data: [ { id: 1, foo: "foo" }] + }); + + dataSource.read(); + + dataSource.pushDestroy({ id: 1 }); + + equal(dataSource.data().length, 0); +}); + +test("hasChanges returns false after pushDestroy", function() { + var dataSource = new DataSource({ + schema: { model: { id: "id" } }, + data: [ { id: 1, foo: "foo" }] + }); + + dataSource.read(); + + dataSource.pushDestroy({ id: 1 }); + + equal(dataSource.hasChanges(), false); +}); + +test("pushDestroy raises the change event", 2, function() { + var dataSource = new DataSource({ + schema: { model: { id: "id" } }, + data: [ { id: 1, foo: "foo" }] + }); + + dataSource.read(); + + dataSource.bind("change", function(e){ + equal(e.action, "remove"); + equal(e.items[0].foo, "foo"); + }); + + dataSource.pushDestroy({ id: 1 }); +}); + +test("pushDestroy removes an array of existing items", function() { + var dataSource = new DataSource({ + schema: { model: { id: "id" } }, + data: [ + { id: 1, foo: "foo" }, + { id: 2, foo: "foo" } + ] + }); + + dataSource.read(); + + dataSource.pushDestroy([ + { id: 1 }, + { id: 2 } + ]); + + equal(dataSource.data().length, 0); +}); + +test("pushDestroy removes an existing from the pristine collection", function() { + var dataSource = new DataSource({ + schema: { model: { id: "id" } }, + data: [ { id: 1, foo: "foo" }] + }); + + dataSource.read(); + + dataSource.pushDestroy({ id: 1 }); + + equal(dataSource._pristineData.length, 0); +}); + +test("pushUpdate doesn't set the dirty flag", function() { + var dataSource = new DataSource({ + schema: { model: { id: "id" } }, + data: [ { id: 1, foo: "foo" }] + }); + + dataSource.read(); + + dataSource.pushUpdate({ id: 1, foo: "bar" }); + + equal(dataSource.at(0).dirty, false); +}); + +test("pushUpdate with observable object instance as parameter", function() { + var dataSource = new DataSource({ + schema: { model: { id: "id" } }, + data: [ { id: 1, foo: "foo" }] + }); + + dataSource.read(); + + dataSource.pushUpdate(new kendo.data.ObservableObject({ id: 1, foo: "bar" })); + + equal(dataSource.at(0).foo, "bar"); +}); + +test("pushUpdate with model instance as parameter", function() { + var dataSource = new DataSource({ + schema: { model: { id: "id" } }, + data: [ { id: 1, foo: "foo" }] + }); + + dataSource.read(); + + dataSource.pushUpdate(new kendo.data.Model({ id: 1, foo: "bar" })); + + equal(dataSource.at(0).foo, "bar"); +}); + +test("pushCreate inserts the item in the pristine collection", function() { + var dataSource = new DataSource(); + + var item = { foo: "foo" }; + + result = dataSource.pushCreate(item); + + equal(dataSource._pristineData[0].foo, item.foo); +}); + +test("pushUpdate updates the model instance in the pristine collection", function() { + var dataSource = new DataSource({ + schema: { model: { id: "id" } }, + data: [ { id: 1, foo: "foo" }] + }); + + dataSource.read(); + + dataSource.pushUpdate({ id: 1, foo: "bar" }); + + equal(dataSource._pristineData[0].foo, "bar"); +}); + +test("items inserted via pushCreate remain in the data source after cancelChanges", function() { + var dataSource = new DataSource(); + + var item = { foo: "foo" }; + + dataSource.add( { foo: "bar" }); + dataSource.pushCreate(item); + dataSource.cancelChanges(); + + equal(dataSource.at(0).foo, "foo"); +}); + +test("pushUpdate inserts the item if a model with corresponding id isn't found", function() { + var dataSource = new DataSource({ + schema: { model: { id: "id" } } + }); + + dataSource.read(); + + dataSource.pushUpdate({ id: 1, foo: "bar" }); + + equal(dataSource.at(0).foo, "bar"); +}); + +test("_pushCreate calls pushCreate for every item when data is returned according to the schema", function() { + var dataSource = new DataSource({ + schema: { + data: "d" + } + }); + + dataSource = stub(dataSource, "pushCreate"); + + var data = [ { }, { }]; + + dataSource._pushCreate( { d: data }); + + equal(dataSource.calls("pushCreate"), 1); + equal(dataSource.args("pushCreate", 0)[0][0], data[0]); + equal(dataSource.args("pushCreate", 0)[0][1], data[1]); +}); + +test("_pushUpdate calls pushUpdate for every item when data is returned according to the schema", function() { + var dataSource = new DataSource({ + schema: { + data: "d" + } + }); + + dataSource = stub(dataSource, "pushUpdate"); + + var data = [ { }, { }]; + + dataSource._pushUpdate( { d: data }); + + equal(dataSource.calls("pushUpdate"), 1); + equal(dataSource.args("pushUpdate", 0)[0][0], data[0]); + equal(dataSource.args("pushUpdate", 0)[0][1], data[1]); +}); + +test("_pushDestroy calls pushDestroy for every item when data is returned according to the schema", function() { + var dataSource = new DataSource({ + schema: { + data: "d" + } + }); + + dataSource = stub(dataSource, "pushDestroy"); + + var data = [ { }, { }]; + + dataSource._pushDestroy( { d: data }); + + equal(dataSource.calls("pushDestroy"), 1); + equal(dataSource.args("pushDestroy", 0)[0][0], data[0]); + equal(dataSource.args("pushDestroy", 0)[0][1], data[1]); +}); + +test("_push accepts array of items even if the schema expects an object", function() { + var dataSource = new DataSource({ + schema: { + data: "d" + } + }); + + dataSource = stub(dataSource, "pushCreate"); + + var data = [ { }, { }]; + + dataSource._push( data, "pushCreate" ); + + equal(dataSource.calls("pushCreate"), 1); + equal(dataSource.args("pushCreate", 0)[0][0], data[0]); + equal(dataSource.args("pushCreate", 0)[0][1], data[1]); +}); + +test("_push accepts a single item even if the schema expects an object", function() { + var dataSource = new DataSource({ + schema: { + data: "d" + } + }); + + dataSource = stub(dataSource, "pushCreate"); + + var item = { }; + + dataSource._push(item, "pushCreate" ); + + equal(dataSource.calls("pushCreate"), 1); + equal(dataSource.args("pushCreate", 0)[0], item); +}); + +}()); diff --git a/tests/data/datasource/query.js b/tests/data/datasource/query.js new file mode 100644 index 00000000000..342e2a6dbde --- /dev/null +++ b/tests/data/datasource/query.js @@ -0,0 +1,2043 @@ +(function(){ +module("data source query", { + setup: function() { + $.mockjaxSettings.contentType = 'text/json'; + $.mockjaxSettings.responseTime = 0; + }, + teardown: function() { + $.mockjaxClear() + } +}); + +var data = []; +var RemoteTransport = kendo.data.RemoteTransport; +var DataSource = kendo.data.DataSource; + +function setup(source) { + data = source || [{ id:1, bar: "foo" },{ id: 2, bar: "foo" }]; + + var dataSource = new DataSource( { + data: data + }); + + dataSource.read(); + return dataSource; +} + +test("query raises the change event", function() { + var dataSource = new DataSource({ + data: data + }); + var changeWasCalled = false; + + dataSource.read(); + + dataSource.bind("change", function() { + changeWasCalled = true; + }); + + dataSource.query({}); + + ok(changeWasCalled); +}); + +test("query sets the pageSize", function() { + var dataSource = new DataSource({ + data: data + }); + dataSource.query({ pageSize: 1 }); + equal(dataSource.pageSize(), 1); +}); + + test("query sets page", function() { + var dataSource = new DataSource({ + data: data + }); + + dataSource.query({ page: 1 }); + equal(dataSource.page(), 1); +}); + +test("query sets sort", function() { + var dataSource = new DataSource({ + data: data + }); + + dataSource.query({ sort: { field: "foo", dir: "asc" }}); + ok($.isArray(dataSource.sort())); + equal(dataSource.sort()[0].field, "foo"); + equal(dataSource.sort()[0].dir, "asc"); +}); + +test("query sets custom comparer", function() { + var dataSource = new DataSource({ + data: data + }); + + var comparer = function() {}; + dataSource.query({ sort: { dir: "asc", compare: comparer }}); + equal(dataSource.sort()[0].compare, comparer); +}); + +test("query sets sort when array is passed", function() { + var dataSource = new DataSource({ + data: data + }); + + dataSource.query({ sort: [{ field: "foo", dir: "asc" }, { field: "bar", dir: "desc" } ]}); + equal(dataSource.sort().length, 2); + equal(dataSource.sort()[1].field, "bar"); + equal(dataSource.sort()[1].dir, "desc"); +}); + +test("paging", function() { + var dataSource = new DataSource({ + data: [1,2,3] + }); + + dataSource.read(); + dataSource.query({ pageSize: 1, page: 2 }); + + var view = dataSource.view(); + + equal(view.length, 1); + equal(view[0], 2); +}); + +test("sorting", function() { + var dataSource = new DataSource({ + data: [{age: 1}, {age: 2}] + }); + dataSource.read(); + dataSource.query( { sort: { field: "age", dir: "desc" } } ); + var view = dataSource.view(); + + equal(view.length, 2); + equal(view[0].age, 2); + equal(view[1].age, 1); +}); + +test("sorting sort expression are removed from the state if not passed", function() { + var dataSource = new DataSource({ + data: [{age: 1}, {age: 2}] + }); + dataSource.read(); + dataSource.query( { sort: { field: "age", dir: "desc" } } ); + dataSource.query({}); + var view = dataSource.view(); + + equal(view.length, 2); + equal(view[0].age, 1); + equal(view[1].age, 2); + equal(dataSource.sort(), undefined); +}); + +test("sorting though sort method", function() { + var dataSource = new DataSource({ + data: [{age: 1}, {age: 2}] + }); + dataSource.read(); + dataSource.sort( { field: "age", dir: "desc" } ); + var view = dataSource.view(); + + equal(view.length, 2); + equal(view[0].age, 2); + equal(view[1].age, 1); +}); + +test("paging is after sorting", function() { + var dataSource = new DataSource({ + data: [{age: 1}, {age: 2}] + }); + + dataSource.read(); + dataSource.query( { page: 2, pageSize: 1, sort: { field: "age", dir: "desc" } } ); + var view = dataSource.view(); + + equal(view[0].age, 1); +}); + +test("original data is not modified", function() { + var data = [{age: 1}, {age: 2}]; + + var dataSource = new DataSource({ + data: data + }); + dataSource.read(); + dataSource.query( { page: 2, pageSize: 1, sort: { field: "age", dir: "desc" } } ); + var view = dataSource.data(); + + equal(view.length, 2); + equal(view[0].age, 1); + equal(view[1].age, 2); +}); + +asyncTest("data is not sorted if serverSorting = true", 3, function() { + var transport = new RemoteTransport({ + read: "foo" + }); + + var dataSource = new DataSource( { + transport: transport, + serverSorting: true + }).bind("change", function() { + start(); + + ok(true); + var view = dataSource.view(); + equal(view[0].age, 1); + equal(view[1].age, 2); + }); + + $.mockjax({ + url: "foo", + responseText: '[{"age": 1}, {"age": 2}]' + }); + + dataSource.query( { sort: { field: "age", dir: "desc" } } ); +}); + +asyncTest("data is not paged if serverPaging = true", 2, function() { + var transport = new RemoteTransport({ + read: "foo" + }); + + var dataSource = new DataSource( { + transport: transport, + serverPaging: true + }).bind("change", function() { + start(); + + var view = dataSource.view(); + equal(view[0].age, 1); + equal(view[1].age, 2); + }); + + $.mockjax({ + url: "foo", + responseText: '[{"age": 1}, {"age": 2}]' + }); + + dataSource.query( { page: 2, pageSize: 1 } ); +}); + +test("group original field name is used if projection with from is set", 2, function() { + var transport = new RemoteTransport({ + read: "foo", + parameterMap: function(options) { + equal(options.group[0].field, "foo"); + equal(options.group[1].field, "baz"); + + return options; + } + }); + + var dataSource = new DataSource( { + transport: transport, + schema: { + model: { + fields: { + bar: { from: "foo" }, + boo: { from: "baz" } + } + } + }, + serverGrouping: true, + }); + + $.mockjax({ + url: "foo", + }); + + dataSource.group([{ field: "bar" }, { field: "boo" }]); +}); + +test("group original field name is used if projection is set", 2, function() { + var transport = new RemoteTransport({ + read: "foo", + parameterMap: function(options) { + equal(options.group[0].field, "foo"); + equal(options.group[1].field, "baz"); + + return options; + } + }); + + var dataSource = new DataSource( { + transport: transport, + schema: { + model: { + fields: { + bar: "foo", + boo: "baz" + } + } + }, + serverGrouping: true, + }); + + $.mockjax({ + url: "foo" + }); + + dataSource.group([{ field: "bar" }, { field: "boo" }]); +}); + +test("group with aggregates original field name is used if projection is set", 2, function() { + var transport = new RemoteTransport({ + read: "foo", + parameterMap: function(options) { + equal(options.group[0].aggregates[0].field, "foo"); + equal(options.group[0].aggregates[1].field, "baz"); + + return options; + } + }); + + var dataSource = new DataSource( { + transport: transport, + schema: { + model: { + fields: { + bar: "foo", + boo: "baz" + } + } + }, + serverGrouping: true, + }); + + $.mockjax({ + url: "foo" + }); + + dataSource.group({ + field: "bar", + aggregates: [{ + field: "bar", + aggregate: "count" + },{ + field: "boo", + aggregate: "count" + }] + }); + +}); + +test("aggregates original field name is used if projection is set", 2, function() { + var transport = new RemoteTransport({ + read: "foo", + parameterMap: function(options) { + equal(options.aggregate[0].field, "foo"); + equal(options.aggregate[1].field, "baz"); + + return options; + } + }); + + var dataSource = new DataSource( { + transport: transport, + schema: { + model: { + fields: { + bar: "foo", + boo: "baz" + } + } + }, + serverAggregates: true, + }); + + $.mockjax({ + url: "foo" + }); + + dataSource.aggregate( + [{ + field: "bar", + aggregate: "count" + },{ + field: "boo", + aggregate: "count" + }]); +}); + +test("filter without model definition and serverFiltering", function() { + var transport = new RemoteTransport({ + read: "foo", + parameterMap: function(options) { + equal(options.filter.filters[0].field, "foo"); + + return options; + } + }); + + var dataSource = new kendo.data.DataSource({ + transport: transport, + serverFiltering: true, + schema: { + model: { + fields: { } + } + } + }); + + $.mockjax({ + url: "foo", + }); + + dataSource.filter({ field: "foo", operator: "eq", value: "bar" }); +}); + +test("filter original field name is used if projection is set", 2, function() { + var transport = new RemoteTransport({ + read: "foo", + parameterMap: function(options) { + equal(options.filter.filters[0].field, "foo"); + equal(options.filter.filters[1].field, "baz"); + + return options; + } + }); + + var dataSource = new DataSource( { + transport: transport, + schema: { + model: { + fields: { + bar: "foo", + boo: "baz" + } + } + }, + serverFiltering: true + }); + + $.mockjax({ + url: "foo", + }); + + + dataSource.filter({ + logic: "and", + filters: [ + { field: "bar", operator: "eq", value: 1 }, + { field: "boo", operator: "eq", value: 1 }, + ] + }); +}); + +test("filter with no descriptors persist filters property", 1, function() { + var transport = new RemoteTransport({ + read: "foo", + parameterMap: function(options) { + ok(options.filter.filters); + + return options; + } + }); + + var dataSource = new kendo.data.DataSource({ + transport: transport, + serverFiltering: true, + schema: { + model: { + fields: { } + } + } + }); + + $.mockjax({ + url: "foo", + }); + + dataSource.filter({ logic: "and", filters: [] }); +}); + +test("sort datasource state is not modified after original field is restored", 1, function() { + var transport = new RemoteTransport({ + read: "foo" + }); + + var dataSource = new DataSource( { + transport: transport, + schema: { + model: { + fields: { + bar: "foo" + } + } + }, + serverSorting: true, + }); + + $.mockjax({ + url: "foo", + }); + + dataSource.sort({ field: "bar", dir: "asc" }); + equal(dataSource.sort()[0].field, "bar"); +}); + +test("filter datasource state is not modified after original field is restored", 1, function() { + var transport = new RemoteTransport({ + read: "foo" + }); + + var dataSource = new DataSource( { + transport: transport, + schema: { + model: { + fields: { + bar: "foo" + } + } + }, + serverFiltering: true, + }); + + $.mockjax({ + url: "foo", + }); + + dataSource.filter({ field: "bar", operator: "eq", value: "42" }); + equal(dataSource.filter().filters[0].field, "bar"); +}); + +test("sort original field name is used if projection is set", 1, function() { + var transport = new RemoteTransport({ + read: "foo", + parameterMap: function(options) { + equal(options.sort[0].field, "foo"); + return options; + } + }); + + var dataSource = new DataSource( { + transport: transport, + schema: { + model: { + fields: { + bar: "foo" + } + } + }, + serverSorting: true, + }); + + $.mockjax({ + url: "foo", + }); + + dataSource.sort({ field: "bar", dir: "asc" }); +}); + +test("sort original field name is used if projection is set if xml is used", 1, function() { + var transport = new RemoteTransport({ + read: "foo", + parameterMap: function(options) { + equal(options.sort[0].field, "bar"); + return options; + } + }); + + var dataSource = new DataSource( { + transport: transport, + schema: { + type: "xml", + model: { + fields: { + bar: "bar/text()" + } + } + }, + serverSorting: true, + }); + + $.mockjax({ + url: "foo", + }); + + dataSource.sort({ field: "bar", dir: "asc" }); +}); + +test("sort original field name is used if projection is set via field definition", 1, function() { + var transport = new RemoteTransport({ + read: "foo", + parameterMap: function(options) { + equal(options.sort[0].field, "foo"); + return options; + } + }); + + var dataSource = new DataSource( { + transport: transport, + schema: { + model: { + fields: { + bar: { field: "foo" } + } + } + }, + serverSorting: true, + }); + + $.mockjax({ + url: "foo", + }); + + dataSource.sort({ field: "bar", dir: "asc" }); +}); + +test("sort original field name is used if projection is set field definiton without a field options", 1, function() { + var transport = new RemoteTransport({ + read: "foo", + parameterMap: function(options) { + equal(options.sort[0].field, "bar"); + return options; + } + }); + + var dataSource = new DataSource( { + transport: transport, + schema: { + model: { + fields: { + bar: { type: "number" } + } + } + }, + serverSorting: true, + }); + + $.mockjax({ + url: "foo", + }); + + dataSource.sort({ field: "bar", dir: "asc" }); +}); + +test("sort original field name is used if complex field", 1, function() { + var transport = new RemoteTransport({ + read: "foo", + parameterMap: function(options) { + equal(options.sort[0].field, "foo.bar"); + return options; + } + }); + + var dataSource = new DataSource( { + transport: transport, + schema: { + model: { + fields: { + foo: { type: "object" } + } + } + }, + serverSorting: true, + }); + + $.mockjax({ + url: "foo", + }); + + dataSource.sort({ field: "foo.bar", dir: "asc" }); +}); + +test("next method gets the subsequent page", function() { + var dataSource = new DataSource({ + data: [1,2,3], + pageSize: 1 + }); + + dataSource.read(); + dataSource.next(); + + var view = dataSource.view(); + + equal(view.length, 1); + equal(view[0], 2); + equal(dataSource.page(), 2); +}); + +test("next method does nothing if no subsequent page", function() { + var dataSource = new DataSource({ + data: [1,2,3], + pageSize: 1 + }); + + dataSource.read(); + dataSource.page(3); + + dataSource.next(); + + var view = dataSource.view(); + + equal(view.length, 1); + equal(view[0], 3); + equal(dataSource.page(), 3); +}); + +test("next method gets the subsequent page from server", 1, function() { + var transport = new RemoteTransport({ + read: "foo", + parameterMap: function(options) { + equal(options.page, 2); + + return options; + } + }); + + var dataSource = new DataSource( { + transport: transport, + serverPaging: true, + pageSize: 1 + }); + + $.mockjax({ + url: "foo", + }); + + dataSource.next(); +}); + +test("next method does nothing if pageSize is not defined (remote transport)", 0, function() { + var transport = new RemoteTransport({ + read: "foo", + parameterMap: function(options) { + ok(false) + return options; + } + }); + + var dataSource = new DataSource( { + transport: transport, + serverPaging: true + }); + + $.mockjax({ + url: "foo", + }); + + dataSource.next(); +}); + +test("next method does nothing (local transport)", 1, function() { + var dataSource = new DataSource( { + data: [1, 2, 3] + }); + + dataSource.next(); + + equal(dataSource.view().length, 0); +}); + +test("next method honors total size", 2, function() { + var dataSource = new DataSource( { + data: [1, 2, 3], + pageSize: 3 + }); + + dataSource.read(); + var page = dataSource.next(); + + equal(dataSource.total(), 3); + equal(page, undefined); +}); + +test("next method accepts parameters", 1, function() { + var dataSource = new DataSource( { + data: [1, 2, 3], + pageSize: 1 + }); + + dataSource.read(); + + stub(dataSource, { + query: dataSource.query + }); + + dataSource.next({ + custom: "custom" + }); + + equal(dataSource.args("query", 0)[0].custom, "custom"); +}); + +test("next page overrides page property of the passed parameters", 1, function() { + var dataSource = new DataSource( { + data: [1, 2, 3], + pageSize: 1 + }); + + dataSource.read(); + + stub(dataSource, { + query: dataSource.query + }); + + dataSource.next({ + page: 3 + }); + + equal(dataSource.args("query", 0)[0].page, 2); +}); + +test("prev method gets the previous page", function() { + var dataSource = new DataSource({ + data: [1,2,3], + pageSize: 1 + }); + + dataSource.read(); + dataSource.page(3); + var page = dataSource.prev(); + + var view = dataSource.view(); + + equal(view.length, 1); + equal(view[0], 2); + equal(dataSource.page(), 2); + equal(page, 2); +}); + +test("prev method does nothing if no previous page", function() { + var dataSource = new DataSource({ + data: [1,2,3], + pageSize: 1 + }); + + dataSource.read(); + dataSource.prev(); + + var view = dataSource.view(); + + equal(view.length, 1); + equal(view[0], 1); + equal(dataSource.page(), 1); +}); + +test("prev method gets the previous page from server", 1, function() { + var transport = new RemoteTransport({ + read: "foo", + parameterMap: function(options) { + equal(options.page, 1); + } + }); + + var dataSource = new DataSource( { + transport: transport, + serverPaging: true, + pageSize: 1 + }); + dataSource._skip = 1; //fake current page (zero based) + + $.mockjax({ + url: "foo", + }); + + dataSource.prev(); +}); + +test("prev method does nothing if pageSize is not defined (remote transport)", 0, function() { + var transport = new RemoteTransport({ + read: "foo", + parameterMap: function(options) { + ok(false) + return options; + } + }); + + var dataSource = new DataSource( { + transport: transport, + serverPaging: true + }); + + $.mockjax({ + url: "foo", + }); + + dataSource.prev(); +}); + +test("prev method does nothing (local transport)", 1, function() { + var dataSource = new DataSource( { + data: [1, 2, 3] + }); + + dataSource.prev(); + + equal(dataSource.view().length, 0); +}); + +test("prev does not page if no previous page (remote transport)", 0, function() { + var transport = new RemoteTransport({ + read: "foo", + parameterMap: function(options) { + ok(false) + return options; + } + }); + + var dataSource = new DataSource( { + transport: transport, + serverPaging: true, + pageSize: 1 + }); + + $.mockjax({ + url: "foo", + }); + + dataSource.prev(); +}); + +test("prev method accepts parameters", 1, function() { + var dataSource = new DataSource( { + data: [1, 2, 3], + pageSize: 1 + }); + + dataSource.read(); + dataSource.page(3); + + stub(dataSource, { + query: dataSource.query + }); + + dataSource.prev({ + custom: "custom" + }); + + equal(dataSource.args("query", 0)[0].custom, "custom"); +}); + +test("prev method overrides passed page parameter", 1, function() { + var dataSource = new DataSource( { + data: [1, 2, 3], + pageSize: 1 + }); + + dataSource.read(); + dataSource.page(3); + + stub(dataSource, { + query: dataSource.query + }); + + dataSource.prev({ + page: 1 + }); + + equal(dataSource.args("query", 0)[0].page, 2); +}); + +test("page should page and persist settings applied through the constructor", function(){ + var dataSource = new DataSource({ + data: [{ age: 1 }, { age: 2 }, { age: 3}], + pageSize: 2, + sort: { + field: "age", + dir: "desc" + } + }); + + dataSource.read(); + dataSource.page(2); + + var view = dataSource.view(); + equal(view.length, 1); + equal(view[0].age, 1); + equal(dataSource.page(), 2); +}); + +test("page with no pageSize set should return all data", function(){ + var dataSource = new DataSource({ + data: [{ age: 1 }, { age: 2 }, { age: 3}] + }); + + dataSource.read(); + dataSource.page(2); + + var view = dataSource.view(); + equal(view.length, 3); + equal(view[0].age, 1); + equal(dataSource.page(), 1); +}); + +test("page cannot be set to value greater than the totalPages", function() { + var dataSource = new DataSource({ + pageSize: 1, + data: [{ age: 1 }, { age: 2 }, { age: 3}] + }); + + dataSource.read(); + dataSource.page(42); + equal(dataSource.page(), 3); +}); + +test("page cannot be set to value lower than the first page", function() { + var dataSource = new DataSource({ + pageSize: 1, + data: [{ age: 1 }, { age: 2 }, { age: 3}] + }); + + dataSource.read(); + dataSource.page(0); + equal(dataSource.page(), 1); +}); + +test("pageSize should take given number of items", function(){ + var dataSource = new DataSource({ + data: [{ age: 1 }, { age: 2 }, { age: 3}], + page: 1 + }); + + dataSource.read(); + dataSource.pageSize(2); + + var view = dataSource.view(); + equal(view.length, 2); + equal(view[0].age, 1); + equal(dataSource.pageSize(), 2); +}); + +test("data is populated if query is called without call to read", function() { + var dataSource = new DataSource({ + data: [{ age: 1 }, { age: 2 }, { age: 3}] + }); + + dataSource.query({ page: 1, pageSize: 2}); + equal(dataSource.view().length, 2); +}); + +test("query triggers change event when called without read", function() { + var dataSource = new DataSource({ + data: [{ age: 1 }, { age: 2 }, { age: 3}] + }); + + var changeWasCalled = false; + dataSource.bind("change", function() { + changeWasCalled = true; + }); + + dataSource.query({ page: 1, pageSize: 2}); + ok(changeWasCalled); +}); + +test("total is populated if query is called without call to read", function() { + var dataSource = new DataSource({ + data: [{ age: 1 }, { age: 2 }, { age: 3}] + }); + + dataSource.query({ page: 1, pageSize: 2}); + equal(dataSource.total(), 3); +}); + +test("query should filter if filter is set", function() { + var dataSource = new DataSource({ + data: [{ id:1, bar: "foo" },{ id: 2, bar: "baz" }] + }); + + dataSource.query( { filter: { field: "bar", operator: "==", value: "baz" } } ); + var view = dataSource.view(); + equal(view.length, 1); + equal(view[0].bar, "baz"); +}); + +test("filter first page is shown", function() { + var dataSource = new DataSource({ + data: [{ id:1 }, { id: 2 }], + pageSize: 1, + page: 2 + }); + + dataSource.filter( { field: "id", operator: "==", value: 2 }); + equal(dataSource.page(), 1); + equal(dataSource.view()[0].id, 2); +}); + +test("filter operators are normalized", function() { + var dataSource = new DataSource({ + data: [{ id:1 }, { id: 2 }] + }); + + dataSource.filter( { field: "id", operator: "==", value: 1 }); + equal(dataSource.filter().filters[0].operator, "eq"); +}); + +test("query should update the total if filtering is enabled", function() { + var dataSource = new DataSource({ + data: [{ id:1, bar: "foo" },{ id: 2, bar: "baz" }] + }); + + dataSource.query( { filter: { field: "bar", operator: "==", value: "baz" } } ); + equal(dataSource.total(), 1); +}); + +asyncTest("query does not filter data if serverFiltering = true", 3, function() { + var transport = new RemoteTransport({ + read: "foo" + }); + + var dataSource = new DataSource( { + transport: transport, + serverFiltering: true + }).bind("change", function() { + start(); + + var view = dataSource.view(); + equal(view.length, 2); + equal(view[0].age, 1); + equal(view[1].age, 2); + }); + + $.mockjax({ + url: "foo", + responseText: '[{"age": 1}, {"age": 2}]' + }); + + dataSource.query( { filter: { field: "age", operator: "==", value: 2 } } ); +}); + +test("cancelChanges refresh the total if serverpaging is enabled", function() { + var dataSource = new DataSource({ + transport: { + read: function(options) { + options.success( { data: [{ id:1, bar: "foo" },{ id: 2, bar: "baz" }], total: 2 }); + } + }, + schema: { + data: "data", + total: "total" + }, + serverPaging: true + }); + + dataSource.read(); + + dataSource.add({}); + dataSource.cancelChanges(); + equal(dataSource.total(), 2); +}); + +test("cancelChanges refresh the total if bound to an observablearray", function() { + var data = new kendo.data.ObservableArray([{ id:1, bar: "foo" },{ id: 2, bar: "baz" }]), + dataSource = new DataSource({ + data: data + }); + + dataSource.read(); + + dataSource.add({}); + dataSource.cancelChanges(); + equal(dataSource.total(), 2); +}); + + +test("cancelChanges refresh the total if serverpaging is enabled and grouping is applied", function() { + var dataSource = new DataSource({ + transport: { + read: function(options) { + options.success( { group: [{ items: [{ id:1, bar: "foo" },{ id: 2, bar: "baz" }] }, { items: [{ id:1, bar: "foo" }] }], total: 10 }); + } + }, + schema: { + groups: "group", + total: "total" + }, + group: { field: "id" }, + serverPaging: true, + serverGrouping: true + }); + + dataSource.read(); + + dataSource.add({}); + dataSource.cancelChanges(); + equal(dataSource.total(), 10); +}); + +test("paging is after filtering", function() { + var dataSource = new DataSource({ + data: [{age: 1}, {age: 2}, {age: 3}] + }); + + dataSource.read(); + dataSource.query( { page: 2, pageSize: 1, filter: { field: "age", operator: "!=", value: 2 } } ); + var view = dataSource.view(); + + equal(view[0].age, 3); +}); + +test("query sets filter when array is passed", function() { + var dataSource = new DataSource({ + data: [{age: 1}, {age: 2}, {age: 3}] + }); + + dataSource.query( { filter: [{ field: "age", operator: ">=", value: 1 },{ field: "age", operator: "<", value: 3 }] }); + equal(dataSource.filter().filters.length, 2); + equal(dataSource.filter().filters[1].field, "age"); + equal(dataSource.filter().filters[1].operator, "lt"); + equal(dataSource.filter().filters[1].value, 3); +}); + +test("query sets filter", function() { + var dataSource = new DataSource({ + data: [{age: 1}, {age: 2}, {age: 3}] + }); + + dataSource.query({ filter: { field: "age", operator: "==", value: 2 } }); + ok($.isArray(dataSource.filter().filters)); + equal(dataSource.filter().filters[0].field, "age"); + equal(dataSource.filter().filters[0].operator, "eq"); + equal(dataSource.filter().filters[0].value, 2); +}); + +test("query removes filter expression from the state if not passed", function() { + var dataSource = new DataSource({ + data: [{age: 1}, {age: 2}] + }); + dataSource.read(); + dataSource.query( { filter: { field: "age", operator: "==", value: 2 } } ); + dataSource.query({}); + var view = dataSource.view(); + + equal(view.length, 2); + equal(view[0].age, 1); + equal(view[1].age, 2); + equal(dataSource.filter(), undefined); +}); + +test("filtering though filter method", function() { + var dataSource = new DataSource({ + data: [{age: 1}, {age: 2}, {age: 3}] + }); + dataSource.read(); + dataSource.filter( { field: "age", operator: "!=", value: 2 } ); + var view = dataSource.view(); + + equal(view.length, 2); + equal(view[0].age, 1); + equal(view[1].age, 3); +}); + +test("query grouping should group data if set", function() { + var dataSource = new DataSource({ + data: [{age: 1}, {age: 1}, {age: 3}] + }); + dataSource.read(); + dataSource.query( { group: [{ field: "age" }] }); + var view = dataSource.view(); + equal(view.length, 2); + equal(view[0].items.length, 2); + equal(view[1].items.length, 1); +}); + +asyncTest("query does not group data if serverGrouping is true", 3, function() { + var transport = new RemoteTransport({ + read: "foo" + }); + + var dataSource = new DataSource( { + transport: transport, + serverGrouping: true + }).bind("change", function() { + start(); + + var view = dataSource.view()[0].items; + equal(view.length, 2); + equal(view[0].age, 1); + equal(view[1].age, 2); + }); + + $.mockjax({ + url: "foo", + responseText: '[{ "items": [{"age": 1}, {"age": 2}] }]' + }); + + dataSource.query( { group: [{ field: "age" }] }); +}); + +test("group with paging", function() { + var data = [{age: 1}, {age: 3}, {age: 1}]; + + var dataSource = new DataSource({ + data: data, + page: 1, + pageSize: 2 + }); + dataSource.read(); + dataSource.group({ field: "age" }); + var view = dataSource.view(); + equal(view.length, 1); + equal(view[0].items.length, 2); +}); + +test("query sets group when single group is passed", function() { + var dataSource = new DataSource({ + data: [{age: 1}, {age: 2}, {age: 3}] + }); + + dataSource.query( { group: { field: "age" } }); + equal(dataSource.group().length, 1); + equal(dataSource.group()[0].field, "age"); +}); + +test("query removes group expression from the state if not passed", function() { + var dataSource = new DataSource({ + data: [{age: 1}, {age: 2}] + }); + dataSource.read(); + dataSource.query( { group: { field: "age" } }); + dataSource.query({}); + var view = dataSource.view(); + + equal(view.length, 2); + equal(view[0].age, 1); + equal(view[1].age, 2); + equal(dataSource.group(), undefined); +}); + +test("group should group data if set", function() { + var dataSource = new DataSource({ + data: [{age: 1}, {age: 1}, {age: 3}] + }); + dataSource.read(); + dataSource.group("age"); + var view = dataSource.view(); + equal(view.length, 2); + equal(view[0].items.length, 2); + equal(view[1].items.length, 1); +}); + +test("group aggregates should be calcualted if paging is enabled", function() { + var dataSource = new DataSource({ + data: [{age: 1}, {age: 1}, {age: 3}], + page: 2, + pageSize: 1 + }); + dataSource.read(); + dataSource.group({field: "age", aggregates: [ {field: "age", aggregate: "count"}] }); + var view = dataSource.view(); + equal(view.length, 1); + equal(view[0].aggregates.age.count, 2); +}); +test("group with sorting order is applied", function() { + var dataSource = new DataSource({ + data: [{age: 1, name: "John" }, {age: 1, name: "Tom" }, {age: 1, name: "Jerry" }] + }); + + dataSource.query( { group: { field: "age" }, sort: { field: "name", dir: "asc" } }); + var group = dataSource.view()[0].items; + equal(group[0].name, "Jerry"); + equal(group[1].name, "John"); + equal(group[2].name, "Tom"); +}); +test("aggregate should be calculated if defined", function() { + var dataSource = new DataSource({ + data: [ {foo: 100, bar: "baz"} , {foo: 100, bar: "bar"} , {foo: 1, bar: "baz"} ] + }); + dataSource.read(); + + dataSource.aggregate( [{ field: "foo", aggregate: "sum" }, { field: "bar", aggregate: "count" }] ); + var result = dataSource.aggregates(); + equal(result.foo.sum, 201); + equal(result.bar.count, 3); +}); + +test("query aggregate should be calculated if defined", function() { + var dataSource = new DataSource({ + data: [ {foo: 100, bar: "baz"} , {foo: 100, bar: "bar"} , {foo: 1, bar: "baz"} ] + }); + + dataSource.query( {aggregate:[{ field: "foo", aggregate: "sum" }, { field: "bar", aggregate: "count" }]} ); + var result = dataSource.aggregates(); + equal(result.foo.sum, 201); + equal(result.bar.count, 3); +}); + +test("query removes aggregates from the state if not passed", function() { + var dataSource = new DataSource({ + data: [{age: 1}, {age: 2}] + }); + dataSource.read(); + dataSource.query( {aggregate:[{ field: "foo", aggregate: "sum" }]} ); + dataSource.query({}); + + equal(dataSource.aggregate(), undefined); + ok($.isEmptyObject(dataSource.aggregates())); +}); + +asyncTest("query does not aggregate data if serverAggregate is true", 1, function() { + var transport = new RemoteTransport({ + read: "foo" + }); + + var dataSource = new DataSource( { + transport: transport, + serverAggregates: true + }).bind("change", function() { + start(); + + ok($.isEmptyObject(dataSource.aggregates())); + }); + + $.mockjax({ + url: "foo", + responseText: '[{"age": 1}, {"age": 2}]' + }); + + dataSource.query( {aggregate:[{ field: "foo", aggregate: "sum" }]} ); +}); + +test("query does pass additional options to the transport", function() { + var options, dataSource = new DataSource( { + transport: { + read: function() { + options = arguments[0].data; + } + } + }); + + dataSource.query({foo: "bar"}); + equal(options.foo, "bar"); +}); +test("query uses skip and take", function() { + var dataSource = new DataSource({ + data: [{age: 1}, {age: 2},{age: 3}, {age: 4},{age: 5}, {age: 6},{age: 7}, {age: 8}] + }); + dataSource.query( { skip: 2, take: 3 }); + var result = dataSource.view(); + + equal(result.length, 3); + equal(result[0].age, 3); + equal(result[1].age, 4); + equal(result[2].age, 5); +}); + +test("skip return skipped items for given page and pageSize", function() { + var dataSource = new DataSource({ + data: [{age: 1}, {age: 2},{age: 3}, {age: 4},{age: 5}, {age: 6},{age: 7}, {age: 8}], + page: 2, + pageSize: 3 + }); + equal(dataSource.skip(), 3); +}); + +test("skip return value set through query", function() { + var dataSource = new DataSource({ + data: [{age: 1}, {age: 2},{age: 3}, {age: 4},{age: 5}, {age: 6},{age: 7}, {age: 8}] + }); + dataSource.query({ skip: 3 }); + equal(dataSource.skip(), 3); +}); + +test("take return pageSize is not set", function() { + var dataSource = new DataSource({ + data: [{age: 1}, {age: 2},{age: 3}, {age: 4},{age: 5}, {age: 6},{age: 7}, {age: 8}], + pageSize: 4 + }); + equal(dataSource.take(), 4); +}); + +test("take return take set through query", function() { + var dataSource = new DataSource({ + data: [{age: 1}, {age: 2},{age: 3}, {age: 4},{age: 5}, {age: 6},{age: 7}, {age: 8}], + pageSize: 4 + }); + dataSource.query({ take: 3 }); + equal(dataSource.take(), 3); +}); + +test("query raised requestStart", function() { + var called = false, + dataSource = new DataSource({ + data: [{age: 1}, {age: 2},{age: 3}, {age: 4},{age: 5}, {age: 6},{age: 7}, {age: 8}], + pageSize: 4, + requestStart: function() { + called = true; + } + }); + dataSource.read(); + dataSource.query({ take: 3 }); + ok(called); +}); + +test("query raised progress event", 1, function() { + var dataSource = new DataSource({ + data: [{age: 1}, {age: 2},{age: 3}, {age: 4},{age: 5}, {age: 6},{age: 7}, {age: 8}], + pageSize: 4 + }); + dataSource.read(); + dataSource.bind("progress", function() { ok(true); }); + + dataSource.query({ take: 3 }); +}); + +test("read raised requestStart", function() { + var called = false, + dataSource = new DataSource({ + data: [{age: 1}, {age: 2},{age: 3}, {age: 4},{age: 5}, {age: 6},{age: 7}, {age: 8}], + pageSize: 4, + requestStart: function() { + called = true; + } + }); + dataSource.read(); + ok(called); +}); + +test("read raised progress", 1, function() { + var dataSource = new DataSource({ + data: [{age: 1}, {age: 2},{age: 3}, {age: 4},{age: 5}, {age: 6},{age: 7}, {age: 8}], + pageSize: 4, + progress: function() { + ok(true); + } + }); + dataSource.read(); +}); + +test("canceling requestStart prevents read", function() { + var dataSource = new DataSource({ + data: [{age: 1}, {age: 2},{age: 3}, {age: 4},{age: 5}, {age: 6},{age: 7}, {age: 8}], + pageSize: 4, + requestStart: function(e) { + e.preventDefault(); + } + }); + + dataSource.read(); + + ok(!dataSource.data().length); +}); + +test("canceling requestStart does not block subsequent reads", function() { + var count = 1, + dataSource = new DataSource({ + data: [{age: 1}, {age: 2},{age: 3}, {age: 4},{age: 5}, {age: 6},{age: 7}, {age: 8}], + pageSize: 4, + requestStart: function(e) { + if (count) { + e.preventDefault(); + count--; + } + } + }); + + dataSource.read(); + + dataSource.read(); + + ok(dataSource.data().length); +}); + +test("canceling requestStart from read does not modify datasource state", function() { + var dataSource = new DataSource({ + data: [{age: 1}, {age: 2},{age: 3}, {age: 4},{age: 5}, {age: 6},{age: 7}, {age: 8}], + pageSize: 4, + requestStart: function(e) { + e.preventDefault(); + } + }); + + dataSource.read({page: 2 }); + + equal(dataSource.page(), 1); +}); + +test("canceling requestStart prevents query", function() { + var count = 0, + dataSource = new DataSource({ + data: [{age: 1}, {age: 2},{age: 3}, {age: 4},{age: 5}, {age: 6},{age: 7}, {age: 8}], + pageSize: 4, + requestStart: function(e) { + if (count) { + e.preventDefault(); + } + count++; + } + }); + + dataSource.read(); + dataSource.page(2); + + equal(dataSource.view()[0].age, 1); +}); + +test("canceling requestStart on query does not modify the datasource state", function() { + var count = 0, + dataSource = new DataSource({ + data: [{age: 1}, {age: 2},{age: 3}, {age: 4},{age: 5}, {age: 6},{age: 7}, {age: 8}], + pageSize: 4, + requestStart: function(e) { + if (count) { + e.preventDefault(); + } + count++; + } + }); + + dataSource.read(); + dataSource.page(2); + + equal(dataSource.page(), 1); +}); + + +test("query raised requestEnd", 1, function() { + var called = false, + dataSource = new DataSource({ + data: [{age: 1}, {age: 2},{age: 3}, {age: 4},{age: 5}, {age: 6},{age: 7}, {age: 8}] + }); + + dataSource.read(); + + dataSource.bind("requestEnd", function() { + ok(true); + }); + + dataSource.query(); +}); + +test("fetch persists dataSource options", function() { + var dataSource = new DataSource({ + serverPaging: true, + serverSorting: true, + serverGrouping: true, + serverFiltering: true, + serverAggregates: true, + data: [ { items: [{foo: 1, bar: "1"}] } ], + page: 10, + pageSize: 5, + sort: { field: "foo", dir: "asc" }, + filter: { field: "bar", operator: "eq", value: "1" }, + group: { field: "foo" }, + aggregate: { field: "bar", aggregate: "count" } + }); + + dataSource.fetch(); + equal(dataSource.page(), 10); + equal(dataSource.pageSize(), 5); + equal(dataSource.sort()[0].field, "foo"); + equal(dataSource.sort()[0].dir, "asc"); + equal(dataSource.filter().filters[0].field, "bar"); + equal(dataSource.filter().filters[0].operator, "eq"); + equal(dataSource.filter().filters[0].value, "1"); + equal(dataSource.group()[0].field, "foo"); + equal(dataSource.aggregate()[0].field, "bar"); +}); + +test("fetch triggers change event", function() { + var view, + dataSource = new DataSource({ + data: [{foo: 1, bar: "1"}], + change: function() { + view = dataSource.view(); + } + }); + + dataSource.fetch(); + equal(view.length, 1); + equal(view[0].foo, "1"); +}); + +test("fetch calls supplied callback only once on multiple fetches", function() { + var view, + called = 0, + dataSource = new DataSource({ + data: [{foo: 1, bar: "1"}] + }); + + dataSource.fetch(function() { + called++; + view = dataSource.view(); + }); + + dataSource.fetch(); + + ok(view); + equal(called, 1); +}); + +test("paging with custom schema", function() { + var dataSource = new DataSource({ + transport: { + read: function(options) { + return options.success({ d: [ { foo: 1 }, { bar: 2 }] }); + } + }, + schema: { + data: function(result) { + return result.d; + }, + total: function(data) { + return data.d.length; + } + }, + pageSize: 1 + }); + + dataSource.read(); + dataSource.page(1); + + equal(dataSource.view().length, 1); + equal(dataSource.view()[0].foo, 1); +}); + +test("removing model re-calculate the total", function() { + var dataSource = new DataSource({ + data: [{ foo: 1, bar: "bar 1" }, { foo: 2, bar: "bar 2" }], + schema: { + model: { + id: "foo", + fields: { + foo: { type: "number" }, + bar: "bar" + } + } + } + }); + + dataSource.read(); + dataSource.remove(dataSource.get(1)); + + equal(dataSource.view().length, 1); + equal(dataSource.total(), 1); +}); + +test("adding model re-calculate the total", function() { + var dataSource = new DataSource({ + data: [{ foo: 1, bar: "bar 1" }, { foo: 2, bar: "bar 2" }], + schema: { + model: { + id: "foo", + fields: { + foo: { type: "number" }, + bar: "bar" + } + } + } + }); + + dataSource.read(); + dataSource.add(new kendo.data.Model()); + + equal(dataSource.view().length, 3); + equal(dataSource.total(), 3); +}); + +test("pushing multiple records to the observable array updates the total", function() { + var dataSource = new DataSource({ + data: [{ foo: 1, bar: "bar 1" }, { foo: 2, bar: "bar 2" }] + }); + + dataSource.read(); + + dataSource.data().push({ foo: 1, bar: "bar 1" }, { foo: 2, bar: "bar 2" }); + + equal(dataSource.view().length, 4); + equal(dataSource.total(), 4); +}); + +test("pushing multiple records to the observable array updates the total - total is string", function() { + var dataSource = new DataSource({ + serverPaging: true, + schema: { + total: function() { + return "2" + } + } + }); + + dataSource.read(); + + dataSource.data().push({ foo: 1, bar: "bar 1" }, { foo: 2, bar: "bar 2" }); + + equal(dataSource.view().length, 2); + equal(dataSource.total(), 4); +}); + +test("adding multiple records to the observable array updates the total", function() { + var dataSource = new DataSource({ + data: [{ foo: 1, bar: "bar 1" }, { foo: 2, bar: "bar 2" }] + }); + + dataSource.read(); + + dataSource.data().splice(0, 0, { foo: 1, bar: "bar 1" }, { foo: 2, bar: "bar 2" }); + + equal(dataSource.view().length, 4); + equal(dataSource.total(), 4); +}); + +test("removing multiple records from the observable array updates the total", function() { + var dataSource = new DataSource({ + data: [{ foo: 1, bar: "bar 1" }, { foo: 2, bar: "bar 2" }] + }); + + dataSource.read(); + + dataSource.data().splice(0, 2); + + equal(dataSource.view().length, 0); + equal(dataSource.total(), 0); +}); + +test("total is calculated on initially empty DataSource", function() { + var dataSource = new DataSource({ + schema: { + model: { + id: "foo", + fields: { + foo: { type: "number" }, + bar: "bar" + } + } + } + }); + + dataSource.add(new kendo.data.Model()); + + equal(dataSource.view().length, 1); + equal(dataSource.total(), 1); +}); + +test("modify model re-calculate the total", function() { + var dataSource = new DataSource({ + data: [{ foo: 1, bar: "bar 1" }, { foo: 2, bar: "bar 2" }], + schema: { + model: { + id: "foo", + fields: { + foo: { type: "number" }, + bar: "bar" + } + } + } + }); + + dataSource.read(); + dataSource.add(new kendo.data.Model()); + dataSource.get(1).set("bar", "foo"); + + equal(dataSource.view().length, 3); + equal(dataSource.total(), 3); +}); + +test("cancelChanges re-calculates the total", function() { + var dataSource = new DataSource({ + data: [{ foo: 1, bar: "bar 1" }, { foo: 2, bar: "bar 2" }], + schema: { + model: { + id: "foo", + fields: { + foo: { type: "number" }, + bar: "bar" + } + } + } + }), + model = new kendo.data.Model(); + + dataSource.read(); + dataSource.add(model); + dataSource.cancelChanges(model); + + equal(dataSource.view().length, 2); + equal(dataSource.total(), 2); +}); + +test("cancelChanges without arguments re-calculates the total", function() { + var dataSource = new DataSource({ + data: [{ foo: 1, bar: "bar 1" }, { foo: 2, bar: "bar 2" }], + schema: { + model: { + id: "foo", + fields: { + foo: { type: "number" }, + bar: "bar" + } + } + } + }); + + dataSource.read(); + dataSource.add(new kendo.data.Model()); + dataSource.cancelChanges(); + + equal(dataSource.view().length, 2); + equal(dataSource.total(), 2); +}); + +test("sync with serverPaging re-calculates the total", function() { + var dataSource = new DataSource({ + transport: { + read: function(options) { + options.success({ + data: [{ foo: 1, bar: "bar 1" }], + total: 2 + }); + }, + create: function(options) { + options.success(); + } + }, + pageSize: 1, + serverPaging: true, + schema: { + data: "data", + total: "total", + model: { + id: "foo", + fields: { + foo: { type: "number" }, + bar: "bar" + } + } + } + }); + + dataSource.read(); + dataSource.add({}); + dataSource.sync(); + + equal(dataSource.view().length, 2); + equal(dataSource.total(), 3); +}); + +test("query with local transport calculates total", function() { + var dataSource = new DataSource({ + data: [{ foo: 1, bar: "bar 1" }, { foo: 2, bar: "bar 2" }], + schema: { + model: { + id: "foo", + fields: { + foo: { type: "number" }, + bar: "bar" + } + } + } + }); + + dataSource.read(); + dataSource.remove(dataSource.get(1)); + dataSource.query({ page: 1 }); + + equal(dataSource.view().length, 1); + equal(dataSource.total(), 1); +}); + +test("sync after remove calculates total", function() { + var dataSource = new DataSource({ + //data: [{ foo: 1, bar: "bar 1" }, { foo: 2, bar: "bar 2" }], + transport: { + read: function(options) { + options.success({ + data: [{ foo: 1, bar: "bar 1" }, { foo: 2, bar: "bar 2" }], + total: 2 + }); + }, + destroy: function(options) { + options.success(); + } + }, + schema: { + data: "data", + total: "total", + model: { + id: "foo", + fields: { + foo: { type: "number" }, + bar: "bar" + } + } + } + }); + + dataSource.read(); + dataSource.remove(dataSource.get(1)); + dataSource.sync(); + + equal(dataSource.view().length, 1); + equal(dataSource.total(), 1); +}); + +test("query does not call transport if all items are deleted and server operations are disabled", function() { + var dataSource = new DataSource({ + data: [{ id: 1, foo: "bar" }] + }); + dataSource.read(); + dataSource.remove(dataSource.at(0)); + dataSource.fetch(); + equal(dataSource.view().length, 0); +}); + +test("query calls transport if all items are deleted and server operations are enabled", function() { + var dataSource = new DataSource({ + data: [{ id: 1, foo: "bar" }], + serverPaging: true + }); + dataSource.read(); + dataSource.remove(dataSource.at(0)); + dataSource.fetch(); + equal(dataSource.view().length, 1); +}); + +test("fetch returns a promise", function() { + var dataSource = new DataSource({ + data: [{ id: 1, foo: "bar" }] + }); + + equal(typeof dataSource.fetch().done, "function"); +}); + +test("change event resolves the promise when bound to local array", function() { + var dataSource = new DataSource({ + data: [{ id: 1, foo: "bar" }] + }); + + var promise = dataSource.fetch(); + + equal(promise.state(), "resolved"); +}); + +asyncTest("custom transport resolves the promess when the success method is called", 1, function() { + var dataSource = new DataSource({ + transport: { + read: function(options) { + setTimeout(function() { + options.success([]); + }, 1); + } + } + }); + + var promise = dataSource.fetch(); + promise.done(function() { + start(); + ok(true); + }); +}); + +asyncTest("custom transport fails the promess when the error method is called", 1, function() { + var dataSource = new DataSource({ + transport: { + read: function(options) { + setTimeout(function() { + options.error([]); + }, 1); + } + } + }); + + var promise = dataSource.fetch(); + + promise.fail(function() { + start(); + ok(true); + }); +}); +}()); diff --git a/tests/data/datasource/range.js b/tests/data/datasource/range.js new file mode 100644 index 00000000000..150ac204e71 --- /dev/null +++ b/tests/data/datasource/range.js @@ -0,0 +1,1085 @@ +(function(){ + + +var data = []; +var DataSource = kendo.data.DataSource; +var timeout; + +module("data source ranges", { + setup: function() { + timeout = window.setTimeout; + window.setTimeout = function(callback) { + callback(); + } + }, + teardown: function() { + window.setTimeout = timeout; + } +}); + +function setup(source) { + data = source || [{ id:1, bar: "foo" },{ id: 2, bar: "foo" }]; + + var dataSource = new DataSource( { + data: data + } ); + + dataSource.read(); + + return dataSource; +} + +function remoteDataSource(callback) { + callback = callback || $.noop; + var total = 10000, + dataSource = new kendo.data.DataSource({ + serverPaging: true, + transport: { + read: function(options) { + var take = options.data.take, + skip = options.data.skip; + + var data = []; + + for (var i = skip; i < Math.min(skip + take, total); i++) { + data.push({ OrderID: i, ContactName: "Contact " + i, ShipAddress: "Ship Address " + i }); + } + callback(); + options.success(data); + } + }, + schema: { + total: function () { + return total; + } + }, + pageSize: 16 + }); + + dataSource._total = total; + return dataSource; +} + +test("prefetch projects request parameters", 2, function() { + var data = [{ id: 1, text: "foo" }, { id: 2, text: "bar" }]; + var dataSource = new DataSource({ + schema: { + model: { + fields: { + Text: { from: "text" } + } + } + }, + serverSorting: true, + sort: { + field: "Text", + dir: "asc" + }, + transport: { + read: function(options) { + options.success(data); + + var sort = options.data.sort[0]; + equal(sort.field, "text"); + equal(sort.dir, "asc"); + } + } + }); + + dataSource.prefetch(0, 1); +}); + +test("inrange returns true if available", function() { + var dataSource = setup(); + + ok(dataSource.inRange(0,2)); +}); + +test("prefetch gets data for given range", function() { + var dataSource = remoteDataSource(); + + dataSource.prefetch(0, 1); + + var ranges = dataSource._ranges; + equal(ranges.length, 1); + equal(ranges[0].start, 0); + equal(ranges[0].end, 1); + equal(ranges[0].data.length, 1); + equal(ranges[0].data[0].OrderID, 0); +}); + +test("prefetched data is converted to ObservableArray", function() { + var dataSource = remoteDataSource(); + + dataSource.prefetch(0, 1); + + var ranges = dataSource._ranges; + equal(ranges.length, 1); + ok(ranges[0].data instanceof kendo.data.ObservableArray); +}); + +test("prefetch multiple calls for same range does not retrieve data multiple times", function() { + var called = 0, + dataSource = remoteDataSource(function () { + called++; + }); + + dataSource.prefetch(0, 1); + dataSource.prefetch(0, 1); + equal(dataSource._ranges.length, 1); + equal(called, 1); +}); + +test("prefetch retrieves different ranges", function() { + var dataSource = remoteDataSource(); + + dataSource.prefetch(0, 1); + dataSource.prefetch(1, 1); + + var ranges = dataSource._ranges; + equal(ranges.length, 2); +}); + +test("prefetch raises requestEnd", 2, function() { + var dataSource = remoteDataSource(); + + dataSource.bind("requestEnd", function(e) { + ok(e.response); + equal(e.type, "read"); + }); + + dataSource.prefetch(1, 1); +}); + + +test("prefetch raises requestStart", 1, function() { + var dataSource = remoteDataSource(); + + dataSource.bind("requestStart", function() { + ok(true); + }); + + dataSource.prefetch(1, 1); +}); + +test("prefetch cancelling requestStart does not block subsequent requests", 1, function() { + var dataSource = remoteDataSource(), + counter = 0; + + dataSource.one("requestStart", function(e) { + e.preventDefault(); + }); + + dataSource.prefetch(1, 1); + + dataSource.one("requestStart", function(e) { + ok(true); + }); + + dataSource.prefetch(1, 1); +}); + + +test("inRange returns true if skip is within range", function() { + var dataSource = remoteDataSource(); + + dataSource.prefetch(0, 1); + dataSource.prefetch(1, 1); + ok(dataSource.inRange(0, 2)); +}); + +test("inRange returns true if start is more than one", function() { + var dataSource = remoteDataSource(); + + dataSource.prefetch(1, 1); + ok(dataSource.inRange(1, 1)); +}); + +test("inRange returns false if skip is in range but take is not", function() { + var dataSource = remoteDataSource(); + + dataSource.prefetch(0, 1); + dataSource.prefetch(1, 1); + ok(!dataSource.inRange(0, 3)); +}); + +test("inRange returns false if skip and take are in range but prefetched data is missing", function() { + var dataSource = remoteDataSource(); + + dataSource.prefetch(0, 1); + dataSource.prefetch(2, 1); + ok(!dataSource.inRange(0, 3)); +}); + +test("ranges are sorted by start", function() { + var dataSource = remoteDataSource(); + + dataSource.prefetch(2, 1); + dataSource.prefetch(0, 1); + equal(dataSource._ranges[0].start, 0); + equal(dataSource._ranges[1].start, 2); +}); + +test("prefetch end of range is correctly set when returned data is less than page size", function() { + var dataSource = remoteDataSource(); + + dataSource.prefetch(10000 - 16, 18); + equal(dataSource._ranges[0].start, 10000 - 16); + equal(dataSource._ranges[0].end, 10000); +}); + +test("prefetch does not create new range if existing sub range is requested", function() { + var dataSource = remoteDataSource(); + + dataSource.prefetch(20, 200); + dataSource.prefetch(30, 50); + equal(dataSource._ranges.length, 1); +}); + +test("range if range exists transport is not called", function() { + var called = 0, + dataSource = remoteDataSource(function () { + called++; + }); + + dataSource.prefetch(0, 1); + dataSource.range(0, 1); + equal(called, 1); +}); + +test("range if range does not exist transport is called", function() { + var called = 0, + dataSource = remoteDataSource(function () { + called++; + }); + + dataSource.range(0, 1); + equal(called, 1); +}); + +test("change is raised when range is prefetched", function() { + var data, + dataSource = remoteDataSource(); + + dataSource.bind("change", function() { + data = dataSource.view(); + }); + + dataSource.prefetch(0, 1); + dataSource.range(0, 1); + + equal(data.length, 1); +}); + +test("change is raised when range is not", function() { + var called = false, dataSource = remoteDataSource(); + dataSource.bind("change", function() { + called = true; + }); + + dataSource.prefetch(0, 1); + dataSource.range(0, 1); + ok(called); +}); + +test("inRange return false if skip is below available range", function() { + var dataSource = remoteDataSource(); + + dataSource.prefetch(20, 40); + ok(!dataSource.inRange(0, 40)); +}); + +test("range calls transport if skip is below available range", function() { + var called = 0, + dataSource = remoteDataSource(function () { + called++; + }); + + dataSource.prefetch(20, 40); + dataSource.range(0, 1); + equal(called, 2); +}); + +test("range fetches range accross multiple prefech ranges", function() { + var dataSource = remoteDataSource(); + + dataSource.prefetch(20, 20); + dataSource.prefetch(0, 20); + dataSource.range(9, 20); + + equal(dataSource.view().length, 20); + equal(dataSource.view()[0].OrderID, 9); + equal(dataSource.view()[19].OrderID, 28); +}); + +test("range fetches range accross multiple overlapping prefech ranges", function() { + var dataSource = remoteDataSource(); + + dataSource.prefetch(0, 15); + dataSource.prefetch(10, 20); + dataSource.range(9, 10); + + equal(dataSource.view().length, 10); + equal(dataSource.view()[0].OrderID, 9); + equal(dataSource.view()[9].OrderID, 18); +}); + +test("range fetches range accross multiple overlapping prefech ranges 2", function() { + var dataSource = remoteDataSource(); + + dataSource.prefetch(0, 20); + dataSource.prefetch(20, 20); + dataSource.range(9, 20); + + equal(dataSource.view().length, 20); + equal(dataSource.view()[0].OrderID, 9); + equal(dataSource.view()[19].OrderID, 28); +}); + +test("range fetches range accross multiple overlapping not prefeched ranges transport is called two times", function() { + var called = 0, dataSource = remoteDataSource(function () { called ++;}); + + dataSource.range(9, 20); + + equal(called, 2); + equal(dataSource.view().length, 20); + equal(dataSource.view()[0].OrderID, 9); + equal(dataSource.view()[19].OrderID, 28); +}); + +test("inRange returns false if not the entire range is available", function() { + var called = 0, + dataSource = remoteDataSource(); + + dataSource.prefetch(0, 5); + dataSource.prefetch(10, 5); + ok(!dataSource.inRange(0, 10)); +}); + +test("read adds result as range", function() { + var dataSource = remoteDataSource(); + dataSource.read(); + equal(dataSource._ranges[0].start, 0); + equal(dataSource._ranges[0].end, 16); +}); + +test("data adds result as range", function() { + var dataSource = remoteDataSource(); + dataSource.data([{ id:1, bar: "foo" },{ id: 2, bar: "foo" }, { id: 3, bar: "foo" }]); + equal(dataSource._ranges.length, 1); + equal(dataSource._ranges[0].start, 0); + equal(dataSource._ranges[0].end, 3); +}); + +test("read clear previous ranges", function() { + var dataSource = remoteDataSource(); + dataSource.prefetch(20, 20); + dataSource.read(); + equal(dataSource._ranges.length, 1); + equal(dataSource._ranges[0].start, 0); + equal(dataSource._ranges[0].end, 16); +}); +test("range page given number of items from index", function() { + var dataSource = new DataSource({ + pageSize: 3, + data: [{age: 1}, {age: 2},{age: 3}, {age: 4},{age: 5}, {age: 6},{age: 7}, {age: 8}] + }); + dataSource.read(); + dataSource.range(2, 3); + + var result = dataSource.view(); + + equal(result.length, 3); + equal(result[0].age, 3); + equal(result[1].age, 4); + equal(result[2].age, 5); +}); + +test("range if index undefined set to zero", function() { + var dataSource = new DataSource({ + pageSize: 3, + data: [{age: 1}, {age: 2},{age: 3}, {age: 4},{age: 5}, {age: 6},{age: 7}, {age: 8}] + }); + dataSource.read(); + dataSource.range(undefined, 3); + + var result = dataSource.view(); + + equal(result.length, 3); + equal(result[0].age, 1); + equal(result[1].age, 2); + equal(result[2].age, 3); +}); + +test("range if count is undefined return all data", function() { + var dataSource = new DataSource({ + data: [{age: 1}, {age: 2},{age: 3}, {age: 4},{age: 5}, {age: 6},{age: 7}, {age: 8}] + }); + dataSource.read(); + dataSource.range(0, undefined); + + var result = dataSource.view(); + + equal(result.length, 8); +}); + +test("range fetches range accross pages where last page is partial", function() { + var dataSource = new DataSource({ + pageSize: 3, + data: [{age: 1}, {age: 2},{age: 3}, {age: 4},{age: 5}] + }); + dataSource.read(); + dataSource.range(3, 3); + + var result = dataSource.view(); + equal(result.length, 2); +}); +test("range fetch range accross multiple pages where second page is already fetched", function() { + var dataSource = remoteDataSource(); + dataSource.range(32, 16); + dataSource.range(30, 16); + dataSource.range(30, 16); + dataSource.range(30, 16); + dataSource.range(30, 16); + + var result = dataSource.view(); + equal(result.length, 16); + equal(result[0].OrderID, 30); + equal(result[15].OrderID, 45); + equal(dataSource._ranges.length, 2); +}); + +test("prefetch multiple request to the last not full page does not add multiple ranges", function () { + var dataSource = remoteDataSource(); + dataSource.prefetch(dataSource.total() - 4, 16); + dataSource.prefetch(dataSource.total() - 4, 16); + dataSource.prefetch(dataSource.total() - 4, 16); + equal(dataSource._ranges.length, 1); +}); + +test("range set skip to the beginning of the second requested page if multi page range is requested", function() { + var dataSource = remoteDataSource(); + dataSource.pageSize(100); + dataSource.range(150, 100); + equal(dataSource.skip(), 200); +}); + +test("range set skip to the beginning of the first requested page if multi page range is requested and pages are before current page", function() { + var dataSource = remoteDataSource(); + dataSource.pageSize(100); + dataSource.page(3); + dataSource.range(80, 100); + equal(dataSource.skip(), 0); +}); + +test("range set skip to requested page begining", function() { + var dataSource = remoteDataSource(); + dataSource.pageSize(100); + dataSource.page(3); + dataSource.range(100, 100); + equal(dataSource.skip(), 100); +}); + +test("range set skip request for range starting on the last page and beyond", function() { + var dataSource = remoteDataSource(), + lastPageSkip = dataSource.total(); + + dataSource.pageSize(100); + dataSource.range(lastPageSkip - 50, 100); + equal(dataSource.skip(), lastPageSkip - 100); +}); + +test("range set skip request for the last page which is not full", function() { + var dataSource = remoteDataSource(); + + dataSource.pageSize(60); + + var lastPageSkip = (dataSource.totalPages() - 1) * 60; + dataSource.range(lastPageSkip, 60); + equal(dataSource.skip(), lastPageSkip); +}); + +test("range set skip part of the first page and current page is before the end of the range", function () { + var dataSource = remoteDataSource(); + + dataSource.pageSize(100); + dataSource.range(30, 100); + equal(dataSource.skip(), 100); + equal(dataSource.page(), 2); +}); + +test("range set skip part of the first page and current page is after", function () { + var dataSource = remoteDataSource(); + + dataSource.pageSize(100); + dataSource.page(2); + dataSource.range(30, 100); + equal(dataSource.skip(), 0); + equal(dataSource.page(), 1); +}); + +test("range does not reset the actual dataSource data when local transport is used", function() { + var dataSource = new DataSource({ + pageSize: 3, + data: [{age: 1}, {age: 2},{age: 3}, {age: 4},{age: 5}, {age: 6},{age: 7}, {age: 8}] + }); + + dataSource.read(); + dataSource.range(4, 3); + + equal(dataSource.data().length, 8); + equal(dataSource.view().length, 3); +}); + +test("range set data and view when remote transport is used", function() { + var dataSource = remoteDataSource(); + + dataSource.read(); + dataSource.range(4, 16); + + equal(dataSource.data().length, 16); + equal(dataSource.view().length, 16); +}); + +test("range from sorted local data is with the correct order", function() { + var dataSource = new DataSource({ + pageSize: 3, + data: [{ foo: 6 },{ foo: 1 },{ foo: 5 },{ foo: 3 },{ foo: 2 },{ foo: 4 },{ foo: 7 }] + }); + + dataSource.sort({ field: "foo", dir: "asc" }); + dataSource.range(1,3); + var view = dataSource.view(); + equal(view.length, 3); + equal(view[0].foo, 2); + equal(view[1].foo, 3); + equal(view[2].foo, 4); +}); + +test("range from grouped and sorted local data is with the correct order", function() { + var dataSource = new DataSource({ + pageSize: 3, + data: [{ foo: 11, bar: 1 },{ foo: 6, bar: 1 },{ foo: 1, bar: 1 },{ foo: 5, bar:1 },{ foo: 3, bar:1 },{ foo: 2, bar:1 },{ foo: 4, bar:1 },{ foo: 7, bar:1 },{ foo: 8, bar:1 },{ foo: 9, bar:1 }, { foo: 10, bar: 1}] + }); + + dataSource.sort({ field: "foo", dir: "asc" }); + dataSource.group({ field: "bar" }); + dataSource.range(0,11); + var view = dataSource.view()[0].items; + equal(view.length, 11); + equal(view[0].foo, 1); + equal(view[1].foo, 2); + equal(view[2].foo, 3); +}); + +test("initial order is preserved after unsorting a range with local data", function() { + var dataSource = new DataSource({ + pageSize: 3, + data: [{ foo: 6 },{ foo: 1 },{ foo: 5 },{ foo: 3 },{ foo: 2 },{ foo: 4 },{ foo: 7 }] + }); + + dataSource.sort({ field: "foo", dir: "asc" }); + dataSource.range(1,3); + + dataSource.sort({ field: "foo" }); + dataSource.range(1,3); + + var view = dataSource.view(); + equal(view.length, 3); + equal(view[0].foo, 1); + equal(view[1].foo, 5); + equal(view[2].foo, 3); +}); + +test("range from filtered local data is with the correct", function() { + var dataSource = new DataSource({ + pageSize: 3, + data: [{ foo: 6 },{ foo: 1 },{ foo: 5 },{ foo: 3 },{ foo: 2 },{ foo: 4 },{ foo: 7 }] + }); + + dataSource.filter({ field: "foo", operator: "gt", value: 3}); + + dataSource.range(1,3); + + var view = dataSource.view(); + equal(view.length, 3); + equal(view[0].foo, 5); + equal(view[1].foo, 4); + equal(view[2].foo, 7); +}); + +test("range server return total less results", function() { + var totalCount = 47, + dataSource = new DataSource({ + pageSize: 40, + serverPaging: true, + transport: { + read: function(options) { + var data = []; + var skip = options.data.skip; + var take = options.data.take; + for (var i = skip; i < Math.min(skip + take, totalCount); i++) { + data.push({ foo: i }); + } + options.success({ data: data, total: totalCount }); + } + }, + schema: { + data: "data", + total: "total" + } + }); + + dataSource.read(); + dataSource.range(6, 40); + + equal(dataSource.view().length, 40); +}); + +function generator(size) { + var data = []; + + for (var idx = 0; idx < size; idx++) { + data.push({ foo: idx }); + } + + return data; +} + +test("range total is change during the request", function() { + var mainData = generator(80), + dataSource = new DataSource({ + pageSize: 10, + serverPaging: true, + serverFiltering: true, + transport: { + read: function(options) { + var data = []; + var skip = options.data.skip; + var take = options.data.take; + + data = mainData.slice(skip, skip + take); + + options.success({ data: data, total: mainData.length }); + } + }, + schema: { + data: "data", + total: "total" + } + }); + + dataSource.page(1); + + mainData = generator(2); + dataSource.range(8, 10); + + equal(dataSource.view().length, 10); + equal(dataSource.view()[0].foo, 0); +}); + +test("range total is updated", function() { + var totalCount = 47, + dataSource = new DataSource({ + pageSize: 40, + serverPaging: true, + transport: { + read: function(options) { + var data = []; + var skip = options.data.skip; + var take = options.data.take; + for (var i = skip; i < Math.min(skip + take, totalCount); i++) { + data.push({ foo: i }); + } + options.success({ data: data, total: totalCount }); + } + }, + schema: { + data: "data", + total: "total" + } + }); + + dataSource.read(); + totalCount = 80; + dataSource.range(6, 40); + + equal(dataSource.total(), 80); +}); + +test("range data is same as the range if remote paging is enabled", function() { + var dataSource = remoteDataSource(); + dataSource.read(); + dataSource.range(30,16); + deepEqual(dataSource.data(), dataSource.view()); +}); + +test("getByUid returns the item after remote range from a diffrent page is retrieved", function() { + var dataSource = remoteDataSource(); + dataSource.read(); + dataSource.range(30,16); + ok(dataSource.getByUid(dataSource.view()[0].uid)); +}); + +test("getByUid returns the item after local range from a diffrent page is retrieved", function() { + var dataSource = new DataSource({ + data: [{foo: "foo"}, {foo: "bar"}, {foo: "baz"}], + pageSize: 1 + }); + dataSource.read(); + dataSource.range(2,1); + ok(dataSource.getByUid(dataSource.view()[0].uid)); +}); + +test("range with server grouping", function() { + var totalCount = 47, + dataSource = new DataSource({ + pageSize: 20, + serverPaging: true, + group: "foo", + serverGrouping: true, + transport: { + read: function(options) { + var skip = options.data.skip; + var take = options.data.take; + var group = { items: [] }; + for (var i = skip; i < Math.min(skip + take, totalCount); i++) { + group.items.push({ foo: i }); + } + options.success({ groups: [group], total: totalCount }); + } + }, + schema: { + data: "data", + groups: "groups", + total: "total" + } + }); + + dataSource.read(); + dataSource.range(6, 20); + var view = dataSource.view(); + + equal(view.length, 1); + equal(view[0].items.length, 20); + equal(view[0].items[0].foo, 6); +}); + +test("range with server grouping ranges are not modfied", function() { + var totalCount = 47, + dataSource = new DataSource({ + pageSize: 20, + serverPaging: true, + group: "foo", + serverGrouping: true, + transport: { + read: function(options) { + var skip = options.data.skip; + var take = options.data.take; + var data = []; + + var group = { items: [] }; + for (var i = 0; i < 10; i++) { + group.items.push({ foo: i }); + } + data.push(group); + + group = { items: [] }; + for (var i = 0; i < 10; i++) { + group.items.push({ foo: i }); + } + data.push(group); + options.success({ groups: data, total: totalCount }); + } + }, + schema: { + data: "data", + groups: "groups", + total: "total" + } + }); + + dataSource.read(); + dataSource.range(6, 20); + equal(dataSource._flatData(dataSource._ranges[0].data).length, 20); +}); + +test("mergeGroup returns a subset of the data", function() { + var dataSource = new DataSource({ + serverGrouping: true, + group: "foo" + }), + data = [{ field: "foo", value:"1", items: [{ foo: 1 },{ foo: 2 },{ foo: 3 }] }]; + + var result = dataSource._mergeGroups([], new kendo.data.ObservableArray(data), 1, 2); + + equal(result[0].items.length, 2); +}); + +test("mergeGroup returns a subset of the data if range is of multiple groups skipping the last group data if not required", function() { + var dataSource = new DataSource({ + serverGrouping: true, + group: "foo" + }), + data = [ + { field: "foo", value:"1", items: [{ foo: 1 },{ foo: 2 },{ foo: 3 }] }, + { field: "foo", value:"2", items: [{ foo: 1 },{ foo: 2 },{ foo: 3 }] }, + { field: "foo", value:"3", items: [{ foo: 1 },{ foo: 2 },{ foo: 3 }] } + ]; + + var result = dataSource._mergeGroups([], new kendo.data.ObservableArray(data), 1, 4); + + equal(result.length, 2); + equal(result[0].items.length, 2); + equal(result[1].items.length, 2); +}); + +test("mergeGroup skips more than one group", function() { + var dataSource = new DataSource({ + serverGrouping: true, + group: "foo" + }), + data = [ + { field: "foo", value:"1", items: [{ foo: 1 },{ foo: 2 },{ foo: 3 }] }, + { field: "foo", value:"2", items: [{ foo: 1 },{ foo: 2 },{ foo: 3 }] }, + { field: "foo", value:"3", items: [{ foo: 31 },{ foo: 32 },{ foo: 33 }] } + ]; + + var result = dataSource._mergeGroups([], new kendo.data.ObservableArray(data), 6, 2); + + equal(result.length, 1); + equal(result[0].items.length, 2); + equal(result[0].items[1].foo, 32); +}); + +test("mergeGroup returns a subset of the data if range is of multiple groups", function() { + var dataSource = new DataSource({ + serverGrouping: true, + group: "foo" + }), + data = [ + { field: "foo", value:"1", items: [{ foo: 1 },{ foo: 2 },{ foo: 3 }] }, + { field: "foo", value:"2", items: [{ foo: 1 },{ foo: 2 },{ foo: 3 }] } + ]; + + var result = dataSource._mergeGroups([], new kendo.data.ObservableArray(data), 1, 4); + + equal(result.length, 2); + equal(result[0].items.length, 2); + equal(result[1].items.length, 2); +}); + +test("mergeGroup returns a subset of the data if range is of multiple groups skiping the first groups", function() { + var dataSource = new DataSource({ + serverGrouping: true, + group: "foo" + }), + data = [ + { field: "foo", value:"1", items: [{ foo: 1 },{ foo: 2 },{ foo: 3 }] }, + { field: "foo", value:"2", items: [{ foo: 1 },{ foo: 2 },{ foo: 3 }] } + ]; + + var result = dataSource._mergeGroups([], new kendo.data.ObservableArray(data), 3, 2); + + equal(result.length, 1); + equal(result[0].items.length, 2); +}); + +test("mergeGroup merges group with previous data", function() { + var dataSource = new DataSource({ + serverGrouping: true, + group: "foo" + }), + data = [ + { field: "foo", value:"1", items: [{ foo: 1 },{ foo: 2 },{ foo: 3 }] }, + { field: "foo", value:"2", items: [{ foo: 1 },{ foo: 2 },{ foo: 3 }] } + ], + originalData = [ { field: "foo", value:"3", items: [{ foo: 1 },{ foo: 2 },{ foo: 3 }] }]; + + var result = dataSource._mergeGroups(originalData, new kendo.data.ObservableArray(data), 1, 4); + + equal(result.length, 3); + equal(result[0].items.length, 3); + equal(result[1].items.length, 2); + equal(result[2].items.length, 2); +}); + +test("mergeGroup merges group with previous data and skips", function() { + var dataSource = new DataSource({ + serverGrouping: true, + group: "foo" + }), + data = [ + { field: "foo", value:"1", items: [{ foo: 1 },{ foo: 2 },{ foo: 3 }] }, + { field: "foo", value:"2", items: [{ foo: 1 },{ foo: 2 },{ foo: 3 }] }, + { field: "foo", value:"3", items: [{ foo: 1 },{ foo: 32 },{ foo: 3 }] } + ], + originalData = [ { field: "foo", value:"3", items: [{ foo: 1 },{ foo: 2 },{ foo: 3 }] }]; + + var result = dataSource._mergeGroups(originalData, new kendo.data.ObservableArray(data), 7, 1); + + equal(result.length, 1); + equal(result[0].items.length, 4); + equal(result[0].items[3].foo, 32); +}); + +test("mergeGroup merges group with previous data and skips", function() { + var dataSource = new DataSource({ + serverGrouping: true, + group: "foo" + }), + data = [ + { field: "foo", value:"3", items: [{ foo: 1 },{ foo: 32 },{ foo: 3 }] }, + { field: "foo", value:"1", items: [{ foo: 1 },{ foo: 2 },{ foo: 3 }] }, + { field: "foo", value:"2", items: [{ foo: 1 },{ foo: 22 },{ foo: 3 }] } + ], + originalData = [ { field: "foo", value:"3", items: [{ foo: 1 },{ foo: 2 },{ foo: 3 }] }]; + + var result = dataSource._mergeGroups(originalData, new kendo.data.ObservableArray(data), 7, 1); + + equal(result.length, 2); + equal(result[0].items.length, 3); + equal(result[1].items.length, 1); + equal(result[1].items[0].foo, 22); +}); + +test("mergeGroup merges group with previous data if from the same group", function() { + var dataSource = new DataSource({ + serverGrouping: true, + group: "foo" + }), + data = [ { field: "foo", value:"1", items: [{ foo: 1 },{ foo: 2 },{ foo: 3 }] } ], + originalData = [ { field: "foo", value:"1", items: [{ foo: 1 },{ foo: 2 },{ foo: 3 }] }]; + + var result = dataSource._mergeGroups(originalData, new kendo.data.ObservableArray(data), 0, 2); + + equal(result.length, 1); + equal(result[0].items.length, 5); +}); + +test("mergeGroup merges group with previous data if from the same group with nested groups", function() { + var dataSource = new DataSource({ + serverGrouping: true, + group: "foo" + }), + data = [{ field: "foo", value:"1", hasSubgroups: true, items: [{ field: "bar", value:"1", items: [{ foo: 1 },{ foo: 2 },{ foo: 3 }] }] } ], + originalData = [{ field: "foo", value:"1", hasSubgroups: true, items: [{ field: "bar", value:"1", items: [{ foo: 1 },{ foo: 2 },{ foo: 3 }] }] } ]; + + var result = dataSource._mergeGroups(originalData, new kendo.data.ObservableArray(data), 0, 2); + + equal(result.length, 1); + equal(result[0].items.length, 1); + equal(result[0].items[0].items.length, 5); +}); + +test("mergeGroup merges group with previous data if from the same group and multi group range", function() { + var dataSource = new DataSource({ + serverGrouping: true, + group: "foo" + }), + data = [ { field: "foo", value:"1", items: [{ foo: 1 },{ foo: 2 },{ foo: 3 }] }, + { field: "foo", value:"2", items: [{ foo: 1 },{ foo: 2 },{ foo: 3 }] }], + originalData = [ { field: "foo", value:"1", items: [{ foo: 1 },{ foo: 2 },{ foo: 3 }] }]; + + var result = dataSource._mergeGroups(originalData, new kendo.data.ObservableArray(data), 0, 5); + + equal(result.length, 2); + equal(result[0].items.length, 6); + equal(result[1].items.length, 2); +}); + +test("mergeGroup merges group with nested groups", function() { + var dataSource = new DataSource({ + serverGrouping: true, + group: "foo" + }), + data = [ + { + field: "foo", value:"1", + hasSubgroups: true, + items: [ + { field: "bar", value: 1, items: [ { foo: 11 }, { foo: 12}] }, + { field: "bar", value: 2, items: [ { foo: 21 }, { foo: 22}] } + ] + } + ]; + + + var result = dataSource._mergeGroups([], new kendo.data.ObservableArray(data), 1, 2); + + equal(result.length, 1); + equal(result[0].items.length, 2); + equal(result[0].items[0].items.length, 1); + equal(result[0].items[1].items.length, 1); + equal(result[0].items[0].items[0].foo, 12); + equal(result[0].items[1].items[0].foo, 21); +}); + +test("mergeGroup merges group with two levels of nested groups", function() { + var dataSource = new DataSource({ + serverGrouping: true, + group: "foo" + }), + data = [ + { + field: "foo", value:"1", + hasSubgroups: true, + items: [ + { field: "bar", value: 1, hasSubgroups: true, items: [ { field: "baz", value: 1, items: [ { foo: 11 }, { foo: 12}] } ] }, + { field: "bar", value: 2, hasSubgroups: true, items: [ { field: "baz", value: 2, items: [ { foo: 21 }, { foo: 22}] } ] } + ] + } + ]; + + + var result = dataSource._mergeGroups([], new kendo.data.ObservableArray(data), 1, 2); + + result = result[0].items; + + equal(result.length, 2); + equal(result[0].items.length, 1); + equal(result[0].items[0].items[0].foo, 12); + equal(result[1].items[0].items[0].foo, 21); +}); + +test("range returns requested size when one group is in multiple ranges", function() { + var count = 0; + var dataSource = new DataSource({ + transport: { + read: function(options) { + count ++; + + options.success({ + data: [ { + field: "foo", + value: 1, + items: [ + { foo: count + "1"}, + { foo: count + "2"} + ] + } ], + total: 4 + }); + } + }, + serverGrouping: true, + serverPaging: true, + pageSize: 2, + schema: { + groups: "data", + total: "total" + }, + group: "foo" + }); + + dataSource.read(); + dataSource.range(1, 2) + var data = dataSource.view(); + + equal(data.length, 1); + equal(data[0].items.length, 2); + equal(data[0].items[0].foo, 12); + equal(data[0].items[1].foo, 21); +}); + +}()); diff --git a/tests/data/datasource/read.js b/tests/data/datasource/read.js new file mode 100644 index 00000000000..8e0238d2851 --- /dev/null +++ b/tests/data/datasource/read.js @@ -0,0 +1,729 @@ +(function() { + +var schema = { + id: function(record) { + return record.id; + }, + data: function(data) { + return data; + } +}; + +var data = []; + +var DataSource = kendo.data.DataSource; + +module("data source read", { + setup: function() { + $.mockjaxSettings.responseTime = 0; + }, + teardown: function() { + $.mockjaxClear(); + } +}); + +function setup(source) { + data = source || [{ id:1, bar: "foo" },{ id: 2, bar: "foo" }]; + + var dataSource = new DataSource( { + schema: $.extend(schema, { + model: { + id: "id" + } + }), + data: data + }); + + dataSource.read(); + return dataSource; +} + +test("reads data through transport", function() { + var readWasCalled = false, + dataSource = new DataSource( { + schema: schema, + transport: { + read: function(callback) { + readWasCalled = true; + } + } + }); + + dataSource.read(); + ok(readWasCalled); +}); + +test("reads data", function() { + var dataSource = setup(); + + ok(dataSource.data().length); +}); + +test("read triggers load event", function(){ + var dataSource = setup(); + var argument; + + dataSource.bind("load", function(data){ + argument = data; + }); + + equal(data.length, 2); +}); + +test("Changes to the raw data in requestEnd event does take effect", 2, function() { + var dataSource = new DataSource({ + data: [] + }); + + dataSource.bind("requestEnd", function(e) { + $.extend(e.response, [ { foo: "bar" }]); + }); + + dataSource.bind("change", function() { + equal(this.data().length, 1); + equal(this.data()[0].foo, "bar"); + }); + + dataSource.read(); +}); + +test("read triggers the requestEnd event passing the raw data", 1, function() { + var dataSource = new DataSource({ + data: data + }); + + dataSource.bind("requestEnd", function(e) { + deepEqual(e.response, data); + }); + + dataSource.read(); +}); + +test("read triggers the requestEnd event passing operation type", 2, function() { + var data = [ { foo: "bar" } ], + dataSource = new DataSource({ + data: data + }); + + dataSource.bind("requestEnd", function(e) { + deepEqual(e.response, data); + deepEqual(e.type, "read"); + }); + + dataSource.read(); +}); + +test("read triggers the requestEnd event if custom error is present", 1, function() { + var dataSource = new DataSource({ + transport: { + read: function(options) { + options.success({ + errors: "foo" + }); + } + } + }); + + dataSource.bind("requestEnd", function() { + ok(true); + }); + + dataSource.read(); +}); + +test("read triggers the requestEnd event if request errors", 1, function() { + var dataSource = new DataSource({ + transport: { + read: function(options) { + options.error({ }); + } + } + }); + + dataSource.bind("requestEnd", function() { + ok(true); + }); + + dataSource.read(); +}); + +test("read raises the change event", function() { + var dataSource = new DataSource({ + data: data + }); + var changeWasCalled = false; + + dataSource.bind("change", function() { + changeWasCalled = true; + }); + + dataSource.read(); + + ok(changeWasCalled); +}); + +test("data is initially empty", function() { + var dataSource = new DataSource({ + data: data + }); + + equal(dataSource.data().length, 0); +}); + +test("view is initially empty", function() { + var dataSource = new DataSource({ + data: data + }); + + equal(dataSource.view().length, 0); +}); + +test("read sorts if sort is set", function() { + var dataSource = new DataSource({ + data: [{ id:1, bar: "foo" },{ id: 2, bar: "baz" }], + sort: { field: "bar", dir: "asc"} + }); + + dataSource.read(); + var view = dataSource.view(); + equal(view.length, 2); + equal(view[0].bar, "baz"); + equal(view[1].bar, "foo"); +}); + +test("read pages if pageSize is set", function() { + var dataSource = new DataSource({ + data: [1,2,3], + page: 2, + pageSize: 1 + }); + + dataSource.read(); + var view = dataSource.view(); + equal(view.length, 1); + equal(view[0], 2); +}); + +test("read does not page if pageSize is set and serverPaging = true", function() { + var dataSource = new DataSource({ + data: [1,2,3], + page: 2, + pageSize: 1, + serverPaging: true + }); + + dataSource.read(); + var view = dataSource.view(); + equal(view.length, 3); + equal(view[0], 1); +}); + +test("read does not sort if sort is set and serverSorting = true", function() { + var dataSource = new DataSource({ + data: [{ id:1, bar: "foo" },{ id: 2, bar: "baz" }], + sort: { field: "bar", dir: "desc"}, + serverSorting: true + }); + + dataSource.read(); + var view = dataSource.view(); + equal(view[0].bar, "foo"); +}); + +test("read calls schema set through constructor", function() { + var dataSource = new DataSource({ + data: [{ id:1, bar: "foo" },{ id: 2, bar: "baz" }], + schema: { + data: function(data) { + readerWasCalled = true; + return data; + } + } + }); + + var readerWasCalled = false; + dataSource.read(); + ok(readerWasCalled); +}); + +test("read reads item total count", function() { + var dataSource = new DataSource({ + data: [{ id:1, bar: "foo" },{ id: 2, bar: "baz" }] + }); + + dataSource.read(); + equal(dataSource.total(), 2); +}); + +test("read reads total through function passed in constructor", function() { + var dataSource = new DataSource({ + data: [{ id:1, bar: "foo" },{ id: 2, bar: "baz" }], + schema: { + total: function() { + totalWasCalled = true; + return arguments[0].length; + } + } + }); + var totalWasCalled = false; + + dataSource.read(); + ok(totalWasCalled); + equal(dataSource.total(), 2); +}); + +asyncTest("error event is raised if transport fails loading data", 4, function() { + var dataSource = new DataSource({ + transport: { + read: "foo" + }, + schema: schema + }), + args; + + $.mockjax({ + contentType: "text/json", + url: "foo", + status: 500, + responseText: 'A text response from the server' + }); + + dataSource.bind("error", function(e) { + start(); + ok(e); + ok(e.xhr); + ok(e.status); + ok("errorThrown" in e); + }); + + dataSource.read(); +}); + +test("error event is raised if custom schema error returns non empty object", 3, function() { + var dataSource = new DataSource({ + transport: { + read: function(options) { + options.success({ myerrors: { myError: "some error" } }); + } + }, + schema: { + errors: "myerrors" + } + }); + + dataSource.bind("error", function(e) { + ok(e); + equal(e.status, "customerror"); + deepEqual(e.errors, { myError: "some error" }); + }); + dataSource.read(); +}); + +test("request is executed after custom schema error is called", 4, function() { + var dataSource = new DataSource({ + transport: { + read: function(options) { + ok(true); + options.success({ myerrors: { myError: "some error" } }); + } + }, + schema: { + errors: "myerrors" + } + }); + + dataSource.bind("error", function(e) { + ok(true); + }); + + dataSource.read(); + dataSource.read(); +}); + +test("error event is raised if custom schema error function returns non empty object", 3, function() { + var dataSource = new DataSource({ + transport: { + read: function(options) { + options.success({ errors: { myError: "some error" } }); + } + }, + schema: { + errors: function(data) { return data.errors; } + } + }); + + dataSource.bind("error", function(e) { + ok(e); + equal(e.status, "customerror"); + deepEqual(e.errors, { myError: "some error" }); + }); + dataSource.read(); +}); + +test("error event is raised if schema error returns non empty object", 3, function() { + var dataSource = new DataSource({ + transport: { + read: function(options) { + options.success({ errors: { myError: "some error" } }); + } + }, + schema: { + errors: "errors" + } + }); + + dataSource.bind("error", function(e) { + ok(e); + equal(e.status, "customerror"); + deepEqual(e.errors, { myError: "some error" }); + }); + dataSource.read(); +}); + +asyncTest("dequeue the request if transport fails to load data", 2, function() { + var dataSource = new DataSource({ + transport: { + read: "foo" + }, + schema: schema + }), + args; + + $.mockjax({ + contentType: "text/json", + url: "foo", + status: 500, + responseText: 'A text response from the server' + }); + + dataSource.bind("error", function(e) { + start(); + ok(!dataSource._requestInProgress); + ok(!dataSource._pending); + }); + + dataSource.read(); +}); + +test("url as a function", 1, function() { + var dataSource = new DataSource({ + transport: { + read: { + url: function() { + ok(true, "url() is called"); + return "foo"; + } + } + }, + schema: schema + }), + args; + + $.mockjax({ + contentType: "text/json", + url: "foo", + responseText: '[]' + }); + + dataSource.read(); +}); + +test("transport data is passed to url when it is a function", 1, function() { + var dataSource = new DataSource({ + transport: { + read: { + url: function(options) { + ok(options.foo, "bar"); + return "foo"; + }, + data: { + foo: "bar" + } + } + }, + schema: schema + }), + args; + + $.mockjax({ + contentType: "text/json", + url: "foo", + responseText: '[]' + }); + + dataSource.read(); +}); + +test("read filters if filter is set", function() { + var dataSource = new DataSource({ + data: [{ id:1, bar: "foo" },{ id: 2, bar: "baz" }], + filter: { field: "bar", operator: "==", value: "baz" } + }); + + dataSource.read(); + var view = dataSource.view(); + equal(view.length, 1); + equal(view[0].bar, "baz"); +}); + +test("read does not filter if filter is set and serverFiltering = true", function() { + var dataSource = new DataSource({ + data: [{ id:1, bar: "foo" },{ id: 2, bar: "baz" }], + filter: { field: "bar", operator: "==", value: "baz" }, + serverFiltering: true + }); + + dataSource.read(); + var view = dataSource.view(); + equal(view.length, 2); + equal(view[0].bar, "foo"); +}); + +test("read does not read data through group if grouping is applied", function() { + var isCalled = false, + dataSource = new DataSource({ + data: [{ id:1, bar: "foo" }, { id: 2, bar: "baz" }, { id: 3, bar: "baz"} ], + group: { field: "bar" }, + schema: { + groups: function() { + isCalled = true; + return []; + } + }, + serverGrouping: false + }); + dataSource.read(); + ok(!isCalled); +}); +test("read group expression are passed to the transport", function() { + var group, dataSource = new DataSource({ + data: [{ id:1, bar: "foo" }, { id: 2, bar: "baz" }, { id: 3, bar: "baz"} ], + group: { field: "bar" }, + transport: { + read: function(options) { + group = options.data.group; + } + }, + serverGrouping: true + }); + dataSource.read(); + ok(group); +}); +test("read aggregates expression are passed to the transport", function() { + var aggregates, dataSource = new DataSource({ + data: [{ id:1, bar: "foo" }, { id: 2, bar: "baz" }, { id: 3, bar: "baz"} ], + aggregate: { field: "bar", aggregates: ["count"] }, + transport: { + read: function(options) { + aggregates = options.data.aggregate; + } + }, + serverGrouping: true, + serverAggregates: true + }); + dataSource.read(); + ok(aggregates); +}); + +test("mutiple simultaneous requests are queued", function() { + var called = 0, dataSource = new DataSource({ + transport: { + read: function(options) { + called++; + } + } + }); + dataSource.read(); + dataSource.read(); + dataSource.read(); + + equal(called, 1); + ok(dataSource._pending); +}); + +test("mutiple simultaneous requests are queued and only last one is executed", function() { + var called = 0, dataSource = new DataSource({ + transport: { + read: function(options) { + called++; + if (called == 1) { + dataSource.read(); + dataSource.read(); + } + options.success([]); + } + } + }); + dataSource.read(); + equal(called, 2); + ok(!dataSource._pending); +}); + +test("requests are dequeued after change event", function() { + var timesCalled = 0; + var dataSource = new DataSource({ + transport: { + read: function(options) { + timesCalled ++; + if (timesCalled == 1) { + dataSource.read(); + options.success([]); + } + } + }, + change: function() { + ok(dataSource._pending, "Second request is not pending"); + } + }); + + dataSource.read(); +}); + +test("setting data should trigger change event", function() { + var called = false, + dataSource = new DataSource({ + data: [1,2,3,4,5], + change: function() { + called = true; + } + }); + dataSource.data([6,7,8,9,10]); + ok(called); +}); + +test("setting data updates the total", function() { + var called = false, + dataSource = new DataSource({ + }); + + dataSource.data([6,7,8,9,10]); + equal(dataSource.total(), 5); +}); + +test("setting data persist the total after query", function() { + var called = false, + dataSource = new DataSource({ + pageSize: 2 + }); + + dataSource.data([6,7,8,9,10]); + dataSource.page(2); + + equal(dataSource.total(), 5); +}); + +test("setting data persist the total after query with initial data", function() { + var called = false, + dataSource = new DataSource({ + data: { data: [ { foo: "bar" } ] }, + schema: { + data: "data" + }, + pageSize: 2 + }); + + dataSource.data([6,7,8,9,10]); + dataSource.page(2); + equal(dataSource.total(), 5); +}); + +test("setting data should updates the dataSource data", function() { + var dataSource = new DataSource({ + data: [1,2,3,4,5], + change: function() { + called = true; + } + }); + + dataSource.data([6,7,8,9,10]); + equal(dataSource.data().length, 5); + equal(dataSource.data()[0], 6); + equal(dataSource.data()[1], 7); + equal(dataSource.data()[2], 8); + equal(dataSource.data()[3], 9); + equal(dataSource.data()[4], 10); +}); + +test("pristine data is not change if data is modified", function() { + var data = [1,2,3,4,5], + dataSource = new DataSource({ + data: data + }); + dataSource.read(); + + dataSource.data()[0] = 6; + equal(dataSource.data()[0], 6); + equal(dataSource._pristineData[0], 1); +}); + +test("paging info is not passed to the transport if serverpaging is false", 4, function() { + var dataSource = new DataSource({ + page: 3, + pageSize: 20, + transport: { + read: function(data) { + ok(!("page" in data.data)); + ok(!("skip" in data.data)); + ok(!("take" in data.data)); + ok(!("pageSize" in data.data)); + } + } + }); + + dataSource.read(); +}); + +test("filter info is not passed to the transport if serverfiltering is false", 1, function() { + var dataSource = new DataSource({ + filter: { field: "foo", op: "eq", value: "bar" }, + transport: { + read: function(data) { + ok(!("filter" in data.data)); + } + } + }); + + dataSource.read(); +}); + +test("sort info is not passed to the transport if serversorting is false", 1, function() { + var dataSource = new DataSource({ + sort: { field: "foo", dir: "asc" }, + transport: { + read: function(data) { + ok(!("sort" in data.data)); + } + } + }); + + dataSource.read(); +}); + +test("aggregate info is not passed to the transport if serveraggregates is false", 1, function() { + var dataSource = new DataSource({ + aggregate: { field: "foo" }, + transport: { + read: function(data) { + ok(!("aggregate" in data.data)); + } + } + }); + + dataSource.read(); +}); + + +test("group info is not passed to the transport if servergrouping is false", 1, function() { + var dataSource = new DataSource({ + group: { field: "foo" }, + transport: { + read: function(data) { + ok(!("group" in data.data)); + } + } + }); + + dataSource.read(); +}); + +}()); diff --git a/tests/data/datasource/sync-response.js b/tests/data/datasource/sync-response.js new file mode 100644 index 00000000000..2ff08b98f5d --- /dev/null +++ b/tests/data/datasource/sync-response.js @@ -0,0 +1,795 @@ +(function() { + +var Model = kendo.data.Model; +var DataSource = kendo.data.DataSource; +var dataSource; + +function setup(options) { + dataSource = new DataSource($.extend(true, { + data: [ { id: 1, foo: "foo" }, { id: 2, foo: "foo2" } ], + schema: { + model: $.extend({}, Model, { id: "id" }) + } + }, options)); + + dataSource.read(); +} + +function stubTransport(method, data) { + var obj = {}; + data = data !== undefined ? data : [ { id: 1, foo: "bar" } ]; + obj[method] = function(options) { + options.success($.isFunction(data) ? data() : data); + } + + stub(dataSource.transport, obj); +} + +module("data source sync response", { + setup: function() { + setup(); + } +}); + +test("sync updates the fields of created model from array server response", function() { + stubTransport("create"); + + var model = new Model(); + dataSource.add(model); + dataSource.sync(); + + equal(model.id, 1); + equal(model.get("foo"), "bar"); +}); + +test("sync updates the fields of updated model from array server response", function() { + stubTransport("update"); + + var model = dataSource.get(1); + model.set("foo", "bar"); + dataSource.sync(); + + equal(model.get("foo"), "bar"); +}); + +test("sync updates data from server response", function() { + stubTransport("update"); + + var model = dataSource.get(1); + model.set("foo", "bar"); + dataSource.sync(); + + equal(dataSource.data()[0].foo, "bar"); +}); + +test("sync updates data if server response without content", function() { + dataSource = new DataSource({ + schema: { + model: { + id: "id" + }, + data: "d.d" + }, + transport: { + read: function(options) { + options.success({ d: { d: [{ id: 1, foo: "foo" }] } }); + }, + update: function(options) { + options.success(null); + } + } + }); + + dataSource.read(); + var model = dataSource.get(1); + model.set("foo", "bar"); + dataSource.sync(); + + equal(dataSource.data()[0].foo, "bar"); +}); + +test("sync updates pristine data if server response is empty object", function() { + dataSource = new DataSource({ + schema: { + model: { + id: "id", + fields: { + foo: { type: "string" } + } + } + }, + transport: { + read: function(options) { + options.success([{id: 1, foo: "bar"}]); + }, + update: function(options) { + options.success({}); + } + } + }); + + dataSource.read(); + var model = dataSource.get(1); + model.set("foo", "car"); + dataSource.sync(); + + equal(dataSource._pristineData[0].foo, "car"); +}); + +test("sync updates pristine data for array property", function() { + dataSource = new DataSource({ + schema: { + model: { + id: "id", + fields: { + foo: { + type: "object", + defaultValue: [] + } + } + } + }, + transport: { + read: function(options) { + options.success([{id: 1, foo: [{bar: 1}, {bar: 2}]}]); + }, + update: function(options) { + options.success(null); + } + } + }); + + dataSource.read(); + var model = dataSource.get(1); + model.set("foo", [{bar:1}]); + dataSource.sync(); + + equal(dataSource.data()[0].foo.length, 1); + equal(dataSource._pristineData[0].foo.length, 1); +}); + +test("sync updates the fields of created model from single object server response", function() { + stubTransport("create", { id: 1, foo: "foo" } ); + + var model = new Model(); + dataSource.add(model); + dataSource.sync(); + + equal(model.id, 1); + equal(model.get("foo"), "foo"); +}); + +test("sync updates the fields of updated model from single object server response", function() { + stubTransport("update", { id: 1, foo: "bar" } ); + + var model = dataSource.get(1); + model.set("foo", "bar"); + dataSource.sync(); + + equal(model.id, 1); + equal(model.get("foo"), "bar"); +}); + +test("sync merges created model data with server response", function() { + stubTransport("create", { id: 1 } ); + + var model = new Model({ foo: "foo" }); + dataSource.add(model); + dataSource.sync(); + + equal(model.id, 1); + equal(model.get("foo"), "foo"); +}); + +test("sync merges updated model data with server response", function() { + stubTransport("update", { id: 1 } ); + + var model = dataSource.get(1); + model.set("foo", "bar"); + dataSource.sync(); + + equal(model.id, 1); + equal(model.get("foo"), "bar"); +}); + +test("sync updates created model when response is empty", function() { + stubTransport("create", null ); + + var model = dataSource.add({ foo: "foo" }); + dataSource.sync(); + + equal(model.get("foo"), "foo"); + equal(model.dirty, false); +}); + +test("sync updates the state of updated model when response is empty", function() { + stubTransport("update", null ); + + var model = dataSource.get(1); + model.set("foo", "bar"); + dataSource.sync(); + + equal(model.get("foo"), "bar"); + equal(model.dirty, false); + equal(dataSource._pristineData[0].foo, "bar"); +}); + +test("sync updates all created models with server response", function() { + var response = [{id:1, foo: "foo"} , {id:2, foo: "bar"}]; + + stubTransport("create", function() { return [response.shift()]; }); + + var model1 = new Model(); + dataSource.add(model1); + + var model2 = new Model(); + dataSource.add(model2); + dataSource.sync(); + + equal(model1.id, 1); + equal(model1.get("foo"), "foo"); + equal(model2.id, 2); + equal(model2.get("foo"), "bar"); +}); + +test("sync updates all updated models with server response", function() { + var response = [{id:1, foo: "bar"} , {id:2, foo: "baz"}]; + + stubTransport("update", function() { return [response.shift()]; }); + + var model1 = dataSource.get(1); + + model1.set("foo", "bar" ); + + var model2 = dataSource.get(2); + + model2.set("foo", "baz"); + + dataSource.sync(); + + equal(model1.get("foo"), "bar"); + equal(model2.get("foo"), "baz"); +}); + +test("sync updates all created models with server response when batch is true and incomplete response", function() { + setup({ batch: true }); + + stubTransport("create", [{id:1, foo: "bar"} , {id:2, foo: "baz"}]); + + var model1 = new Model(); + dataSource.add(model1); + + var model2 = new Model(); + dataSource.add(model2); + dataSource.sync(); + + equal(model1.id, 1); + equal(model1.get("foo"), "bar"); + equal(model2.isNew(), false); + equal(model2.dirty, false); +}); + +test("sync updates all created models with server response when batch is true", function() { + setup({ batch: true }); + + stubTransport("create", [{ id:1, foo: "foo" }, { id:2 , foo: "bar" }]); + + var model1 = new Model(); + dataSource.add(model1); + + var model2 = new Model(); + dataSource.add(model2); + dataSource.sync(); + + equal(model1.id, 1); + equal(model1.get("foo"), "foo"); + equal(model2.id, 2); + equal(model2.get("foo"), "bar"); +}); + +test("sync updates all updated models with server response when batch is true", function() { + setup({ batch: true }); + + stubTransport("update", [{ id:1, foo: "baz" }, { id:2 , foo: "bar" }]); + + var model1 = dataSource.get(1); + + model1.set("foo", "baz"); + + var model2 = dataSource.get(2); + + model2.set("foo", "bar"); + dataSource.sync(); + + equal(model1.get("foo"), "baz"); + equal(model2.get("foo"), "bar"); +}); + +test("created models are no longer new after sync", function() { + stubTransport("create"); + + var model = new Model(); + dataSource.add(model); + dataSource.sync(); + + equal(model.isNew(), false); +}); + +test("created model has no changes after sync", function() { + stubTransport("create"); + + var model = new Model(); + dataSource.add(model); + dataSource.sync(); + + equal(model.dirty, false); +}); + +test("updated model has no changes after sync", function() { + stubTransport("update"); + + var model1 = dataSource.get(1); + + model1.set("foo", "foo"); + + dataSource.sync(); + + equal(model1.dirty, false); +}); + +test("sync clears destroyed models", function() { + stubTransport("destroy"); + var model = dataSource.get(1); + + dataSource.remove(model); + dataSource.sync(); + + dataSource.sync(); + + equal(dataSource.transport.calls("destroy"), 1); +}); + +test("sync uses the parse method of the reader", function() { + var reader = stub(dataSource.reader, { + parse: function() { + return [{id:1}]; + }, + data: function(result) { + return result; + } + }); + + stubTransport("create"); + + var model = new Model(); + dataSource.add(model); + dataSource.sync(); + + equal(reader.calls("parse"), 1); + equal(model.id, 1); +}); + +test("sync uses the data method of the reader", function() { + var reader = stub(dataSource.reader, { + parse: function(result) { + return [{id:1}]; + }, + data: function(result) { + return [{id:1}]; + } + }); + + stubTransport("create"); + + var model = new Model(); + dataSource.add(model); + dataSource.sync(); + + equal(reader.calls("parse"), 1); + equal(model.id, 1); +}); + +test("sync raises requestEnd event", 2, function() { + stubTransport("destroy", { foo: "bar" }); + + dataSource.remove(dataSource.get(1)); + + dataSource.bind("requestEnd", function(e) { + deepEqual(e.response, { foo: "bar" }); + deepEqual(e.type, "destroy"); + }); + + dataSource.sync(); +}); + + +test("sync raises change event after delete", 1, function() { + stubTransport("destroy"); + + dataSource.remove(dataSource.get(1)); + + dataSource.bind("change", function() { + ok(true); + }); + + dataSource.sync(); +}); + +test("sync raises sync event after delete attached through the constructor", 1, function() { + setup({ + sync: function() { + ok(true); + } + }); + + stubTransport("destroy"); + + dataSource.remove(dataSource.get(1)); + + dataSource.sync(); +}); + +test("sync raises sync event after delete", 1, function() { + stubTransport("destroy"); + + dataSource.remove(dataSource.get(1)); + + dataSource.bind("sync", function() { + ok(true); + }); + + dataSource.sync(); +}); + +test("sync raises sync event after update attached through the constructor", 1, function() { + setup({ + sync: function() { + ok(true); + } + }); + + stubTransport("update"); + + dataSource.get(1).set("foo", "bar"); + + dataSource.sync(); +}); + +test("sync raises sync event after update", 1, function() { + + stubTransport("update"); + + dataSource.get(1).set("foo", "bar"); + + dataSource.bind("sync", function() { + ok(true); + }); + + dataSource.sync(); +}); + +test("sync raises sync event after create attached through the constructor", 1, function() { + setup({ + sync: function() { + ok(true); + } + }); + + stubTransport("create"); + + dataSource.add({}); + + dataSource.sync(); +}); + +test("sync raises sync event after create", 1, function() { + + stubTransport("create"); + dataSource.add({}); + + dataSource.bind("sync", function() { + ok(true); + }); + + dataSource.sync(); +}); +test("sync raises change event after create", 1, function() { + stubTransport("create"); + + var model = new Model(); + dataSource.add(model); + + dataSource.bind("change", function() { + ok(true); + }); + + dataSource.sync(); +}); + +test("sync raises change event after update", 1, function() { + stubTransport("update", [{ foo: "moo" }]); + + dataSource.get(1).set("foo", "moo"); + + dataSource.bind("change", function() { + ok(true); + }); + + dataSource.sync(); +}); + +test("get returns new models after sync", function() { + stubTransport("create", [{ id: 3, foo: "moo" }]); + + dataSource.add({}); + dataSource.sync(); + + equal(dataSource.get(3).get("id"), 3); +}); + +test("cancelChanges does not remove the added models after sync", function() { + stubTransport("create", [{ id: 3, foo: "moo" }]); + + dataSource.add({}); + dataSource.sync(); + + dataSource.cancelChanges(); + + ok(dataSource.get(3)); +}); + +test("cancelChanges does not remove the added models after sync", function() { + stubTransport("create", [{ id: 3, foo: "moo" }]); + + dataSource.add({}); + dataSource.sync(); + + dataSource.cancelChanges(); + + ok(dataSource.get(3)); +}); + +test("cancelChanges does not revert the updated models after sync when Model has fields defined", function() { + setup({ + schema: { + model: { + fields: { + foo: "foo" + } + } + } + }); + + stubTransport("create", [{ id: 42, foo: "moo" }]); + + dataSource.add(); + + dataSource.sync(); + + dataSource.cancelChanges(); + + equal(dataSource.get(42).foo, "moo"); +}); + +test("cancelChanges does not revert the deleted models after sync", function() { + stubTransport("destroy", [{ id: 2, foo: "moo" }]); + + dataSource.remove(dataSource.get(2)); + dataSource.sync(); + + dataSource.cancelChanges(); + + ok(!dataSource.get(2)); +}); + +test("sync response data as array is converted if model types are set", function() { + setup({ + data: [ { id: 1, foo: "1" } ], + schema: { model: { id: "id", fields: { foo: { type: "number" } } } } + }); + stubTransport("create", [{ id: 3, foo: "2" }]); + + dataSource.add({}); + dataSource.sync(); + + strictEqual(dataSource.get(3).get("foo"), 2); +}); + +test("sync response data as object is converted if model types are set", function() { + setup({ + data: [ { id: 1, foo: "1" } ], + schema: { model: { id: "id", fields: { foo: { type: "number" } } } } + }); + stubTransport("create", { id: 3, foo: "2" }); + + dataSource.add({}); + dataSource.sync(); + + strictEqual(dataSource.get(3).get("foo"), 2); +}); + +test("destroy sync null response", 1, function() { + setup({ + transport: { + read: function(options) { + options.success({ d:[ { id: 1, foo: "foo" }, { id: 2, foo: "foo2" } ]}); + } + }, + schema: { data: "d", model: { id: "id", fields: { foo: { type: "string" } } } } + }); + stubTransport("destroy", { d: null }); + + dataSource.remove(dataSource.get(1)); + + dataSource.sync(); + equal(dataSource.data().length, 1); +}); + +test("deleted items are not synced after changes are reverted", 1, function() { + dataSource = new kendo.data.DataSource({ + transport: { + read: function(options) { + options.success([{id: 1, foo: "bar"}]); + }, + destroy: function(options) { + ok(false); + } + } + }); + dataSource.read(); + + dataSource.remove(dataSource.at(0)); + + dataSource.cancelChanges(); + dataSource.sync(); + ok(!dataSource._destroyed.length); +}); + +test("deleted items are synced after other record changes are reverted", 2, function() { + dataSource = new kendo.data.DataSource({ + transport: { + read: function(options) { + options.success([{id: 1, foo: "bar"},{id: 2, foo: "baz"}]); + }, + destroy: function(options) { + ok(true); + } + }, + schema: { model: { id: "id" } } + }); + dataSource.read(); + + dataSource.remove(dataSource.at(0)); + + dataSource.cancelChanges(dataSource.get(2)); + dataSource.sync(); + equal(dataSource._destroyed.length, 1); +}); + +test("error event is raised if custom errors are returned", 1, function() { + setup({ + data: [ { id: 1, foo: "1" } ], + schema: { model: { id: "id", fields: { foo: { type: "number" } } } } + }); + stubTransport("create", { errors: "error" }); + + dataSource.add({}); + + dataSource.bind("error", function(e) { + equal(e.errors, "error"); + }); + + dataSource.sync(); +}); + +test("sync updates the pristine data with server grouping", 4, function() { + dataSource = new DataSource({ + schema: { + model: { id: "id" }, + total: function() { + return 1; + } + }, + batch: true, + serverGrouping: true, + group: { field: "foo" } + }); + + stubTransport("update", [{ foo: "moo" }]); + stubTransport("read", [{ items: [{ foo: 1, id: 0}, { foo: 2, id: 1}], field: "foo", value: "bar" }, + { items: [{ foo: 3, id: 2}, { foo: 4, id: 3}], field: "foo", value: "baz" }]); + + dataSource.read(); + + dataSource.get(0).set("foo", "moo"); + + dataSource.sync(); + equal(dataSource._pristineData[0].items[0].foo, "moo"); + equal(dataSource._pristineData[0].items[1].foo, 2); + equal(dataSource._pristineData[1].items[0].foo, 3); + equal(dataSource._pristineData[1].items[1].foo, 4); +}); + +test("sync update the pristine data with created items if server grouping", 6, function() { + dataSource = new DataSource({ + schema: { + model: { id: "id" }, + total: function() { + return 1; + } + }, + batch: true, + serverGrouping: true, + group: { field: "foo" } + }); + + stubTransport("create", [{ foo: "moo" }]); + stubTransport("read", [{ items: [{ foo: 1, id: 0}, { foo: 2, id: 1}], field: "foo", value: "bar" }, + { items: [{ foo: 3, id: 2}, { foo: 4, id: 3}], field: "foo", value: "baz" }]); + + dataSource.read(); + + dataSource.add({}); + + dataSource.sync(); + equal(dataSource.data().length, 3); + + equal(dataSource._pristineData[0].items[0].foo, 1); + equal(dataSource._pristineData[0].items[1].foo, 2); + equal(dataSource._pristineData[1].items[0].foo, 3); + equal(dataSource._pristineData[1].items[1].foo, 4); + equal(dataSource._pristineData[2].items[0].foo, "moo"); +}); + +test("nested object are observable after sync", 2, function() { + setup({ + data: [ { id: 1, obj: { foo: "bar" } } ] + }); + + stubTransport("update", null); + var initial = dataSource.get(1); + initial.set("obj", { foo: "baz" }); + + dataSource.sync(); + + ok(dataSource.get(1).obj instanceof kendo.data.ObservableObject); + equal(dataSource.get(1).uid, initial.uid); +}); + +test("sync updates the pristine data with plain objects", function() { + dataSource = new DataSource({ + schema: { + model: { + id: "id" + } + } + }); + dataSource.insert(0, {}); + + dataSource.sync(); + + equal(dataSource._pristineData[0] instanceof kendo.data.ObservableObject, false); +}); + +test("sync model custom field mapping is persisted after sync with empty response", function() { + setup({ + data: [ { id: 1, foo: "bar" } ], + schema: { + model: { + fields: { + baz: "foo" + } + } + } + }); + stubTransport("update", null); + var initial = dataSource.get(1); + initial.set("baz", "foo" ); + + dataSource.sync(); + + ok(!("foo" in dataSource.get(1))); + equal(dataSource.get(1).baz, "foo"); +}); + +}()); diff --git a/tests/data/datasource/sync.js b/tests/data/datasource/sync.js new file mode 100644 index 00000000000..20acb21a199 --- /dev/null +++ b/tests/data/datasource/sync.js @@ -0,0 +1,633 @@ +(function(){ + +var Model = kendo.data.Model; +var DataSource = kendo.data.DataSource; +var dataSource; + +function setup(options) { + dataSource = new DataSource($.extend({ + data: [{ id: 1, foo: "foo" }], + schema: { + model: $.extend({}, Model, { id: "id" }) + } + }, options)); + + dataSource.read(); +} + +module("data source sync", { + setup: function() { + setup(); + } +}); + +test("change is raised after new model is added to the set", 1, function() { + dataSource.bind("change", function(e) { + equal(e.action, "add"); + }); + + dataSource.add({}); +}); + +test("change is raised after model is deleted from the set", 1, function() { + dataSource.bind("change", function(e) { + equal(e.action, "remove"); + }); + + dataSource.remove(dataSource.get(1)); +}); + +test("data is processed after model changes are reverted", 2, function() { + dataSource.filter({ field: "id", operator: "ge", value: 1 }); + + dataSource.add({ id: 3 }); + + dataSource.bind("change", function() { + equal(dataSource.view().length, 1); + equal(dataSource.view()[0].id, 1); + }); + + dataSource.cancelChanges(); +}); + +test("data is processed after model is added", function() { + dataSource.filter({ field: "id", operator: "ge", value: 1 }); + + dataSource.bind("change", function() { + equal(dataSource.view().length, 2); + equal(dataSource.view()[1].id, 3); + }); + + dataSource.add({ id: 3 }); +}); + +test("add syncs when autoSync is true", function() { + setup({ autoSync: true }); + + stub(dataSource, "sync"); + + dataSource.add({ foo: "bar" }); + + equal(dataSource.calls("sync"), 1); +}); + +test("remove syncs when autoSync is true", function() { + setup({ autoSync: true }); + stub(dataSource, "sync"); + dataSource.remove(dataSource.get(1)); + + equal(dataSource.calls("sync"), 1); +}); + +test("update syncs when autoSync is true", function() { + setup({ autoSync: true }); + stub(dataSource, "sync"); + + dataSource.get(1).set("foo", "moo"); + + equal(dataSource.calls("sync"), 1); +}); + +test("add does not sync when autoSync is false", function() { + stub(dataSource, "sync"); + dataSource.add({ foo: "bar" }); + + equal(dataSource.calls("sync"), 0); +}); + +test("remove does not sync when autoSync is false", function() { + stub(dataSource, "sync"); + + dataSource.remove(dataSource.get(1)); + + equal(dataSource.calls("sync"), 0); +}); + +test("sync calls the create method of the transport", function() { + stub(dataSource.transport, "create"); + + dataSource.add(new Model( { foo: "bar" })); + dataSource.sync(); + + equal(dataSource.transport.calls("create"), 1); +}); + +test("sync does not call the create method of the transport if there are no new models", function() { + stub(dataSource.transport, "create"); + + dataSource.sync(); + + equal(dataSource.transport.calls("create"), 0); +}); + +test("sync sends the data of the created model to the create method of the transport", function() { + stub(dataSource.transport, "create"); + + dataSource.add(new Model( { foo: "bar" })); + dataSource.sync(); + + equal(dataSource.transport.args("create")[0].data.foo, "bar"); +}); + +test("sync sends the data of all created models to the create method of the transport", function() { + stub(dataSource.transport, "create"); + + dataSource.add(new Model( { foo: "bar" })); + dataSource.add(new Model( { foo: "baz" })); + dataSource.sync(); + + equal(dataSource.transport.calls("create"), 2); + equal(dataSource.transport.args("create", 0)[0].data.foo, "bar"); + equal(dataSource.transport.args("create", 1)[0].data.foo, "baz"); +}); + +test("sync calls the update method of the transport if there are updated models", function() { + stub(dataSource.transport, "update"); + + var model = dataSource.get(1); + + model.set("foo", "bar"); + dataSource.sync(); + + equal(dataSource.transport.calls("update"), 1); +}); + +test("sync does not call the update method of the transport if there are no updated models", function() { + stub(dataSource.transport, "update"); + + dataSource.sync(); + + equal(dataSource.transport.calls("update"), 0); +}); + +test("sync sends all updated models to the create method of the transport", function() { + setup({ data: [ { id:1 }, { id: 2}] }); + + stub(dataSource.transport, "update"); + + var model = dataSource.get(1); + model.set("foo", "bar"); + model = dataSource.get(2); + model.set("foo", "baz"); + dataSource.sync(); + + equal(dataSource.transport.calls("update"), 2); + equal(dataSource.transport.args("update", 0)[0].data.foo, "bar"); + equal(dataSource.transport.args("update", 0)[0].data.id, 1); + equal(dataSource.transport.args("update", 1)[0].data.id, 2); + equal(dataSource.transport.args("update", 1)[0].data.foo, "baz"); +}); + +test("sync calls the destroy method of the transport if there are destroyed models", function() { + stub(dataSource.transport, "destroy"); + + var model = dataSource.get(1); + dataSource.remove(model); + dataSource.sync(); + + equal(dataSource.transport.calls("destroy"), 1); +}); + +test("sync calls schange after destroy", function() { + var model = dataSource.get(1), + wasCalled = false; + + dataSource.remove(model); + dataSource.bind("change", function() { + wasCalled = true; + }); + dataSource.sync(); + + ok(wasCalled); +}); + +test("sync does not call the destroy method of the transport if a new model is destroyed", function() { + stub(dataSource.transport, "destroy"); + + var model = new Model(); + dataSource.add(model); + dataSource.remove(model); + dataSource.sync(); + + equal(dataSource.transport.calls("destroy"), 0); +}); + +test("sync sends all destroyed models to the destroy method of the transport", function() { + setup({ data: [ { id:1 }, { id: 2}] }); + stub(dataSource.transport, "destroy"); + + var model = dataSource.get(1); + dataSource.remove(model); + model = dataSource.get(2); + dataSource.remove(model); + dataSource.sync(); + + equal(dataSource.transport.calls("destroy"), 2); + equal(dataSource.transport.args("destroy", 0)[0].data.id, 1); + equal(dataSource.transport.args("destroy", 1)[0].data.id, 2); +}); + +test("sync does not send the automatically generated id of new models", function() { + stub(dataSource.transport, "create"); + + var model = new Model(); + model.set("foo", "bar"); + dataSource.add(model); + dataSource.sync(); + + equal(dataSource.transport.args("create", 0)[0].data.uid, undefined); +}); + +test("sync does not send the automatically generated id of updated models", function() { + stub(dataSource.transport, "update"); + + dataSource.get(1).set("foo", "bar"); + dataSource.sync(); + + equal(dataSource.transport.args("update", 0)[0].data.uid, undefined); +}); + +test("sync does not send the automatically generated id of destroyed models", function() { + stub(dataSource.transport, "destroy"); + + dataSource.remove(dataSource.get(1)); + dataSource.sync(); + + equal(dataSource.transport.args("destroy", 0)[0].data.uid, undefined); +}); + +test("sync calls the create method of the transport only once when batch is true", function() { + setup({ batch: true }); + + stub(dataSource.transport, "create"); + + dataSource.add(new Model()); + dataSource.add(new Model()); + dataSource.sync(); + + equal(dataSource.transport.calls("create"), 1); +}); + +test("sync passes array of created models to transport when batch is true", function() { + setup({ batch: true }); + + stub(dataSource.transport, "create"); + + dataSource.add(new Model({foo: "foo"})); + dataSource.add(new Model({foo: "bar"})); + dataSource.sync(); + + var models = dataSource.transport.args("create")[0].data.models; + + ok($.isArray(models)); + equal(models.length, 2); + equal(models[0].foo, "foo"); + equal(models[1].foo, "bar"); +}); + +test("sync does not send the uid of new models when batch is true", function() { + setup({ batch: true }); + + stub(dataSource.transport, "create"); + + dataSource.add(new Model({foo: "bar"})); + dataSource.sync(); + + var models = dataSource.transport.args("create")[0].data.models; + + equal(models[0].uid, undefined); +}); + +test("sync calls the update method of the transport only once when batch is true", function() { + setup({ batch: true, data: [ { id: 1 }, { id: 2 }] }); + + stub(dataSource.transport, "update"); + + var model = dataSource.get(1); + model.set("foo", "foo"); + model = dataSource.get(2); + model.set("foo", "bar"); + dataSource.sync(); + + equal(dataSource.transport.calls("update"), 1); +}); + +test("sync passes array of updated models to transport when batch is true", function() { + setup({ batch: true, data: [ { id: 1 }, { id: 2 }] }); + + stub(dataSource.transport, "update"); + + var model = dataSource.get(1); + model.set("foo", "foo"); + model = dataSource.get(2); + model.set("foo", "bar"); + dataSource.sync(); + + var models = dataSource.transport.args("update")[0].data.models; + ok($.isArray(models)); + equal(models.length, 2); + equal(models[0].foo, "foo"); + equal(models[1].foo, "bar"); +}); + +test("sync does not send the uid of updated models when batch is true", function() { + setup({ batch: true }); + + stub(dataSource.transport, "update"); + + dataSource.get(1).set("foo", "bar"); + dataSource.sync(); + + var models = dataSource.transport.args("update")[0].data.models; + + equal(models[0].uid, undefined); +}); + +test("sync calls the destroy method of the transport only once when batch is true", function() { + setup({ batch: true, data: [ { id: 1 }, { id: 2 }] }); + + stub(dataSource.transport, "destroy"); + + dataSource.remove(dataSource.get(1)); + dataSource.remove(dataSource.get(2)); + dataSource.sync(); + + equal(dataSource.transport.calls("destroy"), 1); +}); + +test("sync passes array of destroyed models to transport when batch is true", function() { + setup({ batch: true, data: [ { id: 1 }, { id: 2 }] }); + + stub(dataSource.transport, "destroy"); + + dataSource.remove(dataSource.get(1)); + dataSource.remove(dataSource.get(2)); + dataSource.sync(); + + + var models = dataSource.transport.args("destroy")[0].data.models; + ok($.isArray(models)); + equal(models.length, 2); + equal(models[0].id, 1); + equal(models[1].id, 2); +}); + +test("sync does not send the uid of destroyed models when batch is true", function() { + setup({ batch: true }); + + stub(dataSource.transport, "destroy"); + + dataSource.remove(dataSource.get(1)); + dataSource.sync(); + + var models = dataSource.transport.args("destroy")[0].data.models; + + equal(models[0].uid, undefined); +}); + +test("the updated data records are send to the if server grouping is enabled", function() { + var dataSource = new DataSource({ + schema: { + model: { id: "id" }, + groups: function(data) { + return [{ + items: [{ foo: 1, id: 0}], + field: "foo", + value: "bar" + }]; + }, + total: function() { + return 1; + } + }, + batch: true, + serverGrouping: true, + group: { field: "foo" } + }); + + stub(dataSource.transport, "update"); + dataSource.read(); + + dataSource.get(0).set("foo", 2); + dataSource.sync(); + + var models = dataSource.transport.args("update")[0].data.models; + equal(models[0].foo, 2); +}); + +test("the created data records are send to the if server grouping is enabled", function() { + var dataSource = new DataSource({ + schema: { + model: { id: "id" }, + groups: function(data) { + return [{ + items: [{ foo: 1, id: 0}], + field: "foo", + value: "bar" + }]; + }, + total: function() { + return 1; + } + }, + batch: true, + serverGrouping: true, + group: { field: "foo" } + }); + + stub(dataSource.transport, "create"); + dataSource.read(); + + dataSource.add({ foo: 1 }); + dataSource.sync(); + + var models = dataSource.transport.args("create")[0].data.models; + equal(models[0].foo, 1); + equal(models.length, 1); +}); + +test("the destroyed data records are send to the if server grouping is enabled", function() { + var dataSource = new DataSource({ + schema: { + model: { id: "id" }, + groups: function(data) { + return [{ + items: [{ foo: 1, id: 0}], + field: "foo", + value: "bar" + }]; + }, + total: function() { + return 1; + } + }, + batch: true, + serverGrouping: true, + group: { field: "foo" } + }); + + stub(dataSource.transport, "destroy"); + dataSource.read(); + + dataSource.remove(dataSource.get(0)); + dataSource.sync(); + + var models = dataSource.transport.args("destroy")[0].data.models; + equal(models[0].foo, 1); + equal(models.length, 1); +}); + +test("hasChanges returns true if model is updated", function() { + var dataSource = new DataSource({ + schema: { + model: { id: "id" } + }, + data: [{ id: 0, foo: "bar"}] + }); + + dataSource.read(); + + dataSource.get(0).set("foo", "baz"); + + ok(dataSource.hasChanges()); +}); + +test("hasChanges returns false if no changes are made", function() { + var dataSource = new DataSource({ + schema: { + model: { id: "id" } + }, + data: [{ id: 0, foo: "bar"}] + }); + + dataSource.read(); + + ok(!dataSource.hasChanges()); +}); + +test("hasChanges returns true if new model is added", function() { + var dataSource = new DataSource({ + schema: { + model: { id: "id" } + }, + data: [{ id: 0, foo: "bar"}] + }); + + dataSource.read(); + + dataSource.add({}); + + ok(dataSource.hasChanges()); +}); + +test("hasChanges returns true if record is deleted", function() { + var dataSource = new DataSource({ + schema: { + model: { id: "id" } + }, + data: [{ id: 0, foo: "bar"}] + }); + + dataSource.read(); + + dataSource.remove(dataSource.get(0)); + + ok(dataSource.hasChanges()); +}); + +test("requestStart is called for each sync request", 3, function() { + var dataSource = new DataSource({ + schema: { + model: { id: "id" } + }, + data: [{ id: 1, foo: "bar"},{ id: 2, foo: "baz"}] + }); + + dataSource.read(); + + dataSource.bind("requestStart", function() { + ok(true); + }); + + dataSource.add(); + + dataSource.remove(dataSource.get(1)); + + dataSource.get(2).set("foo", "moo"); + + dataSource.sync(); +}); + +test("requestStart contains request type for create request", function() { + var dataSource = new DataSource({ + schema: { + model: { id: "id" } + }, + data: [{ id: 1, foo: "bar"},{ id: 2, foo: "baz"}] + }); + + dataSource.read(); + + dataSource.bind("requestStart", function(e) { + equal(e.type, "create"); + }); + + dataSource.add(); + + dataSource.sync(); +}); + +test("requestStart contains request type for read request", function() { + var dataSource = new DataSource({ + schema: { + model: { id: "id" } + }, + data: [{ id: 1, foo: "bar"},{ id: 2, foo: "baz"}] + }); + + dataSource.bind("requestStart", function(e) { + equal(e.type, "read"); + }); + + dataSource.read(); +}); + +test("requestStart contains request type for update request", function() { + var dataSource = new DataSource({ + schema: { + model: { id: "id" } + }, + data: [{ id: 1, foo: "bar"},{ id: 2, foo: "baz"}] + }); + + dataSource.read(); + + dataSource.bind("requestStart", function(e) { + equal(e.type, "update"); + }); + + dataSource.get(2).set("foo", "moo"); + + dataSource.sync(); +}); + +test("requestStart contains request type for destroy request", function() { + var dataSource = new DataSource({ + schema: { + model: { id: "id" } + }, + data: [{ id: 1, foo: "bar"},{ id: 2, foo: "baz"}] + }); + + dataSource.read(); + + dataSource.bind("requestStart", function(e) { + equal(e.type, "destroy"); + }); + + dataSource.remove(dataSource.get(1)); + + dataSource.sync(); +}); + +}()); diff --git a/tests/data/hierarchy.js b/tests/data/hierarchy.js new file mode 100644 index 00000000000..06561e793e3 --- /dev/null +++ b/tests/data/hierarchy.js @@ -0,0 +1,1158 @@ +(function(){ +var Node = kendo.data.Node; +var HierarchicalDataSource = kendo.data.HierarchicalDataSource; + +function categories() { + return new HierarchicalDataSource({ + schema: { + model: { + children: { + schema: { + data: "products" + } + } + } + }, + data: [ { + categoryName: "Category 1", + products: [ + { productName: "Product 1" } + ] + }] + }); +} + +module("HierarchicalDataSource", { + setup: function() { + $.mockjaxSettings.responseTime = 0; + $.mockjaxSettings.contentType = "text/html"; + }, + teardown: function() { + $.mockjaxClear(); + } +}); + +test("Node inherits from Model", function() { + var node = new Node({}); + + ok(node instanceof kendo.data.Model); +}); + +test("HierarchicalDataSource contains objects of Node type", function() { + var dataSource = new HierarchicalDataSource( { + data: [{}] + }); + + dataSource.read(); + + ok(dataSource.data()[0] instanceof Node); +}); + +test("the children field of a node is a HierarchicalDataSource", function() { + var dataSource = new HierarchicalDataSource( { + data: [{ hasChildren: true }] + }); + + dataSource.read(); + + var root = dataSource.data()[0]; + + ok(root.children instanceof HierarchicalDataSource); +}); + +test("heterogeneous data source from local data", function() { + var dataSource = categories(); + + dataSource.read(); + dataSource.data()[0].children.read(); + + equal(dataSource.data()[0].children.data()[0].productName, "Product 1"); +}); + +test("changes of the children are propagated to the parent data source", 1, function() { + var dataSource = categories(); + + dataSource.read(); + + var parent = dataSource.data()[0]; + parent.children.read(); + dataSource.bind("change", function() { + ok(true, "Change was raised"); + }); + + parent.children.add({ productName: "Product 2" }); +}); + +test("the event argument contains the node whose data source changed",1, function() { + var dataSource = categories(); + + dataSource.read(); + + var parent = dataSource.data()[0]; + parent.children.read(); + dataSource.bind("change", function(e) { + strictEqual(e.node, parent); + }); + + parent.children.add({ productName: "Product 2" }); +}); + +test("the event argument contains the closest node",1, function() { + var dataSource = categories(); + + dataSource.read(); + + var parent = dataSource.data()[0]; + parent.children.read(); + + var child = parent.children.data()[0]; + + dataSource.bind("change", function(e) { + strictEqual(e.node, child); + }); + + child.append({ productName: "Product 2" }); +}); + +test("the event argument contains the index",1, function() { + var dataSource = categories(); + + dataSource.read(); + + var parent = dataSource.data()[0]; + parent.children.read(); + + var child = parent.children.data()[0]; + + dataSource.bind("change", function(e) { + strictEqual(e.index, 0); + }); + + child.append({ productName: "Product 2" }); +}); + +test("adding a child node triggers the change event of the data source", 2, function() { + var dataSource = categories(); + + dataSource.read(); + + var parent = dataSource.data()[0]; + + parent.children.read(); + + dataSource.bind("change", function(e) { + equal(e.items[0].productName, "added"); + equal(e.action, "add"); + }); + + parent.children.add({ productName: "added" }); +}); + +test("removing a child node triggers the change event of the data source", 2, function() { + var dataSource = categories(); + + dataSource.read(); + + var parent = dataSource.data()[0]; + + parent.children.read(); + + var child = parent.children.data()[0]; + + dataSource.bind("change", function(e) { + strictEqual(e.items[0], child); + equal(e.action, "remove"); + }); + + parent.children.remove(child); +}); + +test("reading a the children raises the change event", 1, function() { + var dataSource = categories(); + + dataSource.read(); + + var parent = dataSource.data()[0]; + + dataSource.bind("change", function(e) { + strictEqual(e.items[0], parent.children.data()[0]); + }); + + parent.children.read(); +}); + +asyncTest("error event bubbles from child datasources", function() { + $.mockjax({ url: "bar", dataType: "json", data: { id: 1 }, status: 500, responseText: 'Server response' }); + $.mockjax({ url: "bar", dataType: "json", responseText: [{ id: 1, hasChildren: true, text: "foo" }] }); + + var dataSource = HierarchicalDataSource.create({ + transport: { + read: { + url: "bar", + dataType: "json" + } + } + }); + + dataSource.bind({ + change: function() { + dataSource.data()[0].load(); + }, + + error: function(e) { + start(); + ok(e); + ok(e.xhr); + ok(e.status); + ok(e.node); + ok("errorThrown" in e); + } + }); + + dataSource.read(); +}); + +test("error event bubbles after setting the data through data()", 1, function() { + var dataSource = HierarchicalDataSource.create({}); + + dataSource.bind("error", function() { + ok(true); + }); + + dataSource.data([{ id: 1, text: "foo", hasChildren: true }]); + + dataSource.data().trigger("error"); +}); + +test("subnodes can be loaded after erroring out", function() { + var calls = 0; + var dataSource = HierarchicalDataSource.create({ + transport: { + read: function(options) { + if (!options.data.id) { + options.success([ + { id: 1, hasChildren: true, text: "foo" } + ]); + } else { + calls++; + + if (calls == 1) { + options.error({}); + } else { + options.success([{ id: 2, text: "bar" }]); + } + } + } + }, + schema: { + model: { + id: "id", + hasChildren: "hasChildren" + } + } + }); + + dataSource.read(); + + var foo = dataSource.data()[0]; + + foo.load(); // errors out + + foo.loaded(false); + foo.load(); + equal(foo.children.data().length, 1); +}); + +test("load fetches data from the children data source", function() { + var dataSource = categories(); + + dataSource.read(); + + var parent = dataSource.data()[0]; + + parent.load(); + + equal(parent.children.data().length, 1); +}); + +test("load data from remote data source", 1, function() { + var dataSource = new HierarchicalDataSource({ + transport: { + read: function(options) { + ok(true, "The read method of the transport is called"); + } + } + }); + + dataSource.fetch(); +}); + +test("the parent id is passed when reading children from remote service", 1, function() { + var dataSource = new HierarchicalDataSource({ + transport: { + read: function(options) { + options.success([ { hasChildren: true, categoryId: 1 }]) + } + }, + schema: { + model: { + id: "categoryId", + children: { + transport: { + read: function(options) { + equal(options.data.categoryId, 1); + } + } + } + } + } + }); + + dataSource.fetch(); + + dataSource.data()[0].load(); +}); + +test("getByUid is recursive", function() { + var dataSource = categories(); + + dataSource.fetch(); + dataSource.data()[0].load(); + + var product = dataSource.data()[0].children.data()[0]; + + strictEqual(dataSource.getByUid(product.uid), product); +}); + +test("hasChildren returns the value of the specified field", function() { + var dataSource = new HierarchicalDataSource({ + transport: { + read: function(options) { + options.success([ + { id: 1, isParent: true }, + { id: 2, isParent: false } + ]) + } + }, + schema: { + model: { + hasChildren: "isParent" + } + } + }); + + dataSource.fetch(); + + equal(dataSource.view()[0].hasChildren, true) + equal(dataSource.view()[1].hasChildren, false) +}); + +test("hasChildren returns the false if the specified field is undefined", function() { + var dataSource = new HierarchicalDataSource({ + transport: { + read: function(options) { + options.success([ + { id: 1 } + ]) + } + }, + schema: { + model: { + hasChildren: "isParent" + } + } + }); + + dataSource.fetch(); + + equal(dataSource.view()[0].hasChildren, false) +}); + +test("hasChildren returns false by default", function() { + var dataSource = new HierarchicalDataSource({ + transport: { + read: function(options) { + options.success([ + { id: 1 }, + { id: 2 } + ]) + } + } + }); + + dataSource.fetch(); + equal(dataSource.data()[0].hasChildren, false); +}); + +test("hasChildren as function", 1, function() { + var dataSource = new HierarchicalDataSource({ + transport: { + read: function(options) { + options.success([ + { id: 1 } + ]) + } + }, + schema: { + model: { + hasChildren: function() { + ok(true); + } + } + } + }); + + dataSource.fetch(); +}); + +test("hasChildren set as true", 1, function() { + var dataSource = new HierarchicalDataSource({ + transport: { + read: function(options) { + options.success([ + { id: 1 } + ]) + } + }, + schema: { + model: { + hasChildren: true + } + } + }); + + dataSource.fetch(); + equal(dataSource.data()[0].hasChildren, true); +}); + +test("hasChildren set as false", 1, function() { + var dataSource = new HierarchicalDataSource({ + transport: { + read: function(options) { + options.success([ + { id: 1 } + ]) + } + }, + schema: { + model: { + hasChildren: false + } + } + }); + + dataSource.fetch(); + equal(dataSource.data()[0].hasChildren, false); +}); + +test("the this context in hasChildren is the node itself", 1, function() { + var that; + + var dataSource = new HierarchicalDataSource({ + transport: { + read: function(options) { + options.success([ + { id: 1 } + ]) + } + }, + schema: { + model: { + hasChildren: function() { + that = this; + } + } + } + }); + + dataSource.fetch(); + + strictEqual(dataSource.data()[0], that); +}); + +test("children as string and inline data source", function() { + var dataSource = new kendo.data.HierarchicalDataSource({ + data: [{ + text: "Root 1", + products: [ { text: "Child 1.1" } ] + }], + schema: { + model: { + children: "products" + } + } + }); + + dataSource.fetch(); + + dataSource.data()[0].load(); + equal(dataSource.data()[0].children.data()[0].text, "Child 1.1"); +}); + +test("hasChildren and inline defined data source", function() { + var dataSource = categories(); + + dataSource.fetch(); + + dataSource.data()[0].load(); + + equal(dataSource.data()[0].hasChildren, true); + equal(dataSource.data()[0].children.data()[0].hasChildren, false); +}); + +test("the default children field name is 'items'", function() { + var dataSource = new HierarchicalDataSource({ + data: [ { + text: "foo", + items: [ + { text : "bar" } + ] + } ] + }); + + dataSource.fetch(); + + dataSource.data()[0].load(); + + equal(dataSource.data()[0].hasChildren, true); + equal(dataSource.data()[0].children.data()[0].text, "bar"); +}); + +test("hasChildren propagates to child data sources", function() { + var readData = function(options) { + options.success([ + { isParent: true } + ]) + }, + dataSource = new HierarchicalDataSource({ + transport: { + read: readData + }, + schema: { + model: { + hasChildren: "isParent", + children: { + transport: { + read: readData + } + } + } + } + }); + + dataSource.fetch(); + dataSource.data()[0].load(); + + ok(dataSource.data()[0].children.data()[0].hasChildren === true); +}); + +test("loaded returns false for nodes whose children are not loaded", function() { + var dataSource = categories(); + + dataSource.fetch(); + ok(!dataSource.data()[0].loaded()); +}); + +test("loaded returns true for nodes whose children are loaded", function() { + var dataSource = categories(); + + dataSource.fetch(); + dataSource.data()[0].load() + + ok(dataSource.data()[0].loaded()); +}); + +test("setting loaded to false after a node is loaded returns false", function() { + var dataSource = categories(); + + dataSource.fetch(); + dataSource.data()[0].load() + dataSource.data()[0].loaded(false) + + ok(!dataSource.data()[0].loaded()); +}); + +test("load calls the read method of the transport after setting loaded to false", 2, function() { + var dataSource = new HierarchicalDataSource({ + transport: { + read: function(options) { + options.success([ { hasChildren: true, categoryId: 1 }]) + } + }, + schema: { + model: { + children: { + transport: { + read: function(options) { + options.success([]); + ok(true, "Read is called"); + } + } + } + } + } + }); + + dataSource.fetch(); + + dataSource.data()[0].load(); + dataSource.data()[0].loaded(false); + dataSource.data()[0].load(); +}); + +test("load calls the read method of the transport after setting loaded to false and items have been destroyed", function() { + var dataSource = new HierarchicalDataSource({ + data: [ + { hasChildren: true, id: 1 } + ], + schema: { + model: { + children: { + transport: { + read: function(options) { + options.success([ { id: 2 }, { id: 3 } ]); + } + } + } + } + } + }); + + dataSource.fetch(); + + var root = dataSource.data()[0]; + root.load(); + dataSource.remove(dataSource.get(2)); + root.loaded(false); + root.load(); + equal(root.children.data().length, 2); +}); + +test("parentNode returns the parent of a child node", function() { + var dataSource = categories(); + + dataSource.read(); + var parent = dataSource.data()[0]; + parent.load(); + var child = parent.children.data()[0]; + + strictEqual(child.parentNode(), parent); +}); + +test("remove is recursive", function() { + var dataSource = categories(); + + dataSource.read(); + var parent = dataSource.data()[0]; + parent.load(); + var child = parent.children.data()[0]; + + dataSource.remove(child); + + ok(!dataSource.getByUid(child.uid)); +}); + +test("level returns the node level", function() { + var dataSource = categories(); + + dataSource.read(); + var parent = dataSource.data()[0]; + parent.load(); + + var child = parent.children.data()[0]; + + equal(parent.level(), 0); + equal(child.level(), 1); +}); + +test("removing and adding the same model does not add multiple change events", function() { + var counter = 0; + + var dataSource = categories(); + + dataSource.read(); + + var category = dataSource.data()[0]; + dataSource.bind("change", function() { + counter++; + }); + + dataSource.remove(category); + dataSource.add(category); + + category.set("categoryName", "foo"); + + equal(counter, 3); +}); + +test("removing and adding the same model persists child dataSource", function() { + var dataSource = new HierarchicalDataSource({ + data: [ + { id: 1 } + ] + }); + + dataSource.read(); + + var item = dataSource.get(1); + + item.append({ id: 2 }); + + dataSource.remove(item); + + dataSource.add(item); + + equal(item.children.data().length, 1); +}); + +test("adding items to child dataSource modifies hasChildren state", function() { + var dataSource = new HierarchicalDataSource({ + data: [ + { id: 1 } + ] + }); + + dataSource.read(); + + var item = dataSource.get(1); + + item.append({ id: 2 }); + + ok(item.hasChildren); +}); + +test("removing items from child dataSource modifies hasChildren state", function() { + var dataSource = new HierarchicalDataSource({ + data: [ + { id: 1, items: [ + { id: 2 } + ] } + ] + }); + + dataSource.read(); + + var root = dataSource.get(1); + + root.children.read(); + + dataSource.remove(root.children.get(2)); + + ok(!root.hasChildren); +}); + +test("infer from list", function() { + var list = $("
  • foo
  • bar
"), + dataSource = HierarchicalDataSource.create({ + list: list, + fields: [ { field: "text" } ] + }); + + ok(dataSource instanceof HierarchicalDataSource); + + dataSource.read(); + + var data = dataSource.data(); + + equal(data.length, 2); + equal(data[0].text, "foo"); + equal(data[1].text, "bar"); +}); + +test("infer from nested list", function() { + var list = $("
  • foo
    • bar
"), + dataSource = HierarchicalDataSource.create({ + list: list, + fields: [ { field: "text" } ] + }); + + dataSource.read(); + + var data = dataSource.data(); + + equal(data.length, 1); + equal(data[0].text, "foo"); + ok(data[0].loaded(), "inferred nodes are considered as loaded"); + + data[0].children.read(); + var children = data[0].children.data(); + + equal(children.length, 1); + equal(children[0].text, "bar"); + ok(children[0].loaded(), "inferred child nodes are considered as loaded"); +}); + +test("infer from nested list with text wrapper elements", function() { + var list = $("
  • foo
    • bar
"), + dataSource = HierarchicalDataSource.create({ + list: list, + fields: [ { field: "text" } ] + }); + + dataSource.read(); + + var data = dataSource.data(); + + equal(data.length, 1); + equal(data[0].text, "foo"); + + data[0].children.read(); + var children = data[0].children.data(); + + equal(children.length, 1); + equal(children[0].text, "bar"); +}); + +test("infer of id field", function() { + var list = $("
  • " + + "
    foo
    "+ + "
"), + dataSource = HierarchicalDataSource.create({ + list: list, + fields: [ { field: "text" } ] + }); + + dataSource.read(); + + var data = dataSource.data(); + + equal(data.length, 1); + equal(data[0].id, "42"); +}); + +test("infer of nested url / spriteCssClass / imageUrl fields", function() { + var list = $(""), + dataSource = HierarchicalDataSource.create({ + list: list, + fields: [ + { field: "text" }, + { field: "url" }, + { field: "spriteCssClass" }, + { field: "imageUrl" } + ] + }); + + dataSource.read(); + + var data = dataSource.data(); + + equal(data.length, 1); + + equal(data[0].id, "7"); + equal(data[0].text, "foo"); + equal(data[0].url, "http://kendoui.com/"); + equal(data[0].spriteCssClass, "spriteClass"); + equal(data[0].imageUrl, "image.png"); +}); + +test("infer of plain url fields", function() { + var list = $(""), + dataSource = HierarchicalDataSource.create({ + list: list, + fields: [ + { field: "text" }, + { field: "url" }, + { field: "spriteCssClass" }, + { field: "imageUrl" } + ] + }); + + dataSource.read(); + + var data = dataSource.data(); + + equal(data.length, 1); + + equal(data[0].text, "foo"); + equal(data[0].url, "http://kendoui.com/"); + equal(data[0].spriteCssClass, "spriteClass"); +}); + +test("infer with custom fields", function() { + var list = $("
  • foo
"), + dataSource = HierarchicalDataSource.create({ + list: list, + fields: [ { field: "productName" } ] + }); + + dataSource.read(); + + var data = dataSource.data(); + + equal(data.length, 1); + equal(data[0].productName, "foo"); +}); + +test("infer of hasChildren property", function() { + var list = $("
  • foo
"), + dataSource = HierarchicalDataSource.create({ + list: list, + fields: [ { field: "text" } ] + }); + + dataSource.read(); + + var data = dataSource.data(); + + equal(data.length, 1); + equal(data[0].hasChildren, true); +}); + +test("loading items without children does not repopulate their datasource", function() { + var dataSource = new HierarchicalDataSource({ + data: [ + { text: "foo", items: [ + { text: "bar" } + ] } + ] + }); + + dataSource.read(); + + var children = dataSource.view()[0].children; + children.read(); + dataSource.remove(children.view()[0]); + + dataSource.view()[0].load(); + + equal(dataSource.view()[0].children.view().length, 0); +}); + +test("added observable objects can be loaded", function() { + var dataSource = new HierarchicalDataSource({}); + + var model = kendo.observable({ text: "bar", hasChildren: true }); + + ok(model = dataSource.add(model)); + + model.load(); + + ok(true); +}); + +test("get method works with subitems", function() { + var dataSource = new HierarchicalDataSource({ + data: [ + { id: 1, text: "foo", items: [ + { id: 2, text: "bar" } + ] } + ] + }); + + dataSource.read(); + + var children = dataSource.data()[0].children; + children.read(); + + ok(dataSource.get(2)) + equal(dataSource.get(2).text, children.data()[0].text); +}); + +test("get method works for subitems and custom id field", function() { + var dataSource = new HierarchicalDataSource({ + data: [ + { foo: 1, text: "foo", items: [ + { foo: 2, text: "bar" }, + { foo: 3, text: "baz" } + ] } + ], + schema: { + model: { + id: "foo", + children: "items" + } + } + }); + + dataSource.read(); + + dataSource.data()[0].load(); + + ok(dataSource.get(2)) + equal(dataSource.get(2).text, "bar"); +}); + +test("sorting is used when loading child datasources", function() { + var dataSource = new HierarchicalDataSource({ + data: [ + { foo: 1, text: "foo", items: [ + { foo: 3, text: "alpha" }, + { foo: 2, text: "ghamma" }, + { foo: 2, text: "alpha" }, + { foo: 2, text: "beta" } + ] } + ], + sort: [ + { field: "foo", dir: "asc" }, + { field: "text", dir: "asc" } + ] + }); + + dataSource.read(); + + var root = dataSource.data()[0]; + + root.load(); + + var data = root.children.view(); + + equal(data[0].text, "alpha"); + equal(data[1].text, "beta"); + equal(data[2].text, "ghamma"); + equal(data[3].text, "alpha"); +}); + +test("loading of child datasources updates items field of parent", function() { + var i = 0, + dataSource = new HierarchicalDataSource({ + transport: { + read: function(options) { + options.success([ + { hasChildren: true, foo: i++ } + ]); + } + } + }); + + dataSource.read(); + + var root = dataSource.data()[0]; + root.load(); + + ok("items" in root); + equal(root.items, root.children.data()); +}); + +module("HierarchicalDataSource : parameterMap", { + setup: function() { + $.mockjaxSettings.responseTime = 0; + }, + teardown: function() { + $.mockjaxClear(); + } +}); + +function addFoo(data) { + data.foo = "bar"; + return data; +} + +asyncTest("parameterMap gets called when fetching root nodes", function() { + $.mockjax({ + url: "bar", dataType: "json", + response: function(e) { + start(); + equal(e.data.foo, "bar"); + } + }); + + var dataSource = new HierarchicalDataSource({ + transport: { + read: { url: "bar", dataType: "json" }, + parameterMap: addFoo + } + }); + + dataSource.read(); +}); + +asyncTest("parameterMap gets called when fetching child nodes", function() { + $.mockjax({ + url: "bar", dataType: "json", data: { id: 1 }, + response: function(e) { + start(); + equal(e.data.foo, "bar"); + } + }); + + $.mockjax({ + url: "bar", dataType: "json", + responseText: [{ id: 1, hasChildren: true, text: "foo" }] + }); + + var dataSource = new HierarchicalDataSource({ + transport: { + read: { url: "bar", dataType: "json" }, + parameterMap: addFoo + } + }); + + dataSource.one("change", function() { + this.data()[0].load(); + }); + + dataSource.read(); +}); + +asyncTest("child parameterMap gets called when fetching child nodes", function() { + $.mockjax({ + url: "bar", dataType: "json", data: { id: 1 }, + response: function(e) { + start(); + equal(e.data.foo, "bar"); + } + }); + + $.mockjax({ + url: "bar", dataType: "json", + responseText: [{ id: 1, hasChildren: true, text: "foo" }] + }); + + var bar = { url: "bar", dataType: "json" }; + + var dataSource = new HierarchicalDataSource({ + transport: { read: bar }, + schema: { + model: { + id: "id", + hasChildren: "hasChildren", + children: { + transport: { read: bar, parameterMap: addFoo } + } + } + } + }); + + dataSource.one("change", function() { + this.data()[0].load(); + }); + + dataSource.read(); +}); + +/* +test("child datasources inherit model", function() { + var CustomModel = kendo.data.Node.define({ + foo: function() { + return this.id; + } + }); + + var dataSource = new HierarchicalDataSource({ + data: [ + { id: 1, items: [ + { id: 2 } + ] } + ], + schema: { + model: CustomModel + } + }); + + dataSource.read(); + dataSource.at(0).load(); + + ok($.isFunction(dataSource.at(0).children.at(0).foo)); + equal(dataSource.at(0).children.at(0).foo(), 2); +}); +*/ +}()); diff --git a/tests/data/inmemorycache.js b/tests/data/inmemorycache.js new file mode 100644 index 00000000000..acd74b3e24b --- /dev/null +++ b/tests/data/inmemorycache.js @@ -0,0 +1,79 @@ +(function(){ + +var Cache = kendo.data.Cache, + cache; + +Cache.prototype.length = function() { + var count = 0; + for(key in this._store) { + count++; + } + return count; +} + +module("InMemoryCache", { + setup: function() { + cache = new Cache() + } +}); + +test("find item with given key", function() { + var item = { bar: "baz" }; + cache.add("foo", item); + equal(cache.find("foo").bar, "baz"); +}); + +test("add item with given key", function() { + var item = { bar: "baz" }; + + cache.add("foo", item); + equal(cache.find("foo").bar, "baz"); +}); + +test("clear removes all items", function() { + var item = { bar: "baz" }; + cache.add("foo", item); + cache.add("bar", item); + cache.clear(); + equal(cache.length(), 0); +}); + +test("add overrides previous item with same key", function() { + cache.add("foo", { foo: "bar" }); + cache.add("foo", { moo: "baz" }); + + equal(cache.length(), 1); + equal(cache.find("foo").moo, "baz"); +}); + +test("find return undefined if item does not exists", function() { + equal(cache.find("nonExisiting"), undefined); +}); + +test("add does not add item if key is undefined", function() { + cache.add(); + equal(cache.length(), 0); +}); + +test("remove item with given key", function() { + cache.add("foo", { foo: 1}); + cache.remove("foo"); + equal(cache.find("foo"), undefined); +}); + +test("length returns number of the items in the cache", function() { + cache.add("foo", { foo: 1}); + cache.add("bar", { foo: 1}); + cache.add("baz", { foo: 1}); + cache.add("moo", { foo: 1}); + equal(cache.length(), 4); +}); + +test("add key can be object", function() { + cache.add({ foo: 1}, 1); + cache.add({ foo: 2}, 2); + equal(cache.find({ foo: 1 }), 1); + equal(cache.find({ foo: 2 }), 2); +}); + +}()); diff --git a/tests/data/odata.js b/tests/data/odata.js new file mode 100644 index 00000000000..9ea7cce1492 --- /dev/null +++ b/tests/data/odata.js @@ -0,0 +1,362 @@ +(function(){ + +var parameterMap = kendo.data.transports["odata"].parameterMap; +var DataSource = kendo.data.DataSource; + +test("datasource with type odata creates remote transport with parameterMap", function() { + var dataSource = new DataSource({ + type: "odata", + transport: { + read: "foo" + } + }); + + ok(dataSource.transport.parameterMap === parameterMap); +}); + +test("datasource with type odata creates remote transport and sets default values for read", function() { + var dataSource = new DataSource({ + type: "odata", + transport: { + read: "foo" + } + }); + + var read = dataSource.transport.options.read; + equal(read.dataType, "jsonp"); + equal(read.cache, true); + equal(read.jsonp, "$callback"); +}); + +test("datasource with type odata creates remote transport and sets default values for update", function() { + var dataSource = new DataSource({ + type: "odata", + transport: { + update: { + url: "foo" + } + } + }); + + var update = dataSource.transport.options.update; + equal(update.url, "foo"); + equal(update.dataType, "json"); + equal(update.cache, true); + equal(update.contentType, "application/json"); + equal(update.type, "PUT"); +}); + +test("datasource with type odata creates remote transport and sets default values for create", function() { + var dataSource = new DataSource({ + type: "odata", + transport: { + create: { + url: "foo" + } + } + }); + + var create = dataSource.transport.options.create; + equal(create.url, "foo"); + equal(create.dataType, "json"); + equal(create.cache, true); + equal(create.contentType, "application/json"); + equal(create.type, "POST"); +}); + +test("datasource with type odata creates remote transport and sets default values for destroy", function() { + var dataSource = new DataSource({ + type: "odata", + transport: { + destroy: { + url: "foo" + } + } + }); + + var destroy = dataSource.transport.options.destroy; + equal(destroy.url, "foo"); + equal(destroy.dataType, "json"); + equal(destroy.cache, true); + equal(destroy.type, "DELETE"); +}); + +test("datasource with type odata initializes odata schema", function() { + var dataSource = new DataSource({ + type: "odata", + transport: { + read: "foo" + } + }); + + var schema = dataSource.options.schema; + equal(schema.total, "d.__count"); + ok($.isFunction(schema.data)); +}); + +test("parameterMap adds $format and $inlinecount to the request", function() { + var result = parameterMap(); + equal(result.$format, "json"); + equal(result.$inlinecount, "allpages"); +}); + +test("$format is not set if dataType is json", function() { + var dataSource = new DataSource({ + type: "odata", + transport: { + read: { + url: "foo", + dataType: "json" + } + } + }); + + var result = dataSource.transport.parameterMap(); + ok(!result.$format); +}); + +test("parameterMap adds $skip when skip is specified", function() { + var result = parameterMap({ skip: 1 }); + equal(result.$skip, 1); +}); + +test("parameterMap does not add $skip when skip is not specified", function() { + var result = parameterMap(); + ok(!result.hasOwnProperty("$skip"), "Skip is not set"); +}); + +test("parameterMap adds $top when take is specified", function() { + var result = parameterMap({take: 1}); + equal(result.$top, 1); +}); + +test("parameterMap does not add $top when take is not specified", function() { + var result = parameterMap(); + ok(!result.hasOwnProperty("$top"), "Top is not set"); +}); + +test("parameterMap adds $orderby when sort is specified", function() { + var result = parameterMap({ sort: [ { field:"foo", dir: "asc" } ]}); + equal(result.$orderby, "foo"); +}); + +test("$orderby with nested field", function() { + var result = parameterMap({ sort: [ { field:"foo.bar", dir: "asc" } ]}); + equal(result.$orderby, "foo/bar"); +}); + +test("parameterMap does not add $orderby if sort is not specified", function() { + var result = parameterMap(); + ok(!result.hasOwnProperty("$orderby"), "orderby is not set"); +}); + +test("parameterMap does not add $orderby if sort is empty list", function() { + var result = parameterMap({ sort: [] }); + ok(!result.hasOwnProperty("$orderby"), "orderby is not set"); +}); + +test("$orderby when direction is descending", function() { + var result = parameterMap({ sort: [ { field:"foo", dir: "desc" } ]}); + equal(result.$orderby, "foo desc"); +}); + +test("$orderby when there are multiple order by expressions", function() { + var result = parameterMap({ sort: [ { field:"bar", dir: "desc" }, { field:"foo", dir: "asc" } ]}); + + equal(result.$orderby, "bar desc,foo"); +}); + +test("parametterMap does not add $filter if no filters is applied", function() { + var result = parameterMap({ filter: null }); + equal(typeof result.filter, "undefined"); +}); + +test("parameterMap adds $filter if filter is specified", function() { + var result = parameterMap({ filter: { filters:[ {field: "Name", operator: "startswith", value: "bar"} ]} }); + equal(result.$filter, "startswith(Name,'bar')"); +}); + +test("parameterMap adds tolower(field) if ignoreCase is true", function() { + var result = parameterMap({ filter: { filters:[ {field: "Name", operator: "startswith", value: "bar", ignoreCase: true} ]} }); + equal(result.$filter, "startswith(tolower(Name),'bar')"); +}); + +test("parameterMap does not add $filter if filter is not specified", function() { + var result = parameterMap(); + ok(!result.hasOwnProperty("$filter"), "Filter is not present"); +}); + +test("$filter and endswith operator", function() { + var result = parameterMap({ filter: {filters:[ {field: "Name", operator: "endswith", value: "bar"} ]}}); + equal(result.$filter, "endswith(Name,'bar')"); +}); + +test("$filter on string that contains ' symbol", function() { + var result = parameterMap({ filter: {filters:[ {field: "Name", operator: "contains", value: "bar'foo"} ]}}); + equal(result.$filter, "substringof('bar''foo',Name)"); +}); + +test("$filter and contains operator uses substringof", function() { + var result = parameterMap({ filter: { filters: [ {field: "Name", operator: "contains", value: "bar"} ]}}); + ok(result.$filter, "substringof('bar',Name)"); +}); + +test("$filter and doesnotcontain operator uses substringof", function() { + var result = parameterMap({ filter: { filters: [ {field: "Name", operator: "doesnotcontain", value: "bar"} ]}}); + equal(result.$filter, "substringof('bar',Name) eq false"); +}); + +test("$filter and neq operator", function() { + var result = parameterMap({ filter: { filters: [ {field: "Name", operator: "neq", value: "bar"} ]} }); + + equal(result.$filter, "Name ne 'bar'"); +}); + +test("$filter with nested field", function() { + var result = parameterMap({ filter: { filters: [ {field: "foo.bar", operator: "neq", value: "bar"} ]} }); + + equal(result.$filter, "foo/bar ne 'bar'"); +}); + +test("$filter does not quote apostrophe when numberic value is specifed", function() { + var result = parameterMap({ filter: { filters: [ {field: "ID", operator: "neq", value: 10} ]} }); + + equal(result.$filter, "ID ne 10"); +}); + +test("$filter does not honour ignoreCase if value is number", function() { + var result = parameterMap({ filter: { filters: [ {ignoreCase: true, field: "ID", operator: "neq", value: 10} ]} }); + + equal(result.$filter, "ID ne 10"); +}); + +test("$filter and null value", function() { + var result = parameterMap({ filter: { filters: [ {field: "ID", operator: "neq", value: null} ]} }); + + equal(result.$filter, "ID ne null"); +}); + +test("$filter or", function() { + var result = parameterMap({ filter: { logic: "or", filters: [ {field: "ID", operator: "neq", value: 1}, {field: "ID", operator: "eq", value: 1} ]} }); + + equal(result.$filter, "(ID ne 1 or ID eq 1)"); +}); + +test("$filter and", function() { + var result = parameterMap({ filter: { filters: [ {field: "ID", operator: "neq", value: null}, {field: "ID", operator: "neq", value: null} ]} }); + + equal(result.$filter, "(ID ne null and ID ne null)"); +}); + +test("$filter and nested expressions", function() { + var result = parameterMap({ + filter: { + logic:"and", + filters: [ { + logic: "or", + filters: [{ + field: "ID", + operator: "neq", + value: 1 + }, { + field: "ID", + operator: "neq", + value: 2 + }] + }, { + field: "ID", + operator:"eq", + value: 3 + } + ] + } + }); + + equal(result.$filter, "((ID ne 1 or ID ne 2) and ID eq 3)"); +}); + +test("$filter date encoding", function() { + var result = parameterMap({ filter: { filters: [ { field: "foo", operator: "eq", value: new Date(2011, 1, 1) }] } }); + + equal(result.$filter, "foo eq datetime'2011-02-01T00:00:00'"); +}); + +test("custom arguments are preserved", function() { + var result = parameterMap({ foo: "bar" }); + + equal(result.foo, "bar"); +}); + +test("model is stringified if type is update", function() { + var result = parameterMap({ foo: "bar" }, "update"); + + equal(result, kendo.stringify({ foo: "bar" })); +}); + +test("model is stringified if type is create", function() { + var result = parameterMap({ foo: "bar" }, "create"); + + equal(result, kendo.stringify({ foo: "bar" })); +}); + +test("does not proccess the arguments if type is destroy", function() { + var result = parameterMap({ foo: "bar" }, "destroy"); + + ok(!result); +}); + +test("number values is serialized as string", function() { + var result = parameterMap({ foo: 1 }, "update"); + + equal(result, '{"foo":"1"}'); +}); + +test("update with dataType set to jsonp throws an error", function() { + var dataSource = new DataSource({ + type: "odata", + transport: { + update: { + url: "foo", + dataType: "jsonp" + } + } + }); + + raises(function() { + dataSource.transport.parameterMap({ foo: 1 }, "update"); + }, "dataType for update should be json"); +}); + +test("create with dataType set to jsonp throws an error", function() { + var dataSource = new DataSource({ + type: "odata", + transport: { + create: { + url: "foo", + dataType: "jsonp" + } + } + }); + + raises(function() { + dataSource.transport.parameterMap({ foo: 1 }, "create"); + }, "dataType for create should be json"); +}); + +test("destroy with dataType set to jsonp throws an error", function() { + var dataSource = new DataSource({ + type: "odata", + transport: { + destroy: { + url: "foo", + dataType: "jsonp" + } + } + }); + + raises(function() { + dataSource.transport.parameterMap({ foo: 1 }, "destroy"); + }, "dataType for destroy should be json"); +}); + +}()); diff --git a/tests/data/query-expr.js b/tests/data/query-expr.js new file mode 100644 index 00000000000..523ee517770 --- /dev/null +++ b/tests/data/query-expr.js @@ -0,0 +1,527 @@ +(function(){ + +var Query = kendo.data.Query; + +function compile(expression) { + return Query.filterExpr(Query.normalizeFilter(expression)).expression; +} + +test("and with one filter", function() { + equal(compile({ + logic: "and", + filters: [ {value: 10, operator: "eq"}] + }), "(d == 10)"); +}); + +test("default operator is eq", function() { + equal(compile({ + logic: "and", + filters: [ {value: 10}] + }), "(d == 10)"); +}); + +test("undefined value", function() { + equal(compile({ + logic: "and", + filters: [ {value: undefined}] + }), "(d == undefined)"); +}); + +test("null value", function() { + equal(compile({ + logic: "and", + filters: [ {value: null}] + }), "(d == null)"); +}); + +test("or with one filter", function() { + equal(compile({ + logic: "or", + filters: [ {value: 10, operator: "eq"}] + }), "(d == 10)"); +}); + +test("and with two filters", function() { + equal(compile({ + logic: "and", + filters: [ { value: 10, operator: "eq" }, { value: 10, operator: "eq" }] + }), "(d == 10 && d == 10)"); +}); + +test("or with two filters", function() { + equal(compile({ + logic: "or", + filters: [ { value: 10, operator: "eq" }, { value: 10, operator: "eq" }] + }), "(d == 10 || d == 10)"); +}); + +test("or with nested filters", function() { + equal(compile({ + logic: "or", + filters: [ + { + logic: "and", + filters: [{ value: 10, operator: "eq" }, { value: 10, operator: "eq" }] + }, + { + logic: "or", + filters: [{ value: 10, operator: "eq" }, { value: 10, operator: "eq" }] + } + ] + }), "((d == 10 && d == 10) || (d == 10 || d == 10))"); +}); + +test("and with nested filters", function() { + equal(compile({ + logic: "and", + filters: [ + { + logic: "and", + filters: [{ value: 10, operator: "eq" }, { value: 10, operator: "eq" }] + }, + { + logic: "or", + filters: [{ value: 10, operator: "eq" }, { value: 10, operator: "eq" }] + } + ] + }), "((d == 10 && d == 10) && (d == 10 || d == 10))"); +}); + +test("uses field name", function() { + equal(compile({ + logic: "and", + filters: [ { field: "foo", value: 10, operator: "eq" } ] + }), "(d.foo == 10)"); +}); + +test("gt", function() { + equal(compile({ + logic: "and", + filters: [ { field: "foo", value: 10, operator: "gt" } ] + }), "(d.foo > 10)"); +}); + +test("gte", function() { + equal(compile({ + logic: "and", + filters: [ { field: "foo", value: 10, operator: "gte" } ] + }), "(d.foo >= 10)"); +}); + +test("lt", function() { + equal(compile({ + logic: "and", + filters: [ { field: "foo", value: 10, operator: "lt" } ] + }), "(d.foo < 10)"); +}); + +test("lte", function() { + equal(compile({ + logic: "and", + filters: [ { field: "foo", value: 10, operator: "lte" } ] + }), "(d.foo <= 10)"); +}); + +test("==", function() { + equal(compile({ + logic: "and", + filters: [ { field: "foo", value: 10, operator: "==" } ] + }), "(d.foo == 10)"); +}); + +test("equals", function() { + equal(compile({ + logic: "and", + filters: [ { field: "foo", value: 10, operator: "equals" } ] + }), "(d.foo == 10)"); +}); + +test("equal", function() { + equal(compile({ + logic: "and", + filters: [ { field: "foo", value: 10, operator: "equal" } ] + }), "(d.foo == 10)"); +}); + +test("isequalto", function() { + equal(compile({ + logic: "and", + filters: [ { field: "foo", value: 10, operator: "isequalto" } ] + }), "(d.foo == 10)"); +}); + +test("equalto", function() { + equal(compile({ + logic: "and", + filters: [ { field: "foo", value: 10, operator: "equalto" } ] + }), "(d.foo == 10)"); +}); + +test("operator ignores case", function() { + equal(compile({ + logic: "and", + filters: [ { field: "foo", value: 10, operator: "isEqualTo" } ] + }), "(d.foo == 10)"); +}); + +test("neq", function() { + equal(compile({ + logic: "and", + filters: [ { field: "foo", value: 10, operator: "neq" } ] + }), "(d.foo != 10)"); +}); + +test("!=", function() { + equal(compile({ + logic: "and", + filters: [ { field: "foo", value: 10, operator: "!=" } ] + }), "(d.foo != 10)"); +}); + +test("isnotequalto", function() { + equal(compile({ + logic: "and", + filters: [ { field: "foo", value: 10, operator: "isnotequalto" } ] + }), "(d.foo != 10)"); +}); + +test("notequals", function() { + equal(compile({ + logic: "and", + filters: [ { field: "foo", value: 10, operator: "notequals" } ] + }), "(d.foo != 10)"); +}); + +test("notequalto", function() { + equal(compile({ + logic: "and", + filters: [ { field: "foo", value: 10, operator: "notequalto" } ] + }), "(d.foo != 10)"); +}); + +test("notequal", function() { + equal(compile({ + logic: "and", + filters: [ { field: "foo", value: 10, operator: "notequal" } ] + }), "(d.foo != 10)"); +}); + +test("ne", function() { + equal(compile({ + logic: "and", + filters: [ { field: "foo", value: 10, operator: "ne" } ] + }), "(d.foo != 10)"); +}); + +test("<", function() { + equal(compile({ + logic: "and", + filters: [ { field: "foo", value: 10, operator: "<" } ] + }), "(d.foo < 10)"); +}); + +test("islessthan", function() { + equal(compile({ + logic: "and", + filters: [ { field: "foo", value: 10, operator: "islessthan" } ] + }), "(d.foo < 10)"); +}); + +test("lessthan", function() { + equal(compile({ + logic: "and", + filters: [ { field: "foo", value: 10, operator: "lessthan" } ] + }), "(d.foo < 10)"); +}); + +test("less", function() { + equal(compile({ + logic: "and", + filters: [ { field: "foo", value: 10, operator: "less" } ] + }), "(d.foo < 10)"); +}); + +test("<=", function() { + equal(compile({ + logic: "and", + filters: [ { field: "foo", value: 10, operator: "<=" } ] + }), "(d.foo <= 10)"); +}); + +test("islessthanorequalto", function() { + equal(compile({ + logic: "and", + filters: [ { field: "foo", value: 10, operator: "islessthanorequalto" } ] + }), "(d.foo <= 10)"); +}); + +test("lessthanequal", function() { + equal(compile({ + logic: "and", + filters: [ { field: "foo", value: 10, operator: "lessthanequal" } ] + }), "(d.foo <= 10)"); +}); + +test("le", function() { + equal(compile({ + logic: "and", + filters: [ { field: "foo", value: 10, operator: "le" } ] + }), "(d.foo <= 10)"); +}); + +test(">", function() { + equal(compile({ + logic: "and", + filters: [ { field: "foo", value: 10, operator: ">" } ] + }), "(d.foo > 10)"); +}); + +test("isgreaterthan", function() { + equal(compile({ + logic: "and", + filters: [ { field: "foo", value: 10, operator: "isgreaterthan"} ] + }), "(d.foo > 10)"); +}); + +test("greaterthan", function() { + equal(compile({ + logic: "and", + filters: [ { field: "foo", value: 10, operator: "greaterthan"} ] + }), "(d.foo > 10)"); +}); + +test("greater", function() { + equal(compile({ + logic: "and", + filters: [ { field: "foo", value: 10, operator: "greater"} ] + }), "(d.foo > 10)"); +}); + +test(">=", function() { + equal(compile({ + logic: "and", + filters: [ { field: "foo", value: 10, operator: ">=" } ] + }), "(d.foo >= 10)"); +}); + +test("isgreaterthanorequalto", function() { + equal(compile({ + logic: "and", + filters: [ { field: "foo", value: 10, operator: "isgreaterthanorequalto"} ] + }), "(d.foo >= 10)"); +}); + +test("greaterthanequal", function() { + equal(compile({ + logic: "and", + filters: [ { field: "foo", value: 10, operator: "greaterthanequal"} ] + }), "(d.foo >= 10)"); +}); + +test("ge", function() { + equal(compile({ + logic: "and", + filters: [ { field: "foo", value: 10, operator: "ge" } ] + }), "(d.foo >= 10)"); +}); + +test("startswith", function() { + equal(compile({ + logic: "and", + filters: [ { field: "foo", value: "bar", operator: "startswith" } ] + }), "((d.foo || '').toLowerCase().lastIndexOf('bar', 0) == 0)"); +}); + +test("endswith", function() { + equal(compile({ + logic: "and", + filters: [ { field: "foo", value: "bar", operator: "endswith" } ] + }), "((d.foo || '').toLowerCase().indexOf('bar', (d.foo || '').toLowerCase().length - 3) >= 0)"); +}); + +test("contains", function() { + equal(compile({ + logic: "and", + filters: [ { field: "foo", value: "bar", operator: "contains" } ] + }), "((d.foo || '').toLowerCase().indexOf('bar') >= 0)"); +}); + +test("contains with apostrophe", function() { + equal(compile({ + logic: "and", + filters: [ { field: "foo", value: "'", operator: "contains" } ] + }), "((d.foo || '').toLowerCase().indexOf('\\'') >= 0)"); +}); + +test("using function as field", function() { + equal(compile({ + logic: "and", + filters: [ { field: $.noop, value: 0, operator: "eq" } ] + }), "(__f[0](d) == 0)"); +}); + +test("using multiple fields as function", function() { + equal(compile({ + logic: "and", + filters: [ { field: $.noop, value: 10, operator: "eq" }, {field: $.noop, value: 10, operator: "eq" }] + }), "(__f[0](d) == 10 && __f[1](d) == 10)"); +}); + +test("using function as operator", function() { + equal(compile({ + logic: "and", + filters: [ { value: 0, operator: $.noop } ] + }), "(__o[0](d, 0))"); +}); + +test("using function as operator and field", function() { + equal(compile({ + logic: "and", + filters: [ { field: $.noop, value: 0, operator: $.noop } ] + }), "(__o[0](__f[0](d), 0))"); +}); + +test("using multiple operators as function", function() { + equal(compile({ + logic: "and", + filters: [ { operator: $.noop, value: 10 }, { operator: $.noop, value: 10}] + }), "(__o[0](d, 10) && __o[1](d, 10))"); +}); + +test("or with nested filters and operators as functions", function() { + equal(compile({ + logic: "or", + filters: [ + { + logic: "and", + filters: [{ value: 10, operator: $.noop }, { value: 10, operator: $.noop }] + }, + { + logic: "or", + filters: [{ value: 10, operator: $.noop }, { value: 10, operator: "eq" }] + } + ] + }), "((__o[0](d, 10) && __o[1](d, 10)) || (__o[2](d, 10) || d == 10))"); +}); + +test("or with nested filters and fields as functions", function() { + equal(compile({ + logic: "or", + filters: [ + { + logic: "and", + filters: [{ value: 10, field: $.noop, operator: $.noop }, {field: $.noop, value: 10, operator: $.noop }] + }, + { + logic: "or", + filters: [{ value: 10, field: $.noop, operator: $.noop }, { value: 10, operator: "eq" }] + } + ] + }), "((__o[0](__f[0](d), 10) && __o[1](__f[1](d), 10)) || (__o[2](__f[2](d), 10) || d == 10))"); +}); + +test("deeply nested nested fields as functions", function() { + equal(compile({ + logic: "or", + filters: [ + { + logic: "and", + filters: [ { + logic: "or", + filters: [ { value: 10, field: $.noop }, {field: $.noop, value: 10}] + }, { field:$.noop, value : 10 } + ] + }, + { + logic: "and", + filters: [ { + logic: "or", + filters: [ { value: 10, field: $.noop }, {field: $.noop, value: 10}] + }, { field:$.noop, value : 10 } +] + } + ] + }), "(((__f[0](d) == 10 || __f[1](d) == 10) && __f[2](d) == 10) || ((__f[3](d) == 10 || __f[4](d) == 10) && __f[5](d) == 10))"); +}); + +test("date eq", function() { + var date = new Date(2011, 10, 1); + equal(compile({ + logic: "and", + filters: [ { operator: "eq", value: date} ] + }), "((d?d.getTime():d) == " + date.getTime() + ")"); +}); + +test("date neq", function() { + var date = new Date(2011, 10, 1); + equal(compile({ + logic: "and", + filters: [ { operator: "neq", value: date} ] + }), "((d?d.getTime():d) != " + date.getTime() + ")"); +}); + +test("date gt", function() { + var date = new Date(2011, 10, 1); + equal(compile({ + logic: "and", + filters: [ { operator: "gt", value: date} ] + }), "((d?d.getTime():d) > " + date.getTime() + ")"); +}); + +test("date gte", function() { + var date = new Date(2011, 10, 1); + equal(compile({ + logic: "and", + filters: [ { operator: "gte", value: date} ] + }), "((d?d.getTime():d) >= " + date.getTime() + ")"); +}); + +test("date lt", function() { + var date = new Date(2011, 10, 1); + equal(compile({ + logic: "and", + filters: [ { operator: "lt", value: date} ] + }), "((d?d.getTime():d) < " + date.getTime() + ")"); +}); + +test("date lte", function() { + var date = new Date(2011, 10, 1); + equal(compile({ + logic: "and", + filters: [ { operator: "lte", value: date} ] + }), "((d?d.getTime():d) <= " + date.getTime() + ")"); +}); + +test("string neq", function() { + equal(compile({ + logic: "and", + filters: [ { operator: "neq", value: "foo"} ] + }), "((d || '').toLowerCase() != 'foo')"); +}); +test("string filtering is case insensitive by default", function() { + equal(compile({ + logic: "and", + filters: [ { operator: "neq", value: "Foo"} ] + }), "((d || '').toLowerCase() != 'foo')"); +}); + +test("apostrophe in strings is escaped", function() { + equal(compile({ + filters: [ { operator: "eq", value: "f'oo"} ] + }), "((d || '').toLowerCase() == 'f\\'oo')"); +}); + +test("string filtering is case sensitive", function() { + equal(compile({ + logic: "and", + filters: [ { ignoreCase: false, operator: "neq", value: "Foo"} ] + }), "(d != 'Foo')"); +}); + +test("carriage return in strings is escaped", function() { + equal(compile({ + filters: [ { operator: "eq", value: "foo \r\n bar"} ] + }), "((d || '').toLowerCase() == 'foo bar')"); +}); + +}()); diff --git a/tests/data/query.js b/tests/data/query.js new file mode 100644 index 00000000000..640b9caece8 --- /dev/null +++ b/tests/data/query.js @@ -0,0 +1,1959 @@ +(function(){ + +var Query = kendo.data.Query; + +test("take returns the specified number of records", function() { + var q = new Query([1,2]); + var result = q.take(1).toArray(); + equal(result.length, 1); + equal(result[0], 1); +}); + +test("skip returns new array starting after the specified index", function () { + var q = new Query([1,2]); + var result = q.skip(1).toArray(); + + equal(result.length, 1); + equal(result[0], 2); +}); + +test("skip and take returns a page of records", function () { + var q = new Query([1, 2, 3]); + + var result = q.skip(1).take(2).toArray(); + + equal(result.length, 2); + equal(result[0], 2); + equal(result[1], 3); +}); + +test("range returns given number of items from specific index", function() { + var q = new Query([1, 2, 3, 4, 5, 6, 7, 8]); + + var result = q.range(1, 4).toArray(); + equal(result.length, 4); + equal(result[0], 2); + equal(result[1], 3); + equal(result[2], 4); + equal(result[3], 5); +}); + +test("orderBy sorts numbers in ascending order", function () { + var data = [100, 10, 1]; + + var result = new Query(data).orderBy(function (item) { + return item; + }).toArray(); + + equal(result.length, 3); + equal(result[0], 1); + equal(result[1], 10); + equal(result[2], 100); +}); + +test("orderBy sorts strings in ascending order", function () { + var data = ["foo", "bar", "baz"]; + + var result = new Query(data).orderBy(function (item) { + return item; + }).toArray(); + + equal(result.length, 3); + equal(result[0], "bar"); + equal(result[1], "baz"); + equal(result[2], "foo"); +}); + +test("orderBy ignores string casing", function() { + var data = ["A", "z", "Z", "a"]; + + var result = new Query(data).orderBy(function (item) { + return item; + }).toArray(); + + equal(result.length, 4); + equal(result[0], "a"); + equal(result[1], "A"); + equal(result[2], "z"); + equal(result[3], "Z"); +}); + +test("ascending sort for grouping ignores string case", function() { + var data = [{ text: "A" },{ text: "z" },{ text: "Z" }, { text: "a" }]; + + var result = new Query(data)._sortForGrouping("text", "asc"); + + equal(result.length, 4); + equal(result[0].text, "a"); + equal(result[1].text, "A"); + equal(result[2].text, "z"); + equal(result[3].text, "Z"); +}); + +test("descending sort for grouping ignores string case", function() { + var data = [{ text: "A" },{ text: "z" },{ text: "Z" }, { text: "a" }]; + + var result = new Query(data)._sortForGrouping("text", "desc"); + + equal(result.length, 4); + equal(result[0].text, "Z"); + equal(result[1].text, "z"); + equal(result[2].text, "A"); + equal(result[3].text, "a"); +}); + +test("orderBy sorts dates in ascending order", function () { + var data = [new Date(2011, 1, 1), new Date(2008, 1, 1), new Date(2009, 1, 1)]; + + var result = new Query(data).orderBy(function (item) { + return item; + }).toArray(); + + equal(result.length, 3); + equal(result[0].getFullYear(), 2008); + equal(result[1].getFullYear(), 2009); + equal(result[2].getFullYear(), 2011); +}); + + +test("orderBy sorts dates earlier then 1970 and nulls", function () { + var data = [new Date(1955, 1, 1), null, new Date(2009, 1, 1)]; + + var result = new Query(data).orderBy(function (item) { + return item; + }).toArray(); + + equal(result.length, 3); + ok(!result[0]); + equal(result[1].getFullYear(), 1955); + equal(result[2].getFullYear(), 2009); +}); + +test("orderByDescending sorts dates earlier then 1970 and multiple nulls", function () { + var data = [new Date(1955, 1, 1), null, null, new Date(2009, 1, 1), null]; + + var result = new Query(data).orderByDescending(function (item) { + return item; + }).toArray(); + + equal(result.length, 5); + equal(result[0].getFullYear(), 2009); + equal(result[1].getFullYear(), 1955); + ok(!result[2]); + ok(!result[3]); + ok(!result[4]); +}); + +test("orderBy sorts strings and nulls", function () { + var data = ["a", null, "b"]; + + var result = new Query(data).orderBy(function (item) { + return item; + }).toArray(); + + equal(result.length, 3); + ok(!result[0]); + equal(result[1], "a"); + equal(result[2], "b"); +}); + +test("orderBy sorts negative numbers and zeros", function () { + var data = [1, -2, 0, 3]; + + var result = new Query(data).orderBy(function (item) { + return item; + }).toArray(); + + equal(result.length, 4); + equal(result[0], -2); + equal(result[1], 0); + equal(result[2], 1); + equal(result[3], 3); +}); + +test("orderBy sorts multiple negative numbers and zeros", function () { + var data = [1, -2, 0, -5]; + + var result = new Query(data).orderBy(function (item) { + return item; + }).toArray(); + + equal(result.length, 4); + equal(result[0], -5); + equal(result[1], -2); + equal(result[2], 0); + equal(result[3], 1); +}); + +test("orderBy sorts multiple negative numbers zeros and nulls", function () { + var data = [1, -2, 0, null]; + + var result = new Query(data).orderBy(function (item) { + return item; + }).toArray(); + + equal(result.length, 4); + equal(result[0], null); + equal(result[1], -2); + equal(result[2], 0); + equal(result[3], 1); +}); + +test("orderBy sorts multiple negative numbers", function () { + var data = [-2, -33, -5]; + + var result = new Query(data).orderBy(function (item) { + return item; + }).toArray(); + + equal(result.length, 3); + equal(result[0], -33); + equal(result[1], -5); + equal(result[2], -2); +}); + +test("orderByDescending sorts numbers and nulls", function () { + var data = [1, null, 0, 3]; + + var result = new Query(data).orderByDescending(function (item) { + return item; + }).toArray(); + + equal(result.length, 4); + equal(result[3], null); + equal(result[2], 0); + equal(result[1], 1); + equal(result[0], 3); +}); + +test("orderByDescending sorts negative numbers and zeros", function () { + var data = [1, -2, 0, 3]; + + var result = new Query(data).orderByDescending(function (item) { + return item; + }).toArray(); + + equal(result.length, 4); + equal(result[3], -2); + equal(result[2], 0); + equal(result[1], 1); + equal(result[0], 3); +}); + +test("orderByDescending sorts multiple negative numbers and zeros", function () { + var data = [1, -2, 0, -5]; + + var result = new Query(data).orderByDescending(function (item) { + return item; + }).toArray(); + + equal(result.length, 4); + equal(result[3], -5); + equal(result[2], -2); + equal(result[1], 0); + equal(result[0], 1); +}); + +test("orderByDescending sorts multiple negative numbers zeros and nulls", function () { + var data = [1, -2, 0, null]; + + var result = new Query(data).orderByDescending(function (item) { + return item; + }).toArray(); + + equal(result.length, 4); + equal(result[3], null); + equal(result[2], -2); + equal(result[1], 0); + equal(result[0], 1); +}); + +test("orderByDescending sorts multiple negative numbers", function () { + var data = [-2, -33, -5]; + + var result = new Query(data).orderByDescending(function (item) { + return item; + }).toArray(); + + equal(result.length, 3); + equal(result[2], -33); + equal(result[1], -5); + equal(result[0], -2); +}); + + +test("orderByDescending sorts numbers and nulls", function () { + var data = [1, null, 0, 3]; + + var result = new Query(data).orderByDescending(function (item) { + return item; + }).toArray(); + + equal(result.length, 4); + equal(result[0], 3); + equal(result[1], 1); + equal(result[2], 0); + equal(result[3], null); +}); + +test("orderByDescending sorts strings and nulls", function () { + var data = ["a", null, "b"]; + + var result = new Query(data).orderByDescending(function (item) { + return item; + }).toArray(); + + equal(result.length, 3); + equal(result[0], "b"); + equal(result[1], "a"); + ok(!result[2]); +}); + +test("orderByDescending sorts dates earlier then 1970 and nulls", function () { + var data = [new Date(1955, 1, 1), null, new Date(2009, 1, 1)]; + + var result = new Query(data).orderByDescending(function (item) { + return item; + }).toArray(); + + equal(result.length, 3); + equal(result[0].getFullYear(), 2009); + equal(result[1].getFullYear(), 1955); + ok(!result[2]); +}); + +test("orderBy sorts booleans and nulls", function () { + var data = [true, false, null, true]; + + var result = new Query(data).orderBy(function (item) { + return item; + }).toArray(); + + equal(result.length, 4); + equal(result[0], null); + equal(result[1], false); + equal(result[2], true); + equal(result[3], true); +}); + +test("orderByDescending sorts booleans and nulls", function () { + var data = [true, false, null, false]; + + var result = new Query(data).orderByDescending(function (item) { + return item; + }).toArray(); + + equal(result.length, 4); + equal(result[0], true); + equal(result[1], false); + equal(result[2], false); + equal(result[3], null); +}); + +test("orderBy uses selector when sorting", function () { + var data = [{ name: "foo" }, { name: "bar" }, { name: "foo"}]; + + var result = new Query(data).orderBy(function (item) { + return item.name; + }).toArray(); + + equal(result.length, 3); + equal(result[0].name, "bar"); + equal(result[1].name, "foo"); + equal(result[2].name, "foo"); +}); + +test("orderBy does not modify original", function () { + var data = [3, 2, 1]; + + new Query(data).orderBy(function (item) { + return item.name; + }).toArray(); + + equal(data.length, 3); + equal(data[0], 3); + equal(data[1], 2); + equal(data[2], 1); +}); + +test("orderby without parameters sorts array", function() { + var data = new Query([3, 2, 1]).orderBy().toArray(); + + equal(data.length, 3); + equal(data[0], 1); + equal(data[1], 2); + equal(data[2], 3); + +}); +test("orderByDescending sorts numbers in descending order", function () { + var data = [1, 100, 10]; + + var result = new Query(data).orderByDescending(function (item) { + return item; + }).toArray(); + + equal(result.length, 3); + equal(result[0], 100); + equal(result[1], 10); + equal(result[2], 1); +}); + +test("orderByDescending sorts strings in descending order", function () { + var data = ["foo", "bar", "baz"]; + + var result = new Query(data).orderByDescending(function (item) { + return item; + }).toArray(); + + equal(result.length, 3); + equal(result[0], "foo"); + equal(result[1], "baz"); + equal(result[2], "bar"); +}); + +test("orderByDescending sorts dates in descending order", function () { + var data = [new Date(2011, 1, 1), new Date(2008, 1, 1), new Date(2009, 1, 1)]; + + var result = new Query(data).orderByDescending(function (item) { + return item; + }).toArray(); + + equal(result.length, 3); + equal(result[0].getFullYear(), 2011); + equal(result[1].getFullYear(), 2009); + equal(result[2].getFullYear(), 2008); +}); + +test("orderByDescending uses selector when sorting", function () { + var data = [{ name: "foo" }, { name: "bar" }, { name: "foo"}]; + + var result = new Query(data).orderByDescending(function (item) { + return item.name; + }) + .toArray(); + + equal(result.length, 3); + equal(result[0].name, "foo"); + equal(result[1].name, "foo"); + equal(result[2].name, "bar"); +}); + +test("orderByDescending does not modify original", function () { + var data = [1, 2, 3]; + + new Query(data).orderByDescending(function (item) { + return item.name; + }); + + equal(data[0], 1); + equal(data[1], 2); + equal(data[2], 3); +}); + +test("sort using ascending descriptor", function () { + var data = [{ name: "foo" }, { name: "bar" }, { name: "foo"}]; + + var result = new Query(data).sort( { field: "name", dir: "asc" }).toArray(); + + equal(result.length, 3); + equal(result[0].name, "bar"); + equal(result[1].name, "foo"); + equal(result[2].name, "foo"); +}); + +test("sorting nested objects", function() { + var data = [{ foo: { age: 1 } }, { foo : { age: 2 } }] + + var result = new Query(data).sort({ field: "foo.age", dir: "desc" }).toArray(); + + equal(result[0].foo.age, 2); +}); + +test("sort ignores direction case", function () { + var data = [{ name: "foo" }, { name: "bar" }, { name: "foo"}]; + + var result = new Query(data).sort( { field: "name", dir: "Asc" }).toArray(); + + equal(result.length, 3); + equal(result[0].name, "bar"); + equal(result[1].name, "foo"); + equal(result[2].name, "foo"); +}); + +test("sort using descending descriptor", function () { + var data = [{ name: "foo" }, { name: "bar" }, { name: "foo"}]; + + var result = new Query(data).sort( { field: "name", dir: "desc" }).toArray(); + + equal(result.length, 3); + equal(result[0].name, "foo"); + equal(result[1].name, "foo"); + equal(result[2].name, "bar"); +}); + +test("orderBy using custom comparer", function() { + var data = [{ name: "foo" }, { name: "bar" }, { name: "foo"}]; + + var result = new Query(data).orderBy({ + compare: function(a, b){ + return a.name > b.name ? 1 : (a.name < b.name ? -1 : 0); + } + }).toArray(); + + equal(result.length, 3); + equal(result[0].name, "bar"); + equal(result[1].name, "foo"); + equal(result[2].name, "foo"); +}); + +test("ascending sort using custom comparer", function() { + var data = [{ name: "foo" }, { name: "bar" }, { name: "foo"}]; + + var result = new Query(data).sort({ + dir: "asc", + compare: function(a, b){ + return a.name > b.name ? 1 : (a.name < b.name ? -1 : 0); + } + }).toArray(); + + equal(result.length, 3); + equal(result[0].name, "bar"); + equal(result[1].name, "foo"); + equal(result[2].name, "foo"); +}); + +test("descending sort using custom comparer", function() { + var data = [{ name: "foo" }, { name: "bar" }, { name: "foo"}]; + + var result = new Query(data).sort({ + dir: "desc", + compare: function(a, b){ + return a.name > b.name ? 1 : (a.name < b.name ? -1 : 0); + } + }).toArray(); + + equal(result.length, 3); + equal(result[0].name, "foo"); + equal(result[1].name, "foo"); + equal(result[2].name, "bar"); +}); + +test("sort using multiple descriptors", function () { + var data = [{ name: "foo", age: 42 }, { name: "bar", age: 36 }, { name: "foo", age: 15 }]; + + var result = new Query(data).sort( [ { field: "name", dir: "desc" }, { field: "age", dir: "asc" } ]).toArray(); + + equal(result.length, 3); + equal(result[0].name, "foo"); + equal(result[0].age, 15); + equal(result[1].name, "foo"); + equal(result[1].age, 42); + equal(result[2].name, "bar"); + equal(result[2].age, 36); +}); +test("sort using two strings as arguments", function() { + var data = [{ name: "foo" }, { name: "bar" }, { name: "foo"}]; + + var result = new Query(data).sort("name", "asc").toArray(); + + equal(result.length, 3); + equal(result[0].name, "bar"); + equal(result[1].name, "foo"); + equal(result[2].name, "foo"); +}); + +test("filter on null string", function() { + var data = [{ name: null }, { name: "bar" }, { name: "foo"}]; + + var result = new Query(data).filter({ field: "name", operator: "eq", value: "foo" }).toArray(); + + equal(result.length, 1); +}); + +test("filter on null string with startwith", function() { + var data = [{ name: null }, { name: "bar" }, { name: "foo"}]; + var result = new Query(data).filter({ field: "name", operator: "startswith", value: "foo", ignoreCase: true }).toArray(); + + equal(result.length, 1); +}); + +test("filter on null string with endswith", function() { + var data = [{ name: null }, { name: "bar" }, { name: "foo"}]; + var result = new Query(data).filter({ field: "name", operator: "endswith", value: "foo", ignoreCase: true }).toArray(); + + equal(result.length, 1); +}); + + +test("filter with empty expression", function() { + var data = [{ name: "foo" }, { name: "bar" }, { name: "foo"}]; + + var result = new Query(data).filter(null).toArray(); + + equal(result.length, 3); +}); + +test("filter contains with apostrophe", function() { + var data = [{ name: "f'oo" } ]; + + var result = new Query(data).filter({field: "name", value: "'", operator: "contains"}).toArray(); + + equal(result.length, 1); +}); + +test("filter with slash", function() { + var data = [{ name: "f\\oo" } ]; + + var result = new Query(data).filter({field: "name", value: "\\", operator: "contains"}).toArray(); + + equal(result.length, 1); +}); + +test("filter with apostrophe", function() { + var data = [{ name: "f'oo" } ]; + + var result = new Query(data).filter({field: "name", value: "f'oo"}).toArray(); + + equal(result.length, 1); +}); + +test("filter with empty filters", function() { + var data = [{ name: "foo" }, { name: "bar" }, { name: "foo"}]; + + var result = new Query(data).filter({ filters:[] }).toArray(); + + equal(result.length, 3); +}); + +test("filter filters on numbers", function() { + var data = [ {field: 100} , {field: 10} , {field: 1} ]; + + var result = new Query(data).filter( { + field: "field", + operator: "eq", + value: 1 + }).toArray(); + + equal(result.length, 1); + equal(result[0].field, 1); +}); + +test("filter filters with field as a function", function() { + var data = [ 100, 10, 1 ]; + var fieldFunctionWasCalled = false; + + var result = new Query(data).filter( { + field: function(item) { + fieldFunctionWasCalled = true; + return item; + }, + operator: "eq", + value: 1 + }).toArray(); + + ok(fieldFunctionWasCalled); + equal(result.length, 1); + equal(result[0], 1); +}); + +test("filter filters with operator as a function", function() { + var data = [ {field: 100} , {field: 10} , {field: 1} ]; + + var result = new Query(data).filter( { + field: "field", + operator: function(d, value) { + return d === value; + }, + value: 1 + }).toArray(); + + equal(result.length, 1); + equal(result[0].field, 1); +}); + +test("filter filters on dates", function () { + var data = [new Date(2011, 1, 1), new Date(2008, 1, 1), new Date(2009, 1, 1)]; + + var result = new Query(data).filter( { + field: function(item) { + return item; + }, + operator: "eq", + value: new Date(2011, 1, 1) + }).toArray(); + + equal(result.length, 1); + equal(result[0].getFullYear(), 2011); +}); + +test("filter filters on nullable dates", function () { + var data = [new Date(2011, 1, 1), null, new Date(2009, 1, 1)]; + + var result = new Query(data).filter( { + field: function(item) { + return item; + }, + operator: "eq", + value: new Date(2011, 1, 1) + }).toArray(); + + equal(result.length, 1); + equal(result[0].getFullYear(), 2011); +}); + +test("filter filters without passing operator defaults to eq", function() { + var data = [ {field: 100} , {field: 10} , {field: 1} ]; + + var result = new Query(data).filter( { + field: "field", + value: 1 + }).toArray(); + + equal(result.length, 1); + equal(result[0].field, 1); +}); + +test("filter filters if passing operator allias", function() { + var data = [ {field: 100} , {field: 10} , {field: 1} ]; + + var result = new Query(data).filter( { + field: "field", + operator: "==", + value: 1 + }).toArray(); + + equal(result.length, 1); + equal(result[0].field, 1); +}); + +test("filter filters with neq", function() { + var data = [ {field: 100} , {field: 10} , {field: 1} ]; + + var result = new Query(data).filter( { + field: "field", + operator: "neq", + value: 1 + }).toArray(); + + equal(result.length, 2); + equal(result[0].field, 100); + equal(result[1].field, 10); +}); + +test("filter filters with ne", function() { + var data = [ {field: 100} , {field: 10} , {field: 1} ]; + + var result = new Query(data).filter( { + field: "field", + operator: "ne", + value: 1 + }).toArray(); + + equal(result.length, 2); + equal(result[0].field, 100); + equal(result[1].field, 10); +}); + +test("filter filters with lt", function() { + var data = [ {field: 100} , {field: 10} , {field: 1} ]; + + var result = new Query(data).filter( { + field: "field", + operator: "lt", + value: 100 + }).toArray(); + + equal(result.length, 2); + equal(result[0].field, 10); + equal(result[1].field, 1); +}); + +test("filter filters with le", function() { + var data = [ {field: 100} , {field: 10} , {field: 1} ]; + + var result = new Query(data).filter( { + field: "field", + operator: "le", + value: 10 + }).toArray(); + + equal(result.length, 2); + equal(result[0].field, 10); + equal(result[1].field, 1); +}); + +test("filter filters with lte", function() { + var data = [ {field: 100} , {field: 10} , {field: 1} ]; + + var result = new Query(data).filter( { + field: "field", + operator: "lte", + value: 10 + }).toArray(); + + equal(result.length, 2); + equal(result[0].field, 10); + equal(result[1].field, 1); +}); + +test("filter filters with gt", function() { + var data = [ {field: 100} , {field: 10} , {field: 1} ]; + + var result = new Query(data).filter( { + field: "field", + operator: "gt", + value: 10 + }).toArray(); + + equal(result.length, 1); + equal(result[0].field, 100); +}); + +test("filter filters with gte", function() { + var data = [ {field: 100} , {field: 10} , {field: 1} ]; + + var result = new Query(data).filter( { + field: "field", + operator: "gte", + value: 10 + }).toArray(); + + equal(result.length, 2); + equal(result[0].field, 100); + equal(result[1].field, 10); +}); + +test("filter filters with ge", function() { + var data = [ {field: 100} , {field: 10} , {field: 1} ]; + + var result = new Query(data).filter( { + field: "field", + operator: "ge", + value: 10 + }).toArray(); + + equal(result.length, 2); + equal(result[0].field, 100); + equal(result[1].field, 10); +}); + +test("filter filters with eq on string", function() { + var data = [ {field: "a"} , {field: "b"} , {field: "c"} ]; + + var result = new Query(data).filter( { + field: "field", + operator: "eq", + value: "c" + }).toArray(); + + equal(result.length, 1); + equal(result[0].field, "c"); +}); + +test("filter filters with startswith on string", function() { + var data = [ {field: "abc"} , {field: "bcd"} , {field: "cde"} ]; + + var result = new Query(data).filter( { + field: "field", + operator: "startswith", + value: "c" + }).toArray(); + + equal(result.length, 1); + equal(result[0].field, "cde"); +}); + +test("filter filters with endswith on undefined", function() { + var data = [ {field: "abc"} , {field: "bcd"} , {field: "cde"} ]; + + var result = new Query(data).filter( { + field: "field", + operator: "endswith", + value: undefined + }).toArray(); + + equal(result.length, 0); +}); + +test("filter filters with endswith on string", function() { + var data = [ {field: "abc"} , {field: "bcd"} , {field: "cde"} ]; + + var result = new Query(data).filter( { + field: "field", + operator: "endswith", + value: "c" + }).toArray(); + + equal(result.length, 1); + equal(result[0].field, "abc"); +}); + +test("filter filters with endswith on multiple letters string", function() { + var data = [ {field: "abc"} , {field: "bcd"} , {field: "cde"} ]; + + var result = new Query(data).filter( { + field: "field", + operator: "endswith", + value: "de" + }).toArray(); + + equal(result.length, 1); + equal(result[0].field, "cde"); +}); + +test("filter filters with contains on string", function() { + var data = [ {field: "abc"} , {field: "bcd"} , {field: "cde"} ]; + + var result = new Query(data).filter( { + field: "field", + operator: "contains", + value: "b" + }).toArray(); + + equal(result.length, 2); + equal(result[0].field, "abc"); + equal(result[1].field, "bcd"); +}); + +test("filter filters with doesnotcontain on string", function() { + var data = [ {field: "abc"} , {field: "bcd"} , {field: "cde"} ]; + + var result = new Query(data).filter( { + field: "field", + operator: "doesnotcontain", + value: "a" + }).toArray(); + + equal(result.length, 2); + equal(result[0].field, "bcd"); + equal(result[1].field, "cde"); +}); + +test("filter filters with notsubstringof on string", function() { + var data = [ {field: "abc"} , {field: "bcd"} , {field: "cde"} ]; + + var result = new Query(data).filter( { + field: "field", + operator: "notsubstringof", + value: "a" + }).toArray(); + + equal(result.length, 2); + equal(result[0].field, "bcd"); + equal(result[1].field, "cde"); +}); + +test("filter filters with eq on string case sensitive", function() { + var data = [ {field: "a"} , {field: "b"} , {field: "c"}, {field: "A"} ]; + + var result = new Query(data).filter( { + field: "field", + operator: "eq", + value: "A", + ignoreCase: false + }).toArray(); + + equal(result.length, 1); + equal(result[0].field, "A"); +}); + +test("filter filters with contains on string case sensitive", function() { + var data = [ {field: "abc"} , {field: "Bcd"}]; + + var result = new Query(data).filter( { + field: "field", + operator: "contains", + value: "B", + ignoreCase: false + }).toArray(); + + equal(result.length, 1); + equal(result[0].field, "Bcd"); +}); + +test("filter with multiple expressions", function() { + var data = [ {field: 100} , {field: 10} , {field: 1} ]; + + var result = new Query(data).filter( [{ + field: "field", + operator: "gte", + value: 1 + }, + { + field: "field", + operator: "lt", + value: 100 + }]).toArray(); + + equal(result.length, 2); + equal(result[0].field, 10); + equal(result[1].field, 1); +}); + +test("filter with and expression", function() { + var data = [100, 10, 1]; + + var result = new Query(data).filter( { + logic: "and", + filters: [ + { operator: "gt", value: 1 }, + { operator: "lt", value: 100 } + ] + }).toArray(); + + equal(result.length, 1); + equal(result[0], 10); +}); + +test("filter with or expression", function() { + var data = [100, 10, 1]; + + var result = new Query(data).filter( { + logic: "or", + filters: [ + { operator: "eq", value: 1 }, + { operator: "eq", value: 100 } + ] + }).toArray(); + + equal(result.length, 2); + equal(result[0], 100); + equal(result[1], 1); +}); + +test("filter with nested expression", function() { + var data = [100, 10, 1]; + + var result = new Query(data).filter( { + logic: "or", + filters: [ + { + logic: "and", + filters: [ { operator: "gt", value: 1 }, { operator: "lt", value: 100 } ] + }, + { + operator: "eq", + value: 100 + } + ] + }).toArray(); + + equal(result.length, 2); + equal(result[0], 100); + equal(result[1], 10); +}); + +test("filter with nested or expression", function() { + var data = [100, 10, 1]; + + var result = new Query(data).filter( { + logic: "or", + filters: [ + { + logic: "and", + filters: [ { operator: "gt", value: 1 }, { operator: "lt", value: 100 } ] + }, + { + operator: "eq", + value: 100 + } + ] + }).toArray(); + + equal(result.length, 2); + equal(result[0], 100); + equal(result[1], 10); +}); + +test("filter with nested and expression", function() { + var data = [100, 10, 1]; + + var result = new Query(data).filter( { + logic: "and", + filters: [ + { + logic: "or", + filters: [ { operator: "eq", value: 100 }, { operator: "eq", value: 10 } ] + }, + { + operator: "gt", + value: 1 + } + ] + }).toArray(); + + equal(result.length, 2); + equal(result[0], 100); + equal(result[1], 10); +}); + +test("filter without specifying field fields array", function() { + var data = [100, 10, 1]; + + var result = new Query(data).filter( { + operator: "gte", + value: 10 + }).toArray(); + + equal(result.length, 2); + equal(result[0], 100); + equal(result[1], 10); +}); + +test("filter on nested objects", function () { + var data = [{foo: { bar: 1 }}]; + + var result = new Query(data).filter( { + operator: "gte", + field: "foo.bar", + value: 1 + }).toArray(); + + equal(result.length, 1); + equal(result[0].foo.bar, 1); +}); + +test("filter on dotnet date literals", function () { + var data = [{ bar: new Date(1996, 11, 9)},{ bar: new Date(1996, 11, 12)}]; + + var result = new Query(data).filter( { + operator: "eq", + field: "bar", + value: "/Date(850082400000)/" + }).toArray(); + + equal(result.length, 1); + equal(result[0].bar.getTime(), 850082400000); +}); + +test("filter on nested nullable objects", function () { + var data = [{foo: { bar: 1 }}, {foo: { bar: undefined }}]; + + var result = new Query(data).filter( { + operator: "gte", + field: "foo.bar", + value: 1 + }).toArray(); + + equal(result.length, 1); + equal(result[0].foo.bar, 1); +}); + +test("groupby groups data by field", function() { + var data = [ {field: 100} , {field: 100} , {field: 1} ]; + + var result = new Query(data).groupBy( { + field: "field" + }).toArray(); + equal(result.length, 2); + equal(result[0].value, 1); + equal(result[0].field, "field"); + equal(result[0].items.length, 1); + equal(result[1].value, 100); + equal(result[1].field, "field"); + equal(result[1].items.length, 2); +}); + +test("groupby should be stable", function() { + var data = [{foo:1, bar:1},{foo:2, bar:1},{foo:3, bar:1},{foo:4, bar:1},{foo:5, bar:1}, + {foo:6, bar:1},{foo:7, bar:1},{foo:8, bar:1},{foo:9, bar:1},{foo:0, bar:1},{foo:11, bar:1}]; + + var result = new Query(data) + .sort([ { field: "foo", dir: "asc" }, {field:"bar", dir:"asc" }]) + .groupBy( { + field: "bar" + }).toArray(); + + equal(result.length, 1); + equal(result[0].items.length, 11); + equal(result[0].items[0].foo, 0); + equal(result[0].items[1].foo, 1); +}); + +test("descending groupby should be stable", function() { + var data = [{foo:1, bar:1},{foo:2, bar:1},{foo:3, bar:1},{foo:4, bar:1},{foo:5, bar:1}, + {foo:6, bar:1},{foo:7, bar:1},{foo:8, bar:1},{foo:9, bar:1},{foo:0, bar:1},{foo:11, bar:1}]; + + var result = new Query(data) + .sort([ { field: "foo", dir: "desc" }, {field:"bar", dir:"desc" }]) + .groupBy( { + field: "bar", dir: "desc" + }).toArray(); + + equal(result.length, 1); + equal(result[0].items.length, 11); + equal(result[0].items[0].foo, 11); + equal(result[0].items[1].foo, 9); +}); + +test("groupby on dates should be stable", function() { + var data = [{foo:1, bar: new Date(1999, 1, 1)},{foo:2, bar: new Date(1999, 1,1)},{foo:3, bar: new Date(1999, 1,1)},{foo:4, bar: new Date(1999, 1,1)},{foo:5, bar: new Date(1999, 1,1)}, {foo:6, bar: new Date(1999, 1,1)},{foo:7, bar: new Date(1999, 1,1)},{foo:8, bar: new Date(1999, 1,1)},{foo:9, bar: new Date(1999, 1,1)},{foo:0, bar: new Date(1999, 1,1)},{foo:11, bar: new Date(1999, 1,1)}]; + + var result = new Query(data) + .sort([ { field: "foo", dir: "asc" }]) + .groupBy( { + field: "bar" + }).toArray(); + + equal(result.length, 1); + equal(result[0].items.length, 11); + equal(result[0].items[0].foo, 0); + equal(result[0].items[1].foo, 1); +}); + +test("groupby on dates with descending sort should be stable", function() { + var data = [{foo:11, bar: new Date(1999, 1, 1)},{foo:10, bar: new Date(1999, 1,1)},{foo:9, bar: new Date(1999, 1,1)},{foo:8, bar: new Date(1999, 1,1)},{foo:7, bar: new Date(1999, 1,1)}, {foo:6, bar: new Date(1999, 1,1)},{foo:5, bar: new Date(1999, 1,1)},{foo:4, bar: new Date(1999, 1,1)},{foo:3, bar: new Date(1999, 1,1)},{foo:2, bar: new Date(1999, 1,1)},{foo:1, bar: new Date(1999, 1,1)}]; + + var result = new Query(data) + .sort([ { field: "foo", dir: "desc" }]) + .groupBy( { + field: "bar", dir: "desc" + }).toArray(); + + equal(result.length, 1); + equal(result[0].items.length, 11); + equal(result[0].items[0].foo, 11); + equal(result[0].items[1].foo, 10); + equal(result[0].items[2].foo, 9); + equal(result[0].items[3].foo, 8); + equal(result[0].items[4].foo, 7); + equal(result[0].items[5].foo, 6); + equal(result[0].items[6].foo, 5); + equal(result[0].items[7].foo, 4); + equal(result[0].items[8].foo, 3); + equal(result[0].items[9].foo, 2); + equal(result[0].items[10].foo, 1); +}); + + +test("groupby groups data by date", function() { + var data = [ {field: new Date(2011, 1, 1)} , {field: new Date(2011, 2, 2) } , {field: new Date(2011, 1, 1) } ]; + + var result = new Query(data).groupBy( { + field: "field" + }).toArray(); + + equal(result.length, 2); + equal(result[0].items.length, 2); + equal(result[0].value.getTime(), new Date(2011, 1, 1).getTime()); + equal(result[1].items.length, 1); + equal(result[1].value.getTime(), new Date(2011, 2, 2).getTime()); +}); + +test("groupby returns ungroup collection if no descriptors are provided", function() { + var data = [ {field: 100} , {field: 100} , {field: 1} ]; + + var result = new Query(data).group( ).toArray(); + equal(result, data); +}); + +test("groupby groups data by field and direction", function() { + var data = [ {field: 100} , {field: 100} , {field: 1} ]; + + var result = new Query(data).group( [{ + field: "field", + dir: "desc" + }]).toArray(); + equal(result.length, 2); + equal(result[1].value, 1); + equal(result[1].field, "field"); + equal(result[1].items.length, 1); + equal(result[0].value, 100); + equal(result[0].field, "field"); + equal(result[0].items.length, 2); +}); + +test("groupby groups data by multiple fields", function() { + var data = [ {foo: 100, bar: "baz"} , {foo: 100, bar: "bar"} , {foo: 1, bar: "baz"} ], + firstGroup, + secondGroup; + + var result = new Query(data).group( [{ field: "foo" }, { field: "bar" }]).toArray(); + + equal(result.length, 2); + firstGroup = result[0]; + secondGroup = result[1]; + + equal(firstGroup.value, 1); + equal(firstGroup.field, "foo"); + equal(firstGroup.items.length, 1); + equal(firstGroup.items[0].value, "baz"); + equal(firstGroup.items[0].field, "bar"); + equal(firstGroup.items[0].items.length, 1); + equal(secondGroup.value, 100); + equal(secondGroup.field, "foo"); + equal(secondGroup.items.length, 2); + equal(secondGroup.items[0].value, "bar"); + equal(secondGroup.items[0].field, "bar"); + equal(secondGroup.items[0].items.length, 1); + equal(secondGroup.items[1].value, "baz"); + equal(secondGroup.items[1].field, "bar"); + equal(secondGroup.items[1].items.length, 1); +}); + +test("group by nullable string with more than 10 items", function() { + var data = [ + { foo: 1, bar: null }, + { foo: 2, bar: "foo" }, + { foo: 3, bar: null }, + { foo: 4, bar: "foo" }, + { foo: 5, bar: "foo" }, + { foo: 6, bar: null }, + { foo: 7, bar: "foo" }, + { foo: 8, bar: null }, + { foo: 9, bar: "foo" }, + { foo: 10, bar: null }, + { foo: 11, bar: null }, + { foo: 12, bar: "foo" }, + { foo: 13, bar: "foo" } + ]; + + var result = new Query(data).group({ field: "bar" }).toArray(); + + equal(result.length, 2); + + equal(result[0].field, "bar"); + equal(result[0].value, null); + equal(result[0].items.length, 6); + + equal(result[1].field, "bar"); + equal(result[1].value, "foo"); + equal(result[1].items.length, 7); +}); + +test("group by nullable string with more than 10 items descending", function() { + var data = [ + { foo: 1, bar: null }, + { foo: 2, bar: "foo" }, + { foo: 3, bar: null }, + { foo: 4, bar: "foo" }, + { foo: 5, bar: "foo" }, + { foo: 6, bar: null }, + { foo: 7, bar: "foo" }, + { foo: 8, bar: null }, + { foo: 9, bar: "foo" }, + { foo: 10, bar: null }, + { foo: 11, bar: null }, + { foo: 12, bar: "foo" }, + { foo: 13, bar: "foo" } + ]; + + var result = new Query(data).group({ field: "bar", dir: "desc" }).toArray(); + + equal(result.length, 2); + + equal(result[0].field, "bar"); + equal(result[0].value, "foo"); + equal(result[0].items.length, 7); + + equal(result[1].field, "bar"); + equal(result[1].value, null); + equal(result[1].items.length, 6); +}); + +test("group by nullable boolean with more than 10 items", function() { + var data = [ + { foo: 1, bar: null }, + { foo: 2, bar: true }, + { foo: 3, bar: null }, + { foo: 4, bar: false }, + { foo: 5, bar: true }, + { foo: 6, bar: null }, + { foo: 7, bar: true }, + { foo: 8, bar: null }, + { foo: 9, bar: false }, + { foo: 10, bar: null }, + { foo: 11, bar: null }, + { foo: 12, bar: false }, + { foo: 13, bar: true } + ]; + + var result = new Query(data).group({ field: "bar" }).toArray(); + + equal(result.length, 3); + + equal(result[0].field, "bar"); + equal(result[0].value, null); + equal(result[0].items.length, 6); + + equal(result[1].field, "bar"); + equal(result[1].value, false); + equal(result[1].items.length, 3); + + equal(result[2].field, "bar"); + equal(result[2].value, true); + equal(result[2].items.length, 4); +}); + +test("group by nullable boolean with more than 10 items descending", function() { + var data = [ + { foo: 1, bar: null }, + { foo: 2, bar: true }, + { foo: 3, bar: null }, + { foo: 4, bar: false }, + { foo: 5, bar: true }, + { foo: 6, bar: null }, + { foo: 7, bar: true }, + { foo: 8, bar: null }, + { foo: 9, bar: false }, + { foo: 10, bar: null }, + { foo: 11, bar: null }, + { foo: 12, bar: false }, + { foo: 13, bar: true } + ]; + + var result = new Query(data).group({ field: "bar", dir: "desc" }).toArray(); + + equal(result.length, 3); + + equal(result[0].field, "bar"); + equal(result[0].value, true); + equal(result[0].items.length, 4); + + equal(result[1].field, "bar"); + equal(result[1].value, false); + equal(result[1].items.length, 3); + + equal(result[2].field, "bar"); + equal(result[2].value, null); + equal(result[2].items.length, 6); +}); + +test("group by nullable int with more than 10 items", function() { + var data = [ + { foo: 1, bar: null }, + { foo: 2, bar: 1 }, + { foo: 3, bar: null }, + { foo: 4, bar: 0 }, + { foo: 5, bar: 1 }, + { foo: 6, bar: null }, + { foo: 7, bar: 1 }, + { foo: 8, bar: null }, + { foo: 9, bar: 0 }, + { foo: 10, bar: null }, + { foo: 11, bar: null }, + { foo: 12, bar: 0 }, + { foo: 13, bar: 1 } + ]; + + var result = new Query(data).group({ field: "bar" }).toArray(); + + equal(result.length, 3); + + equal(result[0].field, "bar"); + equal(result[0].value, null); + equal(result[0].items.length, 6); + + equal(result[1].field, "bar"); + equal(result[1].value, 0); + equal(result[1].items.length, 3); + + equal(result[2].field, "bar"); + equal(result[2].value, 1); + equal(result[2].items.length, 4); +}); + +test("group by nullable int with more than 10 items descending", function() { + var data = [ + { foo: 1, bar: null }, + { foo: 2, bar: 1 }, + { foo: 3, bar: null }, + { foo: 4, bar: 0 }, + { foo: 5, bar: 1 }, + { foo: 6, bar: null }, + { foo: 7, bar: 1 }, + { foo: 8, bar: null }, + { foo: 9, bar: 0 }, + { foo: 10, bar: null }, + { foo: 11, bar: null }, + { foo: 12, bar: 0 }, + { foo: 13, bar: 1 } + ]; + + var result = new Query(data).group({ field: "bar", dir: "desc" }).toArray(); + + equal(result.length, 3); + + equal(result[0].field, "bar"); + equal(result[0].value, 1); + equal(result[0].items.length, 4); + + equal(result[1].field, "bar"); + equal(result[1].value, 0); + equal(result[1].items.length, 3); + + equal(result[2].field, "bar"); + equal(result[2].value, null); + equal(result[2].items.length, 6); +}); + + +test("groupby groups data by multiple fields with 3 levels", function() { + var data = [ {foo: 100, bar: "baz", baz: "baz"} , {foo: 100, bar: "bar", baz: "baz"} , {foo: 1, bar: "baz", baz: "baz"} ], + firstGroup, + secondGroup; + + var result = new Query(data).group( [{ field: "foo" }, { field: "bar" },{ field: "baz" }]).toArray(); + equal(result.length, 2); + firstGroup = result[0]; + secondGroup = result[1]; + + equal(firstGroup.value, 1); + equal(firstGroup.field, "foo"); + equal(firstGroup.items.length, 1); + equal(firstGroup.items[0].value, "baz"); + equal(firstGroup.items[0].field, "bar"); + equal(firstGroup.items[0].items.length, 1); + + equal(firstGroup.value, 1); + equal(firstGroup.field, "foo"); + equal(firstGroup.items.length, 1); + equal(firstGroup.items[0].items[0].value, "baz"); + equal(firstGroup.items[0].items[0].field, "baz"); + equal(firstGroup.items[0].items[0].items.length, 1); + + equal(secondGroup.value, 100); + equal(secondGroup.field, "foo"); + equal(secondGroup.items.length, 2); + + equal(secondGroup.items[0].value, "bar"); + equal(secondGroup.items[0].field, "bar"); + equal(secondGroup.items[0].items.length, 1); + equal(secondGroup.items[1].value, "baz"); + equal(secondGroup.items[1].field, "bar"); + equal(secondGroup.items[1].items.length, 1); + +}); + +test("group by nullable boolean", function() { + var data = [ + { + foo: 1, + bar: true + + }, + { + foo: 2, + bar: false + + }, + { + foo: 3, + bar: null + + }, + { + foo: 5, + bar: false + + } + ]; + + var result = new Query(data).sort({ field: "foo", dir: "desc" }).group({ field: "bar" }).toArray(); + + equal(result.length, 3); + + equal(result[0].field, "bar"); + equal(result[0].value, null); + equal(result[0].items.length, 1); + + equal(result[1].field, "bar"); + equal(result[1].value, false); + equal(result[1].items.length, 2); + + equal(result[2].field, "bar"); + equal(result[2].value, true); + equal(result[2].items.length, 1); +}); + +test("sort desc when group by nullable boolean", function() { + var data = [ + { + foo: 1, + bar: null + + }, + { + foo: 2, + bar: null + + } + ]; + + var result = new Query(data).sort({ field: "foo", dir: "desc" }).group({ field: "bar" }).toArray(); + + equal(result.length, 1); + + equal(result[0].field, "bar"); + equal(result[0].value, null); + equal(result[0].items.length, 2); + + equal(result[0].items[0].foo, 2); + equal(result[0].items[1].foo, 1); +}); + +test("sort asc when group by nullable boolean", function() { + var data = [ + { + foo: 2, + bar: null + + }, + { + foo: 1, + bar: null + + } + ]; + + var result = new Query(data).sort({ field: "foo", dir: "asc" }).group({ field: "bar" }).toArray(); + + equal(result.length, 1); + + equal(result[0].field, "bar"); + equal(result[0].value, null); + equal(result[0].items.length, 2); + + equal(result[0].items[0].foo, 1); + equal(result[0].items[1].foo, 2); +}); + +test("sort asc by nullable string with more than 10 items", function() { + var data = [ + { foo: 1, bar: null }, + { foo: 2, bar: "foo" }, + { foo: 3, bar: null }, + { foo: 4, bar: "foo" }, + { foo: 5, bar: "foo" }, + { foo: 6, bar: null }, + { foo: 7, bar: "foo" }, + { foo: 8, bar: null }, + { foo: 9, bar: "foo" }, + { foo: 10, bar: null }, + { foo: 11, bar: undefined }, + { foo: 12, bar: "foo" }, + { foo: 13, bar: "foo" } + ]; + var result = new Query(data).sort({ field: "bar", dir: "asc" }).toArray(); + + equal(result[0].bar, null); + equal(result[1].bar, null); + equal(result[2].bar, null); + equal(result[3].bar, null); + equal(result[4].bar, null); + equal(result[5].bar, null); + equal(result[6].bar, "foo"); + equal(result[7].bar, "foo"); + equal(result[8].bar, "foo"); + equal(result[9].bar, "foo"); + equal(result[10].bar, "foo"); + equal(result[11].bar, "foo"); + equal(result[12].bar, "foo"); +}); + +test("sort desc by nullable string with more than 10 items", function() { + var data = [ + { foo: 1, bar: "foo" }, + { foo: 2, bar: null }, + { foo: 3, bar: null }, + { foo: 4, bar: "foo" }, + { foo: 5, bar: "foo" }, + { foo: 6, bar: null }, + { foo: 7, bar: "foo" }, + { foo: 8, bar: null }, + { foo: 9, bar: "foo" }, + { foo: 10, bar: null }, + { foo: 11, bar: null }, + { foo: 12, bar: "foo" }, + { foo: 13, bar: "foo" } + ]; + + var result = new Query(data).sort({ field: "bar", dir: "desc" }).toArray(); + + equal(result[0].bar, "foo"); + equal(result[1].bar, "foo"); + equal(result[2].bar, "foo"); + equal(result[3].bar, "foo"); + equal(result[4].bar, "foo"); + equal(result[5].bar, "foo"); + equal(result[6].bar, "foo"); + + equal(result[7].bar, null); + equal(result[8].bar, null); + equal(result[9].bar, null); + equal(result[10].bar, null); + equal(result[11].bar, null); + equal(result[12].bar, null); +}); + +test("sort desc by nullable string with more than 10 items", function() { + var data = [ + { foo: 1, bar: "foo" }, + { foo: 2, bar: null }, + { foo: 3, bar: null }, + { foo: 4, bar: "foo" }, + { foo: 5, bar: "foo" }, + { foo: 6, bar: null }, + { foo: 7, bar: "foo" }, + { foo: 8, bar: null }, + { foo: 9, bar: "foo" }, + { foo: 10, bar: null }, + { foo: 11, bar: null }, + { foo: 12, bar: "foo" }, + { foo: 13, bar: "foo" } + ]; + + var result = new Query(data).sort({ field: "bar", dir: "desc" }).toArray(); + + equal(result[0].bar, "foo"); + equal(result[1].bar, "foo"); + equal(result[2].bar, "foo"); + equal(result[3].bar, "foo"); + equal(result[4].bar, "foo"); + equal(result[5].bar, "foo"); + equal(result[6].bar, "foo"); + + equal(result[7].bar, null); + equal(result[8].bar, null); + equal(result[9].bar, null); + equal(result[10].bar, null); + equal(result[11].bar, null); + equal(result[12].bar, null); +}); + + +test("group aggregates are calculated if provided", function() { + var data = [ {foo: 100, bar: "baz"} , {foo: 100, bar: "bar"} , {foo: 1, bar: "baz"} ]; + + var result = new Query(data).group( [{ field: "foo", aggregates: [{ field: "foo", aggregate: "sum" }] }]).toArray(); + + equal(result.length, 2); + + equal(result[0].aggregates["foo"].sum, 1); + equal(result[1].aggregates["foo"].sum, 200); +}); + +test("group aggregates are caseinsensitive", function() { + var data = [ {foo: 100, bar: "baz"} , {foo: 100, bar: "bar"} , {foo: 1, bar: "Baz"} ]; + + var result = new Query(data).group( [{ field: "bar", aggregates: [{ field: "foo", aggregate: "sum" }] }]).toArray(); + + equal(result.length, 3); + + equal(result[0].aggregates["foo"].sum, 100); + equal(result[1].aggregates["foo"].sum, 100); + equal(result[2].aggregates["foo"].sum, 1); +}); + +test("group aggregates are calculated for multiple fields if provided", function() { + var data = [ {foo: 100, bar: "baz"} , {foo: 100, bar: "bar"} , {foo: 1, bar: "baz"} ]; + + var result = new Query(data).group( [{ field: "foo", aggregates: [{ field: "foo", aggregate: "sum" }, { field: "bar", aggregate: "count" }] }]).toArray(); + + equal(result.length, 2); + + equal(result[0].aggregates["foo"].sum, 1); + equal(result[1].aggregates["foo"].sum, 200); + equal(result[0].aggregates["bar"].count, 1); + equal(result[1].aggregates["bar"].count, 2); +}); + +test("group aggregates are calculated for multiple group levels", function() { + var data = [ {foo: 100, bar: "baz"} , {foo: 100, bar: "bar"} , {foo: 1, bar: "baz"} ]; + + var result = new Query(data).group( [ + { field: "foo", aggregates: [{ field: "foo", aggregate: "sum" }] }, + { field: "bar", aggregates: [{ field: "foo", aggregate: "sum" }]} + ]).toArray(); + + equal(result.length, 2); + + equal(result[0].aggregates["foo"].sum, 1); + equal(result[0].items[0].aggregates["foo"].sum, 1); + equal(result[1].aggregates["foo"].sum, 200); + equal(result[1].items[0].aggregates["foo"].sum, 100); + equal(result[1].items[1].aggregates["foo"].sum, 100); +}); + +test("group aggregates with multiple group levels and paging original data is required", function() { + var data = [ {foo: 100, bar: "baz"} , {foo: 100, bar: "bar"} , {foo: 1, bar: "baz"} ]; + + var result = new Query(data).skip(1).take(1).group( [ + { field: "foo", aggregates: [{ field: "foo", aggregate: "sum" }] }, + { field: "bar", aggregates: [{ field: "foo", aggregate: "sum" }]} + ], data).toArray(); + + equal(result.length, 1); + + equal(result[0].aggregates["foo"].sum, 200); + equal(result[0].items[0].aggregates["foo"].sum, 100); +}); + +test("aggregate calculates aggregates for a collection", function() { + var data = [ {foo: 100, bar: "baz"} , {foo: 100, bar: "bar"} , {foo: 1, bar: "baz"} ]; + + var result = new Query(data).aggregate( [{ field: "foo", aggregate: "sum" }, { field: "bar", aggregate: "count" }] ); + + equal(result.foo.sum, 201); + equal(result.bar.count, 3); +}); + +test("aggregate returns empty object if no descriptor are provided", function() { + var data = [ {foo: 100, bar: "baz"} , {foo: 100, bar: "bar"} , {foo: 1, bar: "baz"} ]; + + var result = new Query(data).aggregate(); + + ok(result); +}); + +test("aggregate returns empty object if collection is empty", function() { + var data = [ ]; + + var result = new Query(data).aggregate([{ field: "foo", aggregate: "sum" }, { field: "bar", aggregate: "count" }]); + + ok(result); +}); + +test("aggregate max returns max value for a given field", function() { + var data = [ {foo: 100, bar: "baz"} , {foo: 100, bar: "bar"} , {foo: 1, bar: "baz"} ]; + + var result = new Query(data).aggregate( [{ field: "foo", aggregate: "max" }] ); + + equal(result.foo.max, 100); +}); + +test("aggregate average for a given field", function() { + var data = [ {foo: 100, bar: "baz"} , {foo: 100, bar: "bar"} , {foo: 1, bar: "baz"} ]; + + var result = new Query(data).aggregate( [{ field: "foo", aggregate: "average" }] ); + + equal(result.foo.average, 67); +}); + +test("aggregate function should be caseinsensitive", function() { + var data = [ {foo: 100, bar: "baz"} , {foo: 100, bar: "bar"} , {foo: 1, bar: "baz"} ]; + + var result = new Query(data).aggregate( [{ field: "foo", aggregate: "Min" }] ); + + equal(result.foo.Min, 1); +}); + +test("aggregate min returns min value for a given field", function() { + var data = [ {foo: 100, bar: "baz"} , {foo: 100, bar: "bar"} , {foo: 1, bar: "baz"} ]; + + var result = new Query(data).aggregate( [{ field: "foo", aggregate: "min" }] ); + + equal(result.foo.min, 1); +}); + +test("aggregate min returns min value for a given field with nulls", function() { + var data = [ {foo: 1, bar: "baz"}, {foo: 100, bar: "baz"}, {foo: null, bar: "baz"}, {foo: 100, bar: "bar"} ]; + + var result = new Query(data).aggregate( [{ field: "foo", aggregate: "min" }] ); + + equal(result.foo.min, 1); +}); + +test("aggregate min returns min value for a given field with 0", function() { + var data = [ {foo: 1, bar: "baz"}, {foo: 100, bar: "baz"}, {foo: 0, bar: "baz"}, {foo: 100, bar: "bar"} ]; + + var result = new Query(data).aggregate( [{ field: "foo", aggregate: "min" }] ); + + equal(result.foo.min, 0); +}); + +test("aggregate min returns min value for a given field with undefined", function() { + var data = [ {foo: 1, bar: "baz"}, {foo: 100, bar: "baz"}, {foo: undefined, bar: "baz"}, {foo: 100, bar: "bar"} ]; + + var result = new Query(data).aggregate( [{ field: "foo", aggregate: "min" }] ); + + equal(result.foo.min, 1); +}); + +test("aggregate min returns min value for a given field with 0", function() { + var data = [ {foo: 1, bar: "baz"}, {foo: 100, bar: "baz"}, {foo: 0, bar: "baz"}, {foo: 100, bar: "bar"} ]; + + var result = new Query(data).aggregate( [{ field: "foo", aggregate: "min" }] ); + + equal(result.foo.min, 0); +}); + +test("aggregate min returns min value for a given field with less than 0", function() { + var data = [ {foo: -1, bar: "baz"}, {foo: 100, bar: "baz"}, {foo: 0, bar: "baz"}, {foo: 100, bar: "bar"} ]; + + var result = new Query(data).aggregate( [{ field: "foo", aggregate: "min" }] ); + + equal(result.foo.min, -1); +}); + +test("aggregate max returns min value for a given field with null", function() { + var data = [ {foo: 10, bar: "baz"}, {foo: 100, bar: "baz"}, {foo: null, bar: "baz"}, {foo: 10, bar: "bar"} ]; + + var result = new Query(data).aggregate( [{ field: "foo", aggregate: "max" }] ); + + equal(result.foo.max, 100); +}); + +test("aggregate max returns min value for a given field with undefined", function() { + var data = [ {foo: 10, bar: "baz"}, {foo: 100, bar: "baz"}, {foo: undefined, bar: "baz"}, {foo: 10, bar: "bar"} ]; + + var result = new Query(data).aggregate( [{ field: "foo", aggregate: "max" }] ); + + equal(result.foo.max, 100); +}); + +test("aggregate max returns min value for a given field with 0", function() { + var data = [ {foo: 10, bar: "baz"}, {foo: 100, bar: "baz"}, {foo: 0, bar: "baz"}, {foo: 10, bar: "bar"} ]; + + var result = new Query(data).aggregate( [{ field: "foo", aggregate: "max" }] ); + + equal(result.foo.max, 100); +}); + +test("aggregate count with null", function() { + var data = [ {foo: 10, bar: "baz"}, {foo: 100, bar: "baz"}, {foo: null, bar: "baz"}, {foo: 10, bar: "bar"} ]; + + var result = new Query(data).aggregate( [{ field: "foo", aggregate: "count" }] ); + + equal(result.foo.count, 4); +}); + +test("group parent group should have hasSubgroups set to true", function() { + var data = [ {foo: 100, bar: "baz"} , {foo: 100, bar: "bar"} , {foo: 1, bar: "baz"} ]; + + var result = new Query(data).group( [ + { field: "foo" }, + { field: "bar" } + ], data).toArray(); + + equal(result.length, 2); + + ok(result[0].hasSubgroups); + ok(!result[0].items[0].hasSubgroups); +}); + +test("group group should have hasSubgroups set to false", function() { + var data = [ {foo: 100, bar: "baz"} , {foo: 100, bar: "bar"} , {foo: 1, bar: "baz"} ]; + + var result = new Query(data).group( [ { field: "foo" } ], data).toArray(); + + equal(result.length, 2); + + ok(!result[0].hasSubgroups); +}); + +test("aggregate return empty object if data is undefined", function() { + var result = new Query(undefined).aggregate([{ field: "foo", aggregate: "sum" }, { field: "bar", aggregate: "count" }]); + + ok(result); +}); + +test("group on empty array", function() { + var data = [ ]; + + var result = new Query(data).group( [ { field: "foo" } ], data).toArray(); + + equal(result.length, 0); +}); + +}()); diff --git a/tests/data/remotetransport.js b/tests/data/remotetransport.js new file mode 100644 index 00000000000..35c3fcbc852 --- /dev/null +++ b/tests/data/remotetransport.js @@ -0,0 +1,754 @@ +(function(){ +var RemoteTransport = kendo.data.RemoteTransport; + +module("RemoteTransport", { + setup: function() { + $.mockjaxSettings.contentType = "text/json"; + $.mockjaxSettings.responseTime = 0; + }, + teardown: function() { + $.mockjaxClear(); + } +}); + +asyncTest("read calls $.ajax", 1, function() { + var transport = new RemoteTransport({ + read: { + url: "foo" + } + }); + + $.mockjax({ + url: "foo", + response: function() { + ok(true); + start(); + } + }); + + transport.read(); +}); + +asyncTest("read passes its options to $.ajax", 1, function() { + var transport = new RemoteTransport({ + read: { + } + }); + + $.mockjax({ + url: "foo", + response: function() { + ok(true); + start(); + } + }); + + transport.read({ url: "foo" }); +}); + +asyncTest("read passes options.data to its parameterMap", 1, function() { + var parameterMapWasCalled = false, + transport = new RemoteTransport({ + read: { + url: "foo" + }, + parameterMap: function() { + parameterMapWasCalled = true; + } + }); + + $.mockjax({ + url: "foo", + response: function() { + ok(parameterMapWasCalled); + start(); + } + }); + + transport.read({ url: "foo" }); +}); + +asyncTest("read passes constructor options.read.data to its parameterMap", 2, function() { + var data, + transport = new RemoteTransport({ + read: { + url: "foo", + data: { + foo: "bar" + } + }, + parameterMap: function() { + data = arguments[0]; + return data; + } + }); + + $.mockjax({ + url: "foo", + response: function() { + equal(data.foo, "bar"); + equal(data.baz, "moo"); + start(); + } + }); + + transport.read({ url: "foo", data: { baz: "moo" } }); +}); + +asyncTest("read passes constructor data function result to its parameterMap", 2, function() { + var data, + transport = new RemoteTransport({ + read: { + url: "foo", + data: function(){ + return { + foo: "bar" + } + } + }, + parameterMap: function() { + data = arguments[0]; + return data; + } + }); + + $.mockjax({ + url: "foo", + response: function() { + equal(data.foo, "bar"); + equal(data.baz, "moo"); + start(); + } + }); + + transport.read({ url: "foo", data: { baz: "moo" } }); +}); + +asyncTest("read constructor data function is persisted on multiple requests", 2, function() { + var data, + called = 0, + transport = new RemoteTransport({ + read: { + url: "foo", + data: function(){ + called++; + return { + foo: "bar" + } + } + }, + parameterMap: function() { + data = arguments[0]; + return data; + } + }); + + $.mockjax({ + url: "foo", + response: function() { + if(called == 2) { + ok(true); + start(); + } + } + }); + + transport.read({ url: "foo", data: { baz: "moo" } }); + $.mockjaxClear(); + $.mockjax({ + url: "foo", + response: function() { + if(called == 2) { + ok(true); + start(); + } + } + }); + + stop(); + transport.read({ url: "foo", data: { baz: "moo" } }); +}); + +asyncTest("read constructor data has access to the data to be passed to parameterMap", 2, function() { + var data, + called = 0, + transport = new RemoteTransport({ + read: { + url: "foo", + data: function(data){ + ok(data); + equal(data.baz, "moo"); + } + } + }); + + $.mockjax({ + url: "foo", + response: function() { + start(); + } + }); + + transport.read({ url: "foo", data: { baz: "moo" } }); + + $.mockjaxClear(); +}); + +asyncTest("read original data is not contaminated when additional data is submitted", 1, function() { + var data, + called = 0, + transport = new RemoteTransport({ + read: { + url: "foo", + data: { + foo: "bar" + } + } + }); + + $.mockjax({ + url: "foo", + response: function() { + start(); + } + }); + + transport.read({ url: "foo", data: { baz: "moo" } }); + + ok(!("baz" in transport.options.read.data)); +}); + +asyncTest("update passes data options to parameterMap", 1, function() { + var data, transport = new RemoteTransport({ + update: { + url: "foo" + }, + parameterMap: function() { + data = arguments[0]; + return data; + } + }); + + $.mockjax({ + url: "foo", + response: function() { + equal(data.foo, "bar"); + start(); + } + }); + + transport.update( { data: { foo: "bar" } } ); +}); + +asyncTest("the type argument of the parameterMap is update during updating", 1, function() { + var parameterMapType, transport = new RemoteTransport({ + update: { + url: "foo" + }, + parameterMap: function(data, type) { + parameterMapType = type; + return data; + } + }); + + $.mockjax({ + url: "foo", + response: function() { + equal(parameterMapType, "update"); + start(); + } + }); + + transport.update(); +}); + +asyncTest("the type argument of the parameterMap is destroy during destroying", 1, function() { + var parameterMapType, transport = new RemoteTransport({ + destroy: { + url: "foo" + }, + parameterMap: function(data, type) { + parameterMapType = type; + return data; + } + }); + + $.mockjax({ + url: "foo", + response: function() { + equal(parameterMapType, "destroy"); + start(); + } + }); + + transport.destroy(); +}); + +asyncTest("the type argument of the parameterMap is create during creating", 1, function() { + var parameterMapType, transport = new RemoteTransport({ + create: { + url: "foo" + }, + parameterMap: function(data, type) { + parameterMapType = type; + return data; + } + }); + + $.mockjax({ + url: "foo", + response: function() { + equal(parameterMapType, "create"); + start(); + } + }); + + transport.create(); +}); + +asyncTest("the type argument of the parameterMap is read during reading", 1, function() { + var parameterMapType, transport = new RemoteTransport({ + read: { + url: "foo" + }, + parameterMap: function(data, type) { + parameterMapType = type; + return data; + } + }); + + $.mockjax({ + url: "foo", + response: function() { + equal(parameterMapType, "read"); + start(); + } + }); + + transport.read(); +}); + +test("parameterMap as plain object", function() { + var transport = new RemoteTransport({ + parameterMap: { take: "$take", skip: "$skip" } + }); + + var result = transport.parameterMap({ take: 1, skip: 1 }); + equal(result["$take"], 1); + equal(result["$skip"], 1); +}); + +test("parameterMap as plain object copies unsuported fields", function() { + var transport = new RemoteTransport({ + parameterMap: { take: "$take", skip: "$skip" } + }); + + var result = transport.parameterMap({ take: 1, skip: 1, foo: "bar" }); + equal(result["foo"], "bar"); +}); + +test("parameterMap as plain object calls functions", function() { + var transport = new RemoteTransport({ + parameterMap: { + take: { + key: "$take", + value: function(take) { + return take + "bar"; + } + } + } + }); + + var result = transport.parameterMap({ take: "foo" }); + + equal(result["$take"], "foobar"); +}); + +asyncTest("string options are treated as url", 1, function() { + var transport = new RemoteTransport({ + read: "foo" + }); + + $.mockjax({ + url: "foo", + response: function() { + ok(true); + start(); + } + }); + + transport.read(); +}); + +asyncTest("read calls the success handler when the ajax response is returned", 1, function() { + var transport = new RemoteTransport({ + read: "foo" + }); + + $.mockjax({ + url: "foo", + responseText: "[]" + }); + + transport.read({ + success: function() { + ok(true); + start(); + } + }); +}); + +asyncTest("read calls the error handler when the ajax request fails", 1, function() { + var transport = new RemoteTransport({ + read: "foo" + }); + + $.mockjax({ + url: "foo", + status: 500 + }); + + transport.read({ + success: function() { + ok(false); // we should not be here + }, + error: function() { + start(); + ok(true); + } + }); +}); + +asyncTest("read check if result exists in cache passing the data argumets as key", 1, function() { + var key = false, + transport = new RemoteTransport({ + read: "foo", + cache: { + find: function() { + key = arguments[0]; + return undefined; + }, + add: $.noop + } + }); + + $.mockjax({ + url: "foo", + responseText: [] + }); + + transport.read({ + data: { foo: "bar" }, + success: function() { + start(); + equal(key.foo, "bar"); + } + }); +}); + +asyncTest("read does not send request if data exists in cache", 1, function() { + var data = [1,2,3,4], + transport = new RemoteTransport({ + read: "foo", + cache: { + find: function() { + return data; + } + } + }); + + $.mockjax({ + url: "foo", + response: function() { + ok(false); // we should not be here + } + }); + + transport.read({ + success: function() { + start(); + equal(arguments[0], data); + } + }); + +}); + +asyncTest("read adds item to the cache", 2, function() { + var transport = new RemoteTransport({ + read: "foo", + cache: { + find: function() { + return undefined; + }, + add: function(key, item) { + start(); + equal(key.foo, "bar"); + equal(item[0].age, 1); + } + } + }); + + $.mockjax({ + url: "foo", + responseText: '[{"age": 1}]' + }); + + transport.read({ + data: { foo: "bar" }, + success: $.noop + }); + +}); + +test("setting cache to true applies in memory cache", function() { + var transport = new RemoteTransport({ + read: "foo", + cache: true + }); + + ok(transport.cache instanceof kendo.data.Cache); +}); + +test("setting cache to false disables caching", function() { + var transport = new RemoteTransport({ + cache: false + }); + + ok(!(transport.cache instanceof kendo.data.Cache)); +}); + +test("setting cache to inmemory returns Cache", function() { + var cache = kendo.data.Cache.create("inmemory"); + ok(cache instanceof kendo.data.Cache); +}); + +test("update as string options are treated as url", function() { + var transport = new RemoteTransport({ + update: "foo" + }); + + equal(transport.options.update.url, "foo"); +}); + +test("destroy as string option is treated as url", function() { + var transport = new RemoteTransport({ + destroy: "foo" + }); + + equal(transport.options.destroy.url, "foo"); +}); + +test("create as string option is treated as url", function() { + var transport = new RemoteTransport({ + create: "foo" + }); + + equal(transport.options.create.url, "foo"); +}); + +asyncTest("update calls $.ajax", 1, function() { + var transport = new RemoteTransport({ + update: { + url: "foo" + } + }); + + $.mockjax({ + url: "foo", + response: function() { + ok(true); + start(); + } + }); + + transport.update(); +}); + +asyncTest("destroy calls $.ajax", 1, function() { + var transport = new RemoteTransport({ + destroy: { + url: "foo" + } + }); + + $.mockjax({ + url: "foo", + response: function() { + ok(true); + start(); + } + }); + + transport.destroy(); +}); + +asyncTest("create calls $.ajax", 1, function() { + var transport = new RemoteTransport({ + create: { + url: "foo" + } + }); + + $.mockjax({ + url: "foo", + response: function() { + ok(true); + start(); + } + }); + + transport.create(); +}); + +asyncTest("update passes its options to $.ajax", 1, function() { + var transport = new RemoteTransport({ + update: { + } + }); + + $.mockjax({ + url: "foo", + response: function() { + ok(true); + start(); + } + }); + + transport.update({ url: "foo" }); +}); + +asyncTest("destroy passes its options to $.ajax", 1, function() { + var transport = new RemoteTransport({ + destroy: { + } + }); + + $.mockjax({ + url: "foo", + response: function() { + ok(true); + start(); + } + }); + + transport.destroy({ url: "foo" }); +}); + +asyncTest("update calls the success handler when the ajax response is returned", 1, function() { + var transport = new RemoteTransport({ + update: "foo" + }); + + $.mockjax({ + url: "foo", + responseText: "[]" + }); + + transport.update({ + success: function() { + ok(true); + start(); + } + }); +}); + +asyncTest("update calls the error handler when the ajax request fails", 1, function() { + var transport = new RemoteTransport({ + update: "foo" + }); + + $.mockjax({ + url: "foo", + status: 500 + }); + + transport.update({ + success: function() { + ok(false); // we should not be here + }, + error: function() { + start(); + ok(true); + } + }); +}); + +asyncTest("update calls its parameterMap", 1, function() { + var parameterMapWasCalled = false; + var transport = new RemoteTransport({ + update: { + url: "foo" + }, + parameterMap: function() { + parameterMapWasCalled = true; + } + }); + + $.mockjax({ + url: "foo", + response: function() { + ok(parameterMapWasCalled); + start(); + } + }); + + transport.update({ url: "foo" }); +}); + +asyncTest("update passes constructor options.update.data to its parameterMap", 2, function() { + var data, + transport = new RemoteTransport({ + update: { + url: "foo", + data: { + foo: "bar" + } + }, + parameterMap: function() { + data = arguments[0]; + return data; + } + }); + + $.mockjax({ + url: "foo", + response: function() { + equal(data.foo, "bar"); + equal(data.baz, "moo"); + start(); + } + }); + + transport.update({ url: "foo", data: { baz: "moo" } }); +}); + +asyncTest("update passes constructor data function result to its parameterMap", 2, function() { + var data, + transport = new RemoteTransport({ + update: { + url: "foo", + data: function(){ + return { + foo: "bar" + } + } + }, + parameterMap: function() { + data = arguments[0]; + return data; + } + }); + + $.mockjax({ + url: "foo", + response: function() { + equal(data.foo, "bar"); + equal(data.baz, "moo"); + start(); + } + }); + + transport.update({ url: "foo", data: { baz: "moo" } }); +}); + +}()); diff --git a/tests/data/signalr.js b/tests/data/signalr.js new file mode 100644 index 00000000000..580afbdbede --- /dev/null +++ b/tests/data/signalr.js @@ -0,0 +1,918 @@ +(function() { + +var SignalR; +var transport; + +function promise() { + return { + done: function(callback) { + if (callback) { + callback(); + } + return this; + }, + fail: $.noop + }; +} + +function hub() { + return { + on: $.noop, + invoke: function() { + return promise(); + } + }; +} + +module("SignalR", { + setup: function() { + SignalR = kendo.data.transports.signalr; + + transport = new SignalR({ + promise: promise(), + hub: hub() + }); + } +}); + +test("signalr transport inherits from remote transport", function() { + ok(transport instanceof kendo.data.RemoteTransport); +}); + +test("signalr transport requires the promise option to be set", 1, function() { + try { + new SignalR(); + } catch(e) { + equal(e.toString(), 'Error: The "promise" option must be set.'); + } +}); + +test("the promise option must be a Promise", 1, function() { + try { + new SignalR({ + promise: {} + }); + } catch(e) { + equal(e.toString(), 'Error: The "promise" option must be a Promise.'); + } +}); + +test("signalr transport requires the hub option to be set", 1, function() { + try { + new SignalR({ + promise: promise() + }); + } catch(e) { + equal(e.toString(), 'Error: The "hub" option must be set.'); + } +}); + +test("the hub object must have on and invoke methods", 1, function() { + try { + new SignalR({ + promise: promise(), + hub: {} + }); + } catch(e) { + equal(e.toString(), 'Error: The "hub" option is not a valid SignalR hub proxy.'); + } +}); + +test("the push method listens for create notifications from the hub", function() { + var proxy = stub({}, { + on: $.noop, + invoke: $.noop + }); + + transport = new SignalR({ + promise: promise(), + hub: proxy, + client: { + create: "create" + } + }); + + transport.push({}); + + equal(proxy.calls("on"), 1); + equal(proxy.args("on", 0)[0], "create"); +}); + +test("the push method listens for update notifications from the hub", function() { + var proxy = stub({}, { + on: $.noop, + invoke: $.noop + }); + + transport = new SignalR({ + promise: promise(), + hub: proxy, + client: { + update: "update" + } + }); + + transport.push({}); + + equal(proxy.calls("on"), 1); + equal(proxy.args("on", 0)[0], "update"); +}); + +test("the push method listens for destroy notifications from the hub", function() { + var proxy = stub({}, { + on: $.noop, + invoke: $.noop + }); + + transport = new SignalR({ + promise: promise(), + hub: proxy, + client: { + destroy: "destroy" + } + }); + + transport.push({}); + + equal(proxy.calls("on"), 1); + equal(proxy.args("on", 0)[0], "destroy"); +}); + +test("transport calls pushCreate when the create method is triggered by the hub", function() { + var result = {}; + + transport = new SignalR({ + promise: promise(), + hub: { + invoke: $.noop, + on: function(method, callback) { + callback(result); + } + }, + client: { + create: "c" + } + }); + + var options = stub({}, "pushCreate"); + + transport.push(options); + + equal(options.calls("pushCreate"), 1); + equal(options.args("pushCreate", 0)[0], result); +}); + +test("transport calls pushUpdate when the update method is triggered by the hub", function() { + var result = {}; + + transport = new SignalR({ + promise: promise(), + hub: { + invoke: $.noop, + on: function(method, callback) { + callback(result); + } + }, + client: { + update: "c" + } + }); + + var options = stub({}, "pushUpdate"); + + transport.push(options); + + equal(options.calls("pushUpdate"), 1); + equal(options.args("pushUpdate", 0)[0], result); +}); + +test("transport calls pushDestroy when the destroy method is triggered by the hub", function() { + var result = {}; + + transport = new SignalR({ + promise: promise(), + hub: { + invoke: $.noop, + on: function(method, callback) { + callback(result); + } + }, + client: { + destroy: "c" + } + }); + + var options = stub({}, "pushDestroy"); + + transport.push(options); + + equal(options.calls("pushDestroy"), 1); + equal(options.args("pushDestroy", 0)[0], result); +}); + +test("can override the push method from the options", function() { + var push = $.noop; + + transport = new SignalR({ + promise: promise(), + hub: hub(), + push: push + }); + + equal(transport.push, push); +}); + +test("the context of the custom push method is the transport itself", 1, function() { + transport = new SignalR({ + promise: promise(), + hub: hub(), + push: function() { + strictEqual(this, transport); + } + }); + + transport.push(); +}); + +test("the read method invokes the read server method", function() { + var hub = stub( { + on: $.noop + }, { + invoke: function() { + return promise(); + } + }); + + transport = new SignalR({ + promise: { + done: function(callback) { + callback(); + + equal(hub.calls("invoke"), 1); + equal(hub.args("invoke", 0)[0], "r"); + }, + fail: $.noop + }, + hub: hub, + server: { + read: "r" + } + }); + + transport.read({}); +}); + +test("the read method throws error if server configuration is not specified", 1, function() { + try { + transport.read(); + } catch (e) { + equal(e.toString(), 'Error: The "server.read" option must be set.'); + } +}); + +test("the read method passes the data field of the options to the server read method", function() { + var hub = stub( { + on: $.noop + }, { + invoke: function() { + return promise(); + } + }); + + var options = { data: "data" }; + + transport = new SignalR({ + promise: { + done: function(callback) { + callback(); + + equal(hub.args("invoke", 0)[1], options.data); + }, + fail: $.noop + }, + hub: hub, + server: { + read: "r" + } + }); + + transport.read(options); +}); + +test("the read method invokes the parameterMap", function() { + var transportOptions = { + promise: promise(), + hub: hub(), + server: { + read: "r" + } + }; + + stub(transportOptions, "parameterMap"); + + transport = new SignalR(transportOptions); + + transport.read({}); + + equal(transportOptions.calls("parameterMap"), 1); +}); + +test("the read method passes options.data to the parameterMap", function() { + var transportOptions = { + promise: promise(), + hub: hub(), + server: { + read: "r" + } + }; + + stub(transportOptions, "parameterMap"); + + transport = new SignalR(transportOptions); + + var options = { data: "foo" }; + + transport.read(options); + + equal(transportOptions.args("parameterMap", 0)[0], options.data); +}); + +test("the read method invokes parameterMap and passes 'read' as the type of operation", function() { + var transportOptions = { + promise: promise(), + hub: hub(), + server: { + read: "r" + } + }; + + stub(transportOptions, "parameterMap"); + + transport = new SignalR(transportOptions); + + transport.read({}); + + equal(transportOptions.args("parameterMap", 0)[1], "read"); +}); + +test("read calls options.success when invoke is done", function() { + transport = new SignalR({ + promise: promise(), + hub: { + invoke: function() { + return promise(); + }, + on: $.noop + }, + server: { + read: "r" + } + }); + + var options = stub({}, "success"); + + transport.read(options); + + equal(options.calls("success"), 1); +}); + +test("read calls options.error when invoke fails", function() { + transport = new SignalR({ + promise: promise(), + hub: { + invoke: function() { + return { + done: function() { + return this; + }, + fail: function(callback) { + callback(); + } + }; + }, + on: $.noop + }, + server: { + read: "r" + } + }); + + var options = stub({}, "error"); + + transport.read(options); + + equal(options.calls("error"), 1); +}); + +test("the create method invokes the create server method", function() { + var hub = stub( { + on: $.noop + }, { + invoke: function() { + return promise(); + } + }); + + transport = new SignalR({ + promise: { + done: function(callback) { + callback(); + + equal(hub.calls("invoke"), 1); + equal(hub.args("invoke", 0)[0], "r"); + }, + fail: $.noop + }, + hub: hub, + server: { + create: "r" + } + }); + + transport.create({}); +}); + +test("the create method throws error if server configuration is not specified", 1, function() { + try { + transport.create(); + } catch (e) { + equal(e.toString(), 'Error: The "server.create" option must be set.'); + } +}); + +test("the create method passes the data field of the options to the server create method", function() { + var hub = stub( { + on: $.noop + }, { + invoke: function() { + return promise(); + } + }); + + var options = { data: "foo" }; + + transport = new SignalR({ + promise: { + done: function(callback) { + callback(); + + equal(hub.args("invoke", 0)[1], options.data); + }, + fail: $.noop + }, + hub: hub, + server: { + create: "r" + } + }); + + transport.create(options); +}); + +test("the create method invokes the parameterMap", function() { + var transportOptions = { + promise: promise(), + hub: hub(), + server: { + create: "r" + } + }; + + stub(transportOptions, "parameterMap"); + + transport = new SignalR(transportOptions); + + transport.create({}); + + equal(transportOptions.calls("parameterMap"), 1); +}); + +test("the create method passes options.data to the parameterMap", function() { + var transportOptions = { + promise: promise(), + hub: hub(), + server: { + create: "r" + } + }; + + stub(transportOptions, "parameterMap"); + + transport = new SignalR(transportOptions); + + var options = { data: "foo" }; + + transport.create(options); + + equal(transportOptions.args("parameterMap", 0)[0], options.data); +}); + +test("the create method invokes parameterMap and passes 'create' as the type of operation", function() { + var transportOptions = { + promise: promise(), + hub: hub(), + server: { + create: "r" + } + }; + + stub(transportOptions, "parameterMap"); + + transport = new SignalR(transportOptions); + + transport.create({}); + + equal(transportOptions.args("parameterMap", 0)[1], "create"); +}); + +test("create calls options.success when invoke is done", function() { + transport = new SignalR({ + promise: promise(), + hub: { + invoke: function() { + return promise(); + }, + on: $.noop + }, + server: { + create: "r" + } + }); + + var options = stub({}, "success"); + + transport.create(options); + + equal(options.calls("success"), 1); +}); + +test("create calls options.error when invoke fails", function() { + transport = new SignalR({ + promise: promise(), + hub: { + invoke: function() { + return { + done: function() { + return this; + }, + fail: function(callback) { + callback(); + } + }; + }, + on: $.noop + }, + server: { + create: "r" + } + }); + + var options = stub({}, "error"); + + transport.create(options); + + equal(options.calls("error"), 1); +}); + + +test("the update method invokes the update server method", function() { + var hub = stub( { + on: $.noop + }, { + invoke: function() { + return promise(); + } + }); + + transport = new SignalR({ + promise: { + done: function(callback) { + callback(); + + equal(hub.calls("invoke"), 1); + equal(hub.args("invoke", 0)[0], "r"); + }, + fail: $.noop + }, + hub: hub, + server: { + update: "r" + } + }); + + transport.update({}); +}); + +test("the update method throws error if server configuration is not specified", 1, function() { + try { + transport.update(); + } catch (e) { + equal(e.toString(), 'Error: The "server.update" option must be set.'); + } +}); + +test("the update method passes the data field of the options to the server update method", function() { + var hub = stub( { + on: $.noop + }, { + invoke: function() { + return promise(); + } + }); + + var options = { data: "foo" }; + + transport = new SignalR({ + promise: { + done: function(callback) { + callback(); + + equal(hub.args("invoke", 0)[1], options.data); + }, + fail: $.noop + }, + hub: hub, + server: { + update: "r" + } + }); + + transport.update(options); +}); + +test("the update method invokes the parameterMap", function() { + var transportOptions = { + promise: promise(), + hub: hub(), + server: { + update: "r" + } + }; + + stub(transportOptions, "parameterMap"); + + transport = new SignalR(transportOptions); + + transport.update({}); + + equal(transportOptions.calls("parameterMap"), 1); +}); + +test("the update method passes options.data to the parameterMap", function() { + var transportOptions = { + promise: promise(), + hub: hub(), + server: { + update: "r" + } + }; + + stub(transportOptions, "parameterMap"); + + transport = new SignalR(transportOptions); + + var options = { data: "foo" }; + + transport.update(options); + + equal(transportOptions.args("parameterMap", 0)[0], options.data); +}); + +test("the update method invokes parameterMap and passes 'update' as the type of operation", function() { + var transportOptions = { + promise: promise(), + hub: hub(), + server: { + update: "r" + } + }; + + stub(transportOptions, "parameterMap"); + + transport = new SignalR(transportOptions); + + transport.update({}); + + equal(transportOptions.args("parameterMap", 0)[1], "update"); +}); + +test("update calls options.success when invoke is done", function() { + transport = new SignalR({ + promise: promise(), + hub: { + invoke: function() { + return promise(); + }, + on: $.noop + }, + server: { + update: "r" + } + }); + + var options = stub({}, "success"); + + transport.update(options); + + equal(options.calls("success"), 1); +}); + +test("update calls options.error when invoke fails", function() { + transport = new SignalR({ + promise: promise(), + hub: { + invoke: function() { + return { + done: function() { + return this; + }, + fail: function(callback) { + callback(); + } + }; + }, + on: $.noop + }, + server: { + update: "r" + } + }); + + var options = stub({}, "error"); + + transport.update(options); + + equal(options.calls("error"), 1); +}); + +test("the destroy method invokes the destroy server method", function() { + var hub = stub( { + on: $.noop + }, { + invoke: function() { + return promise(); + } + }); + + transport = new SignalR({ + promise: { + done: function(callback) { + callback(); + + equal(hub.calls("invoke"), 1); + equal(hub.args("invoke", 0)[0], "r"); + }, + fail: $.noop + }, + hub: hub, + server: { + destroy: "r" + } + }); + + transport.destroy({}); +}); + +test("the destroy method throws error if server configuration is not specified", 1, function() { + try { + transport.destroy(); + } catch (e) { + equal(e.toString(), 'Error: The "server.destroy" option must be set.'); + } +}); + +test("the destroy method passes the data field of the options to the server destroy method", function() { + var hub = stub( { + on: $.noop + }, { + invoke: function() { + return promise(); + } + }); + + var options = { data: "foo" }; + + transport = new SignalR({ + promise: { + done: function(callback) { + callback(); + + equal(hub.args("invoke", 0)[1], options.data); + }, + fail: $.noop + }, + hub: hub, + server: { + destroy: "r" + } + }); + + transport.destroy(options); +}); + +test("the destroy method invokes the parameterMap", function() { + var transportOptions = { + promise: promise(), + hub: hub(), + server: { + destroy: "r" + } + }; + + stub(transportOptions, "parameterMap"); + + transport = new SignalR(transportOptions); + + transport.destroy({}); + + equal(transportOptions.calls("parameterMap"), 1); +}); + +test("the destroy method passes options.data to the parameterMap", function() { + var transportOptions = { + promise: promise(), + hub: hub(), + server: { + destroy: "r" + } + }; + + stub(transportOptions, "parameterMap"); + + transport = new SignalR(transportOptions); + + var options = { data: {} }; + + transport.destroy(options); + + equal(transportOptions.args("parameterMap", 0)[0], options.data); +}); + +test("the destroy method invokes parameterMap and passes 'destroy' as the type of operation", function() { + var transportOptions = { + promise: promise(), + hub: hub(), + server: { + destroy: "r" + } + }; + + stub(transportOptions, "parameterMap"); + + transport = new SignalR(transportOptions); + + transport.destroy({}); + + equal(transportOptions.args("parameterMap", 0)[1], "destroy"); +}); + +test("destroy calls options.success when invoke is done", function() { + transport = new SignalR({ + promise: promise(), + hub: { + invoke: function() { + return promise(); + }, + on: $.noop + }, + server: { + destroy: "r" + } + }); + + var options = stub({}, "success"); + + transport.destroy(options); + + equal(options.calls("success"), 1); +}); + +test("destroy calls options.error when invoke fails", function() { + transport = new SignalR({ + promise: promise(), + hub: { + invoke: function() { + return { + done: function() { + return this; + }, + fail: function(callback) { + callback(); + } + }; + }, + on: $.noop + }, + server: { + destroy: "r" + } + }); + + var options = stub({}, "error"); + + transport.destroy(options); + + equal(options.calls("error"), 1); +}); + +}()); diff --git a/tests/data/xmldatareader.js b/tests/data/xmldatareader.js new file mode 100644 index 00000000000..2a4829bcdec --- /dev/null +++ b/tests/data/xmldatareader.js @@ -0,0 +1,517 @@ +(function(){ + +var XmlDataReader = kendo.data.XmlDataReader; + +module("XmlDataReader", { +}); + + +test("parse of empty element", function() { + var reader = new XmlDataReader({}); + + var result = reader.parse(""); + + ok(result.foo); +}); + +test("parse with xml document", function() { + var reader = new XmlDataReader({}); + var result = reader.parse($.parseXML("")); + + ok(result.foo); +}); + +test("parse as function", function() { + var reader = new XmlDataReader({ + parse: function(result) { + return ""; + } + }); + + var result = reader.parse(""); + + ok(result.bar); +}); + +test("parse sets the text field to be the contents of the result", function() { + var reader = new XmlDataReader({}); + + var result = reader.parse("bar"); + + equal(result.foo["#text"], "bar"); +}); + +test("parse child element as a field", function() { + var reader = new XmlDataReader({}); + + var result = reader.parse("baz"); + + equal(result.foo.bar["#text"], "baz"); +}); + +test("parse grand child element as a field", function() { + var reader = new XmlDataReader({}); + + var result = reader.parse(""); + + ok(result.foo.bar.baz); +}); + +test("parse multiple children with same nodeName as array", function() { + var reader = new XmlDataReader({}); + + var result = reader.parse(""); + + ok($.isArray(result.foo.bar)); +}); + +test("parse CDATA as #text", function() { + var reader = new XmlDataReader({}); + var result = reader.parse(""); + equal(result.foo["#text"], "bar"); +}); + +test("parse attributes as @ fields", function() { + var reader = new XmlDataReader({}); + + var result = reader.parse(""); + + equal(result.foo["@bar"], "baz"); +}); + +test("xpathToMember with attribute", function() { + var reader = new XmlDataReader({}); + + equal(reader.xpathToMember("/foo/@bar"), 'foo["@bar"]'); +}); + +test("xpathToMember with attribute only", function() { + var reader = new XmlDataReader({}); + + equal(reader.xpathToMember("@bar"), '["@bar"]'); +}); + +test("xpathToMember with text() only", function() { + var reader = new XmlDataReader({}); + + equal(reader.xpathToMember("text()"), '["#text"]'); +}); + +test("xpathToMember with attribute of nested element", function() { + var reader = new XmlDataReader({}); + + equal(reader.xpathToMember("/foo/bar/@baz"), 'foo.bar["@baz"]'); +}); + +test("xpathToMember and text()", function() { + var reader = new XmlDataReader({}); + + equal(reader.xpathToMember("/foo/text()"), 'foo["#text"]'); +}); + +test("xpathToMember and element only", function() { + var reader = new XmlDataReader({}); + + equal(reader.xpathToMember("/foo"), 'foo'); +}); + +test("xpathToMember and nested elements ", function() { + var reader = new XmlDataReader({}); + + equal(reader.xpathToMember("/foo/bar"), 'foo.bar'); +}); + +test("xpathToMember text() of nested elements ", function() { + var reader = new XmlDataReader({}); + + equal(reader.xpathToMember("/foo/bar/text()"), 'foo.bar["#text"]'); +}); + +test("xpathToMember returns empty string when argument is null, undefined or empty string ", function() { + var reader = new XmlDataReader({}); + + equal(reader.xpathToMember(null), ""); + equal(reader.xpathToMember(undefined), ""); + equal(reader.xpathToMember(""), ""); +}); + +test("errors as a functon", function() { + var reader = new XmlDataReader({ errors: function() { return "foo"; } }); + + var result = reader.parse("someerror"); + + equal(reader.errors(result), "foo"); +}); + +test("errors returns the errors tag content", function() { + var reader = new XmlDataReader({ errors: "/errors['#text']" }); + + var result = reader.parse("someerror"); + + equal(reader.errors(result), "someerror"); +}); + +test("total returns a number", function() { + var reader = new XmlDataReader({ total: "/foo/text()"}); + + var result = reader.parse("1"); + + ok(reader.total(result) === 1); +}); + +test("total as function", function() { + var reader = new XmlDataReader({ total:function() { return 1; } }); + + var result = reader.parse("1"); + + ok(reader.total(result) === 1); +}); + +test("serialize as function", 1, function() { + var reader = new XmlDataReader({ + serialize: function() { + ok(true); + } + }); + + var result = reader.parse("1"); + + reader.serialize(result); +}); + +test("data returns the records", function() { + var reader = new XmlDataReader({ data: "/foo/bar"}); + + var result = reader.data({foo: { bar: [1,2] } }); + + ok($.isArray(result)); + equal(result[0], 1); + equal(result[1], 2); + equal(result.length, 2); +}); + +test("data as function", function() { + var reader = new XmlDataReader({ + data: function(result) { + return result.foo.bar; + } + }); + + var result = reader.data({foo: { bar: [1,2] } }); + + ok($.isArray(result)); + equal(result[0], 1); + equal(result[1], 2); + equal(result.length, 2); +}); + +test("data returns the records with nested elements on two levels", function() { + var reader = new XmlDataReader({ data: "/foo/bar/baz"}); + + var result = reader.data({ + foo: { + bar: [ { + baz: [{},{}] + }, { + baz: [{},{}] + }] + } + }); + + ok($.isArray(result)); + equal(result.length, 4); +}); + +test("data returns the records with nested elements on three levels", function() { + var reader = new XmlDataReader({ data: "/root/foo/bar/baz"}); + + var result = reader.data({ + root: { + foo: [ + { + bar: [ { + baz: [{},{}] + }, { + baz: [{},{}] + }] + }, + { + bar: [ { + baz: [{},{}] + }, { + baz: [{},{}] + }] + } + ] + } + }); + ok($.isArray(result)); + + equal(result.length, 8); +}); +test("data returns the records with nested elements on four levels", function() { + var reader = new XmlDataReader({ data: "/root/foo/bar/baz"}); + + var result = reader.data({ + root: { + foo: [ + { + bar: { + baz: [{},{}] + } + }, + { + bar: { + baz: [{},{}] + } + } + ] + } + }); + + ok($.isArray(result)); + equal(result.length, 4); +}); + +test("data returns the records in right order", function() { + var reader = new XmlDataReader({ data: "/root/foo/bar/baz"}); + + var result = reader.data({ + root: { + foo: [ + { + bar: { + baz: [1, 2] + } + }, + { + bar: { + baz: [3, 4] + } + } + ] + } + }); + + ok($.isArray(result)); + equal(result[0], 1); + equal(result[1], 2); + equal(result[2], 3); + equal(result[3], 4); +}); + +test("data returns the records with mixed items", function() { + var reader = new XmlDataReader({ data: "/root/foo/bar/baz"}); + + var result = reader.data({ + root: { + foo: [ + { + bar: { + baz: [{},{}] + } + }, + { + bar: { + baz: {} + } + } + ] + } + }); + + ok($.isArray(result)); + equal(result.length, 3); +}); + +test("model is initialized from options", function() { + var reader = new XmlDataReader({ + model: { + } + }); + + ok(new reader.model instanceof kendo.data.Model); +}); + +test("model is initialized from options modelBase", function() { + var ModelBase = kendo.data.Model.define({}); + + var reader = new XmlDataReader({ + modelBase: ModelBase, + model: { + } + }); + + ok(new reader.model instanceof ModelBase); +}); + +test("parse model id", function() { + var reader = new XmlDataReader({ + model: { + id: "@id" + }, + data: "/root/foo" + }); + + var result = reader.parse(''); + var data = reader.data(result); + + var model = new reader.model(data[0]); + + equal(model.id, "bar"); +}); + +test("model id is field from the processed data", function() { + var reader = new XmlDataReader({ + model: { + id: "baz", + fields: { + baz: "@id" + } + }, + data: "/root/foo" + }); + + var result = reader.parse(''); + var data = reader.data(result); + + var model = new reader.model(data[0]); + + equal(model.id, "bar"); +}); + +test("model fields as object is parsed", function() { + var reader = new XmlDataReader({ + model: { + id: "@id", + fields: { + foo: { field: "@foo" } + } + }, + data: "/root/foo" + }); + + var result = reader.parse(''); + var data = reader.data(result); + + equal(data[0].foo, "bar"); +}); + + +test("model fields are parsed", function() { + var reader = new XmlDataReader({ + model: { + id: "@id", + fields: { + foo: "@foo" + } + }, + data: "/root/foo" + }); + + var result = reader.parse(''); + var data = reader.data(result); + + equal(data[0].foo, "bar"); +}); + +test("parse xml with nullable property", function() { + var reader = new XmlDataReader({ + model: { + fields: { + bar: "bar/text()" + } + }, + data: "/root/foo" + }); + + var result = reader.parse('bar1'); + var data = reader.data(result); + + equal(data.length, 2); + equal(data[0].bar, "bar1"); + equal(data[1].bar, undefined); +}); + +test("data returns array if there is only one item", function() { + var reader = new XmlDataReader( { data: "/foo"} ); + + var result = reader.parse(""); + var data = reader.data(result); + + ok($.isArray(data)); + equal(data.length, 1); +}); + +test("model fields attrbiutes are preserved", function() { + var reader = new XmlDataReader({ + model: { + fields: { + bar: { field: "bar/text()", type: "string" } + } + }, + data: "/root/foo" + }); + + var result = reader.parse('bar1'); + var data = reader.data(result); + + equal(reader.model.fields["bar"].type, "string"); + equal(typeof reader.model.fields["bar"].field, "function"); +}); + +test("parse converts field values to the specifed type", function() { + var reader = new XmlDataReader({ + model: { + fields: { + bar: { field: "bar/text()", type: "number" }, + baz: { field: "baz/text()" } + } + }, + data: "/root/foo" + }); + + var result = reader.parse('11'); + result = reader.data(result); + + equal(result.length, 2); + strictEqual(result[0].bar, 1); + strictEqual(result[0].baz, "1"); + strictEqual(result[1].bar, null); + strictEqual(result[1].baz, undefined); +}); + +test("returns empty data if source is empty", function() { + var reader = new XmlDataReader({ + model: { + fields: { + bar: { field: "bar/text()" }, + baz: { field: "baz/text()" } + } + }, + data: "/root/foo" + }); + + var result = reader.parse(''); + result = reader.data(result); + + equal(result.length, 0); +}); + +test("additional field is not added to the model if id is not defined", function() { + var reader = new XmlDataReader({ + model: { + fields: { + bar: { field: "bar/text()" } + } + }, + data: "/root/foo" + }); + + var result = reader.parse('moo'); + result = reader.data(result); + + ok(!result[""]); +}); + +}()); diff --git a/tests/datepicker/api.js b/tests/datepicker/api.js new file mode 100644 index 00000000000..983cd47ae42 --- /dev/null +++ b/tests/datepicker/api.js @@ -0,0 +1,487 @@ +(function() { + +var DateView = kendo.DateView, + dateview, + input; + +module("kendo.ui.DateView API", { + setup: function() { + kendo.effects.disable(); + input = $("").appendTo(QUnit.fixture); + }, + teardown: function() { + kendo.effects.enable(); + + dateview.destroy(); + + kendo.destroy(QUnit.fixture); + } +}); + +test("value method should call calendar value and set dateView._value", function() { + var date = new Date(2000, 10, 10); + + dateview = new DateView({ + value: date, + start: "month", + anchor: input, + min: new Date (1900, 10, 10), + max: new Date (2100, 10, 10), + depth: "month" + }); + + dateview._calendar(); + date.setDate(20); + + dateview.value(date); + + equal(+dateview._value, +date); + equal(+dateview.calendar.value(), +date); +}); + +test("min() should set the options.min", function() { + var date = new Date(2000, 10, 10); + + dateview = new DateView(); + + dateview.min(date); + + equal(+dateview.options.min, +date); +}); + +test("min method sets calendar min value", function() { + dateview = new DateView(); + dateview._calendar(); + + var date = new Date(2000, 10, 10), + calendar = dateview.calendar; + + dateview.min(date); + + deepEqual(calendar.min(), date); +}); + +test("max() should set the options.max", function() { + var date = new Date(2000, 10, 10); + + dateview = new DateView(); + + dateview.max(date); + + equal(+dateview.options.max, +date); +}); + +test("max method sets calendar max value", function() { + dateview = new DateView(); + dateview._calendar(); + + var date = new Date(2000, 10, 10), + calendar = dateview.calendar; + + dateview.max(date); + + deepEqual(calendar.max(), date); +}); + +var input; +var datepicker; +var DatePicker = kendo.ui.DatePicker; + +module("kendo.ui.DateView API", { + setup: function() { + kendo.effects.disable(); + input = $("").appendTo(QUnit.fixture); + }, + teardown: function() { + kendo.effects.enable(); + datepicker.destroy(); + kendo.destroy(QUnit.fixture); + } +}); + +test("open method opens the dateView", 1, function() { + datepicker = input.kendoDatePicker().data("kendoDatePicker"); + + stub(datepicker.dateView, "_calendar"); + stub(datepicker.dateView.popup, {open: datepicker.dateView.popup.open}); + + datepicker.open(); + + equal(datepicker.dateView.popup.calls("open"), 1); +}); + +test("close method should closes the dateView", function() { + datepicker = input.kendoDatePicker().data("kendoDatePicker"); + + stub(datepicker.dateView.popup, "close"); + + datepicker.close(); + + equal(datepicker.dateView.popup.calls("close"), 1); +}); + +test("value method should return value of the datepicker", function() { + datepicker = input.kendoDatePicker().data("kendoDatePicker"); + + ok(datepicker.value() === null); +}); + +test("value method updates the input value", function() { + datepicker = input.kendoDatePicker().data("kendoDatePicker"); + + var date = new Date(); + var dateString = kendo.toString(date, datepicker.options.format); + + datepicker.value(date); + + equal(+datepicker._value, +date); + equal(input.val(), dateString); +}); + +test("value method uses options.parseFormats to parse passed value", function() { + var secondFormat = "MM/dd/yy", + date = new Date(2000, 10, 10), + dateString = kendo.toString(date, secondFormat); + + datepicker = input.kendoDatePicker({ + format: "MMMM yyyy", + parseFormats: secondFormat + }).data("kendoDatePicker"); + + datepicker.value(dateString); + + equal(+datepicker._value, +date); +}); + +test("value method parse passed value using options.parseFormats", function() { + var date = new Date(2000, 10, 1), + dateString = kendo.toString(date, "MMMM yyyy"); + + datepicker = input.kendoDatePicker({ + parseFormats: ["MMMM yyyy"] + }).data("kendoDatePicker"); + + datepicker.value(dateString); + + equal(+datepicker.value(), +date); +}); + +test("value should not accept value bigger than max", function() { + var date = new Date(2000, 10, 10); + + datepicker = input.kendoDatePicker({ + max: date + }).data("kendoDatePicker"); + + datepicker.value(new Date(2000, 10, 11)); + + equal(datepicker._value, null); +}); + +test("value should update input when select date from calendar", function() { + var date = new Date(2000, 10, 10); + + datepicker = input.kendoDatePicker().data("kendoDatePicker"); + datepicker.open(); + datepicker.dateView.calendar.value(date); + datepicker.dateView.calendar.trigger("change"); + + equal(+datepicker._value, +date); + equal(input.val(), "11/10/2000"); +}); + +test("empty input if set value ot null", function() { + datepicker = input.kendoDatePicker().data("kendoDatePicker"); + + datepicker.value(null); + + equal(input.val(), ""); + equal(datepicker._value, null); +}); + +test("value method should call dateview.value()", function() { + datepicker = input.kendoDatePicker().data("kendoDatePicker"); + stub(datepicker.dateView, "value"); + + datepicker.value(new Date()); + + equal(datepicker.dateView.calls("value"), 1); +}); + +test("value method should parse value", function() { + datepicker = input.kendoDatePicker().data("kendoDatePicker"); + + var value = new Date("10/10/2000"); + + datepicker.value("10/10/2000"); + + equal(+datepicker.value(), +value); +}); + +test("_change should set value if it was changed", function() { + datepicker = input.kendoDatePicker().data("kendoDatePicker"); + datepicker._change("10/22/2000"); + + equal(+datepicker.value(), +(new Date("10/22/2000"))); +}); + +test("_change should not call value() if value was not changed", function() { + datepicker = input.kendoDatePicker().data("kendoDatePicker"); + + var value = new Date("10/22/2000"); + + datepicker.value(value); + stub(datepicker, "value"); + + datepicker._change("10/22/2000"); + + equal(datepicker.calls("value"), 0); +}); + +test("min() should return min value", function() { + var value = new Date("10/22/2000"); + datepicker = input.kendoDatePicker({min: value}).data("kendoDatePicker"); + + var result = datepicker.min(); + + equal(+result, +value); +}); + +test("min() should set the min value of the datepicker", function() { + datepicker = input.kendoDatePicker().data("kendoDatePicker"); + + var value = new Date("10/22/2000"); + + datepicker.min(value); + + equal(+datepicker.options.min, +value); +}); + +test("min method uses options.parseFormats", function() { + datepicker = input.kendoDatePicker({ + format: "MMMM yyyy", + parseFormats: "MM/dd/yyyy" + }).data("kendoDatePicker"); + + var value = new Date("10/22/2000"); + + datepicker.min("10/22/2000"); + + equal(+datepicker.options.min, +value); +}); + +test("min() should call dateView.min()", function() { + datepicker = input.kendoDatePicker().data("kendoDatePicker"); + + var value = new Date("10/22/2000"); + + stub(datepicker.dateView, { min: datepicker.dateView.min }); + + datepicker.min(value); + + equal(datepicker.dateView.calls("min"), 1); +}); + +test("max() should return max value", function() { + var value = new Date("10/22/2000"); + datepicker = input.kendoDatePicker({max: value}).data("kendoDatePicker"); + + var result = datepicker.max(); + + equal(+result, +value); +}); + +test("max() should set the max value of the datepicker", function() { + datepicker = input.kendoDatePicker().data("kendoDatePicker"); + + var value = new Date("10/22/2000"); + + datepicker.max(value); + + equal(+datepicker.options.max, +value); +}); + +test("max() should call dateView.max()", function() { + datepicker = input.kendoDatePicker().data("kendoDatePicker"); + var value = new Date("10/22/2000"); + + stub(datepicker.dateView, { max: datepicker.dateView.max }); + + datepicker.max(value); + + equal(datepicker.dateView.calls("max"), 1); +}); + +test("enable(false) should disable input element", function() { + datepicker = input.kendoDatePicker().data("kendoDatePicker"); + + datepicker.enable(false); + + equal(datepicker.element.attr("disabled"), "disabled"); +}); + +test("enable(false) should unbind icon click", function() { + datepicker = input.kendoDatePicker().data("kendoDatePicker"); + + datepicker.enable(false); + + stub(datepicker.dateView, {toggle: datepicker.dateView.toggle}); + + datepicker.wrapper.find(".k-select").click(); + + ok(!datepicker.dateView.popup.visible()); +}); + +test("enable() should remove disable attribute", function() { + datepicker = input.kendoDatePicker().data("kendoDatePicker"); + + datepicker.enable(false); + datepicker.enable(true); + + equal(datepicker.element.attr("disabled"), undefined); +}); + +test("readonly() makes input element readonly", function() { + datepicker = input.kendoDatePicker().data("kendoDatePicker"); + + datepicker.readonly(); + + equal(datepicker.element.attr("readonly"), "readonly"); +}); + +test("readonly() unbinds icon click", function() { + datepicker = input.kendoDatePicker().data("kendoDatePicker"); + + datepicker.readonly(); + + stub(datepicker.dateView, {toggle: datepicker.dateView.toggle}); + + datepicker.wrapper.find(".k-select").click(); + + ok(!datepicker.dateView.popup.visible()); +}); + +test("readonly(false) removes readonly attribute", function() { + datepicker = input.kendoDatePicker().data("kendoDatePicker"); + + datepicker.readonly(); + datepicker.readonly(false); + + equal(datepicker.element.attr("readonly"), undefined); +}); + +test("readonly() removes disabled attribute and disabled class", function() { + datepicker = input.kendoDatePicker().data("kendoDatePicker"); + + datepicker.enable(false); + datepicker.readonly(); + + equal(datepicker.element.attr("readonly"), "readonly"); + equal(datepicker.element.attr("disabled"), undefined); + ok(datepicker._inputWrapper.hasClass("k-state-default")); + ok(!datepicker._inputWrapper.hasClass("k-state-disabled")); +}); + +test("enable(false) removes readonly attribute and default class", function() { + datepicker = input.kendoDatePicker().data("kendoDatePicker"); + + datepicker.readonly(); + datepicker.enable(false); + + equal(datepicker.element.attr("readonly"), undefined); + equal(datepicker.element.attr("disabled"), "disabled"); + ok(!datepicker._inputWrapper.hasClass("k-state-default")); + ok(datepicker._inputWrapper.hasClass("k-state-disabled")); +}); + +test("enable() enables widget after readonly()", function() { + datepicker = input.kendoDatePicker().data("kendoDatePicker"); + + datepicker.readonly(); + datepicker.enable(); + + equal(datepicker.element.attr("readonly"), undefined); + equal(datepicker.element.attr("disabled"), undefined); + ok(datepicker._inputWrapper.hasClass("k-state-default")); + ok(!datepicker._inputWrapper.hasClass("k-state-disabled")); +}); + +test("value method honors options.culture", function() { + datepicker = input.kendoDatePicker({ + culture: "bg-BG", + format: "D" + }).data("kendoDatePicker"); + + var value = new Date(2000, 10, 10), + formatted = kendo.toString(value, "D", "bg-BG"); + + datepicker.value(formatted); + + equal(+datepicker.value(), +value); + equal(datepicker.element.val(), formatted); +}); + +test("value method restricts time of the value if it's date part is equal to min", function() { + var today = new Date(), + midnight = new Date(today.getFullYear(), today.getMonth(), today.getDate()); + + datepicker = input.kendoDatePicker({ + min: today, + value: today + }).data("kendoDatePicker"); + + datepicker.value(midnight); + + notEqual(datepicker._value, null); + equal(+datepicker._value, +today); +}); + +test("value method restricts time of the value if it's date part is equal to max", function() { + var today = new Date(), + midnight = new Date(today.getFullYear(), today.getMonth(), today.getDate()); + + datepicker = input.kendoDatePicker({ + max: today, + value: today + }).data("kendoDatePicker"); + + datepicker.value(midnight); + + notEqual(datepicker._value, null); + equal(+datepicker._value, +midnight); +}); + +test("value method does not show text representation of invalid value", function() { + datepicker = input.kendoDatePicker().data("kendoDatePicker"); + + datepicker.value("invalid"); + + equal(datepicker.value(), null); + equal(input.val(), ""); +}); + +test("setOptions method updates calendar options", function() { + datepicker = input.kendoDatePicker().data("kendoDatePicker"); + datepicker.open(); + + datepicker.setOptions({ + start: "year", + depth: "year" + }); + + equal(datepicker.dateView.calendar.view().name, "year"); +}); + +test("setOptions method updates format", function() { + datepicker = input.kendoDatePicker().data("kendoDatePicker"); + datepicker.open(); + datepicker.value(new Date(2013, 10, 10)); + + datepicker.setOptions({ + format: "dd/MM/yyyy" + }); + + equal(datepicker.element.val(), kendo.toString(datepicker.value(), "dd/MM/yyyy")); +}); + +})(); diff --git a/tests/datepicker/aria.js b/tests/datepicker/aria.js new file mode 100644 index 00000000000..5c896b044c6 --- /dev/null +++ b/tests/datepicker/aria.js @@ -0,0 +1,114 @@ +(function() { + +var DatePicker = kendo.ui.DatePicker, + input, instance; + +module("kendo.ui.DatePicker ARIA", { + setup: function() { + kendo.effects.disable(); + input = $("").appendTo(QUnit.fixture); + instance = new DatePicker(input, { + ARIATemplate: "#=kendo.toString(current, 'D')#" + }); + }, + teardown: function() { + kendo.effects.enable(); + instance.destroy(); + kendo.destroy(QUnit.fixture); + } +}); + +test("DatePicker adds role to the input element", function() { + equal(input.attr("role"), "combobox"); +}); + +test("DatePicker adds aria-owns", function() { + equal(input.attr("aria-owns"), "test_dateview"); +}); + +test("DatePicker sets id to the popup element", function() { + equal(instance.dateView.popup.element.attr("id"), "test_dateview"); +}); + +test("DatePicker adds aria-expanded", function() { + equal(input.attr("aria-expanded"), "false"); +}); + +test("DatePicker sets aria-expanded to true", function() { + instance.open(); + equal(input.attr("aria-expanded"), "true"); +}); + +test("DatePicker sets aria-hidden=false to the popup element", function() { + instance.open(); + equal(instance.dateView.popup.element.attr("aria-hidden"), "false"); +}); + +test("DatePicker sets aria-hidden=true to the popup element", function() { + instance.open(); + instance.close(); + equal(instance.dateView.popup.element.attr("aria-hidden"), "true"); +}); + +test("DatePicker adds aria-disabled=false", function() { + equal(input.attr("aria-disabled"), "false"); +}); + +test("DatePicker sets aria-disabled=true", function() { + instance.enable(false); + equal(input.attr("aria-disabled"), "true"); +}); + +test("DatePicker adds role to the toggle button", function() { + equal(instance._dateIcon.attr("role"), "button"); +}); + +test("DatePicker adds aria-controls to the toggle button", function() { + equal(instance._dateIcon.attr("aria-controls"), "test_dateview"); +}); + +test("DatePicker sets id to the calendar", function() { + instance.dateView._calendar(); + + ok(instance.dateView.calendar.element.attr("id")); +}); + +test("DatePicker sets aria-activedescendant after navigation", function() { + instance.open(); + + instance.element.focus().trigger({ + type: "keydown", + preventDefault: function() {}, + keyCode: 40 + }); + + var cell = instance.dateView.calendar.element.find("td.k-state-focused"); + + equal(instance.element.attr("aria-activedescendant"), cell.attr("id")); +}); + +test("DatePicker sets aria-label to focused cell", function() { + instance.open(); + + var date = kendo.date.today(); + var cell = instance.dateView.calendar.element.find("td.k-state-focused"); + + equal(cell.attr("aria-label"), kendo.toString(date, "D")); +}); + +test("DatePicker removes aria-label from previous cell", function() { + instance.open(); + + instance.element.focus().trigger({ + type: "keydown", + preventDefault: function() {}, + keyCode: 40 + }); + + var date = kendo.date.today(); + var cell = instance.dateView.calendar.element.find("td[aria-label]"); + + equal(cell.length, 1); +}); + +})(); diff --git a/tests/datepicker/events.js b/tests/datepicker/events.js new file mode 100644 index 00000000000..e1b9e52a619 --- /dev/null +++ b/tests/datepicker/events.js @@ -0,0 +1,105 @@ +(function() { + +var DateView = kendo.DateView, + DatePicker = kendo.ui.DatePicker, + datepicker, + div, input; + +module("kendo.ui.DatePicker Events", { + setup: function() { + div = $("
").appendTo(QUnit.fixture); + input = $("").appendTo(QUnit.fixture); + }, + teardown: function() { + datepicker.destroy(); + kendo.destroy(QUnit.fixture); + } +}); + +test("blur should call _change event", function() { + datepicker = input.kendoDatePicker({ + change: function() { + ok(true); + } + }) + .data("kendoDatePicker"); + + input.val("10/10/2000").focus(); + input[0].blur(); +}); + +test("raise change event", 1, function() { + datepicker = input.kendoDatePicker({ + change: function() { + ok(true); + } + }) + .data("kendoDatePicker"); + + datepicker._change("10/10/2000"); +}); + +test("raise DOM change event", function() { + datepicker = input.kendoDatePicker().data("kendoDatePicker"); + + input.bind("change", function() { + ok(true); + }); + + datepicker._change("10/10/2000"); +}); + +test("do not raise change event when use API", 1, function() { + datepicker = input.kendoDatePicker({ + change: function() { + ok(false); + } + }) + .data("kendoDatePicker"); + + datepicker.value(new Date(2000, 10, 10)); + + input.focus().blur(); + + ok(true); +}); + +test("raise open event", function() { + datepicker = input.kendoDatePicker({ + open: function() { + ok(true); + ok(this === datepicker); + } + }) + .data("kendoDatePicker"); + + input.next().click(); +}); + +test("raise close event", function() { + datepicker = input.kendoDatePicker({ + close: function() { + ok(true); + } + }) + .data("kendoDatePicker"); + + datepicker.open(); + datepicker._dateIcon.click(); +}); + +test ("raise close event document click", function() { + datepicker = input.kendoDatePicker({ + close: function() { + ok(true); + ok(this === datepicker); + } + }) + .data("kendoDatePicker"); + + datepicker.open(); + + $(document.documentElement).mousedown(); +}); + +})(); diff --git a/tests/datepicker/initialization.js b/tests/datepicker/initialization.js new file mode 100644 index 00000000000..1cf58707b72 --- /dev/null +++ b/tests/datepicker/initialization.js @@ -0,0 +1,315 @@ +(function() { + +var DateView = kendo.DateView; +var dateview; +var anchor; +var div; + +module("kendo.ui.DateView initialization", { + setup: function() { + kendo.ns = "kendo-"; + kendo.effects.disable(); + + anchor = $("").appendTo(QUnit.fixture); + div = $("
").appendTo(QUnit.fixture); + }, + teardown: function() { + kendo.effects.enable(); + + if (dateview) { + dateview.destroy(); + } + + kendo.destroy(QUnit.fixture); + + kendo.ns = ""; + } +}); + +test("DateView should create popup instance", function() { + dateview = new DateView(); + + ok(dateview.popup); +}); + +test("DateView does not create calendar on init", function() { + dateview = new DateView(); + + ok(!dateview.calendar); +}); + +test("DateView creates calendar on first open", function() { + dateview = new DateView(); + + dateview.open(); + + ok(dateview.calendar); +}); + +test("DateView persist focused value when calendar navigate", function() { + var called = false, + date = new Date(2000, 10, 10); + + dateview = new DateView({ + value: date, + min: date, + max: date, + start: "month" + }); + + dateview._calendar(); + dateview.calendar.navigate(date, "month"); + + equal(dateview.calendar._table.find(".k-state-focused").children().attr("data-kendo-value"), "2000/10/10"); + equal(+dateview._current, +dateview.calendar._current); +}); + +var input; +var DatePicker = kendo.ui.DatePicker; + +module("kendo.ui.DatePicker initialization", { + setup: function() { + kendo.ns = "kendo-"; + kendo.effects.disable(); + + input = $("").appendTo(QUnit.fixture); + }, + teardown: function() { + kendo.effects.enable(); + + kendo.destroy(QUnit.fixture); + + kendo.ns = ""; + } +}); + +test("DatePicker should not create footer template", function() { + var datepicker = input.kendoDatePicker({ + footer: false + }).data("kendoDatePicker"); + + deepEqual(datepicker.dateView.footer, undefined); +}); + +test("get value of the input if", function() { + input.val("10/10/2000"); + + var datepicker = new DatePicker(input); + + equal(+datepicker.value(), +new Date(2000, 9, 10)); +}); + +test("_wrapper() wraps input element", function() { + input.css("width", "200"); + + var datepicker = input.kendoDatePicker().data("kendoDatePicker"); + + ok(input.parent().hasClass("k-picker-wrap k-state-default")); + equal(datepicker.wrapper.attr("class"), "k-widget k-datepicker k-header"); +}); + +test("_input should add k-input to the element", function() { + var datepicker = input.kendoDatePicker().data("kendoDatePicker"); + + ok(datepicker.element.hasClass("k-input")); +}); + +test("_input create calendar button", function() { + var datepicker = input.kendoDatePicker().data("kendoDatePicker"), + icon = datepicker.wrapper.find(".k-select"); + + ok(icon); + ok(icon.is("span")); + ok(icon.hasClass("k-select")); + ok(icon.children().is("span")); + ok(icon.children().hasClass("k-icon k-i-calendar")); + ok(icon.children().html()); +}); + +test("create dateview", function() { + var datepicker = input.kendoDatePicker().data("kendoDatePicker"); + + ok(datepicker.dateView); +}); + +test("dateView should have correct options", function() { + var datepicker = input.kendoDatePicker({open: function() {}, close: $.noop}).data("kendoDatePicker"), + dateView = datepicker.dateView, + options = dateView.options, + dpOptions = datepicker.options; + + ok(dateView.options); + equal(options.anchor, datepicker.wrapper); + equal(options.value, dpOptions.value); + equal(+options.min, +dpOptions.min); + equal(+options.max, +dpOptions.max); + notEqual(options.change, dpOptions.change); +}); + +test("dateview updates datepicker on calendar change", function() { + var date = new Date(2010, 10, 10); + var datepicker = new DatePicker(input, { value: new Date(2000, 10, 10) }); + var dateview = datepicker.dateView; + + datepicker.open(); + dateview.calendar.value(date); + dateview.calendar.trigger("change"); + + deepEqual(datepicker.value(), date); +}); + +test("DatePicker wire icon click", function() { + var datepicker = input.kendoDatePicker().data("kendoDatePicker"); + + datepicker.close(); + datepicker._dateIcon.click(); + ok(datepicker.dateView.popup.visible()); +}); + +asyncTest("form reset support", 2, function() { + input.attr("value", "12/12/2000"); + + var form = $("
").appendTo(QUnit.fixture).append(input), + datepicker = input.kendoDatePicker().data("kendoDatePicker"); + + datepicker.open(); + datepicker.value("12/12/2010"); + + form[0].reset(); + + setTimeout(function() { + equal(datepicker.element.val(), "12/12/2000"); + equal(datepicker.dateView.calendar.value().getFullYear(), "2000"); + start(); + }, 200); +}); + +asyncTest("support for form defined by attribute", 2, function() { + input.attr("form", "form1").attr("value", "12/12/2000"); + + var form = $("").appendTo(QUnit.fixture), + datepicker = input.kendoDatePicker().data("kendoDatePicker"); + + datepicker.open(); + datepicker.value("12/12/2010"); + + form[0].reset(); + + setTimeout(function() { + equal(datepicker.element.val(), "12/12/2000"); + equal(datepicker.dateView.calendar.value().getFullYear(), "2000"); + start(); + }, 200); +}); + + +test("extend popup options if datepicker.options.popup", function() { + var appendTo = QUnit.fixture, + datepicker = new kendo.ui.DatePicker(input, { + popup: { + appendTo: appendTo + } + }); + + equal(datepicker.dateView.popup.options.appendTo[0], $(appendTo)[0]); +}); + +test("DatePicker adds format to parseFormats array", function() { + var datepicker = input.kendoDatePicker({ + parseFormats: ["MM/dd/yy"] + }).data("kendoDatePicker"); + + equal(datepicker.options.parseFormats[0], datepicker.options.format); + equal(datepicker.options.parseFormats[1], "MM/dd/yy"); +}); + +test("DatePicker does not modify parseFormats if format exists in the array", function() { + var datepicker = input.kendoDatePicker({ + format: "MM/dd/yy", + parseFormats: ["MM/dd/yyyy", "MM/dd/yy"] + }).data("kendoDatePicker"); + + equal(datepicker.options.parseFormats.length, 2); + equal(datepicker.options.parseFormats[0], "MM/dd/yyyy"); + equal(datepicker.options.parseFormats[1], datepicker.options.format); +}); + +test("DatePicker copies input's className to the wrapper", function() { + var datepicker = input.addClass("test").kendoDatePicker().data("kendoDatePicker"); + + ok(datepicker.wrapper.hasClass("test")); +}); + +test("DatePicker updates calendar if empty input element on open", function() { + var datepicker = input.kendoDatePicker().data("kendoDatePicker"); + + datepicker.value(new Date()); + + input.focus().val(""); + datepicker.open(); + + equal(datepicker.dateView.calendar.value(), null); +}); + +test("DatePicker updates calendar's focused date", function() { + var datepicker = input.kendoDatePicker().data("kendoDatePicker"), + date = new Date(2000, 10, 10); + + datepicker.value(new Date(2000, 9, 1)); + + input.focus().val(kendo.toString(date, "MM/dd/yyyy")); + datepicker.open(); + + var link = datepicker.dateView.calendar.element.find(".k-state-focused > .k-link"); + + equal(+datepicker.dateView.calendar.value(), +datepicker.value()); + equal(link.html(), date.getDate()); +}); + +if (!kendo.support.touch) { + test("DatePickers changes the type of the input", function() { + input = $("").appendTo(QUnit.fixture); + + var datepicker = input.kendoDatePicker().data("kendoDatePicker"); + + equal(datepicker.element[0].type, "text"); + equal(datepicker.element.attr("type"), "text"); + }); +} + +test("DatePicker sets dates property of the calendar", function() { + var dates = [new Date(2000, 10, 10)], + datepicker = input.kendoDatePicker({ + dates: dates + }).data("kendoDatePicker"); + + datepicker.open(); + + ok(datepicker.dateView.calendar.options.dates[0]); +}); + +test("DatePicker honors readonly attribute", function() { + var datepicker = input.attr("readonly", true).kendoDatePicker().data("kendoDatePicker"); + + stub(datepicker.dateView, {toggle: datepicker.dateView.toggle}); + + datepicker.wrapper.find(".k-select").click(); + + ok(!datepicker.dateView.popup.visible()); +}); + +test("DatePicker uses disabled attr over the readonly", function() { + var datepicker = input.attr("readonly", true).attr("disabled", true) + .kendoDatePicker().data("kendoDatePicker"); + + equal(input.attr("readonly"), undefined); +}); + +test("DatePicker does not remove input text on initialization if not valid value", function() { + var datepicker = input.val("test").kendoDatePicker().data("kendoDatePicker"); + + equal(datepicker.value(), null); + equal(input.val(), "test"); +}); + +})(); diff --git a/tests/datepicker/mvvm.js b/tests/datepicker/mvvm.js new file mode 100644 index 00000000000..086ec77207d --- /dev/null +++ b/tests/datepicker/mvvm.js @@ -0,0 +1,416 @@ +(function() { + +var dom; + +module("kendo.ui.Calendar MVVM", { + setup: function() { + window.change = function() { + ok(true); + }; + }, + teardown: function() { + delete window.change; + + kendo.destroy(dom); + } +}); + +test("initializes a datepicker when data role is datepicker", function() { + dom = $(''); + dom.appendTo(QUnit.fixture); + + kendo.bind(dom); + + ok(dom.data("kendoDatePicker") instanceof kendo.ui.DatePicker); +}); + +test("initializes a options from data attributes", function() { + dom = $(''); + dom.appendTo(QUnit.fixture); + + kendo.bind(dom); + + var datepicker = dom.data("kendoDatePicker"); + + equal(datepicker.options.start, "year"); + equal(datepicker.dateView.options.start, "year"); +}); + +test("Preserve options after widget init", function() { + dom = $(''); + dom.appendTo(QUnit.fixture); + dom.kendoDatePicker({ + start: "decade", + depth: "decade" + }); + + kendo.bind(dom); + + var datepicker = dom.data("kendoDatePicker"); + + equal(datepicker.options.start, "decade"); + equal(datepicker.dateView.options.start, "decade"); +}); + +test("initializes options from data attributes after init of the widget", function() { + dom = $(''); + dom.appendTo(QUnit.fixture); + dom.kendoDatePicker(); + + kendo.bind(dom); + + var datepicker = dom.data("kendoDatePicker"); + + equal(datepicker.options.format, "MM yyyy"); + equal(datepicker.dateView.options.format, "MM yyyy"); + + equal(datepicker.options.start, "year"); + equal(datepicker.dateView.options.start, "year"); +}); + +test("initializes a parseFormats option from data attributes", function() { + dom = $(''); + dom.appendTo(QUnit.fixture); + + dom.kendoDatePicker(); + kendo.bind(dom); + + var datepicker = dom.data("kendoDatePicker"); + + equal(datepicker.options.parseFormats[0], "MM yyyy"); + equal(datepicker.options.parseFormats[1], "MM/dd/yyyy"); +}); + +test("initializes a parseFormats option from data attribute with array value", function() { + dom = $(''); + dom.appendTo(QUnit.fixture); + + kendo.bind(dom); + + var datepicker = dom.data("kendoDatePicker"); + + equal(datepicker.options.parseFormats[0], "MM yyyy"); + equal(datepicker.options.parseFormats[1], "MM/dd/yyyy"); + equal(datepicker.options.parseFormats[2], "dd/MM/yyyy"); +}); + +test("initializes value from view model", function() { + dom = $(''); + dom.appendTo(QUnit.fixture); + + var value = new Date(); + + kendo.bind(dom, { value: value } ); + + equal(dom.data("kendoDatePicker").value().getTime(), value.getTime()); +}); + +test("changing a value updates the view model", function() { + dom = $(''); + dom.appendTo(QUnit.fixture); + + var observable = kendo.observable({ value: null }); + + kendo.bind(dom, observable); + var value = new Date(2011, 1, 2); + + dom.data("kendoDatePicker").value(value); + dom.data("kendoDatePicker").trigger("change"); + + equal(observable.value.getTime(), value.getTime()); +}); + +test("changing to invalid value does not clear widget", function() { + dom = $(''); + dom.appendTo(QUnit.fixture); + + var observable = kendo.observable({ value: new Date() }); + + kendo.bind(dom, observable); + dom.val("10/10/0099").focus().blur(); + + equal(observable.value, null); + equal(dom.val(), "10/10/0099"); +}); + +test("binding datepicker initialized before binding", function() { + dom = $(''); + dom.appendTo(QUnit.fixture); + + var value = new Date(2011, 1, 2); + var observable = kendo.observable({ value: null }); + observable.value = value; + + dom.kendoDatePicker(); + + kendo.bind(dom, observable); + + equal(dom.data("kendoDatePicker").value().getTime(), value.getTime()); +}); + +test("binding datepicker initialized after binding", function() { + dom = $(''); + dom.appendTo(QUnit.fixture); + + var observable = kendo.observable({ value: null }); + var value = new Date(2011, 1, 2); + observable.value = value; + + kendo.bind(dom, observable); + + dom.kendoDatePicker(); + + equal(dom.data("kendoDatePicker").value().getTime(), value.getTime()); +}); + +test("updating model value updates the UI", function() { + dom = $(''); + dom.appendTo(QUnit.fixture); + + var observable = kendo.observable({ value: value }); + + kendo.bind(dom, observable); + + dom.kendoDatePicker(); + + var value = new Date(2011, 1, 2); + observable.set("value", value) + equal(dom.data("kendoDatePicker").value().getTime(), value.getTime()); +}); + +test("bindings are removed if element is rebind", 1, function() { + dom = $(''); + dom.appendTo(QUnit.fixture); + + var observable = kendo.observable({ value: new Date(2011, 1, 2) }); + + kendo.bind(dom, observable); + + var destroy = stub(dom[0].kendoBindingTarget, "destroy"); + + kendo.bind(dom, observable); + + equal(destroy.calls("destroy"), 1); +}); + +test("binding target is destroyed", 1, function() { + dom = $(''); + dom.appendTo(QUnit.fixture); + + var observable = kendo.observable({ value: null }); + + kendo.bind(dom, observable); + + var destroy = stub(dom[0].kendoBindingTarget, "destroy"); + + kendo.bind(dom, observable); + + equal(destroy.calls("destroy"), 1); +}); + +test("dataBound event is raised if attached as option", 1, function() { + dom = $(''); + dom.appendTo(QUnit.fixture); + + var observable = kendo.observable({ + items: [{text:"foo"}, {text:"bar"}] + }); + + kendo.bind(dom, observable); + dom.data("kendoDatePicker").trigger("change"); +}); + +test("dataBound event is raised if attached as option to a already initialized datepicker", 1, function() { + dom = $('').kendoDatePicker(); + dom.appendTo(QUnit.fixture); + + var observable = kendo.observable({ + items: [{text:"foo"}, {text:"bar"}] + }); + + kendo.bind(dom, observable); + dom.data("kendoDatePicker").trigger("change"); +}); + +test("binding enabled to false disables the widget", function() { + dom = $(''); + dom.appendTo(QUnit.fixture); + + var observable = kendo.observable({ + enabled: false + }); + + kendo.bind(dom, observable); + + ok(dom.is(":disabled")); +}); + +test("binding enabled to true enables the widget", function() { + dom = $(''); + dom.appendTo(QUnit.fixture); + + var observable = kendo.observable({ + enabled: true + }); + + kendo.bind(dom, observable); + + ok(!dom.is(":disabled")); +}); + +test("binding disable to true disables the widget", function() { + dom = $(''); + dom.appendTo(QUnit.fixture); + + var observable = kendo.observable({ + disabled: false + }); + + kendo.bind(dom, observable); + + ok(!dom.is(":disabled")); +}); + +test("binding disabled to false enables the widget", function() { + dom = $(''); + dom.appendTo(QUnit.fixture); + + var observable = kendo.observable({ + disabled: true + }); + + kendo.bind(dom, observable); + + ok(dom.is(":disabled")); +}); + +test("binding visible to false hides the widget", function() { + dom = $(''); + dom.appendTo(QUnit.fixture); + + var observable = kendo.observable({ + visible: false + }); + + kendo.bind(dom, observable); + + ok(dom.data("kendoDatePicker").wrapper.css("display") == "none", "Display is 'none'"); +}); + +test("binding visible to true shows the widget", function() { + dom = $(''); + dom.appendTo(QUnit.fixture); + + var observable = kendo.observable({ + visible: true + }); + + kendo.bind(dom, observable); + + ok(dom.data("kendoDatePicker").wrapper.css("display") != "none", "Display is not 'none'"); +}); + +test("changing visible to false hides the widget", function() { + dom = $(''); + dom.appendTo(QUnit.fixture); + + var observable = kendo.observable({ + visible: true + }); + + kendo.bind(dom, observable); + observable.set("visible", false); + + ok(dom.data("kendoDatePicker").wrapper.css("display") == "none", "Display is 'none'"); +}); + +test("changing visible to true shows the widget", function() { + dom = $(''); + dom.appendTo(QUnit.fixture); + + var observable = kendo.observable({ + visible: false + }); + + kendo.bind(dom, observable); + observable.set("visible", true); + + ok(dom.data("kendoDatePicker").wrapper.css("display") != "none", "Display is not 'none'"); +}); + +test("binding invisible to true hides the widget", function() { + dom = $(''); + dom.appendTo(QUnit.fixture); + + var observable = kendo.observable({ + invisible: true + }); + + kendo.bind(dom, observable); + + ok(dom.data("kendoDatePicker").wrapper.css("display") == "none", "display is 'none'"); +}); + +test("binding invisible to false shows the widget", function() { + dom = $(''); + dom.appendTo(QUnit.fixture); + + var observable = kendo.observable({ + invisible: false + }); + + kendo.bind(dom, observable); + + ok(dom.data("kendoDatePicker").wrapper.css("display") != "none", "display is not 'none'"); +}); + +test("changing invisible to true hides the widget", function() { + dom = $(''); + dom.appendTo(QUnit.fixture); + + var observable = kendo.observable({ + invisible: false + }); + + kendo.bind(dom, observable); + observable.set("invisible", true); + + ok(dom.data("kendoDatePicker").wrapper.css("display") == "none", "display is 'none'"); +}); + +test("changing invisible to false shows the widget", function() { + dom = $(''); + dom.appendTo(QUnit.fixture); + + var observable = kendo.observable({ + invisible: true + }); + + kendo.bind(dom, observable); + observable.set("invisible", false); + + ok(dom.data("kendoDatePicker").wrapper.css("display") != "none", "display is not 'none'"); +}); + +test("binding datepicker initialized before binding does not override change event handler of calendar", 1, function() { + dom = $(''); + dom.appendTo(QUnit.fixture); + + var value = new Date(2011, 1, 2); + var observable = kendo.observable({ value: null }); + observable.value = value; + + kendo.bind(dom, observable); + + dom.kendoDatePicker({ + change: function() { + equal(this, dom.data("kendoDatePicker")); + } + }); + + dom.data("kendoDatePicker").open(); + dom.data("kendoDatePicker").dateView.calendar.value(new Date(2000, 10, 10)); + dom.data("kendoDatePicker").dateView.calendar.trigger("change"); +}); + +})(); diff --git a/tests/datepicker/navigation.js b/tests/datepicker/navigation.js new file mode 100644 index 00000000000..4fb66a78ff1 --- /dev/null +++ b/tests/datepicker/navigation.js @@ -0,0 +1,763 @@ +(function() { + +var DateView = kendo.DateView, + keys = kendo.keys, + dateview, + anchor, + input; + +module("kendo.ui.DatePicker API", { + setup: function() { + kendo.effects.disable(); + + kendo.ns = "kendo-"; + + input = $("").appendTo(QUnit.fixture); + anchor = $("").appendTo(QUnit.fixture); + }, + teardown: function() { + kendo.effects.enable(); + + if (dateview) { + dateview.destroy(); + } + + kendo.destroy(QUnit.fixture); + + kendo.ns = ""; + } +}); + +test("click enter should raise change event if dateview is closed", function() { + var datepicker = input.kendoDatePicker().data("kendoDatePicker"); + + datepicker.close(); + + stub(datepicker, { _change: datepicker._change }); + + input.focus().val("10/10/2000"); + datepicker._keydown({ + currentTarget: document.createElement("input"), + keyCode: keys.ENTER, + preventDefault: $.noop + }); + + equal(datepicker.calls("_change"), 1); +}); + +test("navigate down should persist current viewedateviewalue", function() { + var value = new Date(2000, 10, 10, 22, 22, 22), + upEvent = { keyCode: keys.UP, ctrlKey: true, preventDefault: $.noop }, + downEvent = { keyCode: keys.DOWN, ctrlKey: true, preventDefault: $.noop }; + + dateview = new DateView({ + value: value, + min: new Date(1999, 10, 10), + max: new Date(2111, 10, 10), + start: "month", + depth: "month" + }); + + dateview.open(); + + dateview.move(upEvent); + dateview.move(upEvent); + + dateview.move(downEvent); + dateview.move(downEvent); + + equal(+dateview._current, +value); +}); + +//MONTH View +test("navigate should not move selection if value is bigger than max", function() { + var event = { keyCode: keys.RIGHT, preventDefault: $.noop }, + date = new Date(2000, 11, 1); + + dateview = new DateView({ + depth: "month", + start: "month", + min: new Date(1900, 10, 10), + value: date, + max: date + }); + + dateview.open(); + dateview.move(event); + + equal(+dateview._current, +date); + equal(dateview.calendar._table.find(".k-state-focused").text(), date.getDate() + ""); +}); + +test("navigate should not move selection if value is less than min", function() { + var event = { keyCode: keys.LEFT, preventDefault: $.noop }, + date = new Date(2000, 11, 1); + + dateview = new DateView({start: "month", depth: "month", value: date, min: date, max: new Date(2100, 10, 10)}); + + dateview.open(); + dateview.move(event); + + equal(+dateview._current, +date); + equal(dateview.calendar._table.find(".k-state-focused").text(), date.getDate() + ""); + +}); + +test("navigate should focus next day in month view", function() { + dateview = new DateView({ + start: "month", + depth: "month", + min: new Date(1999, 10, 10), + max: new Date(2111, 10, 10) + }); + + var event = { keyCode: keys.RIGHT, preventDefault: $.noop }, + focusedDate = new Date(dateview._current); + + kendo.calendar.views[0].setDate(focusedDate, 1); + + dateview.open(); + dateview.move(event); + + equal(dateview.calendar._table.find(".k-state-focused").text(), focusedDate.getDate() + ""); + +}); + +test("navigate should focus previous day in month view", function() { + dateview = new DateView({start: "month", depth: "month", min: new Date(1999, 10, 10), max: new Date(2111, 10, 10)}); + + var event = { keyCode: keys.LEFT, preventDefault: $.noop }, + focusedDate = new Date(dateview._current); + + focusedDate.setDate(focusedDate.getDate() - 1); + + dateview.open(); + dateview.move(event); + + equal(dateview.calendar._table.find(".k-state-focused").text(), focusedDate.getDate() + ""); +}); + +test("navigate should focus day on previous row in month view", function() { + dateview = new DateView({start: "month", depth: "month", min: new Date(1999, 10, 10), max: new Date(2111, 10, 10)}); + + var event = { keyCode: keys.UP, preventDefault: $.noop }, + focusedDate = new Date(dateview._current); + + focusedDate.setDate(focusedDate.getDate() - 7); + + dateview.open(); + dateview.move(event); + + equal(dateview.calendar._table.find(".k-state-focused").text(), focusedDate.getDate() + ""); +}); + +test("navigate should focus day on next row in month view", function() { + dateview = new DateView({start: "month", depth: "month", min: new Date(1999, 10, 10), max: new Date(2111, 10, 10)}); + + var event = { keyCode: keys.DOWN, preventDefault: $.noop }, + focusedDate = new Date(dateview._current); + + focusedDate.setDate(focusedDate.getDate() + 7); + + dateview.open(); + dateview.move(event); + + equal(dateview.calendar._table.find(".k-state-focused").text(), focusedDate.getDate() + ""); +}); + +//YEAR VIEW +test("navigate should focus next month in year view", function() { + dateview = new DateView({value: new Date(2000, 10, 10), start: "month", depth: "month", min: new Date(1999, 10, 10), max: new Date(2111, 10, 10)}); + + var event = { keyCode: keys.RIGHT, preventDefault: $.noop }, + focusedDate = new Date(dateview._current); + + dateview.open(); + dateview.calendar.navigateUp(); + + focusedDate.setMonth(focusedDate.getMonth() + 1); + + dateview.move(event); + + equal(dateview.calendar._table.find(".k-state-focused").text(), "Dec"); +}); + +test("navigate should focus previous month in year view", function() { + dateview = new DateView({value: new Date(2000, 10, 10), start: "month", depth: "month", min: new Date(1999, 10, 10), max: new Date(2111, 10, 10)}); + + var event = { keyCode: keys.LEFT, preventDefault: $.noop }, + focusedDate = new Date(dateview._current); + + dateview.open(); + dateview.calendar.navigateUp(); + + focusedDate.setMonth(focusedDate.getMonth() - 1); + + dateview.move(event); + + equal(+dateview._current, +focusedDate); + equal(dateview.calendar._table.find(".k-state-focused").text(), "Oct"); +}); + +test("navigate should focus month on previous row in year view", function() { + dateview = new DateView({value: new Date(2000, 10, 10), start: "month", depth: "month", min: new Date(1999, 10, 10), max: new Date(2111, 10, 10)}); + + var event = { keyCode: keys.UP, preventDefault: $.noop }, + focusedDate = new Date(dateview._current); + + dateview.open(); + dateview.calendar.navigateUp(); + + focusedDate.setMonth(focusedDate.getMonth() - 4); + + dateview.move(event); + + equal(+dateview._current, +focusedDate); + equal(dateview.calendar._table.find(".k-state-focused").text(), "Jul"); +}); + +test("navigate should focus month on next row in year view", function() { + dateview = new DateView({value: new Date(2000, 10, 10), start: "month", depth: "month", min: new Date(1999, 10, 10), max: new Date(2111, 10, 10)}); + + var event = { keyCode: keys.DOWN, preventDefault: $.noop }, + focusedDate = new Date(dateview._current); + + dateview.open(); + dateview.calendar.navigateUp(); + + focusedDate.setMonth(focusedDate.getMonth() + 4); + + dateview.move(event); + + equal(+dateview._current, +focusedDate); + equal(dateview.calendar._table.find(".k-state-focused").text(), "Mar"); +}); + +//DECADE VIEW +test("navigate should focus next year in decade view", function() { + dateview = new DateView({value: new Date(2000, 10, 10), start: "month", depth: "month", min: new Date(1999, 10, 10), max: new Date(2111, 10, 10)}); + + var event = { keyCode: keys.RIGHT, preventDefault: $.noop }, + focusedDate = new Date(dateview._current); + + dateview.open(); + dateview.calendar.navigate(null, "decade"); + + focusedDate.setFullYear(focusedDate.getFullYear() + 1); + + dateview.move(event); + + equal(+dateview._current, +focusedDate); + equal(dateview.calendar._table.find(".k-state-focused").text(), "2001"); + +}); + +test("navigate should focus previous year in decade view", function() { + dateview = new DateView({value: new Date(2000, 10, 10), start: "month", depth: "month", min: new Date(1999, 10, 10), max: new Date(2111, 10, 10)}); + + var event = { keyCode: keys.LEFT, preventDefault: $.noop }, + focusedDate = new Date(dateview._current); + + dateview.open(); + dateview.calendar.navigate(null, "decade"); + + focusedDate.setFullYear(focusedDate.getFullYear() - 1); + + dateview.move(event); + + equal(+dateview._current, +focusedDate); + equal(dateview.calendar._table.find(".k-state-focused").text(), "1999"); + ok(!dateview.calendar._table.find(".k-state-focused").hasClass("k-other-month")); +}); + +test("navigate should focus year on previous row in decade view", function() { + dateview = new DateView({ + depth: "month", + start: "month", + value: new Date(2000, 10, 10), + min: new Date(1900, 10, 10), + max: new Date(2111, 10, 10) + }); + + var event = { keyCode: keys.UP, preventDefault: $.noop }, + focusedDate = new Date(dateview._current); + + dateview.open(); + dateview.calendar.navigate(null, "decade"); + + focusedDate.setFullYear(focusedDate.getFullYear() - 4); + + dateview.move(event); + + equal(+dateview._current, +focusedDate); + equal(dateview.calendar._table.find(".k-state-focused").text(), "1996"); +}); + +test("navigate should focus year on next row in decade view", function() { + dateview = new DateView({value: new Date(2000, 10, 10), start: "month", depth: "month", min: new Date(1900, 10, 10), max: new Date(2111, 10, 10)}); + + var event = { keyCode: keys.DOWN, preventDefault: $.noop }, + focusedDate = new Date(dateview._current); + + dateview.open(); + dateview.calendar.navigate(null, "decade"); + + focusedDate.setFullYear(focusedDate.getFullYear() + 4); + + dateview.move(event); + + equal(+dateview._current, +focusedDate); + equal(dateview.calendar._table.find(".k-state-focused").text(), "2004"); +}); + +//CENTURY VIEW +test("navigate should focus next decade in century view", function() { + dateview = new DateView({value: new Date(2000, 10, 10), start: "month", depth: "month", min: new Date(1900, 10, 10), max: new Date(2111, 10, 10)}); + + var event = { keyCode: keys.RIGHT, preventDefault: $.noop }, + focusedDate = new Date(dateview._current); + + dateview.open(); + dateview.calendar.navigate(null, "century"); + + focusedDate.setFullYear(focusedDate.getFullYear() + 10); + + dateview.move(event); + + equal(+dateview._current, +focusedDate); + equal(dateview.calendar._table.find(".k-state-focused").text(), "2010 - 2019"); +}); + +test("navigate should focus previous decade in century view", function() { + dateview = new DateView({value: new Date(2000, 10, 10), start: "month", depth: "month", min: new Date(1900, 10, 10), max: new Date(2111, 10, 10)}); + + var event = { keyCode: keys.LEFT, preventDefault: $.noop }, + focusedDate = new Date(dateview._current); + + dateview.open(); + dateview.calendar.navigate(null, "century"); + + focusedDate.setFullYear(focusedDate.getFullYear() - 10); + + dateview.move(event); + + equal(+dateview._current, +focusedDate); + equal(dateview.calendar._table.find(".k-state-focused").text(), "1990 - 1999"); +}); + +test("navigate should focus decade on previous row in century view", function() { + dateview = new DateView({value: new Date(2000, 10, 10), start: "month", depth: "month", min: new Date(1900, 10, 10), max: new Date(2111, 10, 10)}); + + var event = { keyCode: keys.UP, preventDefault: $.noop }, + focusedDate = new Date(dateview._current); + + dateview.open(); + dateview.calendar.navigate(null, "century"); + + focusedDate.setFullYear(focusedDate.getFullYear() - 40); + + dateview.move(event); + + equal(+dateview._current, +focusedDate); + equal(dateview.calendar._table.find(".k-state-focused").text(), "1960 - 1969"); +}); + +test("navigate should focus decade on next row in century view", function() { + dateview = new DateView({value: new Date(2000, 10, 10), start: "month", depth: "month", min: new Date(1900, 10, 10), max: new Date(2111, 10, 10)}); + + var event = { keyCode: keys.DOWN, preventDefault: $.noop }, + focusedDate = new Date(dateview._current); + + dateview.open(); + dateview.calendar.navigate(null, "century"); + + focusedDate.setFullYear(focusedDate.getFullYear() + 40); + + dateview.move(event); + + equal(+dateview._current, +focusedDate); + equal(dateview.calendar._table.find(".k-state-focused").text(), "2040 - 2049"); +}); + +//Navigate through views +test("navigate down", function() { + var event = { keyCode: keys.DOWN, ctrlKey: true, preventDefault: $.noop }; + + dateview = new DateView({ + value: new Date(2000, 10, 10), + start: "month", + depth: "month", + min: new Date(1900, 10, 10), + max: new Date(2111, 10, 10) + }); + + dateview.open(); + + stub(dateview.calendar, { navigateDown: dateview.calendar.navigateDown }); + + dateview.calendar.navigateUp(); + + dateview.calendar._focus(dateview._current); + + dateview.move(event); + + equal(dateview.calendar.calls("navigateDown"), 1); +}); + +test("navigate up", function() { + var event = { keyCode: keys.UP, ctrlKey: true, preventDefault: $.noop }; + + dateview = new DateView({value: new Date(2000, 10, 10), start: "month", depth: "month", min: new Date(1900, 10, 10), max: new Date(2111, 10, 10)}); + + dateview.open(); + stub(dateview.calendar, "navigateUp"); + + dateview.move(event); + + equal(dateview.calendar.calls("navigateUp"), 1); +}); + +test("navigate down selects date", function() { + dateview = new DateView({value: new Date(2000, 10, 10), start: "month", depth: "month", min: new Date(1900, 10, 10), max: new Date(2111, 10, 10)}); + + var event = { keyCode: keys.DOWN, ctrlKey: true, preventDefault: $.noop }, + selectedDate = new Date(2000, 10, 15); + + dateview.open(); + dateview.calendar._focus(selectedDate); + + dateview.move(event); + + equal(+dateview.calendar.value(), +selectedDate); +}); + +test("navigate left", function() { + var event = { keyCode: keys.LEFT, ctrlKey: true, preventDefault: $.noop }; + + dateview = new DateView({value: new Date(2000, 10, 10), start: "month", depth: "month", min: new Date(1900, 10, 10), max: new Date(2111, 10, 10)}); + + dateview.open(); + + stub(dateview.calendar, "navigateToPast"); + + dateview.move(event); + + equal(dateview.calendar.calls("navigateToPast"), 1); +}); + +test("navigate right", function() { + var event = { keyCode: keys.RIGHT, ctrlKey: true, preventDefault: $.noop }; + + dateview = new DateView({value: new Date(2000, 10, 10), start: "month", depth: "month", min: new Date(1900, 10, 10), max: new Date(2111, 10, 10)}); + + dateview.open(); + + stub(dateview.calendar, "navigateToFuture"); + + dateview.move(event); + + equal(dateview.calendar.calls("navigateToFuture"), 1); +}); + +test("Home should focus first day of current month", function() { + var event = { keyCode: keys.HOME, preventDefault: $.noop }; + + dateview = new DateView({value: new Date(2000, 10, 10), start: "month", depth: "month", min: new Date(1900, 10, 10), max: new Date(2111, 10, 10)}); + + dateview.open(); + dateview.move(event); + + var value = dateview.calendar.element.find(".k-state-focused").children(":first").attr("data-kendo-value"); + + equal(value, "2000/10/1"); +}); + +test("End should focus last day of current month", function() { + var event = { keyCode: keys.END, preventDefault: $.noop }; + + dateview = new DateView({value: new Date(2000, 10, 10), start: "month", depth: "month", min: new Date(1900, 10, 10), max: new Date(2111, 10, 10)}); + + dateview.open(); + dateview.move(event); + + var value = dateview.calendar.element.find(".k-state-focused").children(":first").attr("data-kendo-value"); + + equal(value, "2000/10/30"); +}); + +test("PageUp should focus same day in previous month", function() { + var event = { keyCode: keys.PAGEUP, preventDefault: $.noop }; + + dateview = new DateView({value: new Date(2000, 10, 10), start: "month", depth: "month", min: new Date(1900, 10, 10), max: new Date(2111, 10, 10)}); + + dateview.open(); + stub(dateview.calendar, {navigateToPast: dateview.calendar.navigateToPast}); + + dateview.move(event); + + equal(dateview.calendar.calls("navigateToPast"), 1); +}); + +test("PageDown should focus same day in next month", function() { + var event = { keyCode: keys.PAGEDOWN, preventDefault: $.noop }; + + dateview = new DateView({value: new Date(2000, 10, 10), start: "month", depth: "month", min: new Date(1900, 10, 10), max: new Date(2111, 10, 10)}); + + dateview.open(); + + stub(dateview.calendar, {navigateToFuture: dateview.calendar.navigateToFuture}); + + dateview.move(event); + + equal(dateview.calendar.calls("navigateToFuture"), 1); +}); + +test("Enter should close date if select date", function() { + var event = { keyCode: keys.ENTER, preventDefault: $.noop }; + + dateview = new DateView({ + anchor: anchor, + value: new Date(2000, 10, 10), + min: new Date(1900, 10, 10), + max: new Date(2100, 10, 10), + start: "month", + depth: "month" + }); + + dateview.open(); + + dateview.calendar._focus(dateview._current); + + dateview.move(event); + + ok(!dateview.popup.visible()); +}); + +test("Enter should focus viewedDate", function() { + var event = { keyCode: keys.ENTER, preventDefault: $.noop }; + + dateview = new DateView({ + anchor: anchor, + value: new Date(2000, 10, 10), + min: new Date(1900, 10, 10), + max: new Date(2100, 10, 10), + start: "month", + depth: "month" + }); + + dateview.open(); + + dateview.calendar.navigate(new Date(2000, 10, 10), "year"); + dateview.calendar._focus(dateview._current); + dateview.move(event); + + ok(dateview.popup.visible()); + equal(dateview.calendar._table.find(".k-state-focused").length, 1); +}); + +test("Enter should select date", function() { + dateview = new DateView({ + anchor: anchor, + value: new Date(2000, 10, 10), + min: new Date(1900, 10, 10), + max: new Date(2100, 10, 10), + start: "month", + depth: "month" + }); + + var called, event = { keyCode: keys.ENTER, preventDefault: $.noop }, + focused = new Date(2000, 10, 11); + + dateview.open(); + + stub(dateview.calendar, {navigateDown: dateview.calendar.navigateDown}); + + dateview.calendar._focus(focused); + dateview.move(event); + + equal(+dateview.calendar.args("navigateDown")[0], +focused); +}); + +test("Enter should navigate down", function() { + var event = { keyCode: keys.ENTER, preventDefault: $.noop }; + + dateview = new DateView({ + anchor: anchor, + value: new Date(2010, 10, 10), + min: new Date(1900, 10, 10), + max: new Date(2100, 10, 10), + start: "month", + depth: "month" + }); + + dateview.open(); + + stub(dateview.calendar, {navigateDown: dateview.calendar.navigateDown}); + + dateview.calendar.navigateUp(); + dateview.calendar._focus(dateview._current); + + dateview.move(event); + + equal(dateview.calendar.calls("navigateDown"), 1); +}); + +test("Esc should close dateView", function() { + var event = { keyCode: keys.ESC, preventDefault: $.noop }; + + dateview = new DateView({ + anchor: anchor, + value: new Date(2000, 10, 10), + min: new Date(1900, 10, 10), + max: new Date(2100, 10, 10), + start: "month", + depth: "month" + }); + + dateview.open(); + + stub(dateview.popup, "close"); + + dateview.move(event); + + equal(dateview.popup.calls("close"), 1); +}); + +test("type invalide date does not clear input", function() { + datepicker = input.kendoDatePicker({value: new Date()}).data("kendoDatePicker"); + + var value = "invalid date"; + + input.focus().val(value).blur(); + + equal(input.val(), value); + equal(datepicker.value(), null); +}); + +test("click on selected date should close the dateView", 1, function() { + dateview = new DateView({ + min: new Date(1800, 1, 1), + max: new Date(2800, 1, 1), + start: "month", + depth: "month", + anchor: anchor, + clearBlurTimeout: $.noop, + close: function() { + ok(true); + } + }); + + dateview.value(new Date()); + dateview.open(); + + dateview.calendar + .element + .find(".k-state-selected") + .click(); +}); + +test("Alt + Down should open the calendar", function() { + var event = { type: "keydown", keyCode: keys.DOWN, altKey: true, preventDefault: $.noop }; + + datepicker = input.kendoDatePicker().data("kendoDatePicker"); + + stub(datepicker.dateView, "open"); + + input.trigger(event); + + equal(datepicker.dateView.calls("open"), 1); +}); + +test("Alt + UP should close the calendar", function() { + var event = { type: "keydown", keyCode: keys.UP, altKey: true, preventDefault: $.noop }; + + datepicker = input.kendoDatePicker().data("kendoDatePicker"); + + stub(datepicker.dateView, "close"); + + input.trigger(event); + + equal(datepicker.dateView.calls("close"), 1); +}); + +test("DatePicker does not update the input if the entered value is the same but in diff format", function() { + datepicker = input.kendoDatePicker({ + format: "dd MMM yyyy", + parseFormats: ["yyyy/MM/dd"], + value: kendo.toString(today, "dd MMM yyyy") + }).data("kendoDatePicker"); + + var today = new Date(), + todayDiffFormat = kendo.toString(today, "yyyy/MM/dd"); + + input.val(todayDiffFormat); + + //simulate change + datepicker._change(input.val()); + + equal(input.val(), kendo.toString(today, "dd MMM yyyy")); +}); + +test("DatePicker does not call change on blur if no text change", function() { + var date = new Date(1919, 0, 1); + + datepicker = input.kendoDatePicker({ + format: "MM/dd/yy", + value: new Date(date) + }).data("kendoDatePicker"); + + datepicker.options.parseFormats = ["MM/dd/yyyy", "MM/dd/yy"]; + + //simulate change + input.focus().blur(); + + equal(+datepicker.value(), +date); +}); + +test("DatePicker does not call change on ENTER if no text change", function() { + var date = new Date(1919, 0, 1); + + datepicker = input.kendoDatePicker({ + format: "MM/dd/yy", + value: new Date(date) + }).data("kendoDatePicker"); + + datepicker.options.parseFormats = ["MM/dd/yyyy", "MM/dd/yy"]; + + //simulate change + input.focus().trigger({ + type: "keydown", + keyCode: kendo.keys.ENTER + }); + + equal(+datepicker.value(), +date); +}); + +test("DatePicker does set focused date of calendar if no text change", function() { + var date = new Date(1919, 0, 1); + + datepicker = input.kendoDatePicker({ + format: "MM/dd/yy", + value: new Date(date) + }).data("kendoDatePicker"); + + datepicker.options.parseFormats = ["MM/dd/yyyy", "MM/dd/yy"]; + + input.focus(); + datepicker.open(); + + equal(+datepicker.dateView._current, +date); +}); + +test("click enter should raise change event if dateview is closed", function() { + var datepicker = input.kendoDatePicker().data("kendoDatePicker"); + + input.focus(); + datepicker.open(); + + datepicker.dateView.calendar.element.find(".k-nav-fast").click(); + + ok(datepicker.dateView.popup.visible()); +}); + +})(); diff --git a/tests/datetimepicker/api.js b/tests/datetimepicker/api.js new file mode 100644 index 00000000000..fa9aba23411 --- /dev/null +++ b/tests/datetimepicker/api.js @@ -0,0 +1,763 @@ +(function() { + +var DateTimePicker = kendo.ui.DateTimePicker, + input; + +module("kendo.ui.DateTimePicker api", { + setup: function() { + kendo.effects.disable(); + input = $("").appendTo(QUnit.fixture); + }, + teardown: function() { + kendo.effects.enable(); + input.data("kendoDateTimePicker").destroy(); + } +}); + +test("open method with 'date' param opens DateView", function() { + var datetimepicker = new DateTimePicker(input); + + datetimepicker.open("date"); + + ok(datetimepicker.dateView.popup.visible()); +}); + +test("open method with 'time' param opens TimeView", function() { + var datetimepicker = new DateTimePicker(input); + + datetimepicker.open("time"); + + ok(datetimepicker.timeView.popup.visible()); +}); + +test("close method with 'date' param closes DateView", function() { + var datetimepicker = new DateTimePicker(input); + + datetimepicker.open("date"); + datetimepicker.close("date"); + + ok(!datetimepicker.dateView.popup.visible()); +}); + +test("close method with 'time' param closes TimeView", function() { + var datetimepicker = new DateTimePicker(input); + + datetimepicker.open("time"); + datetimepicker.close("time"); + + ok(!datetimepicker.timeView.popup.visible()); +}); + +test("toggle method toggles DateView", function() { + var datetimepicker = new DateTimePicker(input); + + datetimepicker.open("date"); + datetimepicker.toggle("date"); + + ok(!datetimepicker.dateView.popup.visible()); +}); + +test("toggle method toggles TimeView", function() { + var datetimepicker = new DateTimePicker(input); + + datetimepicker.open("time"); + datetimepicker.toggle("time"); + + ok(!datetimepicker.timeView.popup.visible()); +}); + +test("toggle method closes TimeView when DateView is about to open", function() { + var datetimepicker = new DateTimePicker(input); + + datetimepicker.open("time"); + datetimepicker.toggle("date"); + + ok(datetimepicker.dateView.popup.visible()); + ok(!datetimepicker.timeView.popup.visible()); +}); + +test("toggle method closes DateView when TimeView is about to open", function() { + var datetimepicker = new DateTimePicker(input); + + datetimepicker.open("date"); + datetimepicker.toggle("time"); + + ok(!datetimepicker.dateView.popup.visible()); + ok(datetimepicker.timeView.popup.visible()); +}); + +test("value method sets input value", function() { + var datetimepicker = new DateTimePicker(input), + value = "2/10/2000 10:10 AM"; + + datetimepicker.value(value); + + equal(input.val(), value); +}); + +test("value method sets DateView's value", function() { + var datetimepicker = new DateTimePicker(input), + value = "2/10/2000 10:10 AM"; + + stub(datetimepicker.dateView, "value"); + + datetimepicker.value(value); + + equal(datetimepicker.dateView.calls("value"), 1); + ok(datetimepicker.dateView.args("value", 0)[0] instanceof Date); +}); + +test("value method sets TimeView's value", function() { + var datetimepicker = new DateTimePicker(input), + value = "2/10/2000 12:00 AM"; + + datetimepicker.timeView.refresh(); + datetimepicker.value(value); + + ok(datetimepicker.timeView.ul.find(".k-state-selected")[0]); +}); + +test("value method returns value of the datetimepicker", function() { + var datetimepicker = new DateTimePicker(input), + value = new Date(2000, 10, 10); + + datetimepicker.value(value); + + equal(+datetimepicker.value(), +value); +}); + +test("value method sets null if date is out of range", function() { + var datetimepicker = new DateTimePicker(input, { + min: new Date(2000, 10, 10) + }), + value = "2/10/1900 10:10 AM"; + + datetimepicker.value(value); + + equal(datetimepicker.value(), null); +}); + +test("value method uses options.parseFormats to parse passed value", function() { + var secondFormat = "MM/dd/yy", + date = new Date(2000, 10, 10), + datetimepicker = input.kendoDateTimePicker({ + parseFormats: secondFormat + }).data("kendoDateTimePicker"), + dateString = kendo.toString(date, secondFormat); + + datetimepicker.value(dateString); + + equal(+datetimepicker._value, +date); +}); + +test("value method parse passed value using options.parseFormats", function() { + var datetimepicker = input.kendoDateTimePicker({ + parseFormats: ["MMMM yyyy"] + }).data("kendoDateTimePicker"), + date = new Date(2000, 10, 1), + dateString = kendo.toString(date, "MMMM yyyy"); + + datetimepicker.value(dateString); + + equal(+datetimepicker._value, +date); +}); + +test("value method sets timeView's min date", function() { + var date = new Date(2000, 10, 1, 16, 0, 0), + datetimepicker = input.kendoDateTimePicker({ + value: new Date(), + min: date + }).data("kendoDateTimePicker"); + + datetimepicker.value(new Date(2000, 10, 1, 16, 0, 1)); + + equal(+datetimepicker.timeView.options.min, +date); +}); + +test("enable method with false value disables the widget", function() { + var datetimepicker = new DateTimePicker(input); + + datetimepicker.enable(false); + + equal(datetimepicker.element.attr("disabled"), "disabled"); +}); + +test("enable method with false unbind click event of date icon", function() { + var datetimepicker = new DateTimePicker(input); + + datetimepicker.enable(false); + + stub(datetimepicker.dateView, {toggle: datetimepicker.dateView.toggle}); + + datetimepicker._dateIcon.click(); + + ok(!datetimepicker.dateView.popup.visible()); +}); + +test("enable method with false unbind click event of clock icon", function() { + var datetimepicker = new DateTimePicker(input); + + datetimepicker.enable(false); + + stub(datetimepicker.timeView, {toggle: datetimepicker.timeView.toggle}); + + datetimepicker._timeIcon.click(); + + ok(!datetimepicker.timeView.popup.visible()); +}); + +test("enable method with false adds disabled state class to the wrapper", function() { + var datetimepicker = new DateTimePicker(input); + + datetimepicker.enable(false); + + var inputwrapper = datetimepicker.wrapper.children(":first"); + + ok(inputwrapper.hasClass("k-state-disabled")); + ok(!inputwrapper.hasClass("k-state-default")); +}); + +test("enable method with true remove disabled attribute", function() { + var datetimepicker = input.kendoDateTimePicker().data("kendoDateTimePicker"); + + datetimepicker.enable(false); + datetimepicker.enable(true); + + equal(datetimepicker.element.attr("disabled"), undefined); +}); + +test("enable method with true remove disabled class from wrapper", function() { + var datetimepicker = input.kendoDateTimePicker().data("kendoDateTimePicker"); + + datetimepicker.enable(false); + datetimepicker.enable(true); + + ok(datetimepicker.wrapper.children(":first").hasClass("k-state-default")); + ok(!datetimepicker.wrapper.children(":first").hasClass("k-state-disabled")); +}); + +test("readonly() makes input element readonly", function() { + var datetimepicker = input.kendoDateTimePicker().data("kendoDateTimePicker"); + + datetimepicker.readonly(); + + equal(datetimepicker.element.attr("readonly"), "readonly"); +}); + +test("readonly() unbinds date icon click", function() { + var datetimepicker = input.kendoDateTimePicker().data("kendoDateTimePicker"); + + datetimepicker.readonly(); + + datetimepicker._dateIcon.click(); + + ok(!datetimepicker.dateView.popup.visible()); +}); + +test("readonly() unbinds time icon click", function() { + var datetimepicker = input.kendoDateTimePicker().data("kendoDateTimePicker"); + + datetimepicker.readonly(); + + datetimepicker._timeIcon.click(); + + ok(!datetimepicker.timeView.popup.visible()); +}); + +test("readonly(false) removes readonly attribute", function() { + var datetimepicker = input.kendoDateTimePicker().data("kendoDateTimePicker"); + + datetimepicker.readonly(); + datetimepicker.readonly(false); + + equal(datetimepicker.element.attr("readonly"), undefined); +}); + +test("readonly() removes disabled attribute and disabled class", function() { + var datetimepicker = input.kendoDateTimePicker().data("kendoDateTimePicker"); + + datetimepicker.enable(false); + datetimepicker.readonly(); + + equal(datetimepicker.element.attr("readonly"), "readonly"); + equal(datetimepicker.element.attr("disabled"), undefined); + ok(datetimepicker._inputWrapper.hasClass("k-state-default")); + ok(!datetimepicker._inputWrapper.hasClass("k-state-disabled")); +}); + +test("enable(false) removes readonly attribute and default class", function() { + var datetimepicker = input.kendoDateTimePicker().data("kendoDateTimePicker"); + + datetimepicker.readonly(); + datetimepicker.enable(false); + + equal(datetimepicker.element.attr("readonly"), undefined); + equal(datetimepicker.element.attr("disabled"), "disabled"); + ok(!datetimepicker._inputWrapper.hasClass("k-state-default")); + ok(datetimepicker._inputWrapper.hasClass("k-state-disabled")); +}); + +test("enable() enables widget after readonly()", function() { + var datetimepicker = input.kendoDateTimePicker().data("kendoDateTimePicker"); + + datetimepicker.readonly(); + datetimepicker.enable(); + + equal(datetimepicker.element.attr("readonly"), undefined); + equal(datetimepicker.element.attr("disabled"), undefined); + ok(datetimepicker._inputWrapper.hasClass("k-state-default")); + ok(!datetimepicker._inputWrapper.hasClass("k-state-disabled")); +}); + +test("min method returns min value", function() { + var value = new Date("10/22/2000"), + datetimepicker = input.kendoDateTimePicker({min: value}).data("kendoDateTimePicker"); + + var result = datetimepicker.min(); + + equal(+result, +value); +}); + +test("min() sets the min value of the datetimepicker", function() { + var datetimepicker = input.kendoDateTimePicker().data("kendoDateTimePicker"), + value = new Date("10/22/2000"); + + datetimepicker.min(value); + + equal(+datetimepicker.options.min, +value); +}); + +test("min() calls min method of the DateView", function() { + var datetimepicker = input.kendoDateTimePicker().data("kendoDateTimePicker"), + value = new Date(2000, 10, 10, 10, 10, 0); + + stub(datetimepicker.dateView, { min: datetimepicker.dateView.min }); + stub(datetimepicker.timeView, { refresh: datetimepicker.timeView.refresh }); + + datetimepicker.min(value); + + equal(datetimepicker.dateView.calls("min"), 1); +}); + +test("min method does not set TimeView.options.min", function() { + var datetimepicker = input.kendoDateTimePicker({ + value: new Date(2010, 10, 10) + }).data("kendoDateTimePicker"), + min = new Date(2000, 10, 10, 10, 10, 0), + oldMin = +datetimepicker.options.min; + + datetimepicker.min(min); + + equal(+datetimepicker.timeView.options.min, oldMin); +}); + +test("max() returns max value", function() { + var value = new Date("10/22/2000"), + datetimepicker = input.kendoDateTimePicker({max: value}).data("kendoDateTimePicker"); + + var result = datetimepicker.max(); + + equal(+result, +value); +}); + +test("max() sets the max value of the datetimepicker", function() { + var datetimepicker = input.kendoDateTimePicker().data("kendoDateTimePicker"), + value = new Date("10/22/2000"); + + datetimepicker.max(value); + + equal(+datetimepicker.options.max, +value); +}); + +test("max() calls max methods of DateView", function() { + var datetimepicker = input.kendoDateTimePicker().data("kendoDateTimePicker"), + value = new Date(2000, 10, 10, 10, 10, 0); + + stub(datetimepicker.dateView, { max: datetimepicker.dateView.max }); + + datetimepicker.max(value); + + equal(datetimepicker.dateView.calls("max"), 1); +}); + +test("max method does not set TimeView.options.max", function() { + var datetimepicker = input.kendoDateTimePicker({ + value: new Date(2010, 10, 10) + }).data("kendoDateTimePicker"), + max = new Date(2020, 10, 10, 10, 10, 0), + oldMax = +datetimepicker.options.max; + + datetimepicker.max(max); + + equal(+datetimepicker.timeView.options.max, oldMax); +}); + +test("change max date shows all hours", function() { + var datetimepicker = input.kendoDateTimePicker({ + value: new Date(2010, 10, 10), + max: new Date(2010, 10, 10, 16, 0, 0) + }).data("kendoDateTimePicker"); + + datetimepicker.max(new Date(2011, 11, 11, 16, 0, 0)); + + equal(datetimepicker.timeView.ul.children(":last").html(), "11:30 PM"); +}); + +test("max method limits start hours if current value is equal to min", function() { + var date = new Date(2010, 10, 10, 10); + + var datetimepicker = input.kendoDateTimePicker({ + min: date, + max: date, + value: date + }).data("kendoDateTimePicker"); + + var max = new Date(2020, 10, 10, 10, 10, 0); + + datetimepicker.max(max); + + var li = datetimepicker.timeView.ul.find("li"); + + equal(li.first().html(), "10:00 AM"); + equal(li.last().html(), "11:30 PM"); +}); + +test("max method rebinds list if min and max are in the same day", function() { + var datetimepicker = new kendo.ui.DateTimePicker(input, { + min: new Date(2010, 10, 10, 10), + max: new Date(2010, 10, 12, 10), + value: new Date(2010, 10, 10) + }); + + datetimepicker.max(new Date(2010, 10, 10, 11)); + + var li = datetimepicker.timeView.ul.find("li"); + + equal(li.length, 3); + equal(li.first().html(), "10:00 AM"); + equal(li.last().html(), "11:00 AM"); +}); + +test("min method shows all hours in timeView if not edge date", function() { + var datetimepicker = new kendo.ui.DateTimePicker(input, { + value: new Date(2010, 10, 10) + }); + + datetimepicker.min(new Date(2000, 10, 10)); + + var ul = datetimepicker.timeView.ul; + + equal(ul.children(":first").html(), "12:00 AM"); + equal(ul.children(":last").html(), "11:30 PM"); +}); + +test("max method shows only hour from max date if current is edge", function() { + var datetimepicker = new kendo.ui.DateTimePicker(input, { + value: new Date(2010, 10, 10) + }); + + datetimepicker.max(new Date(2010, 10, 10)); + + var ul = datetimepicker.timeView.ul; + + equal(ul.children().length, 1); + equal(ul.children(":first").html(), "12:00 AM"); +}); + +test("min method rebinds timeView to honor min value if current value is min", function() { + var datetimepicker = new kendo.ui.DateTimePicker(input, { + value: new Date(2010, 10, 10) + }); + + datetimepicker.min(new Date(2010, 10, 10, 10, 0, 0)); + + var ul = datetimepicker.timeView.ul; + + equal(ul.children(":first").html(), "10:00 AM"); + equal(ul.children(":last").html(), "11:30 PM"); +}); + +test("max method rebinds timeView to honor max value if current value is max", function() { + var datetimepicker = new kendo.ui.DateTimePicker(input, { + value: new Date(2010, 10, 10) + }); + + datetimepicker.max(new Date(2010, 10, 10, 10, 0, 0)); + + var ul = datetimepicker.timeView.ul; + + equal(ul.children(":first").html(), "12:00 AM"); + equal(ul.children(":last").html(), "10:00 AM"); +}); + +test("min method shows all hours if current value is null", function() { + var datetimepicker = new kendo.ui.DateTimePicker(input); + + datetimepicker.min(new Date(2000, 10, 10)); + + var ul = datetimepicker.timeView.ul; + + equal(ul.children(":first").html(), "12:00 AM"); + equal(ul.children(":last").html(), "11:30 PM"); +}); + +test("value method do not rebind timeView if date is not edge", function () { + var datetimepicker = new kendo.ui.DateTimePicker(input); + + datetimepicker.value(new Date(2000, 10, 10)); + + var ul = datetimepicker.timeView.ul; + + equal(ul.children().length, 0); +}); + +test("value method rebinds timeView if current is equal to min", function() { + var datetimepicker = new kendo.ui.DateTimePicker(input, { + value: new Date(2010, 10, 10), + min: new Date(2000, 10, 10) + }); + + datetimepicker.value(new Date(2000, 10, 10)); + + var ul = datetimepicker.timeView.ul; + + equal(ul.children(":first").html(), "12:00 AM"); + equal(ul.children(":last").html(), "11:30 PM"); +}); + +test("value method rebinds timeView if current is equal to max", function() { + var datetimepicker = new kendo.ui.DateTimePicker(input, { + value: new Date(2000, 10, 10), + max: new Date(2010, 10, 10, 20, 0, 0) + }); + + datetimepicker.value(new Date(2010, 10, 10)); + + var ul = datetimepicker.timeView.ul; + + equal(ul.children(":first").html(), "12:00 AM"); + equal(ul.children(":last").html(), "8:00 PM"); +}); + +test("value method shows only one hour when max is midnight", function() { + var datetimepicker = new kendo.ui.DateTimePicker(input, { + value: new Date(2000, 10, 10), + max: new Date(2010, 10, 10) + }); + + datetimepicker.value(new Date(2010, 10, 10)); + + var ul = datetimepicker.timeView.ul; + + equal(ul.children().length, 1); + equal(ul.children(":first").html(), "12:00 AM"); +}); + +test("value method shows all hours when set diff then edge", function() { + var datetimepicker = new kendo.ui.DateTimePicker(input, { + value: new Date(2010, 10, 10), + max: new Date(2010, 10, 10) + }); + + var ul = datetimepicker.timeView.ul; + + equal(ul.children().length, 1); + equal(ul.children(":first").html(), "12:00 AM"); + + //set value + datetimepicker.value(new Date(2000, 10, 10)); + + ul = datetimepicker.timeView.ul; + + equal(ul.children(":first").html(), "12:00 AM"); + equal(ul.children(":last").html(), "11:30 PM"); +}); + +test("value method do nothing if set to same value as current", function() { + var datetimepicker = new kendo.ui.DateTimePicker(input, { + value: new Date(2010, 10, 10) + }); + + stub(datetimepicker.timeView, "value"); + + datetimepicker.value(new Date(2010, 10, 10)); + + equal(datetimepicker.timeView.calls("value"), 0); +}); + +test("value method do nothing if argument is null", function() { + var datetimepicker = new kendo.ui.DateTimePicker(input, { + value: new Date(2010, 10, 10) + }); + + stub(datetimepicker.timeView, "_bind"); + + datetimepicker.value(null); + + equal(datetimepicker.timeView.calls("_bind"), 0); +}); + +test("value method shows only one date if min and max are in same day", function() { + var datetimepicker = new kendo.ui.DateTimePicker(input, { + value: new Date(2010, 10, 10), + min: new Date(2010, 10, 10), + max: new Date(2010, 10, 10) + }); + + var ul = datetimepicker.timeView.ul; + + equal(ul.children().length, 1); + equal(ul.children(":first").html(), "12:00 AM"); +}); + +test("value method should rebind timeView if select min after max was selected", function() { + var datetimepicker = new kendo.ui.DateTimePicker(input, { + min: new Date(2000, 10, 10, 10, 0, 0), + max: new Date(2010, 10, 10, 20, 0, 0) + }); + + //set value + datetimepicker.value(new Date(2010, 10, 10, 20, 0, 0)); + + var ul = datetimepicker.timeView.ul; + + equal(ul.children(":first").html(), "12:00 AM"); + equal(ul.children(":last").html(), "8:00 PM"); + + //set value + datetimepicker.value(new Date(2000, 10, 10, 10, 0, 0)); + + ul = datetimepicker.timeView.ul; + + equal(ul.children(":first").html(), "10:00 AM"); + equal(ul.children(":last").html(), "11:30 PM"); +}); + +test("value method persist min and max range in timeview", function() { + var datetimepicker = new kendo.ui.DateTimePicker(input, { + min: new Date(2000, 10, 10, 10, 0, 0), + max: new Date(2000, 10, 10, 20, 0, 0) + }); + + //set value + datetimepicker.value(new Date(2000, 10, 10, 12, 0, 0)); + + var ul = datetimepicker.timeView.ul; + + equal(ul.children(":first").html(), "10:00 AM"); + equal(ul.children(":last").html(), "8:00 PM"); +}); + +test("value method updates input element when select max date", function() { + var datetimepicker = new kendo.ui.DateTimePicker(input, { + max: new Date(2000, 9, 10) + }); + + datetimepicker.value(new Date(2000, 9, 10)); + + equal(datetimepicker.element.val(), "10/10/2000 12:00 AM"); +}); + +test("value method restricts time of the value if it's date part is equal to min", function() { + var today = new Date(), + midnight = new Date(today.getFullYear(), today.getMonth(), today.getDate()), + datepicker = input.kendoDateTimePicker({ + min: today, + value: today + }).data("kendoDateTimePicker"); + + datepicker.value(midnight); + + notEqual(datepicker._value, null); + equal(+datepicker._value, +today); +}); + +test("value method restricts time of the value if it's date part is equal to max", function() { + var today = new Date(), + midnight = new Date(today.getFullYear(), today.getMonth(), today.getDate()), + datepicker = input.kendoDateTimePicker({ + max: today, + value: today + }).data("kendoDateTimePicker"); + + datepicker.value(midnight); + + notEqual(datepicker._value, null); + equal(+datepicker._value, +midnight); +}); + +test("value method does not show text representation of invalid value", function() { + var datetimepicker = input.kendoDateTimePicker().data("kendoDateTimePicker"); + + datetimepicker.value("invalid"); + + equal(datetimepicker.value(), null); + equal(input.val(), ""); +}); + +test("setOptions method sets correct timeView min/max values", function() { + var date = new Date(2013, 10, 10, 1, 30); + var min = new Date(2013, 10, 9, 23, 30); + + var datetimepicker = input.kendoDateTimePicker().data("kendoDateTimePicker"); + + datetimepicker.value(date); + + datetimepicker.setOptions({ + min: min + }); + + deepEqual(datetimepicker.timeView.options.min, new Date(1900, 0, 1)); +}); + +test("setOptions rebinds time options", function() { + var datetimepicker = input.kendoDateTimePicker().data("kendoDateTimePicker"); + var timeView = datetimepicker.timeView; + + stub(timeView, { + bind: timeView.bind + }); + + datetimepicker.setOptions({}); + + equal(timeView.calls("bind"), 1); +}); + +test("setOptions supports dynamically format change", function() { + var datetimepicker = input.kendoDateTimePicker().data("kendoDateTimePicker"); + var timeView = datetimepicker.timeView; + + datetimepicker.setOptions({ + timeFormat: "HH:mm" + }); + + var first = timeView.ul.children().first(); + + equal(first.html(), "00:00"); +}); + +test("setOptions method updates calendar options", function() { + var datetimepicker = input.kendoDateTimePicker().data("kendoDateTimePicker"); + datetimepicker.open(); + + datetimepicker.setOptions({ + start: "year", + depth: "year" + }); + + equal(datetimepicker.dateView.calendar.view().name, "year"); +}); + +test("setOptions method updates format", function() { + var datetimepicker = input.kendoDateTimePicker().data("kendoDateTimePicker"); + datetimepicker.open(); + datetimepicker.value(new Date(2013, 10, 10)); + + datetimepicker.setOptions({ + format: "dd/MM/yyyy" + }); + + equal(datetimepicker.element.val(), kendo.toString(datetimepicker.value(), "dd/MM/yyyy")); +}); + +})(); diff --git a/tests/datetimepicker/aria.js b/tests/datetimepicker/aria.js new file mode 100644 index 00000000000..f8934aa1613 --- /dev/null +++ b/tests/datetimepicker/aria.js @@ -0,0 +1,131 @@ +(function() { + +var DateTimePicker = kendo.ui.DateTimePicker, + input, instance; + +module("kendo.ui.DateTimePicker ARIA", { + setup: function() { + input = $("").appendTo(QUnit.fixture); + + kendo.effects.disable(); + instance = new DateTimePicker(input, { + ARIATemplate: "#=kendo.toString(current, 'G')#" + }); + }, + teardown: function() { + instance.destroy(); + } +}); + +test("DateTimePicker adds role to the input element", function() { + equal(input.attr("role"), "combobox"); +}); + +test("DateTimePicker adds aria-expanded", function() { + equal(input.attr("aria-expanded"), "false"); +}); + +test("DateTimePicker sets aria-expanded=true", function() { + instance.open(); + equal(input.attr("aria-expanded"), "true"); +}); + +test("DateTimePicker sets aria-expanded=false", function() { + instance.open(); + instance.close(); + equal(input.attr("aria-expanded"), "false"); +}); + +test("DateTimePicker adds role to the toggle button", function() { + equal(instance._dateIcon.attr("role"), "button"); + equal(instance._timeIcon.attr("role"), "button"); +}); + +test("DateTimePicker adds aria-controls to the toggle button", function() { + equal(instance._dateIcon.attr("aria-controls"), instance.dateView.popup.element.attr("id")); + equal(instance._timeIcon.attr("aria-controls"), instance.timeView.ul.attr("id")); +}); + +test("DateTimePicker sets id to the ul element", function() { + equal(instance.timeView.ul.attr("id"), "test_timeview"); +}); + +test("DateTimePicker sets id to the div element of the dateView", function() { + equal(instance.dateView.div.attr("id"), "test_dateview"); +}); + +test("DateTimePicker sets aria-selected to the selected option", function() { + instance.open("time"); + instance.value("12:00 AM"); + equal(instance.timeView.current().attr("aria-selected"), "true"); +}); + +test("DateTimePicker sets aria-owns to the DateView id", function() { + instance.open("date"); + equal(instance.element.attr("aria-owns"), instance.dateView._dateViewID); +}); + +test("DateTimePicker removes aria-owns to the DateView id", function() { + instance.open("date"); + instance.close("date"); + equal(instance.element.attr("aria-owns"), undefined); +}); + +test("DateTimePicker sets aria-owns to the DateView id", function() { + instance.open("date"); + instance.open("time"); + equal(instance.element.attr("aria-owns"), instance.timeView._timeViewID); +}); + +test("DateTimePicker removes aria-owns to the DateView id", function() { + instance.open("time"); + instance.close("time"); + equal(instance.element.attr("aria-owns"), undefined); +}); + +test("DateTimePicker sets aria-activedescendant", function() { + instance.value("10/10/2000 12:00 AM"); + instance.open("time"); + + equal(instance.element.attr("aria-activedescendant"), instance.timeView._optionID); +}); + +test("DateTimePicker sets aria-activedescendant after navigation", function() { + instance.open(); + + instance.element.focus().trigger({ + type: "keydown", + preventDefault: function() {}, + keyCode: 40 + }); + + var cell = instance.dateView.calendar.element.find("td.k-state-focused"); + + equal(instance.element.attr("aria-activedescendant"), cell.attr("id")); +}); + +test("DateTimePicker sets aria-label to focused cell", function() { + instance.open(); + + var date = kendo.date.today(); + var cell = instance.dateView.calendar.element.find("td.k-state-focused"); + + equal(cell.attr("aria-label"), kendo.toString(date, "G")); +}); + +test("DateTimePicker removes aria-label from previous cell", function() { + instance.open(); + + instance.element.focus().trigger({ + type: "keydown", + preventDefault: function() {}, + keyCode: 40 + }); + + var date = kendo.date.today(); + var cell = instance.dateView.calendar.element.find("td[aria-label]"); + + equal(cell.length, 1); +}); + +})(); diff --git a/tests/datetimepicker/events.js b/tests/datetimepicker/events.js new file mode 100644 index 00000000000..0a01865c2aa --- /dev/null +++ b/tests/datetimepicker/events.js @@ -0,0 +1,150 @@ +(function() { + +var DateTimePicker = kendo.ui.DateTimePicker, + input; + +module("kendo.ui.DateTimePicker events", { + setup: function() { + input = $("").appendTo(QUnit.fixture); + }, + teardown: function() { + input.data("kendoDateTimePicker").destroy(); + } +}); + +test("DateTimePicker triggers change event on DateView change", 1, function() { + var today = new Date(), + datetimepicker = new DateTimePicker(input), + dateView = datetimepicker.dateView; + + datetimepicker.bind("change", function() { + equal(+datetimepicker.value(), +today); + }); + + //simulate user click + dateView._calendar(); + dateView.calendar.value(today); + dateView.calendar.trigger("change"); +}); + +test("DateTimePicker triggers change event on TimeView click", 1, function() { + var datetimepicker = new DateTimePicker(input), + timeView = datetimepicker.timeView, + li, date; + + timeView.refresh(); + li = timeView.ul.children(":first"); + date = timeView._parse(li.text()); + + datetimepicker.bind("change", function() { + equal(+datetimepicker.value(), +date); + }); + + li.click(); +}); + +test("DateTimePicker triggers change on blur", 1, function() { + var datetimepicker = new DateTimePicker(input), + today = new Date(2000, 10, 10, 10, 30, 0); + + datetimepicker.bind("change", function() { + equal(+datetimepicker.value(), +today); + }); + + input.focus().val(kendo.toString(today, datetimepicker.options.format)).blur(); +}); + +test("DateTimePicker raises change event on enter", 1, function() { + var datetimepicker = new DateTimePicker(input, { + change: function() { + ok(true); + } + }); + + input.val("10/10/2000 12:00 AM"); + input.focus().trigger({ + type: "keydown", + keyCode: kendo.keys.ENTER + }); +}); + +test("DateTimePicker does not raise change event on enter", 0, function() { + var datetimepicker = new DateTimePicker(input, { + value: new Date(2000, 10, 10), + change: function() { + ok(false); + } + }); + + input.focus().trigger({ + type: "keydown", + keyCode: kendo.keys.ENTER + }); +}); + +test("DateTimePicker does not raise change when navigate in TimeView", 0, function() { + var datetimepicker = new DateTimePicker(input, { + value: new Date(2000, 10, 10), + change: function() { + ok(false); + } + }); + + datetimepicker.open("time"); + input.focus().trigger({ + type: "keydown", + keyCode: kendo.keys.DOWN + }); +}); + +test("DateTimePicker triggers open event when timeView is opened", 2, function() { + var datetimepicker = new DateTimePicker(input, { + value: new Date(2000, 10, 10), + open: function(e) { + ok(true); + equal(e.view, "time"); + } + }); + + datetimepicker.timeView.popup.open(); +}); + +test("DateTimePicker triggers open event when dateView is opened", 2, function() { + var datetimepicker = new DateTimePicker(input, { + value: new Date(2000, 10, 10), + open: function(e) { + ok(true); + equal(e.view, "date"); + } + }); + + datetimepicker.dateView.popup.open(); +}); + +test("DateTimePicker triggers close event when timeView is opened", 2, function() { + var datetimepicker = new DateTimePicker(input, { + value: new Date(2000, 10, 10), + close: function(e) { + ok(true); + equal(e.view, "time"); + } + }); + + datetimepicker.timeView.popup.open(); + datetimepicker.timeView.popup.close(); +}); + +test("DateTimePicker triggers close event when dateView is opened", 2, function() { + var datetimepicker = new DateTimePicker(input, { + value: new Date(2000, 10, 10), + close: function(e) { + ok(true); + equal(e.view, "date"); + } + }); + + datetimepicker.open("date"); + datetimepicker.dateView.popup.close(); +}); + +})(); diff --git a/tests/datetimepicker/initialization.js b/tests/datetimepicker/initialization.js new file mode 100644 index 00000000000..c9533119fe1 --- /dev/null +++ b/tests/datetimepicker/initialization.js @@ -0,0 +1,305 @@ +(function() { + +var DateTimePicker = kendo.ui.DateTimePicker, + input; + +module("kendo.ui.DateTimePicker initialization", { + setup: function() { + input = $("").appendTo(QUnit.fixture); + }, + teardown: function() { + input.data("kendoDateTimePicker").destroy(); + } +}); + +test("_wrapper() wraps input element", function() { + input.css("width", "200"); + + var datetimepicker = input.kendoDateTimePicker().data("kendoDateTimePicker"); + + ok(input.parent().hasClass("k-picker-wrap k-state-default")); + equal(datetimepicker.wrapper.attr("class"), "k-widget k-datetimepicker k-header"); +}); + +test("DateTimePicker adds k-input class to the element", function() { + var datetimepicker = input.kendoDateTimePicker().data("kendoDateTimePicker"); + + ok(datetimepicker.element.hasClass("k-input")); +}); + +test("_icons method creates calendar and clock button", function() { + var datetimepicker = input.kendoDateTimePicker().data("kendoDateTimePicker"), + icons = datetimepicker.wrapper.find(".k-select"); + + ok(icons.is("span")); + ok(icons.hasClass("k-select")); + + ok(icons.children(":first").hasClass("k-icon k-i-calendar")); + ok(icons.children(":last").hasClass("k-icon k-i-clock")); +}); + +test("DateTimePicker creates DateView", function() { + var datetimepicker = input.kendoDateTimePicker().data("kendoDateTimePicker"); + + ok(datetimepicker.dateView); +}); + +test("DateTimePicker sets correct options to DateView", function() { + var datetimepicker = input.kendoDateTimePicker({open: function() {}, close: $.noop}).data("kendoDateTimePicker"), + dateView = datetimepicker.dateView, + options = dateView.options, + dpOptions = datetimepicker.options; + + ok(dateView.options); + equal(options.anchor, datetimepicker.wrapper); + equal(options.value, dpOptions.value); + equal(+options.min, +dpOptions.min); + equal(+options.max, +dpOptions.max); +}); + +test("DateTimePicker creates TimeView", function() { + var datetimepicker = input.kendoDateTimePicker().data("kendoDateTimePicker"); + + ok(datetimepicker.timeView); +}); + +test("DateTimePicker sets correct options to TimeView", function() { + var datetimepicker = input.kendoDateTimePicker().data("kendoDateTimePicker"), + timeView = datetimepicker.timeView; + + equal(timeView.options.anchor, datetimepicker.wrapper); + equal(timeView.options.format, datetimepicker.options.timeFormat); + equal(timeView.options.interval, datetimepicker.options.interval); +}); + +test("datetimepicker wire date icon click", function() { + var datetimepicker = new DateTimePicker(input); + + datetimepicker.close(); + datetimepicker._dateIcon.click(); + ok(datetimepicker.dateView.popup.visible()); +}); + +test("datetimepicker wire clock icon click", function() { + var datetimepicker = new DateTimePicker(input); + + datetimepicker.close("time"); + datetimepicker._timeIcon.click(); + ok(datetimepicker.timeView.popup.visible()); +}); + +test("datetimepicker disables widget if input has disabled attribute", function() { + var datetimepicker = new DateTimePicker(input.attr("disabled", "disabled")); + + ok(datetimepicker.wrapper.children(":first").hasClass("k-state-disabled")); +}); + +asyncTest("form reset support", 2, function() { + input.attr("value", "12/12/2000 12:00 AM"); + + var form = $("").appendTo(QUnit.fixture).append(input), + datetimepicker = input.kendoDateTimePicker().data("kendoDateTimePicker"); + + datetimepicker.open(); + datetimepicker.value("12/12/2010 12:00 AM"); + + form[0].reset(); + + setTimeout(function() { + equal(datetimepicker.element.val(), "12/12/2000 12:00 AM"); + equal(datetimepicker.dateView.calendar.value().getFullYear(), "2000"); + start(); + }, 100); +}); + +asyncTest("support for form defined by attribute", 2, function() { + input.attr("form", "form1").attr("value", "12/12/2000 12:00 AM"); + + var form = $("").appendTo(QUnit.fixture), + datetimepicker = input.kendoDateTimePicker().data("kendoDateTimePicker"); + + datetimepicker.open(); + datetimepicker.value("12/12/2010 12:00 AM"); + + form[0].reset(); + + setTimeout(function() { + equal(datetimepicker.element.val(), "12/12/2000 12:00 AM"); + equal(datetimepicker.dateView.calendar.value().getFullYear(), "2000"); + start(); + }, 100); +}); + +test("extend popup options if datetimepicker.options.popup", function() { + var appendTo = "body", + datetimepicker = new kendo.ui.DateTimePicker(input, { + popup: { + appendTo: appendTo + } + }); + + equal(datetimepicker.dateView.popup.options.appendTo[0], $(appendTo)[0]); +}); + +test("DateTimePicker strips the format from {0:format}", function() { + var datetimepicker = new kendo.ui.DateTimePicker(input, { + format: "{0:MM/dd/yyyy hh:mm}", + timeFormat: "{0:hh:mm}" + }); + + equal(datetimepicker.options.format, "MM/dd/yyyy hh:mm"); + equal(datetimepicker.options.timeFormat, "hh:mm"); +}); + +test("DateTimePicker adds format to the parseFormats array", function() { + var datetimepicker = input.kendoDateTimePicker({ + parseFormats: ["MM/dd/yy"] + }).data("kendoDateTimePicker"); + + equal(datetimepicker.options.parseFormats[0], datetimepicker.options.format); + equal(datetimepicker.options.parseFormats[1], datetimepicker.options.timeFormat); + equal(datetimepicker.options.parseFormats[2], "MM/dd/yy"); +}); + +test("DateTimePicker does not modify parseFormats if format exists in the array", function() { + var datetimepicker = input.kendoDateTimePicker({ + format: "MM/dd/yy", + parseFormats: ["MM/dd/yyyy", "MM/dd/yy", "h:mm tt"] + }).data("kendoDateTimePicker"); + + equal(datetimepicker.options.parseFormats.length, 3); + equal(datetimepicker.options.parseFormats[0], "MM/dd/yyyy"); + equal(datetimepicker.options.parseFormats[1], datetimepicker.options.format); + equal(datetimepicker.options.parseFormats[2], datetimepicker.options.timeFormat); +}); + +test("DateTimePicker uses options.dates if today is in dates", function() { + var datetimepicker = input.kendoDateTimePicker({ + dates: [new Date(2000, 10, 10, 18, 0, 0)] + }).data("kendoDateTimePicker"); + + datetimepicker.value(new Date(2000, 10, 10)); + + datetimepicker.open("time"); + + equal(datetimepicker.timeView.ul.children().length, 1); + equal(datetimepicker.timeView.ul.children(":first").text(), "6:00 PM"); +}); + +test("DateTimePicker does not use options.dates if today is not in dates", function() { + var datetimepicker = input.kendoDateTimePicker({ + dates: [new Date(2000, 10, 10, 18, 0, 0)] + }).data("kendoDateTimePicker"); + + datetimepicker.value(new Date(2000, 10, 11)); + + datetimepicker.open("time"); + + ok(datetimepicker.timeView.ul.children().length > 1); +}); + +test("DateTimePicker rebinds timeView if other day is selected", function() { + var datetimepicker = input.kendoDateTimePicker({ + dates: [new Date(2000, 10, 10, 18, 0, 0)] + }).data("kendoDateTimePicker"); + + datetimepicker.value(new Date(2000, 10, 10)); + datetimepicker.open("time"); + + datetimepicker.value(new Date(2010, 10, 10)); + + ok(datetimepicker.timeView.ul.children().length > 1); +}); + +test("DateTimePicker uses options.dates even when edge date is selected", function() { + var datetimepicker = input.kendoDateTimePicker({ + dates: [new Date(2000, 10, 10, 18, 0, 0)], + min: new Date(2000, 10, 10), + max: new Date(2000, 10, 10) + }).data("kendoDateTimePicker"); + + datetimepicker.value(new Date(2000, 10, 10)); + datetimepicker.open("time"); + + equal(datetimepicker.timeView.ul.children().length, 1); + equal(datetimepicker.timeView.ul.children().eq(0).html(), "6:00 PM"); +}); + +test("DateTimePicker copies input's className to the wrapper", function() { + var datetimepicker = input.addClass("test").kendoDateTimePicker().data("kendoDateTimePicker"); + + ok(datetimepicker.wrapper.hasClass("test")); +}); + +test("DateTimePicker updates calendar if empty input element on open", function() { + var datetimepicker = input.kendoDateTimePicker().data("kendoDateTimePicker"); + + datetimepicker.value(new Date()); + + input.focus().val(""); + datetimepicker.open(); + + equal(datetimepicker.dateView.calendar.value(), null); +}); + +test("DateTimePicker updates calendar's focused date", function() { + var datetimepicker = input.kendoDateTimePicker().data("kendoDateTimePicker"), + date = new Date(2000, 10, 10); + + datetimepicker.value(new Date(2000, 9, 1)); + + input.focus().val(kendo.toString(date, "MM/dd/yyyy hh:mm tt")); + datetimepicker.open(); + + var link = datetimepicker.dateView.calendar.element.find(".k-state-focused > .k-link"); + + equal(+datetimepicker.dateView.calendar.value(), +datetimepicker.value()); + equal(link.html(), date.getDate()); +}); + +if (!kendo.support.touch) { + test("DateTimePicker changes the type of the input", function() { + input = $("").appendTo(QUnit.fixture); + + datetimepicker = input.kendoDateTimePicker().data("kendoDateTimePicker"); + + equal(datetimepicker.element[0].type, "text"); + }); +} + +test("DateTimePicker honors readonly attribute", function() { + var datetimepicker = input.attr("readonly", true).kendoDateTimePicker().data("kendoDateTimePicker"); + + datetimepicker._timeIcon.click(); + + ok(!datetimepicker.timeView.popup.visible()); +}); + +test("DateTimePicker uses disabled attr over the readonly", function() { + input.attr("readonly", true).attr("disabled", true).kendoDateTimePicker(); + + equal(input.attr("readonly"), undefined); +}); + +test("DateTimePicker does not remove input text on initialization if not valid value", function() { + var datetimepicker = input.val("test").kendoDateTimePicker().data("kendoDateTimePicker"); + + equal(datetimepicker.value(), null); + equal(input.val(), "test"); +}); + +test("DateTimePicker renders only one possible time option if min and max are equal", function() { + var date = new Date(2013, 10, 10, 10); + var datetimepicker = new DateTimePicker(input, { + min: date, + max: date + }); + + datetimepicker._timeIcon.click(); + + var li = datetimepicker.timeView.ul.find("li"); + equal(li.length, 1); + equal(li.html(), "10:00 AM"); +}); + +})(); diff --git a/tests/datetimepicker/mvvm.js b/tests/datetimepicker/mvvm.js new file mode 100644 index 00000000000..ab5b2ecb22b --- /dev/null +++ b/tests/datetimepicker/mvvm.js @@ -0,0 +1,411 @@ +(function() { + +var dom; + +module("DateTimePicker mvvm", { + setup: function() { + window.change = function() { + ok(true); + } + }, + teardown: function() { + delete window.change; + kendo.destroy(dom); + kendo.destroy(QUnit.fixture); + } +}); + +test("initializes a datetimepicker when data role is datetimepicker", function() { + dom = $(''); + + kendo.bind(dom); + + ok(dom.data("kendoDateTimePicker") instanceof kendo.ui.DateTimePicker); +}); + +test("initializes a options from data attributes", function() { + dom = $(''); + + kendo.bind(dom); + + var datetimepicker = dom.data("kendoDateTimePicker"); + + equal(datetimepicker.options.start, "year"); + equal(datetimepicker.dateView.options.start, "year"); +}); + +test("Preserve options after widget init", function() { + dom = $(''); + dom.kendoDateTimePicker({ + start: "decade", + depth: "decade" + }); + + kendo.bind(dom); + + var datetimepicker = dom.data("kendoDateTimePicker"); + + equal(datetimepicker.options.start, "decade"); + equal(datetimepicker.dateView.options.start, "decade"); +}); + +test("Preserve specific options of the views", function() { + dom = $(''); + + var change = function() { }, + close = function() { }, + open = function() { }; + + dom.kendoDateTimePicker({ + format: "dd/MM/yyyy H:mm", + timeFormat: "H:mm", + change: change, + close: close, + open: open + }); + + kendo.bind(dom); + + var datetimepicker = dom.data("kendoDateTimePicker"); + + equal(datetimepicker.options.format, "dd/MM/yyyy H:mm"); + equal(datetimepicker.options.timeFormat, "H:mm"); + + notEqual(datetimepicker.dateView.options.change, change); + notEqual(datetimepicker.dateView.options.close, close); + notEqual(datetimepicker.dateView.options.open, open); + + equal(datetimepicker.timeView.options.format, "H:mm"); + notEqual(datetimepicker.timeView.options.change, change); + notEqual(datetimepicker.timeView.options.close, close); + notEqual(datetimepicker.timeView.options.open, open); +}); + +test("initializes a options from data attributes after init of the widget", function() { + dom = $(''); + dom.kendoDateTimePicker(); + + kendo.bind(dom); + + var datetimepicker = dom.data("kendoDateTimePicker"); + + equal(datetimepicker.options.format, "MM yyyy hh:mm"); + equal(datetimepicker.dateView.options.format, "MM yyyy hh:mm"); + + equal(datetimepicker.options.start, "year"); + equal(datetimepicker.dateView.options.start, "year"); +}); + +test("initializes a parseFormats option from data attribute with array value", function() { + dom = $(''); + dom.kendoDateTimePicker(); + + kendo.bind(dom); + + var datetimepicker = dom.data("kendoDateTimePicker"); + + equal(datetimepicker.options.parseFormats[0], "MM yyyy"); + equal(datetimepicker.options.parseFormats[1], datetimepicker.options.timeFormat); + equal(datetimepicker.options.parseFormats[2], "MM/dd/yyyy"); + equal(datetimepicker.options.parseFormats[3], "dd/MM/yyyy"); +}); + +test("initializes value from view model", function() { + dom = $(''); + var value = new Date(); + + kendo.bind(dom, { value: value } ); + + equal(dom.data("kendoDateTimePicker").value().getTime(), value.getTime()); +}); + +test("changing a value updates the view model", function() { + dom = $(''); + + var observable = kendo.observable({ value: null }); + + kendo.bind(dom, observable); + var value = new Date(2011, 1, 2); + + dom.data("kendoDateTimePicker").value(value); + dom.data("kendoDateTimePicker").trigger("change"); + + equal(observable.value.getTime(), value.getTime()); +}); + +test("binding datetimepicker initialized before binding", function() { + dom = $(''); + + var value = new Date(2011, 1, 2); + var observable = kendo.observable({ value: null }); + observable.value = value; + + dom.kendoDateTimePicker(); + + kendo.bind(dom, observable); + + equal(dom.data("kendoDateTimePicker").value().getTime(), value.getTime()); +}); + +test("binding datetimepicker initialized after binding", function() { + dom = $(''); + + var observable = kendo.observable({ value: null }); + var value = new Date(2011, 1, 2); + observable.value = value; + + kendo.bind(dom, observable); + + dom.kendoDateTimePicker(); + + equal(dom.data("kendoDateTimePicker").value().getTime(), value.getTime()); +}); + +test("updating model value updates the UI", function() { + dom = $(''); + + var observable = kendo.observable({ value: value }); + + kendo.bind(dom, observable); + + dom.kendoDateTimePicker(); + + var value = new Date(2011, 1, 2); + observable.set("value", value) + equal(dom.data("kendoDateTimePicker").value().getTime(), value.getTime()); +}); + +test("bindings are removed if element is rebind", 1, function() { + dom = $(''); + + var observable = kendo.observable({ value: new Date(2011, 1, 2) }); + + kendo.bind(dom, observable); + + var destroy = stub(dom[0].kendoBindingTarget, "destroy"); + + kendo.bind(dom, observable); + + equal(destroy.calls("destroy"), 1); +}); + +test("binding target is destroyed", 1, function() { + dom = $(''); + + var observable = kendo.observable({ value: null }); + + kendo.bind(dom, observable); + + var destroy = stub(dom[0].kendoBindingTarget, "destroy"); + + kendo.bind(dom, observable); + + equal(destroy.calls("destroy"), 1); +}); + +test("change event is raised if attached as option", 1, function() { + dom = $(''); + + var observable = kendo.observable({ + items: [{text:"foo"}, {text:"bar"}] + }); + + kendo.bind(dom, observable); + dom.data("kendoDateTimePicker").trigger("change"); +}); + +test("change event is raised if attached as option to a already initialized datetimepicker", 1, function() { + dom = $('').kendoDateTimePicker(); + + var observable = kendo.observable({ + items: [{text:"foo"}, {text:"bar"}] + }); + + kendo.bind(dom, observable); + dom.data("kendoDateTimePicker").trigger("change"); +}); + +test("binding enabled to false disables the widget", function() { + dom = $(''); + + var observable = kendo.observable({ + enabled: false + }); + + kendo.bind(dom, observable); + + ok(dom.is(":disabled")); +}); + +test("binding enabled to true enables the widget", function() { + dom = $(''); + + var observable = kendo.observable({ + enabled: true + }); + + kendo.bind(dom, observable); + + ok(!dom.is(":disabled")); +}); + +test("binding disable to true disables the widget", function() { + dom = $(''); + + var observable = kendo.observable({ + disabled: false + }); + + kendo.bind(dom, observable); + + ok(!dom.is(":disabled")); +}); + +test("binding disabled to false enables the widget", function() { + dom = $(''); + + var observable = kendo.observable({ + disabled: true + }); + + kendo.bind(dom, observable); + + ok(dom.is(":disabled")); +}); + +test("binding visible to false hides the widget", function() { + dom = $(''); + + var observable = kendo.observable({ + visible: false + }); + + kendo.bind(dom, observable); + + ok(dom.data("kendoDateTimePicker").wrapper.css("display") == "none", "Display is 'none'"); +}); + +test("binding visible to true shows the widget", function() { + dom = $(''); + + var observable = kendo.observable({ + visible: true + }); + + kendo.bind(dom, observable); + + ok(dom.data("kendoDateTimePicker").wrapper.css("display") != "none", "Display is not 'none'"); +}); + +test("changing visible to false hides the widget", function() { + dom = $(''); + + var observable = kendo.observable({ + visible: true + }); + + kendo.bind(dom, observable); + observable.set("visible", false); + + ok(dom.data("kendoDateTimePicker").wrapper.css("display") == "none", "Display is 'none'"); +}); + +test("changing visible to true shows the widget", function() { + dom = $(''); + + var observable = kendo.observable({ + visible: false + }); + + kendo.bind(dom, observable); + observable.set("visible", true); + + ok(dom.data("kendoDateTimePicker").wrapper.css("display") != "none", "Display is not 'none'"); +}); + +test("binding invisible to true hides the widget", function() { + dom = $(''); + + var observable = kendo.observable({ + invisible: true + }); + + kendo.bind(dom, observable); + + ok(dom.data("kendoDateTimePicker").wrapper.css("display") == "none", "display is 'none'"); +}); + +test("binding invisible to false shows the widget", function() { + dom = $(''); + + var observable = kendo.observable({ + invisible: false + }); + + kendo.bind(dom, observable); + + ok(dom.data("kendoDateTimePicker").wrapper.css("display") != "none", "display is not 'none'"); +}); + +test("changing invisible to true hides the widget", function() { + dom = $(''); + + var observable = kendo.observable({ + invisible: false + }); + + kendo.bind(dom, observable); + observable.set("invisible", true); + + ok(dom.data("kendoDateTimePicker").wrapper.css("display") == "none", "display is 'none'"); +}); + +test("changing invisible to false shows the widget", function() { + dom = $(''); + + var observable = kendo.observable({ + invisible: true + }); + + kendo.bind(dom, observable); + observable.set("invisible", false); + + ok(dom.data("kendoDateTimePicker").wrapper.css("display") != "none", "display is not 'none'"); +}); + +test("binding datetimepicker initialized before binding does not override change of calendar", 1, function() { + dom = $(''); + + var observable = kendo.observable({ value: null }); + + kendo.bind(dom, observable); + + dom.kendoDateTimePicker({ + change: function() { + equal(this, dom.data("kendoDateTimePicker")); + } + }); + + dom.data("kendoDateTimePicker").open("date"); + dom.data("kendoDateTimePicker").dateView.calendar.value(new Date()); + dom.data("kendoDateTimePicker").dateView.calendar.trigger("change"); +}); + +test("binding datetimepicker initialized before binding does not override change of timeView", 1, function() { + dom = $(''); + + var observable = kendo.observable({ value: null }); + + kendo.bind(dom, observable); + + dom.kendoDateTimePicker({ + change: function() { + equal(this, dom.data("kendoDateTimePicker")); + } + }); + + dom.data("kendoDateTimePicker").open("time"); + dom.data("kendoDateTimePicker").timeView.options.change("2:00 AM", true); +}); + +})(); diff --git a/tests/datetimepicker/navigation.js b/tests/datetimepicker/navigation.js new file mode 100644 index 00000000000..e74b4730657 --- /dev/null +++ b/tests/datetimepicker/navigation.js @@ -0,0 +1,467 @@ +(function() { + +var DateTimePicker = kendo.ui.DateTimePicker, + input; + +module("kendo.ui.DateTimePicker navigation", { + setup: function() { + kendo.effects.disable(); + input = $("").appendTo(QUnit.fixture); + }, + teardown: function() { + kendo.effects.enable(); + input.data("kendoDateTimePicker").destroy(); + } +}); + +test("DateView sets the value on click", function() { + var today = new Date(), + datetimepicker = new DateTimePicker(input), + dateView = datetimepicker.dateView; + + //simulate user click + dateView._calendar(); + dateView.calendar.value(today); + dateView.calendar.trigger("change"); + + equal(input.val(), kendo.toString(today, datetimepicker.options.format)); +}); + +test("DateView closes itself on click", function() { + var today = new Date(), + datetimepicker = new DateTimePicker(input), + dateView = datetimepicker.dateView; + + datetimepicker.open("date"); + + //simulate user click + dateView.calendar.value(today); + dateView.calendar.trigger("change"); + + ok(!dateView.popup.visible()); +}); + +test("TimeView sets the value on click", function() { + var datetimepicker = new DateTimePicker(input), + timeView = datetimepicker.timeView, + li, date; + + timeView.refresh(); + li = timeView.ul.children(":first"); + date = timeView._parse(li.text()); + + li.click(); + + equal(input.val(), kendo.toString(date, datetimepicker.options.format)); +}); + +test("TimeView puts in range if max less than today", function() { + var max = new Date(2000, 10, 10, 10, 0, 0), + datetimepicker = new DateTimePicker(input, { + max: max + }), + timeView = datetimepicker.timeView; + + datetimepicker.open("time"); + + timeView.ul.children(":last").click(); + + equal(+timeView.options.max, +max); + equal(+datetimepicker.value(), +max); +}); + +test("TimeView puts in range if min bigger than today", function() { + var min = new Date(2030, 10, 10, 10, 0, 0), + datetimepicker = new DateTimePicker(input, { + min: min + }), + timeView = datetimepicker.timeView; + + datetimepicker.open("time"); + + timeView.ul.children(":first").click(); + + equal(+timeView.options.min, +min); + equal(+datetimepicker.value(), +min); +}); + +test("DateTimePicker closes all views on blur", function() { + var datetimepicker = new DateTimePicker(input); + + datetimepicker.open("date"); + datetimepicker.open("time"); + + input.focus().blur(); + + ok(!datetimepicker.dateView.popup.visible()); + ok(!datetimepicker.timeView.popup.visible()); +}); + +test("DateTimePicker add focus state to the wrapper on focus", function() { + var datetimepicker = new DateTimePicker(input); + + input.focus(); + + ok(datetimepicker.wrapper.children(":first").hasClass("k-state-focused")); +}); + +test("DateTimePicker remove focus state to the wrapper on blur", function() { + var datetimepicker = new DateTimePicker(input); + + input.focus().blur(); + + ok(!datetimepicker.wrapper.children(":first").hasClass("k-state-focused")); +}); + +test("DateTimePicker opens DateView when press ALT + DOWN", function() { + var datetimepicker = new DateTimePicker(input); + + input.focus().trigger({ + type: "keydown", + keyCode: kendo.keys.DOWN, + altKey: true + }); + + ok(datetimepicker.dateView.popup.visible()); +}); + +test("DateTimePicker opens TimeView when press ALT + DOWN", function() { + var datetimepicker = new DateTimePicker(input); + + datetimepicker.open("date"); + + input.focus().trigger({ + type: "keydown", + keyCode: kendo.keys.DOWN, + altKey: true + }); + + ok(!datetimepicker.dateView.popup.visible()); + ok(datetimepicker.timeView.popup.visible()); +}); + +test("DateTimePicker closes DateView when press ALT + UP", function() { + var datetimepicker = new DateTimePicker(input); + + datetimepicker.open("date"); + + input.focus().trigger({ + type: "keydown", + keyCode: kendo.keys.UP, + altKey: true + }); + + ok(!datetimepicker.dateView.popup.visible()); +}); + +test("DateTimePicker closes TimeView when press ALT + UP", function() { + var datetimepicker = new DateTimePicker(input); + + datetimepicker.open("time"); + + input.focus().trigger({ + type: "keydown", + keyCode: kendo.keys.UP, + altKey: true + }); + + ok(!datetimepicker.timeView.popup.visible()); +}); + +test("DateTimePicker calls DateView move method if the view is opened", function() { + var datetimepicker = new DateTimePicker(input); + + stub(datetimepicker.dateView, "move"); + + datetimepicker.open("date"); + + input.focus().trigger({ + type: "keydown", + keyCode: kendo.keys.UP + }); + + equal(datetimepicker.dateView.calls("move"), 1); +}); + +test("DateTimePicker calls TimeView move method if the view is opened", function() { + var datetimepicker = new DateTimePicker(input); + + stub(datetimepicker.timeView, "move"); + + datetimepicker.open("time"); + + input.focus().trigger({ + type: "keydown", + keyCode: kendo.keys.DOWN + }); + + equal(datetimepicker.timeView.calls("move"), 1); +}); + +test("TimeView updates the input value on keyboard navigation", function() { + var datetimepicker = new DateTimePicker(input); + + datetimepicker.open("time"); + + input.focus().trigger({ + type: "keydown", + keyCode: kendo.keys.DOWN + }); + + ok(input.val()); +}); + +test("DateTimePicker updates DateView when select time from TimeView", function() { + var datetimepicker = new DateTimePicker(input); + + datetimepicker.open("time"); + + input.focus().trigger({ + type: "keydown", + keyCode: kendo.keys.DOWN + }); + + input.focus().trigger({ + type: "keydown", + keyCode: kendo.keys.ENTER + }); + + var date = kendo.parseDate(input.val(), datetimepicker.options.format); + + equal(+datetimepicker.dateView._value, +date); +}); + +test("DateTimePicker shows only one available hour in time dropdown list", function() { + var date = new Date(2000, 11, 31); + var datetimepicker = new DateTimePicker(input, { + max: date, + value: new Date(2000, 11, 30) + }); + + datetimepicker.open("date"); + datetimepicker.dateView.calendar.value(date); + datetimepicker.dateView.calendar.trigger("change"); + + + equal(datetimepicker.timeView.ul.children().length, 1); + equal(datetimepicker.timeView.ul.children().text(), "12:00 AM"); + ok(datetimepicker.timeView.ul.children().hasClass("k-state-selected")); +}); + +test("DateTimePicker limits the available times to the max date", function() { + var date = new Date(2000, 11, 31, 20, 0, 0); + var datetimepicker = new DateTimePicker(input, { + max: date, + value: new Date(2000, 11, 30) + }); + + //select max date + datetimepicker.open("date"); + datetimepicker.dateView.calendar.value(date); + datetimepicker.dateView.calendar.trigger("change"); + + var liElements = datetimepicker.timeView.ul.children(); + + equal(liElements.eq(0).text(), "12:00 AM"); + equal(liElements.eq(liElements.length - 1).text(), "8:00 PM"); +}); + +test("DateTimePicker shows all hours in TimeView when date is not max", function() { + var date = new Date(2000, 11, 31); + var datetimepicker = new DateTimePicker(input, { + max: date, + value: new Date(2000, 11, 30) + }); + + //select max date + datetimepicker.open("date"); + datetimepicker.dateView.calendar.value(date); + datetimepicker.dateView.calendar.trigger("change"); + + //select other date + datetimepicker.dateView.calendar.value(new Date(2000, 11, 20)); + datetimepicker.dateView.calendar.trigger("change"); + + var liElements = datetimepicker.timeView.ul.children(); + + equal(liElements.eq(0).text(), "12:00 AM"); + equal(liElements.eq(liElements.length - 1).text(), "11:30 PM"); +}); + +test("DateTimePicker updates TimeView when select min date", function() { + var date = new Date(2000, 11, 1, 16, 0, 0); + var datetimepicker = new DateTimePicker(input, { + min: new Date(2000, 11, 1, 0, 0, 0), + value: new Date(2000, 11, 2) + }); + + datetimepicker.open("date"); + datetimepicker.dateView.calendar.value(date); + datetimepicker.dateView.calendar.trigger("change"); + + var liElements = datetimepicker.timeView.ul.children(); + + equal(liElements.eq(0).text(), "12:00 AM"); + equal(liElements.eq(liElements.length - 1).text(), "11:30 PM"); +}); + +test("DateTimePicker sets TimeView max date to 59 to midnight", function() { + var datetimepicker = new DateTimePicker(input, { + min: new Date("09/16/2013 09:00 PM"), + max: new Date("09/17/2013 04:59 AM"), + value: new Date("09/16/2013") + }); + + var min = datetimepicker.timeView.options.min; + var max = datetimepicker.timeView.options.max; + + deepEqual(min, new Date(2013, 8, 16, 21, 0)); + deepEqual(max, new Date(2099, 11, 31, 23, 30)); +}); + +test("DateTimePicker shows all hours in TimeView when date is not min", function() { + var date = new Date(2000, 11, 1, 8, 30, 0); + var datetimepicker = new DateTimePicker(input, { + min: date, + value: date + }); + + //select other date + datetimepicker.open("date"); + datetimepicker.dateView.calendar.value(new Date(2000, 11, 20)); + datetimepicker.dateView.calendar.trigger("change"); + + equal(datetimepicker.timeView.ul.children(":first").text(), "12:00 AM"); + equal(datetimepicker.timeView.ul.children(":last").text(), "11:30 PM"); +}); + +test("DateTimePicker does not update TimeView when selected date in range", function() { + var datetimepicker = new DateTimePicker(input, { + min: new Date(2000, 1, 1) + }); + + stub(datetimepicker.timeView, { + refresh: datetimepicker.timeView.refresh + }); + + datetimepicker.open("date"); + datetimepicker.dateView.calendar.value(new Date(2010, 1, 1)); + datetimepicker.dateView.calendar.trigger("change"); + + equal(datetimepicker.timeView.calls("refresh"), 0); +}); + +test("DateTimePicker does not update TimeView if select time from drop-down list", function() { + var datetimepicker = new DateTimePicker(input, { + min: new Date(2000, 1, 1), + value: new Date(2000, 1, 1) + }); + + datetimepicker.open("time"); + + stub(datetimepicker.timeView, { + refresh: datetimepicker.timeView.refresh + }); + + datetimepicker.timeView.options.change("12:30 AM", true); + + equal(datetimepicker.timeView.calls("refresh"), 0); +}); + +test("DateTimePicker persist time when select min date from calendar", function() { + var datetimepicker = new DateTimePicker(input, { + min: new Date(2000, 11, 8, 8, 30, 0), + value: new Date(2000, 11, 9, 12, 0, 0) + }); + + //select other date + datetimepicker.open("date"); + datetimepicker.dateView.calendar.value(new Date(2000, 11, 8, 8, 30, 0)); + datetimepicker.dateView.calendar.trigger("change"); + + equal(datetimepicker.value().getHours(), 12); + equal(datetimepicker.value().getMinutes(), 0); +}); + +test("DateTimePicker uses options.dates when rebind TimeView", function() { + var date = new Date(2000, 11, 1, 8, 30, 0); + var datetimepicker = new DateTimePicker(input, { + value: date, + dates: [new Date(2000, 10, 10, 12, 10, 0)] + }); + + //select other date + datetimepicker.open("date"); + datetimepicker.dateView.calendar.value(new Date(2000, 10, 10)); + datetimepicker.dateView.calendar.trigger("change"); + + equal(datetimepicker.timeView.ul.children().length, 1); + equal(datetimepicker.timeView.ul.children().text(), "12:10 PM"); +}); + +test("DateTimePicker does not update the input if the entered value is the same but in diff format", function() { + var today = new Date(), + datetimepicker = input.kendoDateTimePicker({ + format: "dd MMM yyyy", + parseFormats: ["yyyy/MM/dd"], + value: kendo.toString(today, "dd MMM yyyy") + }).data("kendoDateTimePicker"), + todayDiffFormat = kendo.toString(today, "yyyy/MM/dd"); + + input.val(todayDiffFormat); + + //simulate change + datetimepicker._change(input.val()); + + equal(input.val(), kendo.toString(today, "dd MMM yyyy")); +}); + +test("DateTimePicker does not call change on blur if no text change", function() { + var date = new Date(1919, 0, 1), + datetimepicker = input.kendoDateTimePicker({ + format: "MM/dd/yy", + value: new Date(date) + }).data("kendoDateTimePicker"); + + datetimepicker.options.parseFormats = ["MM/dd/yyyy", "MM/dd/yy"]; + + //simulate change + input.focus().blur(); + + equal(+datetimepicker.value(), +date); +}); + +test("DateTimePicker does not call change on ENTER if no text change", function() { + var date = new Date(1919, 0, 1), + datetimepicker = input.kendoDateTimePicker({ + format: "MM/dd/yy", + value: new Date(date) + }).data("kendoDateTimePicker"); + + datetimepicker.options.parseFormats = ["MM/dd/yyyy", "MM/dd/yy"]; + + //simulate change + input.focus().trigger({ + type: "keydown", + keyCode: kendo.keys.ENTER + }); + + equal(+datetimepicker.value(), +date); +}); + +test("DateTimePicker does set focused date of calendar if no text change", function() { + var date = new Date(1919, 0, 1), + datetimepicker = input.kendoDateTimePicker({ + format: "MM/dd/yy", + value: new Date(date) + }).data("kendoDateTimePicker"); + + datetimepicker.options.parseFormats = ["MM/dd/yyyy", "MM/dd/yy"]; + + input.focus(); + datetimepicker.open(); + + equal(+datetimepicker.dateView._current, +date); +}); + +})(); diff --git a/tests/dragdrop/draggable.js b/tests/dragdrop/draggable.js new file mode 100644 index 00000000000..229746cc782 --- /dev/null +++ b/tests/dragdrop/draggable.js @@ -0,0 +1,212 @@ +(function() { + var Draggable = kendo.ui.Draggable, + draggable, + span; + + module("kendo.ui.Draggable", { + setup: function() { + span = $("").appendTo(QUnit.fixture); + }, + + teardown: function() { + kendo.destroy(span); + } + }); + + function trigger(type, e, el) { + el = el || span; + el.trigger($.Event(type, e)); + } + + function setup(options) { + draggable = new Draggable(span, options); + return draggable; + } + + test("moving the mouse beyond the allowed distance triggers the dragstart event", 1, function() { + setup({ + dragstart: function() { + ok(true); + } + }); + + trigger("mousedown", { pageX: 1, pageY: 1 }); + trigger("mousemove", { pageX: 10, pageY: 1 }, $(document.documentElement)); + }); + + test("moving the mouse within the allowed distance does not trigger the dragstart event", 0, function() { + draggable = new Draggable(span, { dragstart: function() { + ok(false); + } + }); + + trigger("mousedown", { pageX: 1, pageY: 1 }); + trigger("mousemove", { pageX: 1, pageY: 1 }, $(document.documentElement)); + + }); + + test("prevent default from drag start event does not trigger drag event", 1, function() { + setup({ + dragstart: function(e) { + e.preventDefault(); + ok(true); + }, + drag: function() { + ok(false); + } + }); + + trigger("mousedown", { pageX: 1, pageY: 1 }); + trigger("mousemove", { pageX: 10, pageY: 1 }); + }); + + test("drag event is raised during dragging", 2, function() { + setup({ + drag: function() { + ok(true); + } + }); + + trigger("mousedown", { pageX: 1, pageY: 1 }); + trigger("mousemove", { pageX: 10, pageY: 1 }); + trigger("mousemove", { pageX: 10, pageY: 2 }); + + }); + + test("dragend event is raised", 1, function() { + setup({ dragend: function() { + ok(true); + }}); + + trigger("mousedown", { pageX: 1, pageY: 1 }); + trigger("mousemove", { pageX: 10, pageY: 1 }); + trigger("mouseup", { pageX: 10, pageY: 2 }); + }); + + test("dragend event is raised when pressing escape", 1, function() { + setup({ dragcancel: function() { ok(true) } }); + + trigger("mousedown", { pageX: 1, pageY: 1 }); + trigger("mousemove", { pageX: 10, pageY: 1 }); + trigger("keyup", { keyCode: 27}); + }); + + test("specifying filter", function() { + var dragstartWasCalled = false, + draggable = new Draggable(span.append("foo"), { + dragstart: function() { + dragstartWasCalled = true; + }, + filter: "span" + }); + + + trigger("mousedown", { pageX: 0, pageY: 0 }, span.find("span")); + trigger("mousemove", { pageX: 10, pageY: 10 }); + + ok(dragstartWasCalled); + }); + + test("with filter - the dragged element is currentTarget during the dragstart event", function() { + var e, draggable = new Draggable(span.append("foo"), { + dragstart: function() { + e = arguments[0]; + }, + filter: "span" + }); + + trigger("mousedown", { pageX: 0, pageY: 0 }, span.find("span")); + trigger("mousemove", { pageX: 10, pageY: 10 }, span.find("span")); + + ok(e.currentTarget[0] === span.find("span")[0]); + }); + + test("with filter - the dragged element is currentTarget during the drag event", function() { + var e, draggable = new Draggable(span.append("foo"), { + drag: function() { + e = arguments[0]; + }, + filter: "span" + }); + + trigger("mousedown", { pageX: 0, pageY: 0 }, span.find("span")); + trigger("mousemove", { pageX: 10, pageY: 10 }, span.find("span")); + trigger("mousemove", { pageX: 20, pageY: 10 }, span.find("span")); + + ok(e.currentTarget[0] === span.find("span")[0]); + }); + + test("with filter - the dragged element is currentTarget during the dragend event", function() { + new Draggable(span.append("foo"), { + dragend: function(e) { + ok(e.currentTarget[0] === span.find("span")[0]); + }, + filter: "span" + }); + + trigger("mousedown", { pageX: 0, pageY: 0 }, span.find("span")); + trigger("mousemove", { pageX: 10, pageY: 10 }, span.find("span")); + trigger("mouseup", { pageX: 20, pageY: 10 }, span.find("span")); + + }); + + test("dom event argument is passed to the dragstart event", function() { + var e; + + setup({ + dragstart: function() { + e = arguments[0]; + } + }); + + trigger("mousedown", { pageX: 0, pageY: 0 }); + trigger("mousemove", { pageX: 10, pageY: 10 }); + + ok(e.pageX); + }); + + test("dom event argument is passed to the dragend event", function() { + var e; + + setup({ + dragend: function() { + e = arguments[0]; + } + }); + + trigger("mousedown", { pageX: 0, pageY: 0 }); + trigger("mousemove", { pageX: 10, pageY: 10 }); + trigger("mouseup", { pageX: 20, pageY: 10 }); + + ok(e.pageX); + }); + + test("dom event argument is passed to the drag event", function() { + var e; + + setup({ + drag: function() { + e = arguments[0]; + } + }); + + trigger("mousedown", { pageX: 0, pageY: 0 }); + trigger("mousemove", { pageX: 10, pageY: 10 }); + trigger("mousemove", { pageX: 20, pageY: 10 }); + + ok(e.pageX); + }); + + test("the hint is not active after destroy", function() { + setup({ + hint: $("
").addClass("hint") + }); + + draggable.destroy(); + + trigger("mousedown", { pageX: 1, pageY: 1 }); + trigger("mousemove", { pageX: 10, pageY: 1 }); + + equal($(".hint").length, 0); + }); +})(); diff --git a/tests/dragdrop/droptarget.js b/tests/dragdrop/droptarget.js new file mode 100644 index 00000000000..2af9ddfc61b --- /dev/null +++ b/tests/dragdrop/droptarget.js @@ -0,0 +1,141 @@ +(function() { + var DropTarget = kendo.ui.DropTarget, + Draggable = kendo.ui.Draggable, + span, + targetElement, + target, + draggable; + + module("kendo.ui.DropTarget", { + setup: function() { + span = $("").appendTo(QUnit.fixture); + targetElement = $("
foo
").appendTo(QUnit.fixture); + }, + teardown: function() { + kendo.destroy(QUnit.fixture); + } + }); + + function trigger(type, e, el) { + el = el || span; + el.trigger($.Event(type, e)); + } + + function startDrag() { + var offset = kendo.getOffset(targetElement); + trigger("mousedown", { pageX: 1, pageY: 1 }); + trigger("mousemove", { + pageX: offset.left, + pageY: offset.top, + clientX: offset.left, + clientY: offset.top + }); + } + + function setup(dropTargetOptions, draggableOptions) { + target = new DropTarget(targetElement, dropTargetOptions); + draggable = new Draggable(span, draggableOptions); + startDrag(); + } + + test("dragenter is raised, passing the draggable", 1, function() { + setup({ + dragenter: function(e) { + ok(e.draggable === draggable); + } + }); + }); + + test("dragleave is raised, passing the draggable", 1, function() { + setup({ + dragleave: function(e) { + ok(e.draggable === draggable); + } + }); + + trigger("mousemove", { pageX: 1, pageY: 1, clientX: 1, clientY: 1 }); + }); + + test("drop is raised", 1, function() { + setup({ + drop: function(e) { + ok(e.draggable === draggable); + } + }); + + var offset = kendo.getOffset(targetElement); + trigger("mouseup", { pageX: offset.left, pageY: offset.top }); + }); + + test("dragenter is not raised for draggable from a different group", 0, function() { + setup({ + dragenter: function() { + ok(false); + } + }, { + group: "foo" + }); + }); + + test("dom event argument is passed to the drop event", 1, function() { + setup({ + drop: function(e) { + ok(e.pageX); + } + }); + + var offset = kendo.getOffset(targetElement); + trigger("mouseup", { pageX: offset.left, pageY: offset.top }); + }); + + test("droptarget marks the draggable as dropped", function() { + var e, dropTarget = setup(); + + var offset = kendo.getOffset(targetElement); + trigger("mouseup", { pageX: offset.left, pageY: offset.top }); + + ok(draggable.dropped); + }); + + test("destroy removes droptarget from droptargets object", function() { + target = new DropTarget(targetElement, { + group: "foobarbaz" + }); + + target.destroy(); + + ok(!DropTarget._cache["foobarbaz"]); + }); + + test("destroy removes only destroyed object from cache", function() { + target = new DropTarget(targetElement, { group: "qux" }); + + var quxElement = $("
").appendTo(QUnit.fixture); + var quxTarget = new DropTarget(quxElement, { group: "qux" }); + + target.destroy(); + + ok(DropTarget._cache["qux"]); + equal(DropTarget._cache["qux"].length, 1); + }); + + test("destroyGroup removes complete group from cache", function() { + target = new DropTarget(targetElement, { group: "qux" }); + + var quxElement = $("
").appendTo(QUnit.fixture); + var quxTarget = new DropTarget(quxElement, { group: "qux" }); + + DropTarget.destroyGroup("qux"); + + ok(!DropTarget._cache["qux"]); + }); + + test("DropTarget destroy destroys the Target", function() { + var target = new DropTarget(targetElement), + element = target.element; + + target.destroy(); + + ok(!element.data("kendoDropTarget")); + }); +})(); diff --git a/tests/dragdrop/droptargetarea.js b/tests/dragdrop/droptargetarea.js new file mode 100644 index 00000000000..d6ef666eda1 --- /dev/null +++ b/tests/dragdrop/droptargetarea.js @@ -0,0 +1,117 @@ +(function() { + var DropTargetArea = kendo.ui.DropTargetArea, + Draggable = kendo.ui.Draggable, + span, + targetElement, + target, + draggable; + + module("kendo.ui.DropTargetArea", { + setup: function() { + targetElement = $("
 
 
").prependTo(QUnit.fixture); + span = $("Foo").prependTo(QUnit.fixture); + }, + teardown: function() { + kendo.destroy(QUnit.fixture); + } + }); + + function trigger(type, e, el) { + el = el || span; + el.trigger($.Event(type, e)); + } + + function startDrag() { + var offset = kendo.getOffset(targetElement); + trigger("mousedown", { pageX: 1, pageY: 1, clientX: 1, clientY: 1 }); + + trigger("mousemove", { + pageX: offset.left, + pageY: offset.top, + clientX: offset.left, + clientY: offset.top + }); + } + + function setup(options, draggableOptions) { + target = new DropTargetArea(targetElement, options); + draggable = new Draggable(span, draggableOptions); + startDrag(); + } + + test("dragenter is raised, passing the draggable and the dropTarget", 2, function() { + setup({ + filter: ".test1", + dragenter: function(e) { + ok(e.draggable === draggable); + ok(e.dropTarget[0].className == "test1"); + } + }); + }); + + test("dragleave is raised, passing the draggable and the dropTarget", 2, function() { + setup( { + filter: ".test1", + dragleave: function(e) { + ok(e.draggable === draggable); + ok(e.dropTarget[0].className == "test1"); + } + }); + + trigger("mousemove", { pageX: 0, pageY: 0, clientY: 0, clientX: 0 }); + }); + + test("drop is raised and the dropTarget", 2, function() { + setup({ + filter: ".test1", + drop: function(e) { + ok(e.draggable === draggable); + ok(e.dropTarget[0].className == "test1"); + } + }); + + var offset = kendo.getOffset(targetElement); + trigger("mouseup", { pageX: offset.left, pageY: offset.top }); + }); + + test("dragenter is not raised for draggable from a different group", 0, function() { + setup({ + filter: ".test1", + dragenter: function() { + ok(false); + } + }, { + group: "foo" + }); + }); + + test("dom event argument is passed to the drop event", 1, function() { + setup( { + filter: ".test1", + drop: function(e) { + ok(e.pageX); + } + }); + + var offset = kendo.getOffset(targetElement); + trigger("mouseup", { pageX: offset.left, pageY: offset.top }); + }); + + test("DropTargetArea marks the draggable as dropped", function() { + var e, dropArea = setup({ filter: ".test1" }); + + var offset = kendo.getOffset(targetElement); + trigger("mouseup", { pageX: offset.left, pageY: offset.top }); + + ok(draggable.dropped); + }); + + test("DropTargetArea destroy destroys the Area", function() { + var target = new DropTargetArea(targetElement), + element = target.element; + + target.destroy(); + + ok(!element.data("kendoDropTargetArea")); + }); +})(); diff --git a/tests/dragdrop/hint.js b/tests/dragdrop/hint.js new file mode 100644 index 00000000000..fc203ba54dd --- /dev/null +++ b/tests/dragdrop/hint.js @@ -0,0 +1,153 @@ +(function() { + var Draggable = kendo.ui.Draggable, + draggable, + span, + hint; + + module("kendo Draggable", { + setup: function() { + span = $("").appendTo(QUnit.fixture); + hint = span.clone(); + }, + + teardown: function() { + span.remove(); + + if (draggable) { + draggable.destroy(); + } + if (!$.isFunction(hint)) { + hint.remove(); + } + } + }); + + function trigger(type, e, el) { + el = el || span; + el.trigger($.Event(type, e)); + } + + function startDrag() { + trigger("mousedown", { pageX: 1, pageY: 1 }); + trigger("mousemove", { pageX: 10, pageY: 10 }); + } + + function setup(options) { + return new Draggable(span, $.extend({ hint: hint}, options )); + } + + test("the hint is appended to the body", function() { + draggable = setup(); + + startDrag(); + + ok(hint.parent().is("body")); + }); + + test("the hint is made absolute", function() { + draggable = setup(); + + startDrag(); + + equal(hint.css("position"), "absolute"); + }); + + asyncTest("the hint is removed from DOM after the draggable is destroyed", 1, function() { + draggable = setup(); + + draggable.bind("destroy", function() { + start(); + equal(hint.parents().length, 0); + }); + + startDrag(); + trigger("mouseup", {pageX: 10, pageY: 10}); + + }); + + test("the hint is auto-postioned when dragged", function() { + draggable = setup(); + + var offset = kendo.getOffset(span); + + trigger("mousedown", { pageX: 1, pageY: 1 }); + trigger("mousemove", { pageX: 21, pageY: 21 }); + + equal(parseInt(hint.css("top")), parseInt(offset.top + 20)); + equal(parseInt(hint.css("left")), parseInt(offset.left + 20)); + }); + + test("the hint can be constrained horizontally", function() { + draggable = setup({axis: "x"}); + + var offset = kendo.getOffset(span); + + trigger("mousedown", { pageX: 1, pageY: 1 }); + trigger("mousemove", { pageX: 21, pageY: 21 }); + + var result = kendo.getOffset(hint); + equal(Math.floor(result.top), Math.floor(offset.top)); + equal(result.left, offset.left + 20); + }); + + test("the hint can be constrained vertically", function() { + draggable = setup({axis: "y"}); + + var offset = kendo.getOffset(span); + + trigger("mousedown", { pageX: 1, pageY: 1 }); + trigger("mousemove", { pageX: 21, pageY: 21 }); + + var result = kendo.getOffset(hint); + equal(Math.floor(result.top), Math.floor(offset.top) + 20); + equal(result.left, offset.left); + }); + + test("the hint is positioned using options.cursorOffset", function() { + draggable = setup({ cursorOffset: { left: 1, top: 1 } }); + + startDrag(); + + equal(parseInt(hint.css("top")), 11); + equal(parseInt(hint.css("left")), 11); + }); + + test("the hint is positioned using options.cursorOffset", function() { + draggable = setup({ cursorOffset: { left: 1, top: 1 } }); + + startDrag(); + + equal(hint.css("top"), "11px"); + equal(hint.css("left"), "11px"); + }); + + test("the hint is repositioned during dragging", function() { + draggable = setup({ cursorOffset: { left: 10, top: 10 } }); + + startDrag(); + trigger("mousemove", {pageX: 100, pageY: 100}); + + equal(hint.css("top"), "110px"); + equal(hint.css("left"), "110px"); + }); + + test("hint as a function", function() { + var h = new $(""); + draggable = setup({ hint : function() { return h; } }); + + startDrag(); + + ok(draggable.hint[0] === h[0]); + trigger("mouseup", {pageX: 10, pageY: 10}); + }); + + test("hint as a function which returns a string", function() { + draggable = setup({ hint : function() { return "foo"; } }); + + startDrag(); + + ok(draggable.hint.is("span")); + equal(draggable.hint.text(), "foo"); + trigger("mouseup", {pageX: 10, pageY: 10}); + }); +})(); diff --git a/tests/dragdrop/movable.js b/tests/dragdrop/movable.js new file mode 100644 index 00000000000..18b2e30e0cd --- /dev/null +++ b/tests/dragdrop/movable.js @@ -0,0 +1,84 @@ +(function() { + + function triggerTouchEvent(type, e) { + element.trigger($.Event(type, { originalEvent: { changedTouches: [e] }})); + } + + function elementLocation() { + var values = $(element).css("transform").match(/[\d.]+/g); + return { + scale: parseInt(values[0]), + x: parseFloat(values[4]), + y: parseFloat(values[5]) + }; + } + + var fixture, + Movable = kendo.ui.Movable, + element, + movable; + + module("movable", { + setup: function() { + fixture = $("#qunit-fixture"); + fixture.append("
"); + element = fixture.children().first(); + movable = new Movable(element); + }, + + teardown: function() { + fixture.empty() + } + }); + + test("sets x", 1, function() { + movable.moveAxis("x", 10.5); + equal(elementLocation()["x"], 10.5); + }); + + test("sets y", 1, function() { + movable.moveAxis("y", 10.5); + equal(elementLocation()["y"], 10.5); + }); + + test("rounds x", 1, function() { + movable.round = true; + movable.moveAxis("x", 10.5); + equal(elementLocation()["x"], 11); + }); + + test("rounds y", 1, function() { + movable.round = true; + movable.moveAxis("y", 10.5); + equal(elementLocation()["y"], 11); + }); + + // ------------------------------------------------------------ + var browser; + + module("movable / IE legacy", { + setup: function() { + browser = kendo.support.browser; + kendo.support.browser = { msie: true, version: 9 }; + }, + teardown: function() { + kendo.support.browser = browser; + } + }); + + test("sets x", function() { + movable.moveAxis("x", 10.5); + equal(element.css("left"), "10.5px"); + }); + + test("sets y", function() { + movable.moveAxis("y", 10.5); + equal(element.css("top"), "10.5px"); + }); + + test("sets position", function() { + movable.moveAxis("y", 10.5); + equal(element.css("position"), "absolute"); + }); + +})(); diff --git a/tests/dragdrop/pane.js b/tests/dragdrop/pane.js new file mode 100644 index 00000000000..c9839a13489 --- /dev/null +++ b/tests/dragdrop/pane.js @@ -0,0 +1,140 @@ +(function() { + var movable, + pane, + dimensions, + userEvents, + fixture; + + module("pane dimensions", { + setup: function() { + fixture = $("
").appendTo(QUnit.fixture); + }, + teardown: function() { + fixture.remove(); + } + }); + + test("calculates min scale", 1, function() { + fixture.append('
Element
'); + var container = fixture.children().first(); + + element = container.children().first(); + + dimensions = new kendo.ui.PaneDimensions({ + element: element, + container: container + }); + + dimensions.refresh(); + equal(dimensions.minScale, 0.25); + }) + + test("allows overriding min scale", 1, function() { + fixture.append('
Element
'); + var container = fixture.children().first(); + + element = container.children().first(); + + dimensions = new kendo.ui.PaneDimensions({ + element: element, + container: container, + minScale: 1 + }); + + dimensions.refresh(); + equal(dimensions.minScale, 1); + }) + + module("pane", { + setup: function() { + kendo.support.touch = true; + fixture = $("
").appendTo(QUnit.fixture); + fixture.append('
Element
'); + var container = fixture.children().first(); + + element = container.children().first(); + + movable = new kendo.ui.Movable(element); + + dimensions = new kendo.ui.PaneDimensions({ + element: element, + container: container + }); + + userEvents = new kendo.UserEvents(element, {multiTouch: true}); + + pane = new kendo.ui.Pane({ + movable: movable, + userEvents: userEvents, + dimensions: dimensions + }); + + dimensions.refresh(); + }, + + teardown: function() { + kendo.support.touch = false; + fixture.remove(); + } + }); + + test("zooms content", function() { + press(element, 10, 10); + press(element, 13, 14, 2); + move(element, 15, 22, 2); + equal(movable.scale, 2.6); + }) + + test("zooms content to maxScale", function() { + dimensions.maxScale = 2; + press(element, 10, 10); + press(element, 13, 14, 2); + move(element, 15, 22, 2); + equal(movable.scale, 2); + }) + test("zooms to a given point", 2, function() { + press(element, 10, 10); + press(element, 13, 14, 2); + move(element, 9, 6); + move(element, 14, 18, 2); + + QUnit.close(movable.x, -18.4, 0.1); + QUnit.close(movable.y, -19.2, 0.1); + }) + + test("offsets zoom point", function() { + press(element, 10, 10); + press(element, 13, 14, 2); + move(element, 5, 5); + move(element, 8, 9, 2); + + equal(movable.scale, 1); + QUnit.close(movable.x, -5, 0.1); + QUnit.close(movable.y, -5, 0.1); + }) + + test("zooms to a given point after being offset", function() { + press(element, 30, 10); + move(element, 10, 10); + release(element); + + equal(movable.x, -20); + + press(element, 10, 10); + press(element, 13, 14, 2); + move(element, 9, 6); + move(element, 14, 18, 2); + + QUnit.close(movable.x, -70.4, 0.1); + QUnit.close(movable.y, -19.2, 0.1); + }) + + test("zooming out causes friction", function() { + press(element, 9, 6); + press(element, 14, 18, 2); + move(element, 10, 10); + move(element, 13, 14, 2); + QUnit.close(movable.scale, 0.92 / 2, 0.1); + }); +})(); + diff --git a/tests/dropdownlist/api.js b/tests/dropdownlist/api.js new file mode 100644 index 00000000000..6aa28f406d0 --- /dev/null +++ b/tests/dropdownlist/api.js @@ -0,0 +1,638 @@ +(function() { + var DropDownList = kendo.ui.DropDownList, + data = [{text: "Foo", value: 1}, {text:"Bar", value:2}], + SELECTED = "k-state-selected", + keys = kendo.keys, + dropdownlist, + input; + + module("kendo.ui.DropDownList API", { + setup: function() { + input = $("").appendTo(QUnit.fixture); + + dropdownlist = new DropDownList(input, { + dataTextField: "text", + dataValueField: "value", + dataSource: [{text: "foo", value: 1}, {text:2, value:2}] + }); + }, + + teardown: function() { + dropdownlist.destroy(); + } + }); + + test("value method should select item if exists", function() { + dropdownlist.value("2"); + + ok(dropdownlist.ul.children().eq(1).hasClass(SELECTED)); + equal(dropdownlist.value(), 2); + equal(dropdownlist.text(), 2); + equal(dropdownlist._old, 2); + }); + + test("value method should select first if no such value", function() { + dropdownlist.select(1); + dropdownlist.value(""); + + ok(dropdownlist.ul.children().eq(0).hasClass(SELECTED)); + equal(dropdownlist.value(), "1"); + equal(dropdownlist.text(), "foo"); + equal(dropdownlist._old, 1); + }); + + test("value method selects item with 0 value", function() { + dropdownlist.destroy(); + dropdownlist = new DropDownList(input, { + optionLabel: "select", + dataTextField: "text", + dataValueField: "value", + dataSource: [{text: "foo", value: 1}, {text:2, value:0}] + }); + + dropdownlist.value(0); + + ok(dropdownlist.ul.children().eq(2).hasClass(SELECTED)); + + equal(dropdownlist.value(), "0"); + equal(dropdownlist.text(), "2"); + equal(dropdownlist._old, "0"); + }); + + test("value(value) should call _accessor", function() { + stub(dropdownlist, "_accessor"); + + dropdownlist.value(2); + + ok(dropdownlist.calls("_accessor")); + }); + + test("value should update the selectedIndex", function() { + dropdownlist.value("2"); + + equal(dropdownlist.selectedIndex, 1); + equal(dropdownlist.current().index(), 1); + }); + + test("select should select item by predicate", function() { + dropdownlist.select(function(item) { + return item.text == 2; + }); + + ok(dropdownlist.ul.children().eq(1).hasClass(SELECTED)); + equal(dropdownlist.value(), "2"); + equal(dropdownlist.text(), "2"); + }); + + test("select(-1) should not select anything", function() { + dropdownlist.select(0); + + dropdownlist.select(-1); + + equal(dropdownlist.value(), "1"); + equal(dropdownlist.text(), "foo"); + }); + + test("select(li) should prevent raising of change event", 0, function() { + dropdownlist.bind("change", function() { + ok(false); + }); + + dropdownlist.select(1); + dropdownlist._change(); + }); + + test("select should call _accessor", function() { + stub(dropdownlist, "_accessor"); + + dropdownlist.select(1); + + ok(dropdownlist.calls("_accessor")); + }); + + test("select() should return index", function() { + dropdownlist.select(1); + + equal(dropdownlist.select(), 1); + }); + + asyncTest("open should call _scroll method", 1, function () { + dropdownlist._scroll = function() { ok(true); start(); }; + dropdownlist.open(); + }); + + test("open should open popup", 1, function () { + dropdownlist.bind("open", function(){ + ok(true); + }); + + dropdownlist.open(); + }); + + asyncTest("open method binds the widget and opens the popup", 1, function () { + dropdownlist.destroy(); + dropdownlist = input.kendoDropDownList({autoBind: false, dataSource: data}).data("kendoDropDownList"); + + dropdownlist.bind("open", function(){ + ok(true); + start(); + }); + + dropdownlist.open(); + }); + + test("open() does not initiate second Ajax request", function() { + $.mockjaxSettings.responseTime = 1000; + $.mockjaxSettings.contentType = "application/json"; + $.mockjax({ url: "fake.json", responseText: '[]' }); + + dropdownlist.destroy(); + dropdownlist = new DropDownList($(""), { + autoBind: false, + dataSource: { + transport: { + read: { url: "fake.json", type: "json" } + } + } + }); + + stub(dropdownlist.dataSource, { + fetch: dropdownlist.dataSource.fetch + }); + + dropdownlist.dataSource.fetch(); + dropdownlist.open(); + + equal(dropdownlist.dataSource.calls("fetch"), 1); + + $.mockjaxClear(); + }); + + test("close should close popup", 1, function () { + dropdownlist.bind("close", function(){ + ok(true); + }); + + dropdownlist.open(); + dropdownlist.close(); + }); + + test("text should set span html", function() { + dropdownlist.destroy(); + dropdownlist = new DropDownList(input); + + dropdownlist.text("foo"); + + equal(dropdownlist.span.html(), "foo"); + }); + + test("text with spaces should set span html", function() { + dropdownlist.destroy(); + dropdownlist = new DropDownList(input); + + dropdownlist.text("foo foo"); + + equal(dropdownlist.span.html(), "foo foo"); + }); + + test("set text to html should encode it", function() { + dropdownlist.destroy(); + dropdownlist = input.kendoDropDownList(data).data("kendoDropDownList"); + + dropdownlist.text("\ + '); + }, + teardown: function() { + kendo.destroy(dom); + if (dropdownlist) { + dropdownlist.destroy(); + } + } + }); + + test("initializes a dropdownlist when data role is dropdownlist", function() { + dom = $(''); + + kendo.bind(dom); + + dropdownlist = dom.data("kendoDropDownList"); + + equal(dropdownlist.options.dataTextField, "foo"); + equal(dropdownlist.options.dataValueField, "bar"); + }); + + test("initializes data source", function() { + dom = $(''); + + kendo.bind(dom, { items: ["foo", "bar"], value: "bar" } ); + + equal(dom.data("kendoDropDownList").value(), "bar"); + }); + + test("selects first item on source binding", function() { + dom = $(''); + + var observable = kendo.observable({ items: [{text:"foo"}, {text:"bar"}], value: null }); + observable.value = observable.items[1]; + + kendo.bind(dom, observable); + + equal(dom.data("kendoDropDownList").value(), "bar"); + }); + + test("changing a value updates the view model", function() { + dom = $(''); + + var observable = kendo.observable({ items: [{text:"foo"}, {text:"bar"}], value: null }); + observable.value = observable.items[1]; + + kendo.bind(dom, observable); + dom.data("kendoDropDownList").select(0); + dom.data("kendoDropDownList").trigger("change"); + + equal(observable.value, observable.items[0].text); + }); + + test("widget datasource is use if source binding is not set", function() { + var observable = kendo.observable({ items: [{text:"foo"}, {text:"bar"}], value: null }); + observable.value = observable.items[1]; + + + dom = $(''); + observable.value = "foo"; + + kendo.bind(dom, observable); + + dom.data("kendoDropDownList").select(1); + dom.data("kendoDropDownList").trigger("change"); + + equal(observable.value, "bar"); + }); + + test("binding dropdownlist initialized before binding", function() { + dom = $(''); + + var observable = kendo.observable({ items: [{text:"foo"}, {text:"bar"}], value: null }); + observable.value = observable.items[1]; + + kendo.bind(dom, observable); + + dom.kendoDropDownList({ dataValueField: "text" }); + + equal(dom.data("kendoDropDownList").value(), "bar"); + }); + + test("binding template", function() { + dom = $(''); + + var observable = kendo.observable({ items: [{text:"foo"}, {text:"bar"}] }); + + kendo.bind(dom, observable); + + equal($.trim(dom.data("kendoDropDownList").ul.children().eq(0).html().toLowerCase()), 'foo'); + }); + + test("updating an item from the data source updates the corresponding dropdownlist item", function() { + dom = $(''); + + var observable = kendo.observable({ items: [{ text:"foo"} ] }); + + kendo.bind(dom, observable); + dom.data("kendoDropDownList").refresh(); + + equal(observable.items[0]._events["change"].length, 2); //1 for the text binding and 1 for the ObservableArray + }); + + test("DropDownList is not replaced", function() { + dom = $(''); + + var observable = kendo.observable({ items: [{ text:"foo"},{ text: "bar" },{ text: "baz" }] }); + + kendo.bind(dom, observable); + + dom.kendoDropDownList(); + + observable.items.splice(0,1); + + equal(dom.data("kendoDropDownList").ul.children().length, 2); + }); + + test("destroys detaches the events to widget", function() { + dom = $('
'); + + var observable = kendo.observable({ items: [{text:"foo"}, {text:"bar"}] }); + + kendo.bind(dom, observable); + kendo.unbind(dom); + + dropdownlist = dom.data("kendoDropDownList"); + + equal(dropdownlist._events["dataBound"].length, 0); + equal(dropdownlist._events["dataBinding"].length, 0); + }); + + + test("dataBound event is raised if attached as option", 2, function() { + dom = $('
'); + + var observable = kendo.observable({ + items: [{text:"foo"}, {text:"bar"}] + }); + + kendo.bind(dom, observable); + }); + + test("dataBound event is raised if attached as option to a already initialized dropdownlist", 1, function() { + dom = $('
').kendoDropDownList(); + + var observable = kendo.observable({ + items: [{text:"foo"}, {text:"bar"}] + }); + + kendo.bind(dom, observable); + }); + + test("binding enabled to false disables the widget", function() { + dom = $(''); + + var observable = kendo.observable({ + enabled: true + }); + + kendo.bind(dom, observable); + + ok(!dom.is(":disabled")); + }); + + test("binding disable to true disables the widget", function() { + dom = $(''); + + var observable = kendo.observable({ + disabled: true + }); + + kendo.bind(dom, observable); + + ok(dom.is(":disabled")); + }); + + test("assign to DataSource as ViewModel field", function() { + dom = $(''); + var dataSource = new kendo.data.DataSource({ + data: [{text:"foo"}, {text:"bar"}] + }); + + var observable = kendo.observable({ + dataSource: dataSource, + selected: {} + }); + + kendo.bind(dom, observable); + dropdownlist = dom.data("kendoDropDownList"); + dropdownlist.select(1); + dropdownlist.trigger("change"); + + equal(observable.selected, observable.dataSource.data()[1]); + }); + + test("binding invisible to true hides the widget", function() { + dom = $(''); + + var observable = kendo.observable({ + invisible: false + }); + + kendo.bind(dom, observable); + + ok(dom.data("kendoDropDownList").wrapper.css("display") != "none", "Display is not 'none'"); + }); + + test("changing invisible to true hides the widget", function() { + dom = $(''); + + var observable = kendo.observable({ + invisible: true + }); + + kendo.bind(dom, observable); + observable.set("invisible", false); + + ok(dom.data("kendoDropDownList").wrapper.css("display") != "none", "Display is not 'none'"); + }); + + test("binding visible to false hides the widget", function() { + dom = $(''); + + var observable = kendo.observable({ + visible: true + }); + + kendo.bind(dom, observable); + + ok(dom.data("kendoDropDownList").wrapper.css("display") != "none", "Display is not 'none'"); + }); + + test("changing visible to false hides the widget", function() { + dom = $(''); + + var observable = kendo.observable({ + visible: false + }); + + kendo.bind(dom, observable); + observable.set("visible", true); + + ok(dom.data("kendoDropDownList").wrapper.css("display") != "none", "Display is not 'none'"); + }); + + test("selecting the default value sets the view model field to null", function() { + dom = $(''); + + var observable = kendo.observable({ + items: [{text:"foo"}, {text:"bar"}], + bar: "" + }); + + kendo.bind(dom, observable); + dom.data("kendoDropDownList").select(1); + dom.data("kendoDropDownList").trigger("change"); + + dom.data("kendoDropDownList").select(0); + dom.data("kendoDropDownList").trigger("change"); + strictEqual(observable.bar, ""); + }); + + test("assign to DataSource as ViewModel field", function() { + dom = $(''); + + var observable = kendo.observable({ + dataSource: [{text:"foo"}, {text:"bar"}] + }); + + kendo.bind(dom, observable); + dropdownlist = dom.data("kendoDropDownList"); + + equal(dropdownlist.select(), 0); + equal(dropdownlist.text(), "test"); + }); +})(); diff --git a/tests/dropdownlist/navigation.js b/tests/dropdownlist/navigation.js new file mode 100644 index 00000000000..5d8aa2c65dc --- /dev/null +++ b/tests/dropdownlist/navigation.js @@ -0,0 +1,351 @@ +(function() { + var DropDownList = kendo.ui.DropDownList, + data = ["foo", "bar"], + SELECTED = "k-state-selected", + keys = kendo.keys, + CLICK = kendo.support.touch ? "touchend" : "click", + input; + + module("kendo.ui.DropDownList selection", { + setup: function() { + $.fn.press = function(key) { + return this.trigger({ type: "keydown", keyCode: key } ); + }; + input = $("").appendTo(QUnit.fixture); + }, + teardown: function() { + var ddl = input.data("kendoDropDownList"); + ddl.destroy(); + } + }); + + test("always select first item on dataSource change", function() { + var dropdownlist = new DropDownList(input, ["foo", "bar"]); + + ok(dropdownlist.ul.children().eq(0).hasClass(SELECTED)); + }); + + test("click first li should update text and value", function() { + var dropdownlist = input.kendoDropDownList(data).data("kendoDropDownList"); + dropdownlist.ul.children().eq(1).trigger(CLICK); + + equal(dropdownlist.text(), data[1]); + equal(dropdownlist.value(), data[1]); + }); + + test("value should be set to item.text if no item.value", function() { + var data = [{ text: "Foo", value: 1 }, { text: "Bar" }]; + + dropdownlist = new DropDownList(input, { + dataTextField: "text", + dataValueField: "value", + dataSource: data + }); + + dropdownlist.ul.children().eq(1).trigger(CLICK); + + equal(dropdownlist.text(), data[1].text); + equal(dropdownlist.value(), data[1].text); + }); + + test("selecting a li should update text and value", function() { + var dropdownlist = input.kendoDropDownList(data).data("kendoDropDownList"); + + dropdownlist.select(dropdownlist.ul.children().eq(1)); + + equal(dropdownlist.text(), data[1]); + equal(dropdownlist.value(), data[1]); + }); + + test("click li should close popup", 1, function() { + var dropdownlist = input.kendoDropDownList(data).data("kendoDropDownList"); + + dropdownlist.popup.bind("close", function(){ + ok(true); + }); + + dropdownlist.popup.open(); + dropdownlist.ul.children().eq(1).trigger(CLICK); + }); + + test("select should select a li by index", function() { + var dropdownlist = input.kendoDropDownList(data).data("kendoDropDownList"); + + dropdownlist.select(1); + + equal(dropdownlist.text(), data[1]); + equal(dropdownlist.value(), data[1]); + }); + + test("selected should be persisted", function(){ + var dropdownlist = input.kendoDropDownList(data).data("kendoDropDownList"); + + dropdownlist.select(1); + + dropdownlist.wrapper.trigger(CLICK); + + ok(dropdownlist.ul.children().eq(1).hasClass(SELECTED)); + }); + + test("only one li should be selected at a time", function(){ + var dropdownlist = input.kendoDropDownList(data).data("kendoDropDownList"); + + dropdownlist.select(1); + dropdownlist.select(0); + + dropdownlist.wrapper.trigger(CLICK); + + equal(dropdownlist.ul.children("." + SELECTED).length, 1); + }); + + test("press down arrow should focus next item and update text and value", function() { + var dropdownlist = input.kendoDropDownList(data).data("kendoDropDownList"); + + dropdownlist.wrapper.focus().press(keys.DOWN); + + ok(dropdownlist.ul.children().eq(1).hasClass(SELECTED)); + equal(dropdownlist.text(), data[1]); + equal(dropdownlist.value(), data[1]); + + }); + + test("press right arrow should focus next item", function() { + var dropdownlist = input.kendoDropDownList(data).data("kendoDropDownList"); + + dropdownlist.wrapper.focus().press(keys.RIGHT); + + ok(dropdownlist.ul.children().eq(1).hasClass(SELECTED)); + }); + + test("press down arrow when last item is selected should not do anything", function() { + var dropdownlist = input.kendoDropDownList(data).data("kendoDropDownList"); + + dropdownlist.dataSource.read(); + dropdownlist.select(dropdownlist.ul.children(":last")); + dropdownlist.wrapper.focus().press(keys.DOWN); + + ok(dropdownlist.ul.children().eq(1).hasClass(SELECTED)); + equal(dropdownlist.text(), data[1]); + equal(dropdownlist.value(), data[1]); + + }); + + test("press up arrow should focus prev item and update text and value", function() { + var dropdownlist = input.kendoDropDownList(data).data("kendoDropDownList"); + + dropdownlist.dataSource.read(); + + dropdownlist.select(1); + dropdownlist.wrapper.focus().press(keys.UP); + + ok(dropdownlist.ul.children().eq(0).hasClass(SELECTED)); + equal(dropdownlist.text(), data[0]); + equal(dropdownlist.value(), data[0]); + + }); + + test("press left arrow should focus prev item", function() { + var dropdownlist = input.kendoDropDownList(data).data("kendoDropDownList"); + + dropdownlist.dataSource.read(); + + dropdownlist.select(1); + dropdownlist.wrapper.focus().press(keys.LEFT); + + ok(dropdownlist.ul.children().eq(0).hasClass(SELECTED)); + }); + + test("press up arrow when first item is selected should not do anything", function() { + var dropdownlist = input.kendoDropDownList(data).data("kendoDropDownList"); + + dropdownlist.wrapper.focus().press(keys.UP); + + equal(dropdownlist.selectedIndex, 0); + equal(dropdownlist.text(), data[0]); + equal(dropdownlist.value(), data[0]); + }); + + test("press home should focus first item and update text and value", function() { + var dropdownlist = input.kendoDropDownList(data).data("kendoDropDownList"); + + dropdownlist.dataSource.read(); + + dropdownlist.select(1); + dropdownlist.wrapper.focus().press(keys.HOME); + + ok(dropdownlist.ul.children().eq(0).hasClass(SELECTED)); + equal(dropdownlist.text(), data[0]); + equal(dropdownlist.value(), data[0]); + + }); + + test("press end should focus last item and update text and value", function() { + var dropdownlist = input.kendoDropDownList(data).data("kendoDropDownList"); + + dropdownlist.dataSource.read(); + + dropdownlist.select(0); + dropdownlist.wrapper.focus().press(keys.END); + + ok(dropdownlist.ul.children().eq(1).hasClass(SELECTED)); + equal(dropdownlist.text(), data[1]); + equal(dropdownlist.value(), data[1]); + + }); + + test("press enter should close popup when no change in selection", 1, function() { + var dropdownlist = input.kendoDropDownList(data).data("kendoDropDownList"); + + dropdownlist.popup.bind("close", function(){ + ok(true); + }); + + dropdownlist.popup.open(); + + dropdownlist.select(0); + dropdownlist.wrapper.focus().press(keys.ENTER); + }); + + test("press enter should select current item", 3, function() { + var dropdownlist = input.kendoDropDownList(data).data("kendoDropDownList"); + + dropdownlist.popup.bind("close", function(){ + equal(dropdownlist._current.index(), 1); + ok(dropdownlist._current.hasClass("k-state-focused")); + ok(dropdownlist._current.hasClass("k-state-selected")); + }); + + dropdownlist.popup.open(); + + dropdownlist.select(0); + dropdownlist.wrapper.focus().press(keys.DOWN).press(keys.ENTER); + }); + + test("selected item with enter should persist selected state", function() { + var dropdownlist = input.kendoDropDownList(data).data("kendoDropDownList"); + dropdownlist.popup.options.animation = false; + + dropdownlist.ul.show(); + dropdownlist.select(0); + dropdownlist.wrapper.focus().press(keys.DOWN).press(keys.ENTER); + + dropdownlist.ul.show(); + + equal(dropdownlist._current.index(), 1); + ok(dropdownlist._current.hasClass("k-state-focused")); + ok(dropdownlist._current.hasClass("k-state-selected")); + }); + + + test("press esc should close popup when no change in selection", 1, function() { + var dropdownlist = input.kendoDropDownList(data).data("kendoDropDownList"); + + dropdownlist.popup.bind("close", function(){ + ok(true); + }); + + dropdownlist.popup.open(); + + dropdownlist.select(0); + dropdownlist.wrapper.focus().press(keys.ESC); + }); + + test("pressing enter calls _blur", function() { + var blurWasCalled, dropdownlist = new DropDownList(input, { + dataSource: data + }); + + dropdownlist._blur = function(li) { + blurWasCalled = true; + }; + + dropdownlist._current = dropdownlist.ul.children().first(); + dropdownlist.wrapper.focus().press(kendo.keys.ENTER); + ok(blurWasCalled); + }); + + test("pressing alt + down should open popup", 1, function() { + var dropdownlist = new DropDownList(input, { + dataSource: data, + open: function() { + ok(true); + } + }); + + dropdownlist.wrapper.trigger({type: "keydown", altKey: true, keyCode: kendo.keys.DOWN}); + }); + + test("pressing alt + up should close popup", 1, function() { + var blurWasCalled, dropdownlist = new DropDownList(input, { + dataSource: data + }); + dropdownlist.popup.bind("close", function(){ + ok(true); + }); + dropdownlist.open(); + + dropdownlist.wrapper.trigger({type: "keydown", altKey: true, keyCode: kendo.keys.UP}); + }); + + test("navigation works after rebind", 1, function() { + var dropdownlist = new DropDownList(input, { + dataSource: data + }); + + dropdownlist.dataSource.data(data); + dropdownlist.wrapper.focusin(); + + dropdownlist.wrapper.trigger({type: "keydown", keyCode: kendo.keys.DOWN}); + + equal(dropdownlist.current().index(), 1); + }); + + test("esc calls prevent default if popup is opened", 1, function() { + var dropdownlist = new DropDownList(input, { + dataSource: data + }); + + dropdownlist.open(); + + dropdownlist.wrapper.trigger({ + type: "keydown", + keyCode: kendo.keys.ESC, + preventDefault: function() { + ok(true); + } + }); + }); + + test("add focused class on focus when widget is in readonly state", 1, function() { + var dropdownlist = new DropDownList(input, { + dataSource: data + }); + + dropdownlist.readonly(); + dropdownlist.wrapper.focusin(); + + ok(dropdownlist.wrapper.find(".k-dropdown-wrap").hasClass("k-state-focused")); + }); + + test("DropDownList selects by index after continues selection", 2, function() { + var dropdownlist = input.kendoDropDownList({ + optionLabel: "Any", + dataTextField: "text", + dataValueField: "value", + dataSource: [ + { text: "item1", value: "item1"}, + { text: "item2", value: "item2"} + ], + change: function() { + dropdownlist.dataSource.read(); + } + }).data("kendoDropDownList"); + + dropdownlist.select(1); + dropdownlist.select(0); + dropdownlist.trigger("change"); + + ok(dropdownlist.current()); + equal(dropdownlist.current().text(), "Any"); + }); +})(); diff --git a/tests/dropdownlist/searching.js b/tests/dropdownlist/searching.js new file mode 100644 index 00000000000..6ac87209d8e --- /dev/null +++ b/tests/dropdownlist/searching.js @@ -0,0 +1,249 @@ +(function() { + var DropDownList = kendo.ui.DropDownList, + data = [{text: "Foo", value: 1}, {text:"Bar", value:2}, {text:"Baz", value:3}], + input; + + module("kendo.ui.DropDownList searching", { + setup: function() { + $.fn.press = function(key) { + if (typeof key === "string") { + key = key.charCodeAt(0); + } + + return this.trigger({ type: "keypress", keyCode: key } ); + } + input = $("").appendTo(QUnit.fixture); + }, + teardown: function() { + input.data('kendoDropDownList').destroy(); + input.add($("ul")).parent(".k-widget").remove(); + } + }); + + test("search select first match", function() { + var dropdownlist = new DropDownList(input, { + dataTextField: "text", + dataValueField: "value", + dataSource: data + }); + + dropdownlist.search("b"); + + ok(dropdownlist.ul.children().eq(1).hasClass("k-state-selected")); + }); + + test("search select item if text number", function() { + var dropdownlist = new DropDownList(input, { + dataTextField: "text", + dataValueField: "value", + dataSource: [{text: "Foo", value: 1}, {text:10, value:2}] + }); + + dropdownlist.search("1"); + + ok(dropdownlist.ul.children().eq(1).hasClass("k-state-selected")); + }); + + test("search select item if text is 0", function() { + var dropdownlist = new DropDownList(input, { + dataTextField: "text", + dataValueField: "value", + dataSource: [{text: "Foo", value: 1}, {text:0, value:2}] + }); + + dropdownlist.search("0"); + + ok(dropdownlist.ul.children().eq(1).hasClass("k-state-selected")); + }); + + test("search should not raise error if word is null", function() { + var dropdownlist = new DropDownList(input, { + dataTextField: "text", + dataValueField: "value", + dataSource: data + }); + + dropdownlist.search(); + + ok(true); + }); + + test("search method supports a case sensitive search", function() { + var dropdownlist = new DropDownList(input, { + dataSource: ["TEXT", "text", "3text"], + ignoreCase: false + }); + + dropdownlist.search("t"); + + equal(dropdownlist.selectedIndex, 1); + }); + + test("select next item if starts with same character", 1, function() { + var dropdownlist = new DropDownList(input, { + dataSource: ["text1", "text2", "text3"] + }); + + input.press("t"); + input.press("t"); + + equal(dropdownlist.selectedIndex, 1); + }); + + test("keep selection if typed text is same as current data item", 1, function() { + var dropdownlist = new DropDownList(input, { + dataSource: ["500.122", "500.123"] + }); + + input.press("5"); + input.press("0"); + input.press("0"); + + equal(dropdownlist.selectedIndex, 0); + }); + + test("keep selection if typed text differs", 1, function() { + var dropdownlist = new DropDownList(input, { + dataSource: ["500.122", "500.123"] + }); + + input.press("5"); + input.press("0"); + input.press("0"); + input.press("0"); + + equal(dropdownlist.selectedIndex, 0); + }); + + test("loop items on search trigger change event", 1, function() { + var dropdownlist = new DropDownList(input, { + dataSource: ["text1", "text2", "text3"], + change: function() { + ok(true); + } + }); + + input.press("t"); + input.press("t"); + }); + + test("looping through items honors ignoreCase option", 1, function() { + var dropdownlist = new DropDownList(input, { + dataSource: ["text1", "Text2", "Text3"], + ignoreCase: true + }); + + dropdownlist.select(1); + + input.press("t"); + input.press("t"); + + equal(dropdownlist.selectedIndex, 2); + }); + + test("prevent default behavior of SPACEBAR", 1, function() { + var dropdownlist = new DropDownList(input, { + dataSource: ["text1", "Text2", "Text3"], + ignoreCase: true + }); + + dropdownlist.select(1); + + input.trigger({ + type: "keypress", + charCode: " ".charCodeAt(0), + preventDefault: function() { + ok(true); + } + }); + }); + + test("typing same letter does not move to next item", 1, function() { + var dropdownlist = new DropDownList(input, { + dataSource: ["Bill 1", "Bill 2", "Label"], + ignoreCase: true + }); + + input.press("b"); + input.press("i"); + input.press("l"); + input.press("l"); + + equal(dropdownlist.selectedIndex, 0); + }); + + test("search supports space", 1, function() { + var dropdownlist = new DropDownList(input, { + dataSource: ["Bill 1", "Bill 2", "Label"], + ignoreCase: true + }); + + input.press("b"); + input.press("i"); + input.press("l"); + input.press("l"); + input.press(" "); + input.press("2"); + + equal(dropdownlist.selectedIndex, 1); + }); + + asyncTest("search supports space", 1, function() { + var dropdownlist = new DropDownList(input, { + dataSource: ["Bill 1", "Bill 2", "Label"], + ignoreCase: true, + index: 1, + delay: 0 + }); + + input.press("b"); + + setTimeout(function() { + start(); + input.press("b"); + equal(dropdownlist.selectedIndex, 0); + }, 100); + }); + + test("navigation does not raise exception when data is set through setDataSource", function() { + var dropdownlist = new DropDownList(input, { + dataTextField: "text", + dataValueField: "value" + }); + + dropdownlist.setDataSource(data); + + input.press("b"); + + ok(true); + }); + + test("search does not raise exception when widget is not bound", function() { + var dropdownlist = new DropDownList(input, { + autoBind: false, + dataTextField: "text", + dataValueField: "value", + dataSource: [ + { text: "Item1", value: "1" } + ] + }); + + input.press("i"); + + ok(true); + }); + + test("search empty widget does not raise exception", function() { + var dropdownlist = new DropDownList(input, { + dataTextField: "text", + dataValueField: "value", + dataSource: data + }); + dropdownlist.selectedIndex = -1; //Kendo Editor requires such functionality + + input.press("i"); + + ok(true); + }); + +})(); diff --git a/tests/editable/editable.js b/tests/editable/editable.js new file mode 100644 index 00000000000..28e4497e33d --- /dev/null +++ b/tests/editable/editable.js @@ -0,0 +1,513 @@ +(function() { + var Editable = kendo.ui.Editable, + Model = kendo.data.Model, + div, + defaultModel = new (Model.define({ fields: { foo: "foo" } }))(); + + module("kendo.ui.Editable", { + setup: function() { + div = $("
").appendTo(QUnit.fixture); + }, + teardown: function() { + kendo.destroy(QUnit.fixture); + } + }); + + function setup(options, createModel) { + return new Editable(div, options); + } + + test("kendoEditable is attached to the target element", function() { + var element = div.kendoEditable( { model: defaultModel }); + + ok(element.data("kendoEditable") instanceof Editable); + }); + + test("renders input element for field", function() { + var editable = setup({ fields: "foo", model: defaultModel }); + + equal(editable.element.find(":input").length, 1); + }); + + test("does not clear container is set", function() { + var editable = div.append($('
')).kendoEditable({ + fields: "foo", + model: defaultModel, + clearContainer: false + }); + + equal(editable.find("div").length, 1); + }); + + test("renders input element within the child element container if specified", function() { + var editable = div.append($('
')).kendoEditable({ + fields: "foo", + model: defaultModel, + clearContainer: false + }); + equal(editable.find("div > :input").length, 1); + }); + + test("renders input element within the child element container if specified for complex fields", function() { + var editable = div.append($('
')).kendoEditable({ + fields: "foo.bar", + model: defaultModel, + clearContainer: false + }); + equal(editable.find("div > :input").length, 1); + }); + + test("input name is same as field", function() { + var editable = setup({ fields: "foo", model: defaultModel }); + + equal(editable.element.find(":input[name=foo]").length, 1); + }); + + test("no inputs are rendered when no fields are specifed", function() { + var editable = setup({ model: defaultModel }); + + ok(!editable.element.find(":input").length); + }); + + test("input is rendered for every field", function() { + var editable = setup({ fields: ["foo", "bar"], model: new (Model.define({ fields: { foo: "foo", bar: "bar" } }))() }), + elements = editable.element.find(":input"); + + equal(elements.length, 2); + equal(elements.eq(0).attr("name"), "foo"); + equal(elements.eq(1).attr("name"), "bar"); + }); + + test("input value is bound to the value from model", function() { + var MyModel = Model.define({ fields: { foo: "foo" } }), + model = new MyModel({ foo: "bar" }), + editable = setup({ fields: "foo", model: model }); + + equal(editable.element.find("input[name=foo]").val(), "bar"); + }); + + test("container is cleared", function() { + div.append($("")); + + var editable = setup({ fields: "foo", model: defaultModel }); + + equal(div.children().length, 1); + equal(div.find(":input").length, 1); + }); + + test("input[type=text] is created for field with type set to number", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", + type: "number" + } + } + }), + model = new MyModel(), + editable = setup({ fields: "foo", model: model }); + + equal(div.find(":input[type=text][name=foo]").length, 1); + }); + + test("input[type=text] is created for field without type set", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo" + } + } + }), + model = new MyModel(), + editable = setup({ fields: "foo", model: model }); + + equal(div.find(":input[type=text]").length, 1); + }); + + test("input[type=text] is created for field with type set to string", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", + type: "string" + } + } + }), + model = new MyModel(), + editable = setup({ fields: "foo", model: model }); + + equal(div.find(":input[type=text]").length, 1); + }); + + test("input[type=text] is created for field which type does not have editor defined", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", + type: "bar" + } + } + }), + model = new MyModel(), + editable = setup({ fields: "foo", model: model }); + + equal(div.find(":input[type=text]").length, 1); + }); + + test("input[type=checkbox] is created for field of type boolean", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", + type: "boolean" + } + } + }), + model = new MyModel(), + editable = setup({ fields: "foo", model: model }); + + equal(div.find(":input[type=checkbox]").length, 1); + }); + + test("custom editor is used if set", function() { + var wasCalled = false, + MyModel = Model.define({ + fields: { + foo: { + field: "foo", + type: "string" + } + } + }), + model = new MyModel(), + editable = setup({ + fields: { + field: "foo", + editor: function() { + wasCalled = true; + return $(); + } + }, + model: model + }); + + ok(wasCalled); + }); + + test("custom editor is bind by name", function() { + var model = kendo.observable({ foo: "bar" }), + editable = setup({ + fields: { + field: "foo", + editor: function(container) { + container.append($('')); + } + }, + model: model + }); + + equal(div.find("input").val(), "bar"); + }); + + test("custom editor checkbox is bind by name", function() { + var model = kendo.observable({ foo: true }), + editable = setup({ + fields: { + field: "foo", + type: "boonlean", + editor: function(container) { + container.append($('')); + } + }, + model: model + }); + + ok(div.find("input:checked").length); + }); + + test("custom editor radio button is bind by name", function() { + var model = kendo.observable({ foo: true }), + editable = setup({ + fields: { + field: "foo", + editor: function(container) { + container.append($('')); + } + }, + model: model + }); + + ok(div.find("input:first:checked").length); + }); + test("custom editor as string", function() { + var wasCalled = false, + MyModel = Model.define({ + fields: { + foo: { + field: "foo", + type: "string" + } + } + }), + model = new MyModel(), + editable = setup({ + fields: { + field: "foo", + editor: '' + }, + model: model + }); + + ok(div.find("input[name=foo]").length); + }); + + test("custom editor name binding is added to already existing one", function() { + var model = kendo.observable({ foo: "bar", items: ["foo", "bar"] }), + editable = setup({ + fields: { + field: "foo", + editor: function(container) { + container.append($('')); + } + }, + model: model + }); + + equal(div.find("select").data("kendoDropDownList").value(), "bar"); + }); + + test("input[type=text] is created for field with type set to date", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", + type: "date" + } + } + }), + model = new MyModel(), + editable = setup({ fields: "foo", model: model }); + + equal(div.find(":input[type=text]").length, 1); + }); + + test("container and options are passed to the custom editor", function() { + var args, + MyModel = Model.define({ + fields: { + foo: { + field: "foo", + type: "string" + } + } + }), + model = new MyModel(), + editable = setup({ + fields: { + field: "foo", + editor: function() { + args = arguments; + } + }, + model: model + }); + + equal(args.length, 2); + equal(args[1].field, "foo"); + equal(args[1].model, model); + ok(args[0]); + }); + + test("format is passed to editor", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo" + } + } + }), + format, + model = new MyModel(), + editable = setup({ + fields: { + field: "foo", + format: "bar", + editor: function(container, options) { + format = options.format; + } + }, + model: model + }); + + equal(format, "bar"); + }); + + test("format is passed to date type editor", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", + type: "date" + } + } + }), + model = new MyModel(), + editable = setup({ + fields: { + field: "foo", + format: "bar" + }, + model: model + }); + + equal(div.find("input").data("kendoDatePicker").options.format, "bar"); + }); + + test("extacted format is passed to date type editor", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", + type: "date" + } + } + }), + model = new MyModel(), + editable = setup({ + fields: { + field: "foo", + format: "{0:dd.MM.yyyy}" + }, + model: model + }); + + equal(div.find("input").attr(kendo.attr("format")), "dd.MM.yyyy"); + }); + + test("default picker format is preserved if no field format is set", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", + type: "date" + } + } + }), + model = new MyModel(), + editable = setup({ + fields: { + field: "foo" + }, + model: model + }); + + equal(div.find("input").data("kendoDatePicker").options.format, "M/d/yyyy"); + }); + + test("format is passed to number type editor", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", + type: "number" + } + } + }), + model = new MyModel(), + editable = setup({ + fields: { + field: "foo", + format: "bar" + }, + model: model + }); + + equal(div.find("input").eq(1).data("kendoNumericTextBox").options.format, "bar"); + }); + + test("default numeric format is preserved if no field format is set", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", + type: "number" + } + } + }), + model = new MyModel(), + editable = setup({ + fields: { + field: "foo" + }, + model: model + }); + + equal(div.find("input").eq(1).data("kendoNumericTextBox").options.format, "n"); + }); + + test("binds input without bindings to the model", function() { + var editable = div.append($('
')).kendoEditable({ + fields: "foo", + model: defaultModel, + clearContainer: false + }); + + defaultModel.set("foo", "baz"); + + equal(div.find("input").val(), "baz"); + }); + + test("skip binding input type file without binding", function() { + var editable = div.append($('
')).kendoEditable({ + fields: "foo", + model: defaultModel, + clearContainer: false + }); + + ok(!div.find("input[type=file]").filter("[data-bind]").length); + }); + + test("does not bind input element of upload widget", function() { + var editable = div.append($('
')).kendoEditable({ + model: defaultModel, + clearContainer: false + }); + + ok(!div.find("input").data("bind")); + }); + + test("does not bind input element with skip attribute", function() { + var editable = div.append($('
')).kendoEditable({ + model: defaultModel, + clearContainer: false + }); + + ok(!div.find("input").data("bind")); + }); + + test("dropdown is displayed if field values are set", function() { + var editable = div.append($('
')).kendoEditable({ + fields: { field: "foo", values: [ { text: "bar", value: "foo" }] }, + model: defaultModel + }); + + ok(div.find("select").data("kendoDropDownList")); + equal(div.find("select").data("kendoDropDownList").value(), "foo"); + equal(div.find("select").data("kendoDropDownList").text(), "bar"); + }); +})(); diff --git a/tests/editable/validation.js b/tests/editable/validation.js new file mode 100644 index 00000000000..7f78e9a74bc --- /dev/null +++ b/tests/editable/validation.js @@ -0,0 +1,534 @@ +(function() { + var Editable = kendo.ui.Editable, + Model = kendo.data.Model, + div; + + module("kendo.ui.Editable", { + setup: function() { + div = $("
").appendTo(QUnit.fixture); + }, + teardown: function() { + kendo.destroy(QUnit.fixture); + } + }); + + test("setting required validation rule renderes required attr", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", + validation: { + required: true + } + } + } + }), + model = new MyModel(), + editable = new Editable(div, { fields: "foo", model: model }); + + ok(div.find(":input[required]").length); + }); + + test("setting custom validation rule does not renders attr", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", + validation: { + bar: function() {} + } + } + } + }), + model = new MyModel(), + editable = new Editable(div, { fields: "foo", model: model }); + + ok(!div.find(":input").data("type")); + }); + + test("setting multiple validation rules renders attr", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", + validation: { + required: true, + pattern: "foo" + } + } + } + }), + model = new MyModel(), + editable = new Editable(div, { fields: "foo", model: model }), + input = div.find(":input"); + + ok(input.attr("required")); + ok(input.attr("pattern")); + }); + + test("setting url rule renderes data-type=url attr", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", + validation: { + url: true + } + } + } + }), + model = new MyModel(), + editable = new Editable(div, { fields: "foo", model: model }), + input = div.find(":input"); + + ok(!input.attr("url")); + equal(input.data("type"), "url"); + }); + + test("setting email rule renderes data-type=email attr", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", + validation: { + email: true + } + } + } + }), + model = new MyModel(), + editable = new Editable(div, { fields: "foo", model: model }), + input = div.find(":input"); + + ok(!input.attr("email")); + equal(input.data("type"), "email"); + }); + + test("for field of type number data-type=number attr is rendered", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", + type: "number" + } + } + }), + model = new MyModel(), + editable = new Editable(div, { fields: "foo", model: model }), + input = div.find("input[name=foo]"); + + equal(input.data("type"), "number"); + }); + + test("for field of type date data-type=date attr is rendered", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", + type: "date" + } + } + }), + model = new MyModel(), + editable = new Editable(div, { fields: "foo", model: model }), + input = div.find(":input"); + + equal(input.data("type"), "date"); + }); + + test("for field of type date format attrr is rendered", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", + type: "date" + } + } + }), + model = new MyModel(), + editable = new Editable(div, { fields: [{ field: "foo", format: "format" }], model: model }), + input = div.find(":input"); + + equal(input.attr(kendo.attr("format")), "format"); + }); + + test("for field of type boolean data-type=boolean attr is rendered", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", + type: "boolean" + } + } + }), + model = new MyModel(), + editable = new Editable(div, { fields: "foo", model: model }), + input = div.find(":input"); + + equal(input.data("type"), "boolean"); + }); + + test("setting custom validation rule does not render attr", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", + validation: { + bar: function() { return true; } + } + } + } + }), + model = new MyModel(), + editable = new Editable(div, { fields: "foo", model: model }), + input = div.find(":input"); + + ok(!input.data("type")); + ok(!input.attr("bar")); + }); + + test("custom validation message is rendered as input attr", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", + validation: { + required: { message: "my message" } + } + } + } + }), + model = new MyModel(), + editable = new Editable(div, { fields: "foo", model: model }), + input = div.find(":input"); + + equal(input.data("required-msg"), "my message"); + }); + + test("validation message is not rendered as input attr", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", + validation: { + required: true + } + } + } + }), + model = new MyModel(), + editable = new Editable(div, { fields: "foo", model: model }), + input = div.find(":input"); + + ok(!input.filter("[data-required-msg]").length); + }); + + test("multiple custom validation messages are rendered as input attr", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", + validation: { + required: { message: "required message" }, + email: { message: "email message" } + } + } + } + }), + model = new MyModel(), + editable = new Editable(div, { fields: "foo", model: model }), + input = div.find(":input"); + + equal(input.attr("required"), "required"); + equal(input.data("required-msg"), "required message"); + equal(input.data("email-msg"), "email message"); + }); + + test("for field of type number min constraint attr is rendered", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", + type: "number", + validation: { + min: 10 + } + } + } + }), + model = new MyModel(), + editable = new Editable(div, { fields: "foo", model: model }), + input = div.find("input[name=foo]"); + + equal(input.attr("min"), 10); + }); + + test("for field of type number min constraint and validation message attrs are rendered", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", + type: "number", + validation: { + min: { value: 10, message: "min message" } + } + } + } + }), + model = new MyModel(), + editable = new Editable(div, { fields: "foo", model: model }), + input = div.find("input[name=foo]"); + + equal(input.attr("min"), 10); + equal(input.data("min-msg"), "min message"); + }); + + test("for field of type email and validation message attrs are rendered", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", + validation: { + email: { message: "email message" } + } + } + } + }), + model = new MyModel(), + editable = new Editable(div, { fields: "foo", model: model }), + input = div.find(":input"); + + equal(input.data("type"), "email"); + equal(input.data("email-msg"), "email message"); + }); + + test("custom validation rules are assign to validation instance", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", + validation: { + foo: function() { + + } + } + } + } + }), + model = new MyModel(), + editable = new Editable(div, { fields: "foo", model: model }), + validatable = editable.validatable, + input = div.find(":input"); + + ok($.isFunction(validatable.options.rules.foo)); + }); + + test("custom validation rules are assign to validation instance if no fields are assigned", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", + validation: { + foo: function() { + + } + } + } + } + }), + model = new MyModel(), + editable = new Editable(div, { model: model }), + validatable = editable.validatable, + input = div.find(":input"); + + ok($.isFunction(validatable.options.rules.foo)); + }); + + test("model is not updated if validation fails", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", + validation: { + foo: function() { + return false; + } + } + } + } + }), + model = new MyModel({ foo: "bar" }), + editable = new Editable(div, { fields: "foo", model: model }), + input = div.find(":input"); + + input.val("foo").trigger("change"); + + equal(model.get("foo"), "bar"); + }); + + test("change event is triggered if validation success", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", + validation: { + foo: function() { + return true; + } + } + } + } + }), + model = new MyModel({ foo: "bar" }), + wasCalled = false, + editable = new Editable(div, { fields: "foo", model: model, change: function() { wasCalled = true; } }), + input = div.find(":input"); + + input.val("foo").trigger("change"); + + equal(model.get("foo"), "foo"); + ok(wasCalled); + }); + + test("change event is not triggered if validation fails", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", + validation: { + foo: function() { + return false; + } + } + } + } + }), + model = new MyModel({ foo: "bar" }), + wasCalled = false, + editable = new Editable(div, { fields: "foo", model: model, change: function() { wasCalled = true; } }), + input = div.find(":input"); + + input.val("foo").trigger("change"); + + equal(model.get("foo"), "bar"); + ok(!wasCalled); + }); + + test("end method detaches the change event", 1, function() { + var model = new Model({ foo: "bar" }), + editable = new Editable(div, { + fields: "foo", + model: model, + change: function() { + ok(true); + } + }); + model.set("foo", "foo"); + editable.destroy(); + model.set("foo", "baz"); + }); + + test("end method triggers validation", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", + validation: { + foo: function() { + } + } + } + } + }), + model = new MyModel({ foo: "bar" }), + editable = new Editable(div, { fields: "foo", model: model }); + + var validatable = stub(editable.validatable, "validate"); + editable.end(); + + equal(validatable.calls("validate"), 1); + }); + + test("end method returns false when validation fails", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", + validation: { + foo: function() { + return false; + } + } + } + } + }), + model = new MyModel({ foo: "bar" }), + editable = new Editable(div, { fields: "foo", model: model }); + + ok(!editable.end()); + }); + + test("end method returns true when validation pass", function() { + var MyModel = Model.define({ + fields: { + foo: "foo" + } + }), + model = new MyModel({ foo: "bar" }), + editable = new Editable(div, { fields: "foo", model: model }); + + ok(editable.end()); + }); + + test("changing model field validates the input", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", + validation: { + required: true + } + }, + bar: { + field: "bar", + validation: { + required: true + } + } + } + }), + model = new MyModel({ foo: "bar" }), + editable = new Editable(div, { fields: ["foo", "bar"], model: model }), + validateInput = stub(editable.validatable, "validateInput"); + + model.set("foo", "baz"); + + equal(validateInput.calls("validateInput"), 1); + equal(validateInput.args("validateInput", 0)[0].data("bind"), "value:foo"); + }); + + test("changing boolean model field validates the input", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", + type: "boolean" + }, + bar: { + field: "bar", + validation: { + required: true + } + } + } + }), + model = new MyModel({ foo: false }), + editable = new Editable(div, { fields: ["foo", "bar"], model: model }), + validateInput = stub(editable.validatable, "validateInput"); + + model.set("foo", true); + + equal(validateInput.calls("validateInput"), 1); + equal(validateInput.args("validateInput", 0)[0].data("bind"), "checked:foo"); + }); +})(); diff --git a/tests/fx/animation.js b/tests/fx/animation.js new file mode 100644 index 00000000000..a160bd4bf7e --- /dev/null +++ b/tests/fx/animation.js @@ -0,0 +1,424 @@ +(function() { + var animate = kendo.animate, + transforms = kendo.support.transforms, + matrix3dRegExp = /matrix3?d?\s*\(.*,\s*([\d\.\-]+)\w*?,\s*([\d\.\-]+)\w*?,\s*([\d\.\-]+)\w*?,\s*([\d\.\-]+)\w*?/i, + translateXRegExp = /translatex?$/i, + TRANSFORM = kendo.support.transforms.css + "transform", + span; + + function animationProperty(element, property) { + if (transforms) { + var transform = element.css(TRANSFORM); + if (transform == "none") { + return property == "scale" ? 1 : 0; + } + + var match = transform.match(new RegExp(property + "\\s*\\(([\\d\\w\\.]+)")), + computed = 0; + + if (match) { + computed = parseInt(match[1], 10); + } else { + match = transform.match(matrix3dRegExp) || [0, 0, 0, 0, 0]; + property = property.toLowerCase(); + + if (translateXRegExp.test(property)) { + computed = parseFloat(match[3] / match[2]); + } else if (property == "translatey") { + computed = parseFloat(match[4] / match[2]); + } else if (property == "scale") { + computed = parseFloat(match[2]); + } else if (property == "rotate") { + computed = parseFloat(Math.atan2(match[2], match[1])); + } + } + + return computed; + } else { + return element.css(property); + } + } + + module("animate", { + setup: function() { + span = $("foo").appendTo(document.body); + }, + teardown: function() { + span.remove(); + } + }); + + test("kendoStop calls callback", 1, function() { + var span = kendo.jQuery(""); + + span.kendoAnimate({ + effects: "fadeOut", + duration: 600, + complete: function() { + ok(true); + } + }); + + span.kendoStop(true, true); + }); + + asyncTest("animate waits all effects to finish", function() { + var fooFinished = false, barFinished = false; + + kendo.effects.createEffect("foo", { + prepare: function() { + fooFinished = true; + return { start: {}, end: {} }; + } + }); + + kendo.effects.createEffect("bar", { + prepare: function() { + barFinished = true; + return { start: {}, end: {} }; + } + }); + + animate(span, "foo bar", function() { + ok(fooFinished); + ok(barFinished); + start(); + }); + }); + + test("reverse method of the effect is called if reverse = true", 1, function() { + var reverseWasCalled = false; + + kendo.effects.createEffect("foo", { + prepare: function() { + equal(this._reverse, true); + return { start: {}, end: {} }; + } + }); + + animate(span, "foo", true); + }); + + asyncTest("passing options to animate works", 2, function() { + var reverseWasCalled = false, callbackWasCalled = false; + + kendo.effects.createEffect("foo", { + prepare: function() { + equal(this._reverse, true); + return { start: {}, end: {} }; + } + }); + + animate(span, { + effects: { foo: {} }, + reverse: true, + complete: function() { + ok(true); + start(); + } + }); + }); + + asyncTest("passing options to animate effects as string", 2, function() { + var reverseWasCalled = false, callbackWasCalled = false; + + kendo.effects.createEffect("foo", { + prepare: function() { + equal(this._reverse, true); + return { start: {}, end: {} }; + } + }); + + animate(span, { + reverse: true, + complete: function() { + ok(true); + start(); + }, + effects: "foo" + }); + }); + + // legacy test, not sure why + asyncTest("make sure css, setup, teardown and restore are called in sequence", 2, function() { + span.css("overflow", "visible"); + + kendo.effects.createEffect("foo", { + restore: [ "overflow" ], + + prepare: function() { + ok(this.element.data("overflow") == "visible") + return { start: { overflow: "hidden" } }; + }, + + teardown: function() { + ok(this.element.css("overflow") == "visible"); + start(); + } + }); + + animate(span, "foo"); + }); + + asyncTest("callback is fired asynchronously after animate", 1, function() { + var called = false; + + kendo.effects.createEffect("moo", { + prepare: function() { + return { end: { translateX: "10px" } }; + } + }); + + span.kendoAnimate({ + effects: "moo", + duration: 100, + init: function () { + oldTime = +new Date(); + }, + complete: function() { + called = true; + start(); + } + }); + + ok(!called); + }); + + if (!kendo.support.browser.mozilla) { + asyncTest("Passing properties to the effect overrides the end state", 2, function() { + var height = -1; + + kendo.effects.createEffect("foo", { + prepare: function(start, end) { + start.height = 0; + start.display = "block"; + end.height = 100; + } + }); + + span.kendoAnimate({ + effects: { foo: { properties: { height: 20 } } }, + + duration: 20, + + init: function () { + height = span.height(); + }, + + complete: function(element) { + equal(height, 0); + equal(span.height(), 20); + start(); + } + }); + }); + + asyncTest("animating height from 0 to 100 results in 100px high element", 2, function() { + var height = -1; + + kendo.effects.createEffect("foo", { + prepare: function(start, end) { + start.height = 0; + start.display = "block"; + end.height = 100; + } + }); + + span.kendoAnimate({ + effects: "foo", + duration: 20, + init: function () { + height = span.height(); + }, + complete: function(element) { + equal(height, 0); + equal(span.height(), 100); + start(); + } + }); + }); + + asyncTest("fadeIn animates the opacity from 0 to 1", function() { + span.css({ position: "absolute", display: "block" }); + + var opacity = 5; + + span.kendoAnimate({ + effects: "fadeIn", + duration: 10, + init: function () { + opacity = span.css("opacity"); + }, + complete: function () { + ok(opacity == 0); + ok(span.css("opacity") == 1); + start(); + } + }); + }); + + asyncTest("fadeOut animates the opacity from 1 to 0", function() { + span.css({ position: "absolute", display: "block" }); + + var opacity = 5; + + kendo.effects.Fade.prototype.restore = []; + + span.kendoAnimate({ + effects: "fadeOut", + duration: 10, + complete: function () { + equal(span.css("opacity"), 0); + start(); + } + }); + }); + + if (!kendo.support.browser.msie) // TODO: Write the IE part of this test. + asyncTest("zoomIn animates the scale from 0.01 to 1", function() { + span.css({ position: "absolute", display: "block" }); + + var scale = 5; + + span.kendoAnimate({ + effects: "zoomIn", + duration: 10, + init: function () { + scale = animationProperty(span, "scale"); + }, + complete: function () { + ok(scale == 0.01); + ok(animationProperty(span, "scale") == 1); + start(); + } + }); + }); + + asyncTest("slideIn:right moves the element right from - its width to 0", function() { + span.css({ position: "absolute", display: "block", left: 10 }); + + var position = 1; + if (transforms) + span.css(TRANSFORM, "translateX(10px)"); + + span.kendoAnimate({ + effects: "slideIn:right", + duration: 20, + init: function () { + position = (transforms ? animationProperty(span, "translateX") : span.offset().left); + }, + complete: function () { + ok(position == -span.width()); + ok((transforms ? animationProperty(span, "translateX") : span.offset().left) == 0); + start(); + } + }); + }); + + asyncTest("slideIn:down moves the element down from - its height to 0", function() { + span.css({ position: "absolute", display: "block", top: 10 }); + + var position = 1; + if (transforms) + span.css(TRANSFORM, "translateY(10px)"); + + span.kendoAnimate({ + effects: "slideIn:down", + duration: 20, + init: function () { + position = (transforms ? animationProperty(span, "translateY") : span.offset().top); + }, + complete: function () { + ok(position == -span.height()); + ok((transforms ? animationProperty(span, "translateY") : span.offset().top) == 0); + start(); + } + }); + }); + + asyncTest("expand:vertical expands the element from 0 to its height", function() { + span.css({ position: "absolute", display: "block", height: 100 }); + var initialHeight = 100; + + span.kendoAnimate({ + effects: "expand:vertical", + duration: 20, + init: function () { + initialHeight = span.height(); + }, + complete: function () { + ok(initialHeight == 0); + ok(span.height() == 100); + start(); + } + }); + }); + + asyncTest("expand:horizontal expands the element from 0 to its width", function() { + span.css({ position: "absolute", display: "block", width: 100, height: 100 }); + var initialWidth = 100; + + span.kendoAnimate({ + effects: "expand:horizontal", + duration: 20, + init: function () { + initialWidth = span.width(); + }, + complete: function () { + ok(initialWidth == 0); + ok(span.width() == 100); + start(); + } + }); + }); + } + + module("animationFrame Animation", {}); + + asyncTest("executes callbacks", 1, function() { + var animation = kendo.effects.Animation.extend({ + counter: 0, + tick: function() { + this.counter ++; + }, + + onEnd: function() { + start(); + equal(this.counter, 3); + }, + + done: function() { + return this.counter === 3; + } + }); + + new animation().start(); + }); + + asyncTest("is cancellable", 1, function() { + var animation = kendo.effects.Animation.extend({ + counter: 0, + tick: function() { + this.counter ++; + if (this.counter === 2) { + this.cancel(); + } + }, + + onCancel: function() { + start(); + equal(this.counter, 2); + }, + + onEnd: function() { + ok(false); + }, + + done: function() { + return this.counter === 3; + } + }); + + new animation().start(); + }); +})(); diff --git a/tests/fx/new.js b/tests/fx/new.js new file mode 100644 index 00000000000..e9047697ef3 --- /dev/null +++ b/tests/fx/new.js @@ -0,0 +1,173 @@ +(function() { + + module("new FX API"); + + function getTransform(element) { + var chunks = $.grep(element.css("transform").split(/[\(, \)]/), function(chunk) { + return chunk.length > 0; + }); + + return { + scale: chunks[1], + translateX: chunks[5], + translateY: chunks[6] + }; + } + + test("Creating effects registers API constructor", 1, function() { + kendo.effects.createEffect("foo", { + + }); + + var fx = kendo.fx($("
")); + + ok($.isFunction(fx.foo)); + }); + + test("Creating effects registers API constructor", 2, function() { + kendo.effects.createEffect("foo", { + directions: ["left", "right"] + }); + + var fx = kendo.fx($("
")); + + ok($.isFunction(fx.fooLeft)); + ok($.isFunction(fx.fooRight)); + }); + + module("FX integration tests") + + function verifyEffect(effectName, before, after, withEffect) { + withEffect = withEffect || $.noop; + + var effect = kendo.fx($("
").appendTo(QUnit.fixture))[effectName](); + effect.duration(0); + + withEffect(effect); + + var setup = effect.setup; + effect.setup = function() { + setup.call(this); + before(this.element); + }; + + effect.run().then(function() { + after(effect.element); + }); + } + + asyncTest("slideIn slides the element", 2, function() { + verifyEffect("slideInLeft", + function(element) { ; equal(getTransform(element).translateX, 200); }, + function(element) { start(); equal(getTransform(element).translateX, 0); } + ); + }); + + asyncTest("tile tiles the element", 2, function() { + var foo = $("
").appendTo(QUnit.fixture), + bar = $("
").appendTo(QUnit.fixture), + effect = kendo.fx(foo).tile("left", bar); + + effect.duration(0); + + effect.run().then(function() { + start(); + equal(getTransform(foo).translateX, 0); + equal(getTransform(bar).translateX, -200); + }); + }); + + asyncTest("fade in fades the element", 2, function() { + verifyEffect("fadeIn", + function(element) { equal(element.css("opacity"), "0") }, + function(element) { start(); equal(element.css("opacity"), "1") } + ); + }); + + asyncTest("fade in accepts custom start/end values", 2, function() { + verifyEffect("fadeIn", + function(element) { QUnit.close(element.css("opacity"), 0.3, 0.1) }, + function(element) { start(); QUnit.close(element.css("opacity"), 0.8, 0.1); }, + function(effect) { effect.startValue(0.3).endValue(0.8); } + ); + }); + + asyncTest("fade out can fade the element to a given value", 3, function() { + verifyEffect("fadeOut", + function(element) { QUnit.close(element.css("opacity"), 1, 0.1); }, + function(element) { start(); QUnit.close(element.css("opacity"), 0.8, 0.1); equal(element.css("display"), "block"); }, + function(effect) { effect.endValue(0.8); } + ); + }); + + asyncTest("fade out fades the element and hides it", 3, function() { + verifyEffect("fadeOut", + function(element) { equal(element.css("opacity"), "1") }, + function(element) { + start(); + equal(element.css("opacity"), "0"); + equal(element.css("display"), "none"); + } + ); + }); + + asyncTest("zoom in zooms the element", 2, function() { + verifyEffect("zoomIn", + function(element) { equal(getTransform(element).scale, 0.01) }, + function(element) { start(); equal(getTransform(element).scale, 1) } + ); + }); + + asyncTest("expanding expands the element", 2, function() { + verifyEffect("expandVertical", + function(element) { equal(element.css("height"), "0px") }, + function(element) { start(); equal(element.css("height"), "200px") } + ); + }); + + asyncTest("transfer transfers the element", 3, function() { + var foo = $("
"), + bar = $("
").prependTo(QUnit.fixture), + effect = kendo.fx(foo).transfer(bar); + + effect.duration(0); + + effect.run().then(function() { + start(); + equal(foo.css("transform"), "matrix(0.5, 0, 0, 0.5, 0, 0)"); + var transformOrigin = foo.css("transformOrigin").match(/(\d+)\.?\d+px/g).map(function(px) { return parseInt(px) }); + equal(transformOrigin[0], 616); + equal(transformOrigin[1], 16); + }); + }); + + asyncTest("page turn turns the two pages, hiding the first one", 2, function() { + var container = $("
Foo
Bar
"); + foo = container.find("#foo"), + bar = container.find("#bar"), + effect = kendo.fx(container).pageturn("horizontal", foo, bar); + + effect.duration(0); + + effect.run().then(function() { + start(); + equal(foo.css("display"), "none"); + equal(bar.css("display"), "block"); + }); + }); + + asyncTest("flip flips the two pages, hiding the first one", 2, function() { + var container = $("
Foo
Bar
"); + foo = container.find("#foo"), + bar = container.find("#bar"), + effect = kendo.fx(container).flip("horizontal", foo, bar); + + effect.duration(0); + + effect.run().then(function() { + start(); + equal(foo.css("display"), "none"); + equal(bar.css("display"), "block"); + }); + }); +}); diff --git a/tests/jquery.mockjax.js b/tests/jquery.mockjax.js new file mode 100644 index 00000000000..ef56cdfe3b7 --- /dev/null +++ b/tests/jquery.mockjax.js @@ -0,0 +1,599 @@ +/*! + * MockJax - jQuery Plugin to Mock Ajax requests + * + * Version: 1.5.1 + * Released: + * Home: http://github.com/appendto/jquery-mockjax + * Author: Jonathan Sharp (http://jdsharp.com) + * License: MIT,GPL + * + * Copyright (c) 2011 appendTo LLC. + * Dual licensed under the MIT or GPL licenses. + * http://appendto.com/open-source-licenses + */ +(function($) { + var _ajax = $.ajax, + mockHandlers = [], + CALLBACK_REGEX = /=\?(&|$)/, + jsc = (new Date()).getTime(); + + + // Parse the given XML string. + function parseXML(xml) { + if ( window.DOMParser == undefined && window.ActiveXObject ) { + DOMParser = function() { }; + DOMParser.prototype.parseFromString = function( xmlString ) { + var doc = new ActiveXObject('Microsoft.XMLDOM'); + doc.async = 'false'; + doc.loadXML( xmlString ); + return doc; + }; + } + + try { + var xmlDoc = ( new DOMParser() ).parseFromString( xml, 'text/xml' ); + if ( $.isXMLDoc( xmlDoc ) ) { + var err = $('parsererror', xmlDoc); + if ( err.length == 1 ) { + throw('Error: ' + $(xmlDoc).text() ); + } + } else { + throw('Unable to parse XML'); + } + return xmlDoc; + } catch( e ) { + var msg = ( e.name == undefined ? e : e.name + ': ' + e.message ); + $(document).trigger('xmlParseError', [ msg ]); + return undefined; + } + } + + // Trigger a jQuery event + function trigger(s, type, args) { + (s.context ? $(s.context) : $.event).trigger(type, args); + } + + // Check if the data field on the mock handler and the request match. This + // can be used to restrict a mock handler to being used only when a certain + // set of data is passed to it. + function isMockDataEqual( mock, live ) { + var identical = true; + // Test for situations where the data is a querystring (not an object) + if (typeof live === 'string') { + // Querystring may be a regex + return $.isFunction( mock.test ) ? mock.test(live) : mock == live; + } + $.each(mock, function(k) { + if ( live[k] === undefined ) { + identical = false; + return identical; + } else { + if ( typeof live[k] == 'object' ) { + identical = identical && isMockDataEqual(mock[k], live[k]); + } else { + if ( $.isFunction( mock[k].test ) ) { + identical = identical && mock[k].test(live[k]); + } else { + identical = identical && ( mock[k] == live[k] ); + } + } + } + }); + + return identical; + } + + // Check the given handler should mock the given request + function getMockForRequest( handler, requestSettings ) { + // If the mock was registered with a function, let the function decide if we + // want to mock this request + if ( $.isFunction(handler) ) { + return handler( requestSettings ); + } + + // Inspect the URL of the request and check if the mock handler's url + // matches the url for this ajax request + if ( $.isFunction(handler.url.test) ) { + // The user provided a regex for the url, test it + if ( !handler.url.test( requestSettings.url ) ) { + return null; + } + } else { + // Look for a simple wildcard '*' or a direct URL match + var star = handler.url.indexOf('*'); + if (handler.url !== requestSettings.url && star === -1 || + !new RegExp(handler.url.replace(/[-[\]{}()+?.,\\^$|#\s]/g, "\\$&").replace(/\*/g, '.+')).test(requestSettings.url)) { + return null; + } + } + + // Inspect the data submitted in the request (either POST body or GET query string) + if ( handler.data && requestSettings.data ) { + if ( !isMockDataEqual(handler.data, requestSettings.data) ) { + // They're not identical, do not mock this request + return null; + } + } + // Inspect the request type + if ( handler && handler.type && + handler.type.toLowerCase() != requestSettings.type.toLowerCase() ) { + // The request type doesn't match (GET vs. POST) + return null; + } + + return handler; + } + + // If logging is enabled, log the mock to the console + function logMock( mockHandler, requestSettings ) { + if ( window.console && console.log ) { + var message = 'MOCK ' + requestSettings.type.toUpperCase() + ': ' + requestSettings.url; + var request = $.extend({}, requestSettings); + + if (typeof console.log === 'function') { + console.log(message, request); + } else { + try { + console.log( message + ' ' + JSON.stringify(request) ); + } catch (e) { + console.log(message); + } + } + } + } + + // Process the xhr objects send operation + function _xhrSend(mockHandler, requestSettings, origSettings) { + + // This is a substitute for < 1.4 which lacks $.proxy + var process = (function(that) { + return function() { + return (function() { + // The request has returned + this.status = mockHandler.status; + this.statusText = mockHandler.statusText; + this.readyState = 4; + + // We have an executable function, call it to give + // the mock handler a chance to update it's data + if ( $.isFunction(mockHandler.response) ) { + mockHandler.response(origSettings); + } + // Copy over our mock to our xhr object before passing control back to + // jQuery's onreadystatechange callback + if ( requestSettings.dataType == 'json' && ( typeof mockHandler.responseText == 'object' ) ) { + this.responseText = JSON.stringify(mockHandler.responseText); + } else if ( requestSettings.dataType == 'xml' ) { + if ( typeof mockHandler.responseXML == 'string' ) { + this.responseXML = parseXML(mockHandler.responseXML); + } else { + this.responseXML = mockHandler.responseXML; + } + } else { + this.responseText = mockHandler.responseText; + } + if( typeof mockHandler.status == 'number' || typeof mockHandler.status == 'string' ) { + this.status = mockHandler.status; + } + if( typeof mockHandler.statusText === "string") { + this.statusText = mockHandler.statusText; + } + // jQuery < 1.4 doesn't have onreadystate change for xhr + if ( $.isFunction(this.onreadystatechange || this.onload) ) { + if( mockHandler.isTimeout) { + this.status = -1; + } + (this.onreadystatechange || this.onload)( mockHandler.isTimeout ? 'timeout' : undefined ); + } else if ( mockHandler.isTimeout ) { + // Fix for 1.3.2 timeout to keep success from firing. + this.status = -1; + } + }).apply(that); + }; + })(this), + percentage = 10, + that = this, + progress = (function(that) { + return function() { + return (function() { + this.progressTimer = setTimeout(function () { + mockHandler.progress({ + lengthComputable: true, + loaded: percentage, + total: 100 + }); + percentage += 10; + if (percentage < 100) { + that.progressTimer = setTimeout(progress, (mockHandler.responseTime - mockHandler.progressWait) / 10 - 10); + } + }, mockHandler.progressRan ? 0 : mockHandler.progressWait || 0); + mockHandler.progressRan = true; + }).apply(that); + }; + })(this); + + if ( mockHandler.proxy ) { + // We're proxying this request and loading in an external file instead + _ajax({ + global: false, + url: mockHandler.proxy, + type: mockHandler.proxyType, + data: mockHandler.data, + dataType: requestSettings.dataType === "script" ? "text/plain" : requestSettings.dataType, + complete: function(xhr) { + mockHandler.responseXML = xhr.responseXML; + mockHandler.responseText = xhr.responseText; + mockHandler.status = xhr.status; + mockHandler.statusText = xhr.statusText; + that.responseTimer = setTimeout(process, mockHandler.responseTime || 0); + + if (mockHandler.mockProgress) { + progress(); + } + } + }); + } else { + // type == 'POST' || 'GET' || 'DELETE' + if ( requestSettings.async === false ) { + // TODO: Blocking delay + process(); + } else { + that.responseTimer = setTimeout(process, mockHandler.responseTime || 50); + + if (mockHandler.mockProgress) { + progress(); + } + } + } + } + + // Construct a mocked XHR Object + function xhr(mockHandler, requestSettings, origSettings, origHandler) { + // Extend with our default mockjax settings + mockHandler = $.extend(true, {}, $.mockjaxSettings, mockHandler); + + if (typeof mockHandler.headers === 'undefined') { + mockHandler.headers = {}; + } + if ( mockHandler.contentType ) { + mockHandler.headers['content-type'] = mockHandler.contentType; + } + + return { + status: mockHandler.status, + statusText: mockHandler.statusText, + readyState: 1, + open: function() { }, + send: function() { + origHandler.fired = true; + _xhrSend.call(this, mockHandler, requestSettings, origSettings); + }, + abort: function() { + clearTimeout(this.responseTimer); + clearTimeout(this.progressTimer); + }, + setRequestHeader: function(header, value) { + mockHandler.headers[header] = value; + }, + getResponseHeader: function(header) { + // 'Last-modified', 'Etag', 'content-type' are all checked by jQuery + if ( mockHandler.headers && mockHandler.headers[header] ) { + // Return arbitrary headers + return mockHandler.headers[header]; + } else if ( header.toLowerCase() == 'last-modified' ) { + return mockHandler.lastModified || (new Date()).toString(); + } else if ( header.toLowerCase() == 'etag' ) { + return mockHandler.etag || ''; + } else if ( header.toLowerCase() == 'content-type' ) { + return mockHandler.contentType || 'text/plain'; + } + }, + getAllResponseHeaders: function() { + var headers = ''; + $.each(mockHandler.headers, function(k, v) { + headers += k + ': ' + v + "\n"; + }); + return headers; + } + }; + } + + // Process a JSONP mock request. + function processJsonpMock( requestSettings, mockHandler, origSettings ) { + // Handle JSONP Parameter Callbacks, we need to replicate some of the jQuery core here + // because there isn't an easy hook for the cross domain script tag of jsonp + + processJsonpUrl( requestSettings ); + + requestSettings.dataType = "json"; + if(requestSettings.data && CALLBACK_REGEX.test(requestSettings.data) || CALLBACK_REGEX.test(requestSettings.url)) { + createJsonpCallback(requestSettings, mockHandler, origSettings); + + // We need to make sure + // that a JSONP style response is executed properly + + var rurl = /^(\w+:)?\/\/([^\/?#]+)/, + parts = rurl.exec( requestSettings.url ), + remote = parts && (parts[1] && parts[1] !== location.protocol || parts[2] !== location.host); + + requestSettings.dataType = "script"; + if(requestSettings.type.toUpperCase() === "GET" && remote ) { + var newMockReturn = processJsonpRequest( requestSettings, mockHandler, origSettings ); + + // Check if we are supposed to return a Deferred back to the mock call, or just + // signal success + if(newMockReturn) { + return newMockReturn; + } else { + return true; + } + } + } + return null; + } + + // Append the required callback parameter to the end of the request URL, for a JSONP request + function processJsonpUrl( requestSettings ) { + if ( requestSettings.type.toUpperCase() === "GET" ) { + if ( !CALLBACK_REGEX.test( requestSettings.url ) ) { + requestSettings.url += (/\?/.test( requestSettings.url ) ? "&" : "?") + + (requestSettings.jsonp || "callback") + "=?"; + } + } else if ( !requestSettings.data || !CALLBACK_REGEX.test(requestSettings.data) ) { + requestSettings.data = (requestSettings.data ? requestSettings.data + "&" : "") + (requestSettings.jsonp || "callback") + "=?"; + } + } + + // Process a JSONP request by evaluating the mocked response text + function processJsonpRequest( requestSettings, mockHandler, origSettings ) { + // Synthesize the mock request for adding a script tag + var callbackContext = origSettings && origSettings.context || requestSettings, + newMock = null; + + + // If the response handler on the moock is a function, call it + if ( mockHandler.response && $.isFunction(mockHandler.response) ) { + mockHandler.response(origSettings); + } else { + + // Evaluate the responseText javascript in a global context + if( typeof mockHandler.responseText === 'object' ) { + $.globalEval( '(' + JSON.stringify( mockHandler.responseText ) + ')'); + } else { + $.globalEval( '(' + mockHandler.responseText + ')'); + } + } + + // Successful response + jsonpSuccess( requestSettings, callbackContext, mockHandler ); + jsonpComplete( requestSettings, callbackContext, mockHandler ); + + // If we are running under jQuery 1.5+, return a deferred object + if($.Deferred){ + newMock = new $.Deferred(); + if(typeof mockHandler.responseText == "object"){ + newMock.resolveWith( callbackContext, [mockHandler.responseText] ); + } + else{ + newMock.resolveWith( callbackContext, [$.parseJSON( mockHandler.responseText )] ); + } + } + return newMock; + } + + + // Create the required JSONP callback function for the request + function createJsonpCallback( requestSettings, mockHandler, origSettings ) { + var callbackContext = origSettings && origSettings.context || requestSettings; + var jsonp = requestSettings.jsonpCallback || ("jsonp" + jsc++); + + // Replace the =? sequence both in the query string and the data + if ( requestSettings.data ) { + requestSettings.data = (requestSettings.data + "").replace(CALLBACK_REGEX, "=" + jsonp + "$1"); + } + + requestSettings.url = requestSettings.url.replace(CALLBACK_REGEX, "=" + jsonp + "$1"); + + + // Handle JSONP-style loading + window[ jsonp ] = window[ jsonp ] || function( tmp ) { + data = tmp; + jsonpSuccess( requestSettings, callbackContext, mockHandler ); + jsonpComplete( requestSettings, callbackContext, mockHandler ); + // Garbage collect + window[ jsonp ] = undefined; + + try { + delete window[ jsonp ]; + } catch(e) {} + + if ( head ) { + head.removeChild( script ); + } + }; + } + + // The JSONP request was successful + function jsonpSuccess(requestSettings, callbackContext, mockHandler) { + // If a local callback was specified, fire it and pass it the data + if ( requestSettings.success ) { + requestSettings.success.call( callbackContext, ( mockHandler.response ? mockHandler.response.toString() : mockHandler.responseText || ''), status, {} ); + } + + // Fire the global callback + if ( requestSettings.global ) { + trigger(requestSettings, "ajaxSuccess", [{}, requestSettings] ); + } + } + + // The JSONP request was completed + function jsonpComplete(requestSettings, callbackContext) { + // Process result + if ( requestSettings.complete ) { + requestSettings.complete.call( callbackContext, {} , status ); + } + + // The request was completed + if ( requestSettings.global ) { + trigger( "ajaxComplete", [{}, requestSettings] ); + } + + // Handle the global AJAX counter + if ( requestSettings.global && ! --$.active ) { + $.event.trigger( "ajaxStop" ); + } + } + + + // The core $.ajax replacement. + function handleAjax( url, origSettings ) { + var mockRequest, requestSettings, mockHandler; + + // If url is an object, simulate pre-1.5 signature + if ( typeof url === "object" ) { + origSettings = url; + url = undefined; + } else { + // work around to support 1.5 signature + origSettings.url = url; + } + + // Extend the original settings for the request + requestSettings = $.extend(true, {}, $.ajaxSettings, origSettings); + + // Iterate over our mock handlers (in registration order) until we find + // one that is willing to intercept the request + for(var k = 0; k < mockHandlers.length; k++) { + if ( !mockHandlers[k] ) { + continue; + } + + mockHandler = getMockForRequest( mockHandlers[k], requestSettings ); + if(!mockHandler) { + // No valid mock found for this request + continue; + } + + // Handle console logging + // logMock( mockHandler, requestSettings ); + + + if ( requestSettings.dataType === "jsonp" ) { + if ((mockRequest = processJsonpMock( requestSettings, mockHandler, origSettings ))) { + // This mock will handle the JSONP request + return mockRequest; + } + } + + + // Removed to fix #54 - keep the mocking data object intact + //mockHandler.data = requestSettings.data; + + mockHandler.progress = requestSettings.progress; + mockHandler.cache = requestSettings.cache; + mockHandler.timeout = requestSettings.timeout; + mockHandler.global = requestSettings.global; + + copyUrlParameters(mockHandler, origSettings); + + (function(mockHandler, requestSettings, origSettings, origHandler) { + mockRequest = _ajax.call($, $.extend(true, {}, origSettings, { + // Mock the XHR object + xhr: function() { return xhr( mockHandler, requestSettings, origSettings, origHandler ); } + })); + })(mockHandler, requestSettings, origSettings, mockHandlers[k]); + + return mockRequest; + } + + // We don't have a mock request, trigger a normal request + return _ajax.apply($, [origSettings]); + } + + /** + * Copies URL parameter values if they were captured by a regular expression + * @param {Object} mockHandler + * @param {Object} origSettings + */ + function copyUrlParameters(mockHandler, origSettings) { + //parameters aren't captured if the URL isn't a RegExp + if (!mockHandler.url instanceof RegExp) { + return; + } + //if no URL params were defined on the handler, don't attempt a capture + if (!mockHandler.hasOwnProperty('urlParams')) { + return; + } + var captures = mockHandler.url.exec(origSettings.url); + //the whole RegExp match is always the first value in the capture results + if (captures.length === 1) { + return; + } + captures.shift(); + //use handler params as keys and capture resuts as values + var i = 0, + capturesLength = captures.length, + paramsLength = mockHandler.urlParams.length, + //in case the number of params specified is less than actual captures + maxIterations = Math.min(capturesLength, paramsLength), + paramValues = {}; + for (i; i < maxIterations; i++) { + var key = mockHandler.urlParams[i]; + paramValues[key] = captures[i]; + } + origSettings.urlParams = paramValues; + } + + + // Public + + $.extend({ + ajax: handleAjax + }); + + $.mockjaxSettings = { + //url: null, + //type: 'GET', + log: function() { + if (window.console && window.console.log) { + var log = Function.prototype.bind.call(console.log, console); + log.apply(console, arguments); + } + }, + status: 200, + statusText: "OK", + responseTime: 500, + isTimeout: false, + contentType: 'text/plain', + response: '', + responseText: '', + responseXML: '', + proxy: '', + proxyType: 'GET', + + lastModified: null, + etag: '', + headers: { + etag: 'IJF@H#@923uf8023hFO@I#H#', + 'content-type' : 'text/plain' + } + }; + + $.mockjax = function(settings) { + var i = mockHandlers.length; + mockHandlers[i] = settings; + return i; + }; + $.mockjaxClear = function(i) { + if ( arguments.length == 1 ) { + mockHandlers[i] = null; + } else { + mockHandlers = []; + } + }; + $.mockjax.handler = function(i) { + if ( arguments.length == 1 ) { + return mockHandlers[i]; + } + }; +})(jQuery); diff --git a/tests/kendo-test-helpers.js b/tests/kendo-test-helpers.js new file mode 100644 index 00000000000..8d351dc79b5 --- /dev/null +++ b/tests/kendo-test-helpers.js @@ -0,0 +1,189 @@ +function stub(that, methods) { + var stubs = {}; + + if (typeof methods === "string") { + var obj = {}; + obj[methods] = $.noop; + methods = obj; + } + + $.each(methods, function(method, impl) { + stubs[method] = { calls: 0, args: [] }; + + that[method] = function() { + stubs[method].calls ++; + stubs[method].args.push(arguments); + return impl.apply(that, arguments); + } + }); + + that.calls = function(method) { + return stubs[method].calls; + } + + that.args = function(method, index) { + method = stubs[method]; + + index = index !== undefined ? index: method.args.length - 1; + return method.args[index]; + } + + return that; +} + +function arrayClose(a, b, tolerance) { + if (a.length != b.length) { + ok(false, "Arrays differ in size " + "(expected " + b.length + ", got " + a.length + " elements)"); + } else if (a.length) { + for (var i = 0; i < a.length; i++) { + if (a[i].length) { + arrayClose(a[i], b[i], tolerance, "Values at index " + i); + } else { + QUnit.close(a[i], b[i], tolerance, "Values at index " + i); + } + } + } else { + ok(true); + } +} + +function isBrazilTimezone() { + var d = new Date().toString(); + return d.indexOf("BRST") !== -1 || + d.indexOf("BRT") != -1 || + d.indexOf("South America Daylight Time") != -1 || + d.indexOf("South America Standard Time") != -1; +} + +function brazilTimezoneTest(testName, expected, callback ) { + if ( arguments.length === 2 ) { + callback = expected; + expected = null; + } + + if (isBrazilTimezone()) { + QUnit.test(testName, expected, callback); + } +} + +function triggerTouchEvent(element, type, info) { + info.target = element; + element.trigger($.Event(type, { originalEvent: { changedTouches: [ info ] }})); +} + +function press(element, x, y, id) { + triggerTouchEvent(element, "touchstart", { + pageX: x, + pageY: y, + clientX: x, + clientY: y, + identifier: id || 1 + }) +} + +function move(element, x, y, id) { + triggerTouchEvent(element, "touchmove", { + pageX: x, + pageY: y, + clientX: x, + clientY: y, + identifier: id || 1 + }) +} + +function release(element, x, y, id) { + triggerTouchEvent(element, "touchend", { + pageX: x, + pageY: y, + clientX: x, + clientY: y, + identifier: id || 1 + }) +} + +function mousewheel(element, delta) { + $(element).trigger($.Event("mousewheel", { originalEvent: { detail: delta * 3 } })); +} + +if (!$('link[rel=stylesheet][href*="kendo.common.css"]').length) { + $('head') + .append('') + .append(''); +} + +(function() { + var domContentsLength; + + var Widget = kendo.ui.Widget; + var init = Widget.fn.init; + var destroy = Widget.fn.destroy; + var widgets = []; + + Widget.fn.init = function() { + widgets.push(this); + init.apply(this, arguments); + } + + Widget.fn.destroy = function() { + widgets.splice(widgets.indexOf(this), 1); + destroy.apply(this, arguments); + } + + function getDomContentsLength() { + return $(document.body).children(":not(script,#editor-fixture)").length; + } + + $(function() { + QUnit.fixture = $("
").appendTo(document.body); + QUnit.config.fixture = ""; + domContentsLength = getDomContentsLength(); + }); + + QUnit.testDone(function( details ) { + QUnit.fixture.empty().attr("class", "").attr("style", "").css("height", "100px"); + + if (!QUnit.suppressCleanupCheck) { + var length = getDomContentsLength(); + + if (length > domContentsLength) { + console.warn(details.module, details.name, 'test did not clean DOM contents properly'); + } + + if (widgets.length) { + console.error.apply(console, [ details.module, details.name, 'active widgets left'].concat(widgets.map(function(widget) { + var name = widget.options.name; + + if (widget.element[0].className) { + name = name + "(" + widget.element[0].className + ")"; + } + + return name; + }))); + + widgets = []; + } + + domContentsLength = length; + } + }); +})(); + + +QUnit.extend( QUnit, { + close: function(actual, expected, maxDifference, message) { + var passes = (actual === expected) || Math.abs(actual - expected) <= maxDifference; + QUnit.push(passes, actual, expected, message); + }, + + notClose: function(actual, expected, minDifference, message) { + QUnit.push(Math.abs(actual - expected) > minDifference, actual, expected, message); + } +}); + +QUnit.brazilTimezoneTest = brazilTimezoneTest; +QUnit.config.testTimeout = 1500; +QUnit.config.reorder = false; + +var close = QUnit.close, + notClose = QUnit.notClose; + diff --git a/tests/listview/aria.js b/tests/listview/aria.js new file mode 100644 index 00000000000..acd15c2b633 --- /dev/null +++ b/tests/listview/aria.js @@ -0,0 +1,113 @@ +(function() { + var DataSource = kendo.data.DataSource, + dataSource; + + function setup(options) { + options = $.extend({ + template: "
  • ", + navigatable: true, + selectable: true, + dataSource: dataSource = new DataSource({ data: [1,2,3,4,5] }) + }, options); + return $("
      ").appendTo(QUnit.fixture).kendoListView(options); + } + + module("listview ARIA", { + setup: function() { + kendo.ns = "kendo-"; + $("
      ").appendTo(QUnit.fixture); + }, + teardown: function() { + kendo.destroy(QUnit.fixture); + $("#pager").remove(); + kendo.ns = ""; + } + }); + + test("ListView adds role list", function() { + var ul = setup(); + + equal(ul.attr("role"), "listbox"); + }); + + test("ListView adds aria-multiselectable if selectable=multiple", function() { + var ul = setup({ + selectable: "multiple" + }); + + equal(ul.attr("aria-multiselectable"), "true"); + }); + + test("ListView adds role listitem to all child elements", function() { + var ul = setup(); + + equal(ul.find("li").attr("role"), "option"); + }); + + test("ListView adds aria-selected=false to all child elements", function() { + var ul = setup(); + + equal(ul.find("li").attr("aria-selected"), "false"); + }); + + test("ListView adds aria-selected=true on SPACEBAR", function() { + var ul = setup(); + + ul.data("kendoListView").current(ul.children().eq(0)); + ul.trigger({ + type: "keydown", + keyCode: kendo.keys.SPACEBAR + }); + + equal(ul.data("kendoListView").current().attr("aria-selected"), "true"); + }); + + test("ListView adds id to the last selected item", function() { + var ul = setup(); + + ul.data("kendoListView").current(ul.children().eq(0)); + ul.trigger({ + type: "keydown", + keyCode: kendo.keys.SPACEBAR + }); + + equal(ul.data("kendoListView").current().attr("id"), "test_lv_active"); + }); + + test("ListView adds aria-activedescendant to the listview", function() { + var ul = setup(); + + ul.data("kendoListView").current(ul.children().eq(0)); + ul.trigger({ + type: "keydown", + keyCode: kendo.keys.SPACEBAR + }); + + equal(ul.attr("aria-activedescendant"), "test_lv_active"); + }); + + test("ListView preserves the id of the LI elements", function() { + var listview = setup({ + template: "
    • #=data#
    • ", + selectable: true, + navigatable: true + }).data("kendoListView"); + + listview.current(listview.element.children().eq(0)); + var li = listview.element.find(".k-state-focused"); + + equal(li.attr("id"), "custom[1]"); + }); + + test("ListView uses id of the LI element for the aria-activedescendant", function() { + var listview = setup({ + template: "
    • #=data#
    • ", + selectable: true, + navigatable: true + }).data("kendoListView"); + + listview.current(listview.element.children().eq(0)); + + equal(listview.element.attr("aria-activedescendant"), "custom[1]"); + }); +})(); diff --git a/tests/listview/editing.js b/tests/listview/editing.js new file mode 100644 index 00000000000..c43b16430c4 --- /dev/null +++ b/tests/listview/editing.js @@ -0,0 +1,470 @@ +(function() { + var DataSource = kendo.data.DataSource, + dataSource, + ul; + + function setup(options) { + var data = []; + for (var idx = 0; idx < 5; idx++) { + data.push({ id: idx, foo: "foo " + idx }); + } + + options = $.extend({ + template: "
    • ${foo}
    • ", + dataSource: dataSource = new DataSource({ + transport: { + read: function(options) { + options.success(data); + }, + destroy: function() { + } + }, + schema: { + model: { + id: "id", + fields: { + id: { type: "number", defaultValue: -1 }, + foo: { type: "string" } + } + } + } + }) + }, options); + return ul.kendoListView(options).data("kendoListView"); + } + + module("listView editing", { + setup: function() { + ul = $("
        ").appendTo(QUnit.fixture); + }, + teardown: function() { + kendo.destroy(QUnit.fixture); + ul.remove(); + } + }); + + test("default edit template is empty string", function() { + var listView = setup(); + + equal(listView.editTemplate({}), ""); + }); + + test("editTemplate options defined", function() { + var editTemplate = "
      • edit template
      • ", + listView = setup({ editTemplate: editTemplate }); + + equal(listView.editTemplate({}), editTemplate); + }); + + test("edit renders editTemplate for the current item", function() { + var editTemplate = "
      • template
      • ", + listView = setup({ editTemplate: editTemplate }); + + listView.edit(listView.element.children().first()); + equal(listView.element.children().first().html(), "template"); + ok(listView.element.children().first().hasClass("k-edit-item")); + }); + + test("edit binds the edit template", function() { + var listView = setup({ editTemplate: "
      • edit ${foo}
      • " }); + + listView.edit(listView.element.children().first()); + equal(listView.element.children().first().html(), "edit foo 0"); + }); + + test("edit instantiates editable for edited item", function() { + var listView = setup({ editTemplate: "
      • ${foo}
      • " }); + + listView.edit(listView.element.children().first()); + ok(listView.element.children().first().data("kendoEditable")); + ok(listView.editable); + }); + + test("editable is destroyed on refresh", function() { + var listView = setup({ editTemplate: "
      • ${foo}
      • " }); + + listView.edit(listView.element.children().first()); + dataSource.read(); + + ok(!listView.editable); + }); + + test("item is refreshed on itemchange", function() { + var listView = setup(); + dataSource.get(0).set("foo", "bar"); + + equal(listView.element.children().first().text(), "bar"); + }); + + test("edited item is not refreshed on itemchange", function() { + var listView = setup({ editTemplate: "
      • ${foo}
      • " }); + listView.edit(listView.element.find("li:first")); + dataSource.get(0).set("foo", "bar"); + + ok(listView.element.find("li:first").hasClass("k-edit-item")); + equal(listView.element.find("li:first").text(), "foo 0"); + }); + + test("correct model is passed to editable", function() { + var listView = setup({ editTemplate: "
      • " }); + + listView.edit(listView.element.children().first()); + equal(listView.editable.options.model, dataSource.get(0)); + }); + + test("edit item triggers edit event", function() { + var called = false, + listView = setup({ + editTemplate: "
      • ", + edit: function() { + called = true; + } + }); + + listView.edit(listView.element.children().first()); + ok(called); + }); + + test("clicking the cancel button raises the cancel event", 2, function() { + var called = false, + listView = setup({ + editTemplate: '
      • ', + cancel: function(e) { + ok(e.model); + equal(e.container.length, 1); + } + }); + + listView.edit(listView.element.children().first()); + + listView.element.find(".k-cancel-button").click(); + }); + + test("preventing the cancel event leaves the item in edit mode", function() { + var called = false, + listView = setup({ + editTemplate: '
      • ', + cancel: function(e) { + e.preventDefault(); + } + }); + + listView.edit(listView.element.children().first()); + + listView.element.find(".k-cancel-button").click(); + + equal(listView.element.find(".k-cancel-button").length, 1); + }); + + test("item and model is send to edit event arguments", function() { + var args = {}, + listView = setup({ + editTemplate: "
      • ", + edit: function() { + args = arguments[0]; + } + }); + + listView.edit(listView.element.children().first()); + + equal(args.model, dataSource.get(0)); + equal(args.item[0], listView.element.children()[0]); + }); + + test("save destroys the editable", function() { + var listView = setup({ editTemplate: "
      • ${foo}
      • " }); + + listView.edit(listView.element.children().first()); + listView.save(); + + ok(!listView.element.children().first().data("kendoEditable")); + ok(!listView.editable); + }); + + test("save renders item template", function() { + var listView = setup({ editTemplate: "
      • edit ${foo}
      • " }); + + listView.edit(listView.element.children().first()); + listView.save(); + + equal(listView.element.children().first().html(), "foo 0"); + }); + + test("save renders item alternating template", function() { + var listView = setup({ + editTemplate: "
      • edit ${foo}
      • ", + altTemplate: "
      • bar
      • " + }); + + listView.edit(listView.element.children().eq(1)); + listView.save(); + + equal(listView.element.children().eq(1).html(), "bar"); + }); + + test("edit closes previous edited item", function() { + var listView = setup({ editTemplate: "
      • ${foo}
      • " }); + + listView.edit(listView.element.children().eq(0)); + listView.edit(listView.element.children().eq(1)); + + ok(!listView.element.children().eq(0).data("kendoEditable")); + ok(listView.element.children().eq(1).data("kendoEditable")); + }); + + test("edit cancels previous edited item changes", function() { + var listView = setup({ editTemplate: "
      • ${foo}
      • " }); + + listView.edit(listView.element.children().eq(0)); + dataSource.get(0).set("foo", "bar"); + listView.edit(listView.element.children().eq(1)); + + equal(dataSource.get(0).foo, "foo 0"); + }); + + test("save does not close edited item if validation fails", function() { + var listView = setup({ editTemplate: '
      • ' }); + + listView.edit(listView.element.children().eq(0)); + listView.element.find(":input").val(""); + listView.save(); + + ok(listView.element.children().eq(0).data("kendoEditable")); + }); + + test("save calls DataSource sync", function() { + var listView = setup({ editTemplate: '
      • ' }), + sync = stub(dataSource, "sync"); + + listView.edit(listView.element.children().eq(0)); + listView.element.find(":input").val(""); + listView.save(); + + ok(sync.calls("sync")); + }); + + test("remove hides the item", function() { + var listView = setup(), + item = listView.element.children().first(); + + listView.remove(item); + + ok(!item.is(":visible")); + }); + + test("remove calls dataSource remove", function() { + var listView = setup(), + removeMethod = stub(dataSource, "remove"); + + listView.remove(listView.element.children().first()); + + ok(removeMethod.calls("remove")); + ok(removeMethod.args("remove", 0)[0] instanceof kendo.data.Model); + equal(removeMethod.args("remove", 0)[0].get("id"), 0); + }); + + test("remove triggers remove event", function() { + var called = false, + listView = setup({ + remove: function() { + called = true; + } + }); + + listView.remove(listView.element.children().first()); + + ok(called); + }); + + test("remove event pass model and item as arguments", function() { + var args, + listView = setup({ + remove: function() { + args = arguments[0]; + } + }), + item = listView.element.children().first(); + + listView.remove(item); + + equal(args.item[0], item[0]); + equal(args.model.id, 0); + }); + + test("remove event prevention", function() { + var listView = setup({ + remove: function(e) { + e.preventDefault(); + } + }), + item = listView.element.children().first(); + + listView.remove(item); + + ok(item.is(":visible")); + ok(dataSource.get(0)); + }); + + test("remove calls dataSource sync", function() { + var listView = setup(), + syncMethod= stub(dataSource, "sync"); + + listView.remove(listView.element.children().first()); + + ok(syncMethod.calls("sync")); + }); + + test("add adds new model in DataSource", function() { + var listView = setup(); + listView.add(); + + ok(dataSource.at(0).isNew()); + }); + + test("add adds new model before first item in the view", function() { + var listView = setup(); + dataSource.query({ page: 2, pageSize: 1 }); + listView.add(); + + ok(dataSource.at(1).isNew()); + }); + + test("add adds new model if DataSource has no data", function() { + var listView = setup({ + template: "
      • ", + dataSource: { + schema: { + model: { + id: "id" + } + } + } + }); + listView.add(); + + ok(listView.dataSource.at(0).isNew()); + }); + + test("add edit first item", function() { + var listView = setup({ + editTemplate: '
      • ' + }); + + listView.add (); + + var item = listView.element.children().first(); + ok(item.hasClass("k-edit-item")); + equal(item.find(":input").val(), ""); + equal(listView.editable.element[0], item[0]); + }); + + test("add triggers edit event", function() { + var args, + listView = setup({ + editTemplate: '
      • ', + edit: function() { + args = arguments[0]; + } + }); + + listView.add(); + + var item = listView.element.children().first(); + equal(args.item[0], item[0]); + ok(args.model.isNew()); + }); + + test("add cancels previous edited item changes", function() { + var listView = setup({ editTemplate: "
      • ${foo}
      • " }); + + listView.edit(listView.element.children().eq(0)); + dataSource.get(0).set("foo", "bar"); + listView.add(); + + equal(dataSource.get(0).foo, "foo 0"); + }); + + test("cancel calls cancelChanges of DataSource for the edited item", function() { + var listView = setup({ + editTemplate: '
      • ' + }); + + var cancelChanges = stub(dataSource, "cancelChanges"); + listView.edit(ul.children().eq(0)); + listView.cancel(); + + equal(cancelChanges.calls("cancelChanges"), 1); + equal(cancelChanges.args("cancelChanges", 0)[0].id, 0); + }); + + test("cancel does not call cancelChanges of DataSource if no edited item", function() { + var listView = setup({ + editTemplate: '
      • ' + }); + + var cancelChanges = stub(dataSource, "cancelChanges"); + listView.cancel(); + + equal(cancelChanges.calls("cancelChanges"), 0); + }); + + test("cancel revert the item to item template", function() { + var listView = setup({ + editTemplate: '
      • ' + }); + + listView.edit(ul.children().eq(0)); + listView.cancel(); + + equal(ul.children().eq(0).html(), "foo 0"); + }); + + test("cancel revert the item to item alternative template", function() { + var listView = setup({ + editTemplate: '
      • ', + altTemplate: "
      • bar
      • " + }); + + listView.edit(ul.children().eq(1)); + listView.cancel(); + + equal(ul.children().eq(1).html(), "bar"); + }); + + test("save event is triggered", function() { + var called = false, + listView = setup({ + editTemplate: "
      • ", + save: function() { + called = true; + } + }); + + listView.edit(listView.element.children().first()); + listView.save(); + ok(called); + }); + + test("save event can be prevented", function() { + var listView = setup({ + editTemplate: "
      • ", + save: function(e) { + e.preventDefault(); + } + }); + + listView.edit(listView.element.children().first()); + listView.save(); + ok(listView.element.children().first().hasClass("k-edit-item")); + }); + + test("edit after add cancels previous edit item", function() { + var listView = setup({ editTemplate: "
      • ${foo}
      • " }); + + listView.add(); + listView.edit(listView.element.children().eq(1)); + + ok(listView.element.children().eq(0).hasClass("k-edit-item")); + equal(dataSource.get(0).foo, "foo 0"); + }); +})(); diff --git a/tests/listview/listview.js b/tests/listview/listview.js new file mode 100644 index 00000000000..1f1d3f29b15 --- /dev/null +++ b/tests/listview/listview.js @@ -0,0 +1,395 @@ +(function() { + var DataSource = kendo.data.DataSource, + ul, + dataSource; + + + function setup(options) { + options = $.extend({ + template: "
      • ", + navigatable: true, + dataSource: dataSource = new DataSource({ data: [1,2,3,4,5] }) + }, options); + return ul.kendoListView(options); + } + + module("listview initialization", { + setup: function() { + kendo.ns = "kendo-"; + + $.fn.press = function(key, ctrl, shift) { + return this.trigger( { type: "keydown", keyCode: key, ctrlKey: ctrl, shiftKey: shift } ); + }; + + ul = $("
          ").appendTo(QUnit.fixture); + $("
          ").appendTo(QUnit.fixture); + }, + teardown: function() { + kendo.destroy(QUnit.fixture); + kendo.ns = ""; + $("#pager").remove(); + ul.remove(); + } + }); + + test("kendoListView attaches listView to element", function() { + var ul = setup(); + + ok(ul.data("kendoListView") instanceof kendo.ui.ListView); + }); + + test("k-widget and k-listview classes are applied on element", function() { + var ul = setup(); + + ok(ul.hasClass("k-widget")); + ok(ul.hasClass("k-listview")); + }); + + test("renders item for dataSource items", function() { + var ul = setup(); + + equal(ul.find("li").length, 5); + }); + + test("options as array is used for dataSource", function() { + var div = $("
          ").appendTo(QUnit.fixture).kendoListView([1,2,3]), + dataSource = div.data("kendoListView").dataSource.data(); + + equal(dataSource.length, 3); + }); + + test("dataBound event should be raised when bound", function() { + var called = false, + ul = setup({ + dataBound: function() { + called = true; + } + }); + ok(called); + }); + + test("cancelling databinding event prevents refresh", function() { + var ul = setup({ + dataBinding: function(e) { + e.preventDefault(); + } + }); + + equal(ul.find("li").length, 0); + }); + + test("DataSource change action is passed to databinding event", 3, function() { + var listView = setup().data("kendoListView"); + + listView.bind("dataBinding", function(e) { + equal(e.action, "add"); + equal(e.items.length, 1); + equal(e.index, 1); + }); + + listView.dataSource.insert(1, {}); + }); + + test("autoBind false does not populate listView", function() { + var ul = setup({autoBind: false}); + equal(ul.find("li").length, 0); + }); + + test("altTemplate defaults to template if is not set", function() { + var listView = setup({ template: "
        • 1
        • " }).data("kendoListView"); + + equal(listView.template({}), "
        • 1
        • "); + equal(listView.altTemplate({}), "
        • 1
        • "); + }); + + test("altTemplate defined", function() { + var listView = setup({ template: "
        • 1
        • ", altTemplate: "
        • 2
        • " }).data("kendoListView"); + + equal(listView.template({}), "
        • 1
        • "); + equal(listView.altTemplate({}), "
        • 2
        • "); + }); + + test("altTemplate is rendered", function() { + var ul = setup({ template: "
        • 1
        • ", altTemplate: "
        • 2
        • " }); + + equal(ul.children().eq(0).html(), "1"); + equal(ul.children().eq(1).html(), "2"); + }); + + test("progress mask is shown when request starts", function() { + var ul = setup(); + + dataSource.bind("progress", function() { + equal(ul.find("div.k-loading-mask").length, 1); + }); + dataSource.read(); + }); + + test("progress mask is hidden when request finish", function() { + var ul = setup(); + + dataSource.read(); + + equal(ul.find("div.k-loading-mask").length, 0); + }); + + test("selectable false does not instantiate Selectable object", function() { + var ul = setup({ selectable: false }); + ok(!ul.data("kendoListView").selectable); + }); + + test("selectable true instantiate Selectable object", function() { + var ul = setup({ selectable: true }); + ok(ul.data("kendoListView").selectable); + }); + + test("selectable true instantiate Selectable object", function() { + var listView = setup({ selectable: true }).data("kendoListView"); + + ok(listView.selectable); + ok(!listView.selectable.options.multiple); + }); + + test("selectable multiple set multiple mode of the selectable", function() { + var listView = setup({ selectable: "multiple" }).data("kendoListView"); + + ok(listView.selectable.options.multiple); + }); + + test("focusing grid element focus first item ", function() { + var listView = setup(); + listView.focus(); + ok(listView.find("li").first().is(".k-state-focused")); + }); + + test("down arrow moves focus on the next row same cell", function() { + var listView = setup(); + listView.focus().press(kendo.keys.DOWN); + ok(listView.find("li:eq(1)").hasClass("k-state-focused")); + }); + + test("right arrow moves focus on the next cell on the same row", function() { + var listView = setup(); + listView.focus().press(kendo.keys.RIGHT); + ok(listView.find("li:eq(1)").hasClass("k-state-focused")); + }); + + test("left arrow moves focus on the prev cell on the same row", function() { + var listView = setup(); + listView.focus().press(kendo.keys.RIGHT).press(kendo.keys.LEFT); + ok(listView.find("li:eq(0)").hasClass("k-state-focused")); + }); + + test("up arrow moves focus on the prev row same cell", function() { + var listView = setup(); + listView.focus().press(kendo.keys.DOWN).press(kendo.keys.UP); + ok(listView.find("li:eq(0)").hasClass("k-state-focused")); + }); + + test("space key select the focused item", function() { + var listView = setup({ selectable: true }); + + listView.focus().press(kendo.keys.DOWN).press(kendo.keys.SPACEBAR); + + ok(listView.find("li:eq(1)").hasClass("k-state-selected")); + }); + + test("ctrl + space key when multiple selectoin is enabled persist the selected items", function() { + var listView = setup({ selectable: "multiple" }); + + listView.focus().press(kendo.keys.DOWN).press(kendo.keys.SPACEBAR); + listView.press(kendo.keys.DOWN).press(kendo.keys.SPACEBAR, true); + + equal(listView.find(".k-state-selected").length, 2); + ok(listView.find("li:eq(1)").hasClass("k-state-selected")); + ok(listView.find("li:eq(2)").hasClass("k-state-selected")); + }); + + test("space key on already selected item when multiple selectoin is enabled unselects the item", function() { + var listView = setup({ selectable: "multiple" }); + + listView.focus().press(kendo.keys.DOWN).press(kendo.keys.SPACEBAR).press(kendo.keys.SPACEBAR, true); + + ok(!listView.find("li:eq(1)").hasClass("k-state-selected")); + }); + + test("select without arguments returns selected items", function() { + var ul = setup({ selectable: true }), + selected; + + ul.find("li:first").addClass("k-state-selected"); + + selected = ul.data("kendoListView").select(); + equal(selected.length, 1); + }); + + test("select with arguments mark the arguments as selected", function() { + var ul = setup({ + selectable: true + }), + item = ul.find("li:eq(0)"); + + ul.data("kendoListView").select(item); + + ok(item.hasClass("k-state-selected")); + }); + + test("select clears previously selected items if single select", function() { + var ul = setup({ + selectable: true + }), + items = ul.children(); + items.eq(0).addClass("k-state-selected"); + ul.data("kendoListView").select(items.eq(1)); + + ok(!items.eq(0).hasClass("k-state-selected")); + ok(items.eq(1).hasClass("k-state-selected")); + }); + + test("select persist previously selected items if multi select", function() { + var ul = setup({ + selectable: "multiple" + }), + items = ul.children(); + items.eq(0).addClass("k-state-selected"); + ul.data("kendoListView").select(items.eq(1)); + + ok(items.eq(0).hasClass("k-state-selected")); + ok(items.eq(1).hasClass("k-state-selected")); + }); + + test("select with array of items as argument select first if single select", function() { + var ul = setup({ + selectable: true + }), + items = ul.children(); + + ul.data("kendoListView").select(items); + + ok(items.eq(0).hasClass("k-state-selected")); + ok(!items.eq(1).hasClass("k-state-selected")); + ok(!items.eq(2).hasClass("k-state-selected")); + }); + + test("clearSelection clears selected items", function() { + var listView = setup({ + selectable: true + }).data("kendoListView"), + item = listView.element.find("li:eq(1)").addClass("k-state-selected"); + + listView.clearSelection(); + + ok(!item.hasClass("k-state-selected")); + }); + + test("clearSelection triggers change event", function() { + var triggered = false, + listView = setup({ + selectable: true, + change: function() { + triggered = true; + } + }).data("kendoListView"), + item = listView.element.find("li:eq(1)").addClass("k-state-selected"); + + listView.clearSelection(); + + ok(triggered); + }); + + test("resetting dataSource detaches the previouse events",1, function() { + var listView = new kendo.ui.ListView($("
            ").appendTo(QUnit.fixture), { template: "
          • " }); + + var dataSource = listView.dataSource; + listView._dataSource(); + + listView.bind("dataBound", function() { + ok(false, "Change event is not detached"); + }); + + dataSource.read(); + notStrictEqual(listView.dataSource, dataSource); + }); + + test("resetting DataSource rebinds the widget", function() { + var listView = new kendo.ui.ListView($("
              ").appendTo(QUnit.fixture), { template: "
            • " }); + + listView.setDataSource(new kendo.data.DataSource({ + data:[{text: 1, value: 1}, {text:2, value:2}] + })); + + equal(listView.element.find("li").length, 2); + }); + + test("pageable option initialize pager", function() { + var listView = setup({ pageable: { pagerId: "pager" } }); + + ok($("#pager").data("kendoPager") instanceof kendo.ui.Pager); + }); + + test("listview DataSource is applied on the pager", function() { + var listView = setup({ pageable: { pagerId: "pager" } }).data("kendoListView"); + var pager = $("#pager").data("kendoPager"); + + ok(pager.dataSource === listView.dataSource); + }); + + test("listview pageable settings are applied on the pager", function() { + var listView = setup({ + pageable: { + pagerId: "pager", + selectTemplate: "
            • foo
            • " + } + }) + .data("kendoListView"); + var pager = $("#pager").data("kendoPager"); + + equal(pager.options.selectTemplate, "
            • foo
            • "); +}); + +test("uid is set to item wrapper", function() { + var listView = setup({ + dataSource: { + data: [{ foo: 1 }, { foo: 2 }] + } + }).data("kendoListView"), + view = listView.dataSource.view(), + items = listView.items(); + + equal(items.eq(0).attr(kendo.attr("uid")), view[0].uid); + equal(items.eq(1).attr(kendo.attr("uid")), view[1].uid); +}); + +test("uid is set to item wrapper on dataSource change", function() { + var listView = setup({ + dataSource: { + data: [{ foo: 1 }, { foo: 2 }] + } + }).data("kendoListView"); + + listView.dataSource.view()[0].set("foo", 3); + + var view = listView.dataSource.view(), + items = listView.items(); + + equal(items.eq(0).attr(kendo.attr("uid")), view[0].uid); + equal(items.eq(1).attr(kendo.attr("uid")), view[1].uid); +}); + +test("correct item is updated when model itemchange changes the sorting order", function() { + var listView = setup({ + dataSource: { + data: [{ foo: 1 }, { foo: 2 }], + sort: {field: "foo", dir: "asc"} + } + }).data("kendoListView"); + + listView.dataSource.at(0).set("foo", 3); + + var view = listView.dataSource.view(), + items = listView.items(); + + equal(items.eq(0).attr(kendo.attr("uid")), view[1].uid); + equal(items.eq(1).attr(kendo.attr("uid")), view[0].uid); +}); +})(); diff --git a/tests/listview/mvvm.js b/tests/listview/mvvm.js new file mode 100644 index 00000000000..fae741d5486 --- /dev/null +++ b/tests/listview/mvvm.js @@ -0,0 +1,281 @@ +(function() { + module("listview mvvm", { + setup: function() { + QUnit.fixture.append('\ + \ + \ + \ + '); + + window.dataBound = function() { + ok(true); + } + }, + teardown: function() { + window.dataBound = null; + kendo.destroy(QUnit.fixture); + } + }); + + test("initializes a listview when data role is listview", function() { + var dom = $('
              ').appendTo(QUnit.fixture); + + kendo.bind(dom); + + ok(dom.data("kendoListView") instanceof kendo.ui.ListView); + }); + + test("initalizes data source", function() { + var dom = $('
              ').appendTo(QUnit.fixture); + + kendo.bind(dom, { items: ["foo", "bar"] } ); + + equal(dom.data("kendoListView").dataSource.view()[0], "foo"); + equal(dom.data("kendoListView").dataSource.view()[1], "bar"); + }); + + test("binding listview initialized before binding", function() { + var dom = $('
              ').appendTo(QUnit.fixture); + + var observable = kendo.observable({ items: [{text:"foo"}, {text:"bar"}]}); + + dom.kendoListView(); + + kendo.bind(dom, observable); + + equal(dom.data("kendoListView").dataSource.at(0).text, "foo"); + }); + + test("binding listview initialized after binding", function() { + var dom = $('
              ').appendTo(QUnit.fixture); + + var observable = kendo.observable({ items: [{text:"foo"}, {text:"bar"}]}); + + kendo.bind(dom, observable); + + dom.kendoListView(); + + equal(dom.data("kendoListView").dataSource.at(0).text, "foo"); + }); + + test("binding template", function() { + var dom = $('
              ').appendTo(QUnit.fixture); + + var observable = kendo.observable({ items: [{text:"foo"}, {text:"bar"}] }); + + kendo.bind(dom, observable); + + equal($.trim(dom.data("kendoListView").element.children().first().html()), "foo"); + }); + + test("binding template containing binding attributes", function() { + var dom = $('
              ').appendTo(QUnit.fixture); + + var observable = kendo.observable({ items: [{text:"foo"}, {text:"bar"}] }); + + kendo.bind(dom, observable); + + equal($.trim(dom.data("kendoListView").element.children().first().html()), 'foo'); + }); + + test("binding altTemplate", function() { + var dom = $('
              ').appendTo(QUnit.fixture); + + var observable = kendo.observable({ items: [{text:"foo"}, {text:"bar"}] }); + + kendo.bind(dom, observable); + + equal($.trim(dom.data("kendoListView").element.children().eq(1).html()), "bar"); + }); + + test("binding editTemplate", function() { + var dom = $('
              ').appendTo(QUnit.fixture); + + var observable = kendo.observable({ items: [{text:"foo"}, {text:"bar"}] }); + + kendo.bind(dom, observable); + + dom.data("kendoListView").edit(dom.children().eq(0)); + + equal($.trim(dom.data("kendoListView").element.find(":input:first").val()), "foo"); + }); + + test("updating an item from the data source updates the corresponding listview item", function() { + var dom = $('
              ').appendTo(QUnit.fixture); + + var observable = kendo.observable({ items: [{text:"foo"}, {text:"bar"}] }); + + kendo.bind(dom, observable); + + observable.items[0].set("text", "baz"); + + equal($.trim(dom.data("kendoListView").element.children().first().text()), "baz"); + }); + + test("destroys binding targets when datasource changes", function() { + var dom = $('
              ').appendTo(QUnit.fixture); + + var observable = kendo.observable({ items: [{text:"foo"}, {text:"bar"}] }); + + kendo.bind(dom, observable); + dom.data("kendoListView").refresh(); + + equal(observable.items[0]._events["change"].length, 2); //1 for the text and 1 because the observable array tracks its items + }); + + test("destroys detaches the events to widget", function() { + var dom = $('
              ').appendTo(QUnit.fixture); + + var observable = kendo.observable({ items: [{text:"foo"}, {text:"bar"}] }); + + kendo.bind(dom, observable); + kendo.unbind(dom); + + var listView = dom.data("kendoListView"); + equal(listView ._events["dataBound"].length, 0); + equal(listView._events["dataBinding"].length, 0); + }); + + test("dataBound event is raised if attached as option", 2, function() { + var dom = $('
              ').appendTo(QUnit.fixture); + + var observable = kendo.observable({ + items: [{text:"foo"}, {text:"bar"}] + }); + + kendo.bind(dom, observable); + }); + + test("dataBound event is raised if attached as option to a already initialized listview", 1, function() { + var dom = $('
              ').appendTo(QUnit.fixture).kendoListView(); + + var observable = kendo.observable({ + items: [{text:"foo"}, {text:"bar"}] + }); + + kendo.bind(dom, observable); + }); + + + test("binding visible to true shows the listview", function() { + var dom = $('
              ').appendTo(QUnit.fixture); + + kendo.bind(dom, { visible: true }); + + var listview = dom.data("kendoListView"); + + ok(listview.wrapper.css("display") != "none", "listview is visible"); + }); + + test("binding visible to false hides the listview", function() { + var dom = $('
              ').appendTo(QUnit.fixture); + + kendo.bind(dom, { visible: false }); + + var listview = dom.data("kendoListView"); + + ok(listview.wrapper.css("display") == "none", "listview is not visible"); + }); + + test("binding invisible to true hides the listview", function() { + var dom = $('
              ').appendTo(QUnit.fixture); + + kendo.bind(dom, { invisible: true }); + + var listview = dom.data("kendoListView"); + + ok(listview.wrapper.css("display") == "none", "listview is invisible"); + }); + + test("binding invisible to false shows the listview", function() { + var dom = $('
              ').appendTo(QUnit.fixture); + + kendo.bind(dom, { invisible: false }); + + var listview = dom.data("kendoListView"); + + ok(listview.wrapper.css("display") != "none", "listview is not invisible"); + }); + + test("setting autobind when bound to DataSource", function() { + var dom = $('
              ').appendTo(QUnit.fixture); + + var dataSource = new kendo.data.DataSource({ + data: [{text:"foo"}, {text:"bar"}] + }); + + var observable = kendo.observable({ + dataSource: dataSource + }); + + kendo.bind(dom, observable); + var listView = dom.data("kendoListView"); + + ok(!listView.wrapper.children().length); + }); + + test("binding selectable to true", function() { + var dom = $('
              ').appendTo(QUnit.fixture); + + kendo.bind(dom); + + var listview = dom.data("kendoListView"); + + ok(listview.selectable, "listview is not selectable"); + }); + + test("binding navigatable to true", function() { + var dom = $('
              ').appendTo(QUnit.fixture); + + kendo.bind(dom); + + var listview = dom.data("kendoListView"); + + ok(listview.options.navigatable, "listview is not navigatable"); + }); + + test("binds event handlers in template to root view model when item changes", function() { + var dom = $('
              ').appendTo(QUnit.fixture); + + var observable = kendo.observable({ + dataSource: [{ text:"foo" }] + }); + + stub(observable, "rootHandler"); + + kendo.bind(dom, observable); + + observable.dataSource[0].set("text", "bar"); + + dom.find("div strong").click(); + + equal(observable.calls("rootHandler"), 1); + equal($.trim(dom.find("div span").html()), "foo"); + equal($.trim(dom.find("div strong").html()), "bar"); + }); + + test("setOptions changes template", function() { + var dom = $('
              ').appendTo(QUnit.fixture); + + var observable = kendo.observable({ items: [{text:"foo"}, {text:"bar"}] }); + + kendo.bind(dom, observable); + + var listView = dom.data("kendoListView"); + listView.setOptions({ template: "
              template
              " }); + listView.refresh(); + + var firstItemHtml = $.trim(listView.element.children().first().html()); + equal(firstItemHtml, "template"); + }); +})(); diff --git a/tests/menu/api.js b/tests/menu/api.js new file mode 100644 index 00000000000..755100e0458 --- /dev/null +++ b/tests/menu/api.js @@ -0,0 +1,357 @@ +(function() { +var isRaised, isOpenRaised, isCloseRaised, isSelectRaised, selected; + +function getRootItem(index) { + return $('#menu').find('> .k-item > .k-link').eq(index) +} + + //handlers +function Open() { + isOpenRaised = true; +} + +function Close() { + isCloseRaised = true; +} + +function Select() { + selected++; + isSelectRaised = true; +} + + +var onLoadMenu; + +function Load() { + isRaised = true; + onLoadMenu = getMenu(); +} + + +var menu, + CLICK = kendo.support.touch ? "touchend" : "click"; + +module("menu api", { + setup: function () { + QUnit.fixture.append( + ' ' + ); + menu = new kendo.ui.Menu("#menu", { animation: false, select: Select, open: Open, close: Close, hoverDelay: 0, popupCollision: "flip" }); + }, + teardown: function() { + kendo.destroy(QUnit.fixture); + } +}); + +test('click method should set handled flag and select event is only fired once', function() { + var link = getRootItem(7); + var isCalled = false; + + var e = { target: link[0], stopPropagation: function () {}, preventDefault: function () {} }; + + selected = 0; + menu._click(e); + + ok(e.handled); + ok(selected == 1); +}); + +asyncTest('hovering root item opens it and raises open event', function() { + var item = getRootItem(1).parent(); + + menu._mouseenter({ currentTarget: item[0], delegateTarget: menu.element[0] }); + + setTimeout(function () { + ok(isOpenRaised); + start(); + }, 1); +}); + +asyncTest('leaving root item closes it and raises close event', 1, function() { + var item = getRootItem(1).parent(); + + menu._mouseenter({ currentTarget: item[0], delegateTarget: menu.element[0] }); + + menu.bind("close", function() { + ok(true); + start(); + }) + + setTimeout(function () { + menu._mouseleave({ currentTarget: item[0] }); + }, 1); +}); + +test('clicking should raise select event', function() { + var link = getRootItem(2); + + isSelectRaised = false; + + link.trigger(CLICK); + + ok(isSelectRaised); +}); + +test('clicking on sub item should close the menu', function() { + var link = getRootItem(1); + + menu._mouseenter({currentTarget: link[0]}); + + var e = { stopPropagation: function () {}, preventDefault: function () {} }; + + link.trigger(CLICK); + + ok(link.parent().is(":visible")); +}); + +asyncTest('open should open item even if disabled', function() { + var item = getRootItem(6).parent(); + + menu.disable(item); + menu.open(item); + + setTimeout(function () { + ok(item.find('.k-group').is(":visible")); + start(); + }, 1); +}); + +asyncTest('open should apply max-height and overflow styles to group UL', 3, function() { + var item = getRootItem(1).parent(), + ul = item.find(".k-group"); + + menu.open(item); + + setTimeout(function () { + var maxHeightStyle = parseInt(ul.css("max-height"), 10), + overflowStyle = ul.css("overflow"), + windowHeight = parseInt($(window).height(), 10); + + ok(!isNaN(maxHeightStyle)); + equal(overflowStyle, "auto"); + equal(maxHeightStyle, windowHeight); + start(); + }, 30); +}); + +asyncTest('open should not apply max-height and overflow styles to group UL if it has children groups', function() { + var item = getRootItem(0).parent(), + ul = item.find(".k-group").css({maxHeight: 1, overflow: "auto"}); + + menu.open(item); + + setTimeout(function () { + var maxHeightStyle = parseInt(ul.css("max-height"), 10), + overflowStyle = ul.css("overflow"); + + ok(isNaN(maxHeightStyle)); + notEqual(overflowStyle, "auto"); + start(); + }, 1); +}); + +test('clicking should not open item if disabled', function() { + var item = getRootItem(4).parent(); + + menu.disable(item); + + item.children(".k-link").trigger(CLICK); + + ok(!item.find('.k-group').is(":visible")); +}); + +test('disable method should disable enabled item', function() { + var item = getRootItem(2).parent(); + + menu.disable(item); + + ok(item.hasClass('k-state-disabled')); +}); + +test('enable method should enable disabled item', function() { + var item = getRootItem(3).parent(); + + menu.enable(item); + + ok(item.hasClass('k-state-default')); +}); + +asyncTest('configure with popupCollision overrides the default', function() { + var item = getRootItem(3).parent(); + + menu.open(item); + + setTimeout(function () { + ok(item.find(".k-group").eq(0).data("kendoPopup").options.collision == "flip"); + start(); + }, 1); +}); + +test('setOptions resets the animation', function() { + var m = new kendo.ui.Menu("
              "); + + ok(!("effects" in m.options.animation.open)); + + m.setOptions({ animation: false }); + + ok("effects" in m.options.animation.open); + ok(kendo.size(m.options.animation.open.effects) == 0); + m.destroy(); +}); + +test('setOptions resets the dataSource object', function() { + var m = new kendo.ui.Menu("
              ", { dataSource: [ { text: "Item 1" } ] }); + + ok(m.element.find("li").text() == "Item 1"); + + m.setOptions({ dataSource: [ { text: "Changed" } ] }); + + ok(m.element.find("li").text() == "Changed"); + m.destroy(); +}); + +test("Element with class k-icon doesn't get removed in an item", function () { + var m = new kendo.ui.Menu("
              "); + + ok(m.element.find(".k-icon")[0]); + m.destroy(); +}); + +test("Add dynamic item with cssClass", function () { + var m = new kendo.ui.Menu("
                "); + + m.append({ text: "test", cssClass: "cssClass" }); + + ok(m.element.find(".cssClass")[0]); + m.destroy(); +}); + +test("Adding dynamic content element renders properly on root and inner levels", function () { + var m = new kendo.ui.Menu("
                  "); + + m.append([ + { + text: "Item 1", + content: "Item 1 Content" + }, + { + text: "Item 2", + items: [ + { + text: "Sub Item 1", + content: "Sub Item 1 Content" + } + ] + } + ]); + + ok(m.element.children("li:first").children("div.k-content")[0]); + ok(m.element.find("> li:last > ul > li:first").children("div.k-content")[0]); + m.destroy(); +}); + +test("Adding dynamic contentUrl element renders contents on root and inner levels", function () { + var m = new kendo.ui.Menu("
                    "); + + m.append([ + { + text: "Item 1", + contentUrl: "AjaxView1.html" + }, + { + text: "Item 2", + items: [ + { + text: "Sub Item 1", + contentUrl: "AjaxView2.html" + } + ] + } + ]); + + ok(m.element.children("li:first").children("div.k-content")[0]); + ok(m.element.find("> li:last > ul > li:first").children("div.k-content")[0]); + m.destroy(); +}); + + test('insertAfter method moves an item if called with existing item', 1, function() { + var menu = $("
                    • Item 1
                    • Item 2
                    ").kendoMenu().data("kendoMenu"); + + try { + menu.insertAfter("li:first-child", "li:last-child"); + + ok(menu.element.children("li:last-child").text() == "Item 1"); + } finally { + menu.destroy(); + } + }); + +})(); + diff --git a/tests/menu/aria.js b/tests/menu/aria.js new file mode 100644 index 00000000000..05ed92390ec --- /dev/null +++ b/tests/menu/aria.js @@ -0,0 +1,117 @@ +(function() { +var menu; + +function setup(options) { + menu = $("
                      ").appendTo(QUnit.fixture).kendoMenu(options); + return menu; +} + +module("ARIA support", { + setup: function() { + $.fn.press = function(key) { + return this.trigger({ type: "keydown", keyCode: key } ); + }; + }, + teardown: function () { + kendo.destroy(QUnit.fixture); + } +}); + +test("menubar role is added to the wrapper", function() { + setup(); + ok(menu.filter("[role=menubar]").length); +}); + +test("menuitem role is added to the items of bound menu", function() { + setup({ dataSource: [ {text: "foo" } ] }); + ok(menu.find("[role=menuitem]").length); +}); + +test("menuitem role is added to the items of html created menu", function() { + menu = $("
                      • foo
                      ") + .appendTo(QUnit.fixture) + .kendoMenu(); + + ok(menu.find("[role=menuitem]").length); +}); + +test("has-popup attribute is added if node has childs", function() { + setup({ dataSource: [ {text: "foo", items: [{ text: "bar" }] } ] }); + + equal(menu.find("[aria-haspopup=true] span:first").text(), "foo"); +}); + +test("menu role is added to the group container", function() { + setup({ dataSource: [ {text: "foo", items: [{ text: "bar" }] } ] }); + + equal(menu.find("[role=menu] span:first").text(), "bar"); +}); + +test("menu role is added to the group container when created from html", function() { + menu = $("
                      • foo
                        • bar
                      ") + .appendTo(QUnit.fixture) + .kendoMenu(); + + equal(menu.find("[role=menu] span:first").text(), "bar"); +}); + +test("disabled attribute is added if node is disabled", function() { + setup({ dataSource: [ { text: "foo", enabled: false } ] }); + + equal(menu.find("[aria-disabled=true] span:first").text(), "foo"); +}); + +test("disabled attribute is added if node is disabled via the API", function() { + setup({ dataSource: [ { text: "foo" } ] }); + + menu.data("kendoMenu").disable(menu.find("li:first")); + + equal(menu.find("[aria-disabled=true] span:first").text(), "foo"); +}); + +test("disabled attribute is added if child node is disabled via the API", function() { + setup({ dataSource: [ { text: "foo", items: [{ text: "bar" }] } ] }); + + menu.data("kendoMenu").disable(menu.find(".k-group li:first")); + + equal(menu.find("[aria-disabled=true] span:first").text(), "bar"); +}); + +test("disabled attribute is added if node is disabled when created from html", function() { + menu = $("
                      • foo
                      ") + .appendTo(QUnit.fixture) + .kendoMenu(); + + equal(menu.find("[aria-disabled=true] span:first").text(), "foo"); +}); + +test("hidden attribute is added to the group when created from html", function() { + menu = $("
                      • foo
                        • bar
                      ") + .appendTo(QUnit.fixture) + .kendoMenu(); + + ok(menu.find(".k-group[aria-hidden=true]").length); +}); + +test("aria-activedescendant is added to the wrapper when item is focused", function() { + menu = $("
                        ") + .appendTo(QUnit.fixture) + .kendoMenu({ dataSource: [ {text: "foo", items: [{ text: "bar" }] } ] }); + + menu[0].focus(); + + ok(menu.filter("[aria-activedescendant]").length); + ok(menu.find("li#" + menu.data("kendoMenu")._ariaId).length); +}); + +test("aria-activedescendant is added to the wrapper when item is focused", function() { + menu = $("
                        • foo
                        ") + .appendTo(QUnit.fixture) + .kendoMenu(); + + menu[0].focus(); + + ok(menu.filter("[aria-activedescendant=bar]").length); + ok(menu.find("li#bar").length); +}); +})(); diff --git a/tests/menu/events.js b/tests/menu/events.js new file mode 100644 index 00000000000..763a0433688 --- /dev/null +++ b/tests/menu/events.js @@ -0,0 +1,159 @@ +(function() { + +function onSelect() { + isRaised = true; +} + +function getRootItem(index) { + return $('> .k-item', menu.element).eq(index); +} + +var menu, isRaised, + CLICK = "click"; + +module("menu events", { + setup: function () { + QUnit.fixture.append( +' ' + ); + menu = new kendo.ui.Menu("#menu", { animation: false, select: onSelect, hoverDelay: 0 }); + }, + teardown: function() { + kendo.destroy(QUnit.fixture); + } +}); + +asyncTest("close event can be canceled", 1, function() { + menu.bind("close", function (e) { e.preventDefault() }); + + menu.bind("activate", function() { + menu.close(menu.element.children("li:eq(2)")); + equal(menu.element.find(">li:eq(2) ul").is(":visible"), true); + start(); + }); + + menu.open(menu.element.children("li:eq(2)")); +}); + + +asyncTest("activate event is fired after open", 1, function() { + menu.unbind("open"); + var activated = false; + + menu.bind("activate", function() { + activated = true; + }); + + menu.open(menu.element.children("li:eq(1)")); + + setTimeout(function () { + equal(activated, true); + start(); + }, 10); +}); + + +test("element select is triggered when menu element is clicked", function() { + var item = getRootItem(0), + triggerCount = 0; + + menu.bind("select", function() { + triggerCount++; + }); + + item.trigger(CLICK); + + equal(triggerCount, 1); +}); + + +test('clicking disabled item should not raise onSelect event on parent item', function() { + var item = getRootItem(1); + + isRaised = false; + + item.find('.k-item > .k-link').eq(3).trigger('click'); + + ok(!isRaised); +}); + +asyncTest("open event can be canceled", 1, function() { + menu.bind("open", function (e) { e.preventDefault() }); + menu.open(menu.element.children("li:first")); + + setTimeout(function () { + equal(menu.element.find(">li:first ul").is(":visible"), false); + start(); + }, 10); +}); + + +})(); diff --git a/tests/menu/keyboard.js b/tests/menu/keyboard.js new file mode 100644 index 00000000000..bf431b5f429 --- /dev/null +++ b/tests/menu/keyboard.js @@ -0,0 +1,152 @@ +(function() { +var menu, + openedItem, + FOCUSEDSTATE = "k-state-focused", + FOCUSEDCLASS = "." + FOCUSEDSTATE; + +var keys = kendo.keys; + +module("menu keyboard navigation", { + setup: function () { + $.fn.press = function(key) { + return this.trigger({ type: "keydown", keyCode: key } ); + }; + + QUnit.fixture.append( + ''); + + menu = new kendo.ui.Menu("#menu", { animation: false}) + menu._oldHoverItem = null; + menu.wrapper.find(FOCUSEDCLASS).removeClass(FOCUSEDSTATE); + + }, + teardown: function() { + kendo.destroy(QUnit.fixture); + openedItem = null; + } +}); + +test('Menu focus makes first root item active', function() { + menu.wrapper[0].focus(); + + ok(menu.wrapper.children(".k-item").first().hasClass(FOCUSEDSTATE)); +}); + +asyncTest("Template focus focuses the parent Menu item", function () { + var template = menu.element.find("#template"); + menu.open("#menuItem4"); + + setTimeout(function() { + start(); + template[0].focus(); + ok(template.parents(".k-item").eq(1).hasClass(FOCUSEDSTATE)); + }, 100); +}); + +test('Left and right arrows move focus between first and second item', function() { + menu.wrapper.focus().press(keys.RIGHT); + var firstItem = menu.wrapper.children(".k-item").first(); + + ok(firstItem.next().hasClass(FOCUSEDSTATE)); + + menu.wrapper.press(keys.LEFT); + ok(firstItem.hasClass(FOCUSEDSTATE)); +}); + +test('Down arrow opens subitems group', function() { + menu.open = function(item) { openedItem = item; }; + menu.wrapper.focus().press(keys.DOWN); + + equal(openedItem[0], menu.wrapper.children(".k-item").first()[0]); +}); + +test('Left arrow moves focus from first to last item', function() { + menu.wrapper.focus().press(keys.LEFT); + + ok(menu.wrapper.children(".k-item").last().hasClass(FOCUSEDSTATE)); +}); + +test('Mouse events reset the keyboard navigation active item', function() { + menu.wrapper.focus().press(keys.RIGHT); + + var firstItem = menu.wrapper.children(".k-item").first(), + secondItem = firstItem.next(); + + firstItem.children(".k-link").mouseenter(); + + ok(!secondItem.hasClass(FOCUSEDSTATE)); + + menu.wrapper.press(keys.RIGHT); + + ok(secondItem.hasClass(FOCUSEDSTATE)); +}); + +test('Disabled root item does not open subgroup', function() { + menu.wrapper.focus().press(keys.RIGHT).press(keys.RIGHT).press(keys.DOWN); + + var thirdItem = menu.wrapper.children(".k-item").eq(2); + + ok(thirdItem.hasClass(FOCUSEDSTATE)); +}); + +test('Disabled subitem does not open sub-subgroup', function() { + menu.wrapper.focus().press(keys.DOWN).press(keys.DOWN).press(keys.RIGHT); + + var secondSubItem = menu.wrapper.children(".k-item").first().find(".k-item").eq(1); + + ok(secondSubItem.hasClass(FOCUSEDSTATE)); +}); + +test('Hitting Enter key navigates an item hyperlink', function() { + var fired = false; + menu.wrapper.find("#fooLink").click(function(e){ + e.preventDefault(); + fired = true; + }); + menu.wrapper.focus().press(keys.RIGHT).press(keys.ENTER); + + ok(fired); +}); +})(); diff --git a/tests/menu/mvvm.js b/tests/menu/mvvm.js new file mode 100644 index 00000000000..9ef93c447a3 --- /dev/null +++ b/tests/menu/mvvm.js @@ -0,0 +1,112 @@ +(function() { + +var dom; + +module('menu MVVM', { + teardown: function() { + kendo.destroy(dom); + } +}); + +test("initializes a menu when data role is menu", function() { + dom = $('
                          '); + + kendo.bind(dom); + + ok(dom.data("kendoMenu") instanceof kendo.ui.Menu); +}); + +test("initializes a options from data attributes", function() { + dom = $('
                            '); + + kendo.bind(dom); + + var menu = dom.data("kendoMenu"); + + ok($.isEmptyObject(menu.options.animation.effects)); +}); + +test("binding menu initialized before binding", function() { + dom = $('
                              '); + + var menu = dom.kendoMenu().data("kendoMenu"); + + kendo.bind(dom); + + ok($.isEmptyObject(menu.options.animation.effects)); +}); + +test("binding containing binding attributes", function() { + dom = $('
                              '); + + var observable = kendo.observable({ text:"foo" }); + + kendo.bind(dom, observable); + + equal($.trim(dom.find("span:first").html()), "foo"); +}); + +test("updating viewModel updates the content", function() { + dom = $('
                              '); + + var observable = kendo.observable({ text:"foo" }); + + kendo.bind(dom, observable); + + observable.set("text", "bar"); + + equal($.trim(dom.find("span:first").html()), "bar"); +}); + +test("event is raised if attached as option", 1, function() { + window.menuMVVMSelect = function() { + ok(true); + } + dom = $('
                                '); + + kendo.bind(dom); + + dom.data("kendoMenu").trigger("select"); +}); + + +test("binding visible to true shows the menu", function() { + dom = $('
                                '); + + kendo.bind(dom, { visible: true }); + + var menu = dom.data("kendoMenu"); + + ok(menu.wrapper.css("display") != "none", "menu is visible"); +}); + +test("binding visible to false hides the menu", function() { + dom = $('
                                '); + + kendo.bind(dom, { visible: false }); + + var menu = dom.data("kendoMenu"); + + ok(menu.wrapper.css("display") == "none", "menu is not visible"); +}); + +test("binding invisible to true hides the menu", function() { + dom = $('
                                '); + + kendo.bind(dom, { invisible: true }); + + var menu = dom.data("kendoMenu"); + + ok(menu.wrapper.css("display") == "none", "menu is invisible"); +}); + +test("binding invisible to false shows the menu", function() { + dom = $('
                                '); + + kendo.bind(dom, { invisible: false }); + + var menu = dom.data("kendoMenu"); + + ok(menu.wrapper.css("display") != "none", "menu is not invisible"); +}); +})(); diff --git a/tests/menu/open-on-click.js b/tests/menu/open-on-click.js new file mode 100644 index 00000000000..1d2713180da --- /dev/null +++ b/tests/menu/open-on-click.js @@ -0,0 +1,186 @@ +(function() { +var isRaised; + +function getRootItem(index) { + return $('#menu').find('> .k-item > .k-link')[index]; +} + +var open; +var close; +var menu; + +module("menu open on click", { + setup: function() { + QUnit.fixture.append( + '' + ); + + menu = new kendo.ui.Menu("#menu", { animation: false, openOnClick: true, hoverDelay: 0 }); + open = menu.open; + close = menu.close; + }, + teardown: function() { + kendo.destroy(QUnit.fixture); + } +}); + +test('open on click is serialized', function() { + ok(menu.options.openOnClick); +}); + +test('click method should call preventDefault method', function() { + var item = getRootItem(3); + var isCalled = false; + + var e = { target: item, preventDefault: function () { isCalled = true; }, stopPropagation: function () {} }; + + menu._click(e); + + ok(isCalled); +}); + +test('click method on item with URL shouldn\'t call preventDefault method', function() { + var item = getRootItem(7); + var isCalled = false; + + var e = { target: item, preventDefault: function () { isCalled = true; }, stopPropagation: function () {} }; + + menu._click(e); + + ok(!isCalled); +}); + +test('hovering root item does not open it', function() { + var opened = false, + item = $("li:first", menu.element)[0], + menuElement = menu.wrapper[0], + e = {target: item, currentTarget: item, delegateTarget: menuElement, relatedTarget: menuElement, preventDefault: $.noop, stopPropagation: $.noop }; + + menu.open = function() { opened = true }; + + menu._mouseenter(e, item); + + ok(!opened); +}); + +test('hovering root item does not open it after using close method', 2, function() { + var opened, + item = $("li:first", menu.element)[0], + menuElement = menu.wrapper[0], + e = {target: item, currentTarget: item, delegateTarget: menuElement, relatedTarget: menuElement, preventDefault: $.noop, stopPropagation: $.noop }; + + menu.open = function() { opened = true }; + + menu._click(e, item); + opened = false; + menu.close(item); + menu._mouseenter(e, item); + + ok(!opened); + equal(menu.clicked, false); +}); + +test('clicking root item should open it', function() { + var opened = false; + menu.open = function() { opened = true }; + var element = $("li:first", menu.element)[0]; + menu._click({ target: element, preventDefault: function () { }, stopPropagation: function () { } }, element); + ok(opened); + ok(menu.clicked); +}); + +test('leaving opened item does not close it', function() { + var opened = false; + menu.clicked = true; + menu.open = function() { opened = true }; + + menu._mouseleave({}, $("li:first", menu.element)[0]); + + ok(!opened); +}); + +test('leaving opened and hovering a sibling closes it and opens the sibling', function() { + var opened = false; + menu.clicked = true; + menu.open = function() { opened = true }; + + var element = $("li:first", menu.element)[0]; + menu._mouseenter({ currentTarget: element, delegateTarget: menu.element[0], indexOf: function() { }, type:'mouseenter' }, element.nextSibling); + + ok(opened); +}); + +test('clicking the document closes the open item', function() { + menu.clicked = true; + menu._documentClick({ target: document.body }, document ); + ok(menu.clicked === false); +}); +})(); diff --git a/tests/model/get.js b/tests/model/get.js new file mode 100644 index 00000000000..03f314bfe5f --- /dev/null +++ b/tests/model/get.js @@ -0,0 +1,29 @@ +(function(){ + +var Model; + +module("model get", { + setup: function() { + Model = kendo.data.Model.define(); + } +}); + +test("get returns the value of the specified field", function() { + var m = new Model({ + foo: "bar" + }); + + equal(m.get("foo"), "bar"); +}); + +test("get evaluates nested expression", function() { + var m = new Model({ + foo: { + bar: "bar" + } + }); + + equal(m.get("foo.bar"), "bar"); +}); + +}()); diff --git a/tests/model/initialization.js b/tests/model/initialization.js new file mode 100644 index 00000000000..370833423aa --- /dev/null +++ b/tests/model/initialization.js @@ -0,0 +1,371 @@ +(function(){ + +var Model = kendo.data.Model; + +module("model initialization"); + +test("define returns a new model which is subclass of Model", function() { + var MyModel = Model.define(); + ok(new MyModel instanceof Model); +}); + +test("define assigns data", function() { + var MyModel = Model.define(), + model = new MyModel({ foo: "bar"}); + + equal(model.foo, "bar"); +}); + +test("define assigns the fields", function() { + var MyModel = Model.define({ + fields: { + foo: {} + } + }); + + var model = new MyModel(); + + ok(model.fields.foo); +}); + +test("define assigns the fields as array of object", function() { + var MyModel = Model.define({ + fields: [ { field: "foo" } ] + }); + + var model = new MyModel(); + + ok(model.fields.foo); +}); + +test("define assigns the fields as array of strings", function() { + var MyModel = Model.define({ + fields: [ "foo" ] + }); + + var model = new MyModel(); + + ok(model.fields.foo); +}); + +test("define assigns field type", function() { + var MyModel = Model.define({ + fields: { + foo: { type: "string" } + } + }); + + var model = new MyModel(); + + equal(model.fields.foo.type, "string"); +}); + +test("define if key is assign model is not new", function() { + var MyModel = Model.define({ + id: "id" + }); + + var model = new MyModel( { id: 1 } ); + + ok(!model.isNew()); +}); + +test("define if no key is assign model is new", function() { + var MyModel = Model.define({ + id: "id" + }); + var model = new MyModel(); + ok(model.isNew()); +}); + +test("define with custom field.name mapping", function() { + var MyModel = Model.define({ + id: "id", + fields: { + name: { field: "Name" } + } + }); + + var model = new MyModel(); + ok("name" in model); + ok(!("Name" in model)); +}); + +test("define with custom field mapping", function() { + var MyModel = Model.define({ + id: "id", + fields: { + name: "Name" + } + }); + + var model = new MyModel(); + ok("name" in model); + ok(!("Name" in model)); +}); + +test("isNew returns true if no key is defined", function() { + var MyModel = Model.define({ + id: "id" + }); + var model = new MyModel(); + ok(model.isNew()); +}); + +test("id returns the value of the key", function() { + var MyModel = Model.define({ + id: "foo" + }); + var model = new MyModel({ foo: 1 }); + equal(model.id, 1); +}); + +test("id is implicitly set if not set in metadata", function() { + var MyModel = Model.define(); + var model = new MyModel({ id: 1 }); + + equal(model.id, 1); +}); + +test("id is implicitly set if not set in metadata and no data", function() { + var MyModel = Model.define(); + var model = new MyModel({}); + + ok(!("undefined" in model)); +}); + +test("define assigns field validation rules", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", + validation: { + required: true + } + } + } + }); + + var model = new MyModel(); + + ok($.isPlainObject(model.fields.foo.validation)); + ok(model.fields.foo.validation.required); +}); + +test("define accepts custom validation rules", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", + validation: { + bar: $.noop + } + } + } + }); + + var model = new MyModel(); + + ok(model.fields.foo.validation.bar); + ok($.isFunction(model.fields.foo.validation.bar)); +}); + +test("field can be set as editable false", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", + editable: false + } + } + }); + + var model = new MyModel(); + + ok(!model.fields.foo.editable); +}); + +test("empty string default value is set for field of type string", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", type: "string" + } + } + }); + + var model = new MyModel(); + + equal(model.defaults["foo"], ""); + equal(model.get("foo"), ""); +}); + +test("model data is synchronized with original data", function() { + var data = { id: 1, foo: "bar"}; + var model = new (Model.define())(data); + + model.set("foo", "foo"); + + equal(model.get("foo"), "foo"); +}); + +test("model data is synchronized with original data as empty object", function() { + var data = {}; + var model = new (Model.define({ fields: { foo: "foo", bar: "bar" } }))(data); + + model.set("foo", "foo"); + + equal(model.get("foo"), "foo"); + equal(model.foo, "foo"); + equal(model.bar, ""); +}); + +test("zero is set as default value for numeric field", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", type: "number" + } + } + }); + + var model = new MyModel(); + + ok(model.defaults["foo"] === 0); + ok(model.get("foo") === 0); +}); + +test("date is set as default value for date field", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", type: "date" + } + } + }); + + var model = new MyModel(); + + ok(model.defaults["foo"].getDate() === new Date().getDate()); + ok(model.get("foo").getDate() === new Date().getDate()); +}); + +test("setting default value by type should be case insensitive", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", type: "DATE" + } + } + }); + + var model = new MyModel(); + + ok(model.defaults["foo"].getDate() === new Date().getDate()); + ok(model.get("foo").getDate() === new Date().getDate()); +}); + +test("false is set as default value for boolean field", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", type: "Boolean" + } + } + }); + + var model = new MyModel(); + + ok(model.defaults["foo"] === false); + ok(model.get("foo") === false); +}); + +test("defaultValue sets field default value", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", + defaultValue: "foo" + } + } + }); + + var model = new MyModel(); + + equal(model.defaults["foo"], "foo"); + equal(model.get("foo"), "foo"); +}); + +test("defaultValue set to 0 is set", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", + defaultValue: 0 + } + } + }); + + var model = new MyModel(); + + ok(model.defaults["foo"] === 0); + ok(model.get("foo") === 0); +}); + +test("isNew and default id value", function() { + var MyModel = Model.define({ + id: "foo", + fields: { + foo: { + field: "foo", + defaultValue: 0 + } + } + }); + + var model = new MyModel(); + + ok(model.isNew()); +}); + +test("type convert is assign to the field definition", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", type: "number" + } + } + }); + + ok($.isFunction(MyModel.fields.foo.parse)); +}); + +test("custom type converter is assign to the field definition", function() { + var MyModel = Model.define({ + fields: { + foo: { + field: "foo", + type: "number", + parse: function() { + return true; + } + } + } + }); + + ok(MyModel.fields.foo.parse()); +}); + +test("toJSON skips the id if id field is not declared", function() { + var model = new Model({ foo: 1 }); + ok(!("id" in model.toJSON())); +}); + +test("toJSON skips the id if id field is not default", function() { + var MyModel = Model.define({ id: "foo" }), + model = new MyModel({ foo: 1 }); + + equal(typeof model.toJSON().id, "undefined"); +}); + +}()); diff --git a/tests/model/set.js b/tests/model/set.js new file mode 100644 index 00000000000..f8c9c640462 --- /dev/null +++ b/tests/model/set.js @@ -0,0 +1,362 @@ +(function(){ + +var Model; + +module("kendo.data.Model.set", { + setup: function() { + Model = kendo.data.Model.define(); + } +}); + +test("set updates the value of the specified field", function() { + var m = new Model({ + foo: "bar" + }); + + m.set("foo", "baz"); + equal(m.get("foo"), "baz"); +}); + +test("set updates the value of the specified expression", function() { + var m = new Model({ + foo: { + bar: "bar" + } + }); + + m.set("foo.bar", "baz"); + equal(m.get("foo.bar"), "baz"); +}); + +test("model is dirty after set", function() { + var m = new Model(); + + m.set("foo", "foo"); + + ok(m.dirty); +}); + +test("model is dirty during change event", 1, function() { + var m = new Model(); + m.bind("change", function() { + ok(m.dirty); + }); + m.set("foo", "foo"); +}); + + +test("model is not dirty if the same string value is set", function() { + var m = new Model({ + foo: "foo" + }); + + m.set("foo", "foo"); + ok(!m.dirty); +}); + +test("model is not dirty if the same numeric value is set", function() { + var m = new Model({ + foo: 1 + }); + + m.set("foo", 1); + ok(!m.dirty); +}); + +test("model is not dirty if the same date value is set", function() { + var m = new Model({ + foo: new Date(2011, 1, 1) + }); + + m.set("foo", new Date(2011, 1, 1)); + ok(!m.dirty); +}); + +test("model is not dirty if the same object value is set", function() { + var m = new Model({ + foo: { + bar: "bar" + } + }); + + m.set("foo", { bar: "bar" }); + + ok(!m.dirty); +}); + +test("change is raised if the model is modifed after set", function() { + var changeWasCalled = false, m = new Model().bind("change", function() { + changeWasCalled = true; + }); + + m.set("foo", "bar"); + ok(changeWasCalled); +}); + +test("change is not raised if the model is not modifed after set", function() { + var changeWasCalled = false, m = new Model({ + foo: "bar" + }).bind("change", function() { + changeWasCalled = true; + }); + + m.set("foo", "bar"); + ok(!changeWasCalled); +}); + +test("set parse value to defined type", function() { + var MyModel = kendo.data.Model.define({ + fields: { + bar: { field: "bar", type: "number" } + } + }), m = new MyModel(); + + m.set("bar", "1"); + equal(m.get("bar"), 1); + equal(typeof m.get("bar"), "number"); +}); + +test("setting number when no type defined", function() { + var MyModel = kendo.data.Model.define({ + fields: { + bar: { field: "bar" } + } + }), m = new MyModel(); + + m.set("bar", 1); + equal(m.get("bar"), 1); + equal(typeof m.get("bar"), "number"); +}); + +test("setting boolean as string is converted", function() { + var MyModel = kendo.data.Model.define({ + fields: { + bar: { field: "bar", type: "boolean" } + } + }), m = new MyModel(); + + m.set("bar", "TRUE"); + ok(m.get("bar") === true); + equal(typeof m.get("bar"), "boolean"); +}); + +test("setting boolean as false string is converted", function() { + var MyModel = kendo.data.Model.define({ + fields: { + bar: { field: "bar", type: "boolean" } + } + }), m = new MyModel(); + + m.set("bar", "false"); + ok(m.get("bar") === false); + equal(typeof m.get("bar"), "boolean"); +}); + +test("setting boolean as number is converted", function() { + var MyModel = kendo.data.Model.define({ + fields: { + bar: { field: "bar", type: "boolean" } + } + }), m = new MyModel(); + + m.set("bar", 1); + ok(m.get("bar") === true); + equal(typeof m.get("bar"), "boolean"); +}); + +test("setting boolean as null returns null", function() { + var MyModel = kendo.data.Model.define({ + fields: { + bar: { field: "bar", type: "boolean" } + } + }), m = new MyModel(); + + m.set("bar", null); + equal(m.get("bar"), null); +}); + +test("setting boolean as invalid string value is converted to false", function() { + var MyModel = kendo.data.Model.define({ + fields: { + bar: { field: "bar", type: "boolean" } + } + }), m = new MyModel(); + + m.set("bar", "foo"); + ok(m.get("bar") === false); + equal(typeof m.get("bar"), "boolean"); +}); + +test("setting number as string is converted to string", function() { + var MyModel = kendo.data.Model.define({ + fields: { + bar: { field: "bar", type: "string" } + } + }), m = new MyModel(); + + m.set("bar", 42); + equal(m.get("bar"), "42"); + equal(typeof m.get("bar"), "string"); + +}); + +test("set float number as string is parsed as float", function() { + var MyModel = kendo.data.Model.define({ + fields: { + bar: { field: "bar", type: "number" } + } + }), m = new MyModel(); + + m.set("bar", "1.1"); + equal(m.get("bar"), 1.1); + equal(typeof m.get("bar"), "number"); +}); + +test("set ignores type case", function() { + var MyModel = kendo.data.Model.define({ + fields: { + bar: { field: "bar", type: "Number" } + } + }), m = new MyModel(); + + m.set("bar", "1"); + equal(m.get("bar"), 1); + equal(typeof m.get("bar"), "number"); +}); + +test("set when no converter for the type", function() { + var MyModel = kendo.data.Model.define({ + fields: { + bar: { field: "bar", type: "foo" } + } + }), m = new MyModel(); + + m.set("bar", "1"); + equal(m.get("bar"), "1"); +}); + +test("set date as string is parsed", function() { + var MyModel = kendo.data.Model.define({ + fields: { + bar: { field: "bar", type: "date" } + } + }), m = new MyModel(); + + m.set("bar", "1/1/2000"); + equal(m.get("bar").getTime(), new Date("1/1/2000").getTime()); + equal(typeof m.get("bar"), "object"); +}); + + +test("set with custom parse", function() { + var wasCalled = false, + MyModel = kendo.data.Model.define({ + fields: { + bar: { + field: "bar", + type: "string", + parse: function(value) { wasCalled = true; } + } + } + }), m = new MyModel(); + + m.set("bar", "some value"); + ok(wasCalled); +}); + +test("set with custom parse without type set", function() { + var wasCalled = false, + MyModel = kendo.data.Model.define({ + fields: { + bar: { + field: "bar", + parse: function(value) { wasCalled = true; } + } + } + }), m = new MyModel(); + + m.set("bar", "some value"); + ok(wasCalled); +}); + +test("set date as .net date literal", function() { + var MyModel = kendo.data.Model.define({ + fields: { + bar: { field: "bar", type: "date" } + } + }), m = new MyModel(); + + m.set("bar", "/Date(836524800000)/"); + equal(m.get("bar").getTime(), new Date(836524800000).getTime()); + equal(typeof m.get("bar"), "object"); +}); + +test("setting value of field marked as editable=false is ignored", function() { + var MyModel = kendo.data.Model.define({ + fields: { + bar: { field: "bar", editable: false } + } + }), m = new MyModel({ bar: "foo" }); + + m.set("bar", "baz"); + equal(m.get("bar"), "foo"); + ok(!m.dirty); +}); + +test("editable returns false for field marked as editable=false", function() { + var MyModel = kendo.data.Model.define({ + fields: { + bar: { field: "bar", editable: false } + } + }), m = new MyModel({ bar: "foo" }); + + ok(!m.editable("bar")); +}); + +test("editable returns true when no fields definition", function() { + var MyModel = kendo.data.Model.define(), + m = new MyModel({ bar: "foo" }); + ok(m.editable("bar")); +}); + +test("changes returns false if value is same as default value", function() { + var MyModel = kendo.data.Model.define({ + fields: { + bar: { field: "bar", defaultValue: "bar"} + } + }), m = new MyModel({ }); + + m.set("bar", "bar"); + + ok(!m.dirty); +}); + +test("setting a field raises set event", 2, function() { + var model = new Model({ foo: "bar" }); + + model.bind("set", function(e) { + equal(e.field, "foo"); + equal(e.value, "foo"); + }); + + model.set("foo", "foo"); +}); + +test("setting number to string field returns its string representation", function() { + var MyModel = kendo.data.Model.define({ fields: { foo: { type: "string" }}}); + var model = new MyModel(); + + model.set("foo", 1); + + equal(model.get("foo"), "1"); +}); + +test("setting null to string field returns null", function() { + var MyModel = kendo.data.Model.define({ fields: { foo: { type: "string" }}}); + var model = new MyModel(); + + model.set("foo", null); + + equal(model.get("foo"), null); +}); +}()); diff --git a/tests/multiselect/api.js b/tests/multiselect/api.js new file mode 100644 index 00000000000..615e9cca6b7 --- /dev/null +++ b/tests/multiselect/api.js @@ -0,0 +1,389 @@ +(function() { + var MultiSelect = kendo.ui.MultiSelect, + select; + + function popuplateSelect(length) { + var options = []; + length = length || 5; + for (var i=0; i < length; i++) { + options.push(""); + } + + select.html(options); + } + + module("kendo.ui.MultiSelect API", { + setup: function() { + kendo.ns = "kendo-"; + kendo.effects.disable(); + select = $("").appendTo(QUnit.fixture); + }, + teardown: function() { + kendo.effects.enable(); + kendo.ns = ""; + if (input.data("kendoMultiSelect")) { + input.data("kendoMultiSelect").destroy(); + } + } + }); + + test("MultiSelect adds role to the input", function() { + var multiselect = new MultiSelect(input); + + equal(multiselect.input[0].getAttribute("role"), "listbox"); + }); + + test("MultiSelect adds aria-owns", function() { + var multiselect = new MultiSelect(input.attr("id", "test")); + var id = multiselect.tagList.attr("id") + " " + multiselect.ul.attr("id"); + + equal(multiselect.input.attr("aria-owns"), id); + }); + + test("MultiSelect adds aria-disabled='true'", function() { + var multiselect = new MultiSelect(input.attr("disabled", "disabled")); + + equal(multiselect.input.attr("aria-disabled"), "true"); + }); + + test("MultiSelect adds aria-disabled='false'", function() { + var multiselect = new MultiSelect(input); + + equal(multiselect.input.attr("aria-disabled"), "false"); + }); + + test("MultiSelect adds aria-expanded='false'", function() { + var multiselect = new MultiSelect(input); + + equal(multiselect.input.attr("aria-expanded"), "false"); + }); + + test("MultiSelect adds aria-expanded='true'", function() { + var multiselect = new MultiSelect(input, { + dataSource: ["item1", "item2"] + }); + + multiselect.open(); + + equal(multiselect.input.attr("aria-expanded"), "true"); + }); + + test("MultiSelect sets aria-expanded to false on close", function() { + var multiselect = new MultiSelect(input, { + dataSource: ["item1", "item2"] + }); + + multiselect.open(); + multiselect.close(); + + ok(!multiselect.popup.visible()); + equal(multiselect.input.attr("aria-expanded"), "false"); + }); + + test("MultiSelect adds aria-hidden to the popup element", 3, function() { + var multiselect = new MultiSelect(input, { + dataSource: ["item1", "item2"] + }); + + equal(multiselect.ul.attr("aria-hidden"), "true"); + + multiselect.open(); + + equal(multiselect.ul.attr("aria-hidden"), "false"); + + multiselect.close(); + + equal(multiselect.ul.attr("aria-hidden"), "true"); + }); + + test("MultiSelect adds aria-live=polite if filter is set", function() { + var multiselect = new MultiSelect(input, { + dataSource: ["item1", "item2"], + filter: "startswith" + }); + + equal(multiselect.ul.attr("aria-live"), "polite"); + }); + + asyncTest("MultiSelect adds aria-busy=true when loader is shown", 1, function() { + var multiselect = new MultiSelect(input, { + dataSource: ["item1", "item2"], + filter: "startswith" + }); + + multiselect._showBusy(); + + setTimeout(function() { + start(); + equal(multiselect.input.attr("aria-busy"), "true"); + }, 150); + }); + + test("MultiSelect adds aria-busy=false when loader is hidden", 1, function() { + var multiselect = new MultiSelect(input, { + dataSource: ["item1", "item2"], + filter: "startswith" + }); + + multiselect._hideBusy(); + equal(multiselect.input.attr("aria-busy"), "false"); + }); + + test("MultiSelect sets activedescendant on refresh", function() { + var multiselect = new MultiSelect(input.attr("id", "test"), { + dataSource: ["item1", "item2"], + filter: "startswith" + }); + + equal(multiselect.input.attr("aria-activedescendant"), undefined); + }); + + test("MultiSelect makes first item active on open", function() { + var multiselect = new MultiSelect(input.attr("id", "test"), { + dataSource: ["item1", "item2"], + value: "item1" + }); + + multiselect.open(); + equal(multiselect.input.attr("aria-activedescendant"), multiselect.current().attr("id")); + }); + + test("MultiSelect remove aria-activedescendant on close", function() { + var multiselect = new MultiSelect(input.attr("id", "test"), { + dataSource: ["item1", "item2"], + value: "item1" + }); + + multiselect.open(); + multiselect.close(); + equal(multiselect.input.attr("aria-activedescendant"), undefined); + }); + + test("MultiSelect sets aria-activedescendant attr to the last li of tagList", function() { + var multiselect = new MultiSelect(input.attr("id", "test"), { + dataSource: ["item1", "item2"], + value: "item1" + }); + + multiselect.input.focus().trigger({ + type: "keydown", + keyCode: kendo.keys.LEFT + }); + + ok(multiselect.currentTag().attr("id")); + equal(multiselect.input.attr("aria-activedescendant"), multiselect.currentTag().attr("id")); + }); +})(); diff --git a/tests/multiselect/events.js b/tests/multiselect/events.js new file mode 100644 index 00000000000..5f6ede8575b --- /dev/null +++ b/tests/multiselect/events.js @@ -0,0 +1,156 @@ +(function() { + var MultiSelect = kendo.ui.MultiSelect, + select; + + function populateSelect(length) { + var options = []; + length = length || 5; + for (var i=0; i < length; i++) { + options.push(""); + } + + select.html(options); + } + + module("kendo.ui.MultiSelect Events", { + setup: function() { + kendo.ns = "kendo-"; + select = $("").appendTo(QUnit.fixture); + }, + teardown: function() { + kendo.ns = ""; + if (select.data("kendoMultiSelect")) { + select.data("kendoMultiSelect").destroy(); + } + + select.parents(".k-widget").remove(); + } + }); + + asyncTest("MultiSelect filters items on keydown", 1, function() { + popuplateSelect(); + var multiselect = new MultiSelect(select, { + delay: 0 + }); + + multiselect.input.val("Option1").press("1"); + + setTimeout(function() { + start(); + equal(multiselect.ul.children().length, 1); + }); + }); + + test("MultiSelect filters data on rebind depending on the selected items", function() { + popuplateSelect(); + + var multiselect = new MultiSelect(select, { + delay: 0 + }); + + multiselect.search("Option1"); + multiselect.ul.children().first().click(); + + multiselect.open(); + + ok(!multiselect.ul.children().eq(1).is(":visible")); + }); + + test("MultiSelect filters data using selected items too", function() { + popuplateSelect(); + + var multiselect = new MultiSelect(select, { + delay: 0 + }); + + multiselect.ul.children().first().click(); + multiselect.search("Option1"); + multiselect.ul.children().first().click(); + + multiselect.input.click(); + + ok(!multiselect.ul.children().eq(0).is(":visible")); + ok(!multiselect.ul.children().eq(1).is(":visible")); + + ok(select[0].children[0].selected); + ok(select[0].children[1].selected); + }); + + test("MultiSelect filters data and hides already clicked items", function() { + popuplateSelect(); + + var multiselect = new MultiSelect(select, { + delay: 0 + }); + + multiselect.value(["0", "1"]); + multiselect.search("Opt"); + + var children = multiselect.ul.children(); + + equal(children.length, multiselect.dataSource.view().length); + ok(!children.eq(0).is(":visible")); + ok(!children.eq(1).is(":visible")); + }); + + test("MultiSelect hides popup if no data", function() { + popuplateSelect(); + var multiselect = new MultiSelect(select); + + multiselect.wrapper.click(); + multiselect.search("no such item"); + + ok(!multiselect.popup.visible()); + }); + + test("MultiSelect do not show initial values on rebind", function() { + popuplateSelect(); + var multiselect = new MultiSelect(select, { delay: 0, value: ["1", "2"] }); + + multiselect.search("Option0"); + multiselect.ul.children().first().click(); + multiselect.value(null); + + multiselect.open(); + + equal(multiselect.value().length, 0); + equal(multiselect.element.val(), null); + }); +})(); diff --git a/tests/multiselect/initialization.js b/tests/multiselect/initialization.js new file mode 100644 index 00000000000..1c6c7c661c8 --- /dev/null +++ b/tests/multiselect/initialization.js @@ -0,0 +1,444 @@ +(function() { + var MultiSelect = kendo.ui.MultiSelect, + select; + + function popuplateSelect() { + var options = []; + for (var i=0; i < 5; i++) { + options.push(""); + } + + select.html(options); + } + + module("kendo.ui.MultiSelect Initialization", { + setup: function() { + kendo.ns = ""; + select = $("").appendTo(QUnit.fixture)); + + var input = multiselect.input; + + equal(input.attr("tabIndex"), 5); + multiselect.destroy(); + }); + + test("do not highlight first on open", function() { + popuplateSelect(); + var multiselect = new MultiSelect(select, { highlightFirst: false }); + + multiselect.open(); + + equal(multiselect.current(), null); + }); + + test("do not highlight first item on refresh", function() { + popuplateSelect(); + var multiselect = new MultiSelect(select, { highlightFirst: false }); + + multiselect.open(); + multiselect.refresh(); + + equal(multiselect.current(), null); + }); + + test("Copy accesskey to the visible input", function() { + popuplateSelect(); + var multiselect = new MultiSelect(select.attr("accesskey", "w"), { highlightFirst: false }); + + ok(!multiselect.element.attr("accesskey")); + equal(multiselect.input.attr("accesskey"), "w"); + }); + + test("Scales correctly input element when init in hidden element", function() { + var div = $("
                                ").appendTo(document.documentElement); + div.append(select); + var multiselect = new MultiSelect(select, { placeholder: "Select something..." }); + + ok(multiselect.input.width() > 50); + }); + + test("MultiSelect honors readonly attribute", function() { + var multiselect = new MultiSelect(select.attr("readonly", true)); + + equal(multiselect.element.attr("readonly"), "readonly"); + equal(multiselect.element.attr("disabled"), undefined); + }); + + test("MultiSelect uses disabled attr over the readonly", function() { + var multiselect = new MultiSelect(select.attr("readonly", true).attr("disabled", true)); + + equal(select.attr("readonly"), undefined); + }); + + test("MultiSelect binds to simple data passed to value option if autoBind is false", function() { + var multiselect = new MultiSelect(select, { + autoBind: false, + value: [ + "Item1", + "Item3" + ] + }); + + equal(multiselect.element.children().length, 2); + equal(multiselect.dataItems().length, 2); + }); + + test("MultiSelect binds to complex data passed to value option if autoBind is false", function() { + var multiselect = new MultiSelect(select, { + autoBind: false, + dataValueField: "optionID", + dataTextField: "optionText", + value: [ + { optionID: "1", optionText: "Item1" }, + { optionID: "2", optionText: "Item2" } + ] + }); + + equal(multiselect.element.children().length, 2); + equal(multiselect.dataItems().length, 2); + equal(multiselect.value()[0], "1"); + equal(multiselect.value()[1], "2"); + }); + + test("MultiSelect binds to complex object passed to value option if autoBind is false", function() { + var multiselect = new MultiSelect(select, { + autoBind: false, + dataValueField: "optionID", + dataTextField: "optionText", + value: { optionID: "2", optionText: "Item2" } + }); + + equal(multiselect.element.children().length, 1); + equal(multiselect.dataItems().length, 1); + equal(multiselect.value()[0], "2"); + }); + + test("MultiSelect selects value even when values contains complex objects", function() { + var multiselect = new MultiSelect(select, { + dataSource: [ + { optionID: "1", optionText: "Item1" }, + { optionID: "2", optionText: "Item2" } + ], + dataValueField: "optionID", + dataTextField: "optionText", + value: [ + { optionID: "1", optionText: "Item1" }, + { optionID: "2", optionText: "Item2" } + ] + }); + + equal(multiselect.element.children().length, 2); + equal(multiselect.dataItems().length, 2); + equal(multiselect.value()[0], "1"); + equal(multiselect.value()[1], "2"); + }); + + test("MultiSelect does nothing if autoBind:false and simple strings is set as value", function() { + var multiselect = new MultiSelect(select, { + autoBind: false, + dataValueField: "optionID", + dataTextField: "optionText", + value: ["1", "2"] + }); + + equal(multiselect.element.children().length, 0); + equal(multiselect.dataItems().length, 0); + }); +})(); diff --git a/tests/multiselect/interaction.js b/tests/multiselect/interaction.js new file mode 100644 index 00000000000..69a5d251bbd --- /dev/null +++ b/tests/multiselect/interaction.js @@ -0,0 +1,399 @@ +(function() { + +var MultiSelect = kendo.ui.MultiSelect, + select; + +function populateSelect() { + var options = []; + for (var i=0; i < 5; i++) { + options.push(""); + } + + select.html(options); +} + +module("kendo.ui.MultiSelect interaction", { + setup: function() { + kendo.effects.disable(); + select = $("").appendTo(QUnit.fixture); + }, + teardown: function() { + kendo.effects.enable(); + select.data("kendoMultiSelect").destroy(); + } +}); + +test("MultiSelect selects corresponding option", function() { + populateSelect(); + + var multiselect = new MultiSelect(select); + multiselect.input.mousedown(); + multiselect.ul.children().eq(1).click(); + + ok(select[0].children[1].selected); +}); + +test("MultiSelect unselects option", function() { + populateSelect(); + + var multiselect = new MultiSelect(select); + multiselect.input.mousedown(); + multiselect.ul.children().eq(1).click(); + + multiselect.tagList.children().first().find(".k-delete").click(); + + ok(!select[0].children[1].selected); +}); + +test("MultiSelect persists selected data items", function() { + populateSelect(); + + var multiselect = new MultiSelect(select); + + multiselect.input.mousedown(); + multiselect.ul.children().eq(1).click(); + + //TODO: use method instead of _dataItems + equal(multiselect._dataItems.length, 1); +}); + +test("MultiSelect removes corresponding data item", function() { + populateSelect(); + + var multiselect = new MultiSelect(select); + + multiselect.input.mousedown(); + multiselect.ul.children().eq(1).click(); + multiselect.ul.children().eq(0).click(); + + //unselect item + multiselect.tagList.children().first().find(".k-delete").click(); + + //TODO: use method instead of _dataItems + equal(multiselect._dataItems.length, 1); + equal(multiselect._dataItems[0].value, 0); +}); + +test("MultiSelect clears input on selection", function() { + populateSelect(); + + var multiselect = new MultiSelect(select); + + multiselect.input.mousedown().val("option"); + multiselect.search("option"); + + multiselect.ul.children().eq(0).click(); + + equal(multiselect.input.val(), ""); +}); + +test("MultiSelect clears input on blur", function() { + var multiselect = new MultiSelect(select); + + multiselect.input.focus().val("test").blur(); + + equal(multiselect.input.val(), ""); +}); + +test("MultiSelect shows all available items if input is clear", function() { + populateSelect(); + var multiselect = new MultiSelect(select); + + multiselect.input.focus().val("nothing"); + multiselect.search("nothing"); + + multiselect.input.blur(); + + multiselect.open(); + + equal(multiselect.ul.children().length, 5); +}); + +test("MultiSelect focuses input on click", function() { + populateSelect(); + var multiselect = new MultiSelect(select); + + multiselect.wrapper.mousedown(); + + equal(multiselect.input[0], document.activeElement); +}); + +test("MultiSelect focuses input on click", function() { + populateSelect(); + var multiselect = new MultiSelect(select); + + multiselect.input.mousedown(); + multiselect.ul.children().eq(1).click(); + multiselect.ul.children().eq(0).click(); + multiselect.open(); + + multiselect.tagList.children().first().find(".k-delete").click(); + + ok(!multiselect.popup.visible()); +}); + +test("MultiSelect selects all selected options after filtering", function() { + populateSelect(); + var multiselect = new MultiSelect(select); + + multiselect.input.mousedown(); + multiselect.ul.children().eq(0).click(); + multiselect.ul.children().eq(1).click(); + + multiselect.input.mousedown(); + multiselect.search("Option4"); + + multiselect.ul.children().eq(0).click(); + + var options = select[0].children; + + equal(options.length, 3); + ok(options[0].selected); + ok(options[1].selected); + ok(options[2].selected); +}); + +test("MultiSelect highlights first item on refresh", function() { + populateSelect(); + var multiselect = new MultiSelect(select); + + multiselect.open(); + multiselect.refresh(); + + ok(multiselect.current().parent()[0]); +}); + +test("MultiSelect unselects custom option", function() { + var multiselect = new MultiSelect(select, { + dataSource: ["item1", "item2"], + value: ["item1", "item2"] + }); + + multiselect.dataSource.data(["item3", "item4"]); + multiselect.ul.children().eq(0).click(); + + multiselect.tagList.children().first().find(".k-delete").click(); + + ok(!select[0].children[2].selected); +}); + +test("MultiSelect closes popup on blur", function() { + populateSelect(); + var multiselect = new MultiSelect(select); + + multiselect.input.focus(); + multiselect.open(); + multiselect.input.blur(); + + ok(!multiselect.popup.visible()); +}); + +test("MultiSelect sets height on select", function() { + populateSelect(); + var multiselect = new MultiSelect(select); + + stub(multiselect, { + _height: multiselect._height + }); + + multiselect._select(0); + + equal(multiselect.calls("_height"), 1); +}); + +test("MultiSelect sets height on unselect", function() { + populateSelect(); + var multiselect = new MultiSelect(select, { + value: "0" + }); + + stub(multiselect, { + _height: multiselect._height + }); + + multiselect._unselect(multiselect.tagList.children(":first")); + + equal(multiselect.calls("_height"), 1); +}); + +test("MultiSelect honours minLength on click", function() { + populateSelect(); + var multiselect = new MultiSelect(select, { + minLength: 1, + autoBind: false + }); + + multiselect.wrapper.mousedown(); + + equal(multiselect.input[0], document.activeElement); + equal(multiselect.ul.children().length, 0); + ok(!multiselect.popup.visible()); +}); + +test("MultiSelect triggers blur event of the hidden element", 1, function() { + populateSelect(); + var multiselect = new MultiSelect(select, { + minLength: 1, + autoBind: false + }); + + select.blur(function() { + ok(true); + }); + + multiselect.input.focus().blur(); +}); + +test("MultiSelect calls dataSource fetch if autoBind:false", 1, function() { + var multiselect = new MultiSelect(select, { + autoBind: false, + value: ["Item1", "Item2"] + }); + + stub(multiselect.dataSource, { + filter: multiselect.dataSource.filter + }); + + multiselect.open(); + + ok(multiselect.dataSource.calls("filter") > 0); +}); + +test("MultiSelect does not prevent default when click input", 0, function() { + var multiselect = new MultiSelect(select); + + multiselect.input.trigger({ + type: "mousedown", + preventDefault: function() { + ok(false); + } + }); +}); + +})(); diff --git a/tests/multiselect/mvvm.js b/tests/multiselect/mvvm.js new file mode 100644 index 00000000000..ece8b81610d --- /dev/null +++ b/tests/multiselect/mvvm.js @@ -0,0 +1,727 @@ +(function() { + var Model = kendo.data.Model, dom; + + module('multiselect MVVM', { + setup: function() { + window.multiSelectDataBound = function() { + ok(true); + } + + QUnit.fixture.html(' \ + '); + }, + + teardown: function() { + kendo.destroy(dom); + } + }); + + test("initializes a multiselect when data role is multiselect", function() { + dom = $(''); + + kendo.bind(dom); + + var multiselect = dom.data("kendoMultiSelect"); + + equal(multiselect.options.dataTextField, "foo"); + equal(multiselect.options.dataValueField, "bar"); + }); + + test("initalizes data source", function() { + dom = $(''); + + kendo.bind(dom, { items: ["foo", "bar"], value: "bar" } ); + + equal(dom.data("kendoMultiSelect").value().length, 1); + equal(dom.data("kendoMultiSelect").value()[0], "bar"); + }); + + test("initalizes complex value from view model", function() { + dom = $(''); + + var viewModel = kendo.observable({ + items: [ { name: "foo" }, { name: "bar" }, { name: "baz" } ], + selectedItem: [] + }); + + viewModel.selectedItem.push(viewModel.items[1]); + viewModel.selectedItem.push(viewModel.items[2]); + + kendo.bind(dom, viewModel); + ok(dom.find("option").eq(1).is(":selected")); + ok(dom.find("option").eq(2).is(":selected")); + }); + + test("binding multi select value to observable object", function() { + dom = $(''); + + var observable = kendo.observable({ + items: [ { name: "foo" }, { name: "bar" }, { name: "baz" } ], + selectedItem: [] + }); + + kendo.bind(dom, observable); + dom.data("kendoMultiSelect").value(["foo", "bar"]); + dom.data("kendoMultiSelect").trigger("change"); + + equal(observable.selectedItem[0], observable.items[0]); + equal(observable.selectedItem[1], observable.items[1]); + }); + + test("uses data value field if data-value-primitive is set to true", function() { + dom = $(''); + + var observable = kendo.observable({ + items: [ { name: "foo" }, { name: "bar" }, { name: "baz" } ], + selectedItem: [] + }); + + var observableInstance = observable.selectedItem; + + kendo.bind(dom, observable); + dom.data("kendoMultiSelect").value(["foo", "bar"]); + dom.data("kendoMultiSelect").trigger("change"); + + equal(observable.selectedItem, observableInstance); + }); + + test("selecting initial value marks model as dirty", 1, function() { + dom = $(''); + + var observable = new Model({ + items: [ { name: "foo" }, { name: "bar" }, { name: "baz" } ], + selectedItem: [ { name: "foo" } ] + }); + + observable.bind("change", function() { + equal(this.dirty, true); + }); + + kendo.bind(dom, observable); + dom.data("kendoMultiSelect").value([]); + dom.data("kendoMultiSelect").trigger("change"); + }); + + test("remove last item triggers change once", 2, function() { + dom = $(''); + + var observable = new Model({ + items: [ { name: "foo" }, { name: "bar" }, { name: "baz" } ], + selectedItem: [ { name: "foo" }, { name: "bar" } ] + }); + + var timesCalled = 0; + + observable.bind("change", function() { + timesCalled ++; + }); + + kendo.bind(dom, observable); + dom.data("kendoMultiSelect").value([ "bar" ]); + dom.data("kendoMultiSelect").trigger("change"); + + equal(timesCalled, 1); + equal(observable.selectedItem.length, 1); + }); + + test("changing a value updates ObservableArray property when multiselect is filtered", function() { + dom = $(''); + + var multiselect; + + var observable = kendo.observable({ + items: [ { name: "foo" }, { name: "bar" }, { name: "baz" } ], + nested: { + selectedItem: [{ name: "foo" }] + } + }); + + kendo.bind(dom, observable); + + multiselect = dom.data("kendoMultiSelect"); + multiselect.search("bar"); + multiselect.ul.children().first().click(); //select "bar" + + equal(observable.nested.selectedItem.length, 2); + equal(multiselect.dataItems().length, 2); + }); + + test("clearing value of the widget sets model property to empty array", function() { + dom = $(''); + + var observable = kendo.observable({ + items: [ { name: "foo" }, { name: "bar" }, { name: "baz" } ], + value: "foo" + }); + + kendo.bind(dom, observable); + dom.data("kendoMultiSelect").value(null); + dom.data("kendoMultiSelect").trigger("change"); + + ok(observable.value instanceof kendo.data.ObservableArray); + equal(observable.value.length, 0); + }); + + test("binding multiselect initialized before binding", function() { + dom = $(''); + + var observable = kendo.observable({ items: [{text:"foo"}, {text:"bar"}], value: null }); + observable.value = observable.items[1]; + + kendo.bind(dom, observable); + + dom.kendoMultiSelect(); + + equal(dom.data("kendoMultiSelect").value().length, 1); + equal(dom.data("kendoMultiSelect").value()[0], "bar"); + }); + + test("binding template", function() { + dom = $(''); + + var observable = kendo.observable({ items: [{text:"foo"}, {text:"bar"}] }); + + kendo.bind(dom, observable); + + equal($.trim(dom.data("kendoMultiSelect").ul.children().eq(0).html()), 'foo'); + }); + + test("updating an item from the data source updates the corresponding multiselect item", function() { + dom = $(''); + + var observable = kendo.observable({ items: [{ text:"foo"} ] }); + + kendo.bind(dom, observable); + dom.data("kendoMultiSelect").refresh(); + + equal(observable.items[0]._events["change"].length, 2); //1 for the text binding and 1 for the ObservableArray + }); + + test("removing items from the model updates the UI", function() { + dom = $(''); + + var observable = kendo.observable({ items: [{ text:"foo"},{ text: "bar" } ] }); + + kendo.bind(dom, observable); + + var destroy = stub(dom[0].kendoBindingTarget, "destroy"); + + kendo.bind(dom, observable); + + equal(destroy.calls("destroy"), 1); + }); + + test("expressions are destroyed", 1, function() { + dom = $(''); + + var observable = kendo.observable({ + enabled: false + }); + + kendo.bind(dom, observable); + + ok(dom.is(":disabled")); + }); + + test("binding enabled to true enables the widget", function() { + dom = $(''); + + var observable = kendo.observable({ + disabled: false + }); + + kendo.bind(dom, observable); + + ok(!dom.is(":disabled")); + }); + + test("binding disabled to false enables the widget", function() { + dom = $(''); + + var observable = kendo.observable({ + invisible: true + }); + + kendo.bind(dom, observable); + + ok(dom.data("kendoMultiSelect").wrapper.css("display") == "none", "Display is 'none'"); + }); + + test("binding invisible to false shows the widget", function() { + dom = $(''); + + var observable = kendo.observable({ + invisible: false + }); + + kendo.bind(dom, observable); + observable.set("invisible", true); + + ok(dom.data("kendoMultiSelect").wrapper.css("display") == "none", "Display is 'none'"); + }); + + test("changing invisible to false shows the widget", function() { + dom = $(''); + + var observable = kendo.observable({ + enabled: false + }); + + kendo.bind(dom, observable); + + ok(dom.is(":disabled")); + }); + + test("binding visible to false hides the widget", function() { + dom = $(''); + + var observable = kendo.observable({ + visible: true + }); + + kendo.bind(dom, observable); + + ok(dom.data("kendoMultiSelect").wrapper.css("display") != "none", "Display is not 'none'"); + }); + + test("changing visible to false hides the widget", function() { + dom = $(''); + + var observable = kendo.observable({ + visible: false + }); + + kendo.bind(dom, observable); + observable.set("visible", true); + + ok(dom.data("kendoMultiSelect").wrapper.css("display") != "none", "Display is not 'none'"); + }); + + test("assign to DataSource as ViewModel field", function() { + dom = $(''); + var observable = kendo.observable({ + data: [1,2], + multiselectData: [{ID: 1, Text: "Text1"}, {ID: 2, Text: "Text2"}, {ID: 3, Text: "Text3"}] + }); + + kendo.bind(dom, observable); + ok(true); + }); + + test("Adding item to empty observable array raises change with add action", 4, function() { + dom = $(''); + var observable = kendo.observable({ + data: [], + multiselectData: [{ID: 1, Text: "Text1"}, {ID: 2, Text: "Text2"}, {ID: 3, Text: "Text3"}] + }); + + kendo.bind(dom, observable); + + var multiselect = dom.data("kendoMultiSelect"); + + observable.data.bind("change", function(e) { + equal(e.action, "add"); + equal(e.items.length, 1); + equal(e.items[0], observable.multiselectData[0]); + equal(e.index, 0); + }); + + multiselect.value([1]); + multiselect.trigger("change"); + }); + + test("Adding item to non-empty observable array raises change event with add action (value primitive)", 4, function() { + dom = $(''); + var observable = kendo.observable({ + data: [1], + multiselectData: [{ID: 1, Text: "Text1"}, {ID: 2, Text: "Text2"}, {ID: 3, Text: "Text3"}] + }); + + kendo.bind(dom, observable); + + var multiselect = dom.data("kendoMultiSelect"); + + observable.data.bind("change", function(e) { + equal(e.action, "add"); + equal(e.items.length, 1); + equal(e.items[0], 2); + equal(e.index, 1); + }); + + multiselect.value([1, 2]); + multiselect.trigger("change"); + }); + + test("Remove item raises change with remove action (value primitive)", 4, function() { + dom = $(''); + var observable = kendo.observable({ + data: [1,2], + multiselectData: [{ID: 1, Text: "Text1"}, {ID: 2, Text: "Text2"}, {ID: 3, Text: "Text3"}] + }); + + kendo.bind(dom, observable); + + var multiselect = dom.data("kendoMultiSelect"); + + observable.data.bind("change", function(e) { + equal(e.action, "remove"); + equal(e.items.length, 1); + equal(e.items[0], 2); + equal(e.index, 1); + }); + + multiselect.value([1]); + multiselect.trigger("change"); + }); + + test("Remove first item raises change with correct index", 1, function() { + dom = $(''); + var observable = kendo.observable({ + data: [1,2], + multiselectData: [{ID: 1, Text: "Text1"}, {ID: 2, Text: "Text2"}, {ID: 3, Text: "Text3"}] + }); + + kendo.bind(dom, observable); + + var multiselect = dom.data("kendoMultiSelect"); + + observable.data.bind("change", function(e) { + equal(e.index, 0); + }); + + multiselect.value([2]); + multiselect.trigger("change"); + }); +})(); diff --git a/tests/multiselect/navigation.js b/tests/multiselect/navigation.js new file mode 100644 index 00000000000..6ff671a512b --- /dev/null +++ b/tests/multiselect/navigation.js @@ -0,0 +1,540 @@ +(function() { + var MultiSelect = kendo.ui.MultiSelect, + keys = kendo.keys, + select; + + function populateSelect(length) { + var options = []; + length = length || 5; + for (var i=0; i < length; i++) { + options.push(""); + } + + select.html(options); + } + + module("kendo.ui.MultiSelect navigation", { + setup: function() { + $.fn.press = function(character) { + var keyCode = character.charCodeAt(0); + $(this).trigger({ + type: "keydown", + keyCode: keyCode + }); + } + + kendo.ns = "kendo-"; + kendo.effects.disable(); + select = $("").appendTo(document.body); + populateSelect(); + }, + teardown: function() { + if (select.data("kendoMultiSelect")) { + select.data("kendoMultiSelect").destroy(); + } + + select.parents(".k-widget").remove(); + } + }); + + test("MultiSelect focuses last tag if input is empty", function() { + var multiselect = new MultiSelect(select); + + //opens popup and scrolls + multiselect.value(["1", "2"]); + + multiselect.input.focus(); + + multiselect.input.trigger({ + type: "keydown", + keyCode: keys.LEFT + }); + + var tag = multiselect.tagList.children().last(); + + ok(tag.hasClass("k-state-focused")); + }); + + test("MultiSelect focuses previous tag if input is empty", function() { + var multiselect = new MultiSelect(select); + + //opens popup and scrolls + multiselect.value(["1", "2"]); + multiselect.input.focus(); + multiselect.currentTag(multiselect.tagList.children().last()); + multiselect.input.trigger({ + type: "keydown", + keyCode: keys.LEFT + }); + + var tag = multiselect.currentTag(); + + equal(tag.index(), 0); + ok(tag.hasClass("k-state-focused")); + }); + + test("MultiSelect persist focus to the first LI on LEFT", function() { + var multiselect = new MultiSelect(select); + + //opens popup and scrolls + multiselect.value(["1", "2"]); + multiselect.input.focus(); + multiselect.currentTag(multiselect.tagList.children().first()); + multiselect.input.trigger({ + type: "keydown", + keyCode: keys.LEFT + }); + + var tag = multiselect.currentTag(); + + equal(tag.index(), 0); + ok(tag.hasClass("k-state-focused")); + }); + + test("MultiSelect focuses next tag if any is focused", function() { + var multiselect = new MultiSelect(select); + + //opens popup and scrolls + multiselect.value(["1", "2"]); + multiselect.input.focus(); + + multiselect.currentTag(multiselect.tagList.children().first()); + + multiselect.input.trigger({ + type: "keydown", + keyCode: keys.RIGHT + }); + + var tag = multiselect.currentTag(); + + equal(tag.index(), 1); + ok(tag.hasClass("k-state-focused")); + }); + + test("MultiSelect un-focuses last tag if RIGHT is pressed ", function() { + var multiselect = new MultiSelect(select); + + //opens popup and scrolls + multiselect.value(["1", "2"]); + multiselect.input.focus(); + + multiselect.currentTag(multiselect.tagList.children().last()); + + multiselect.input.trigger({ + type: "keydown", + keyCode: keys.RIGHT + }); + + var tag = multiselect.currentTag(); + + equal(tag, null); + }); + + test("MultiSelect un-focuses tag on selection", function() { + var multiselect = new MultiSelect(select); + + //opens popup and scrolls + multiselect.input.mousedown(); + + multiselect.currentTag(multiselect.tagList.children().last()); + + multiselect.input.trigger({ + type: "keydown", + keyCode: keys.ENTER + }); + + var tag = multiselect.currentTag(); + + equal(tag, null); + }); + + + test("MultiSelect deletes focused tag", function() { + var multiselect = new MultiSelect(select); + + //opens popup and scrolls + multiselect.value(["1", "2"]); + multiselect.input.focus(); + + multiselect.currentTag(multiselect.tagList.children().last()); + + multiselect.input.trigger({ + type: "keydown", + keyCode: keys.DELETE + }); + + equal(multiselect.currentTag(), null); + equal(multiselect.tagList.children().length, 1); + }); + + test("MultiSelect deletes last tag on BACKSPACE if input is empty", function() { + var multiselect = new MultiSelect(select); + + //opens popup and scrolls + multiselect.value(["0", "1"]); + multiselect.input.focus(); + + multiselect.input.trigger({ + type: "keydown", + keyCode: keys.BACKSPACE + }); + + equal(multiselect.currentTag(), null); + equal(multiselect.tagList.children().length, 1); + equal(multiselect.tagList.children().eq(0).find("span").html(), "Option0"); + }); + + test("MultiSelect does not raise exception on DELETE", 1, function() { + var multiselect = new MultiSelect(select); + multiselect.input.focus(); + + multiselect.input.trigger({ + type: "keydown", + keyCode: keys.BACKSPACE + }); + + ok(true); + }); + + test("MultiSelect focuses first tag on HOME", function() { + var multiselect = new MultiSelect(select); + + //opens popup and scrolls + multiselect.value(["0", "1"]); + multiselect.input.focus(); + + multiselect.input.trigger({ + type: "keydown", + keyCode: keys.HOME + }); + + var tag = multiselect.currentTag(); + + equal(tag.index(), 0); + }); + + test("MultiSelect focuses last tag on END", function() { + var multiselect = new MultiSelect(select); + + //opens popup and scrolls + multiselect.value(["0", "1"]); + multiselect.input.focus(); + + multiselect.input.trigger({ + type: "keydown", + keyCode: keys.END + }); + + var tag = multiselect.currentTag(); + + equal(tag.index(), 1); + }); + + test("MultiSelect closes popup when deletes tag", function() { + var multiselect = new MultiSelect(select); + + //opens popup and scrolls + multiselect.value(["0", "1"]); + multiselect.input.click(); + + multiselect.input.trigger({ + type: "keydown", + keyCode: keys.BACKSPACE + }); + + ok(!multiselect.popup.visible()); + }); + + test("MultiSelect highlights last item of the popup on END", function() { + var multiselect = new MultiSelect(select); + + //opens popup and scrolls + multiselect.value(["0", "1"]); + multiselect.open(); + + multiselect.input.focus().trigger({ + type: "keydown", + keyCode: keys.END + }); + + var item = multiselect.current(); + + equal(item[0], multiselect.ul.children().last()[0]); + }); + + test("MultiSelect clears focused tag when navigate through the popup", function() { + var multiselect = new MultiSelect(select); + + //opens popup and scrolls + multiselect.value(["0", "1"]); + multiselect.open(); + + multiselect.currentTag(multiselect.tagList.children().first()); + multiselect.input.focus().trigger({ + type: "keydown", + keyCode: keys.END + }); + + equal(multiselect.currentTag(), null); + }); + + test("MultiSelect highlights first item of the popup on HOME", function() { + var multiselect = new MultiSelect(select); + + //opens popup and scrolls + multiselect.value(["0", "1"]); + multiselect.open(); + + multiselect.current(multiselect.ul.children().last()); + multiselect.input.focus().trigger({ + type: "keydown", + keyCode: keys.HOME + }); + + var item = multiselect.current(); + + equal(item[0], multiselect.ul.children(":visible").first()[0]); + }); + + test("MultiSelect clears focused tag when navigate through the popup", function() { + var multiselect = new MultiSelect(select); + + //opens popup and scrolls + multiselect.value(["0", "1"]); + multiselect.open(); + + multiselect.currentTag(multiselect.tagList.children().first()); + multiselect.input.focus().trigger({ + type: "keydown", + keyCode: keys.HOME + }); + + equal(multiselect.currentTag(), null); + }); + + test("MultiSelect clears selection in selected items on ESC", function() { + var multiselect = new MultiSelect(select, { value: "1" }); + + multiselect.input.trigger({ + type: "keydown", + keyCode: keys.HOME + }); + multiselect.input.trigger({ + type: "keydown", + keyCode: keys.ESC + }); + + equal(multiselect.currentTag(), null); + }); +})(); diff --git a/tests/multiselect/placeholder.js b/tests/multiselect/placeholder.js new file mode 100644 index 00000000000..a2904e44b02 --- /dev/null +++ b/tests/multiselect/placeholder.js @@ -0,0 +1,94 @@ +(function() { + var MultiSelect = kendo.ui.MultiSelect, + select; + + function populateSelect() { + var options = []; + for (var i=0; i < 5; i++) { + options.push(""); + } + + select.html(options); + } + + module("kendo.ui.MultiSelect Placeholder", { + setup: function() { + kendo.ns = "kendo-"; + select = $("'); + + kendo.bind(dom, { foo: "foo" }); + equal(dom.val(), "foo"); +}); + +test("title binding", function() { + dom = $(''); + + kendo.bind(dom, { foo: "foo" }); + equal(dom.attr("title"), "foo"); +}); + +test("alt binding", function() { + dom = $(''); + + kendo.bind(dom, { foo: "foo" }); + equal(dom.attr("alt"), "foo"); +}); + +test("src binding", function() { + dom = $(''); + + kendo.bind(dom, { foo: "http://www.example.com" }); + equal(dom.attr("src"), "http://www.example.com"); +}); + +test("href binding", function() { + dom = $(''); + + kendo.bind(dom, { foo: "foo" }); + equal(dom.attr("href"), "foo"); +}); + +test("data attribute binding", function() { + dom = $(''); + + kendo.bind(dom, { foo: "foo" }); + equal(dom.attr("data-foo"), "foo"); +}); + +test("binding to array access expression", function() { + dom = $(''); + + kendo.bind(dom, { "1": "foo" }); + + equal(dom.text(), "foo"); +}); + +test("binding immediate children", function() { + dom = $(''); + + kendo.bind(dom, { foo: "foo" }); + equal(dom.find("img").attr("alt"), "foo"); +}); + +test("binding arbitrary children", function() { + dom = $(''); + + kendo.bind(dom, { foo: "foo" }); + equal(dom.find("img").attr("alt"), "foo"); +}); + +test("binding multiple attributes", function() { + dom = $(''); + + kendo.bind(dom, { foo: "foo" }); + equal(dom.attr("href"), "foo"); + equal(dom.attr("title"), "foo"); +}); + +test("binding custom attributes", function() { + dom = $(''); + + kendo.bind(dom, { foo: "foo" }); + equal(dom.attr("custom"), "foo"); +}); + +test("click binding", 1, function() { + dom = $(''); + + kendo.bind(dom, { + foo: function() { + ok(true, "click is raised"); + } + }); + + dom.trigger("click"); +}); + +test("click event binding is detached", 1, function() { + dom = $(''); + + kendo.bind(dom, { + foo: function() { + ok(true, "click is raised"); + } + }); + + dom.trigger("click"); + + kendo.unbind(dom); + + dom.trigger("click"); +}); + +test("events binding is detached", 1, function() { + dom = $(''); + + kendo.bind(dom, { + foo: function() { + ok(true, "click is raised"); + } + }); + + dom.trigger("click"); + + kendo.unbind(dom); + + dom.trigger("click"); +}); + +test("change binding", 1, function() { + dom = $(''); + + kendo.bind(dom, { + foo: function() { + ok(true, "change is raised"); + } + }); + + dom.trigger("change"); +}); + +test("the context of the event handler is the viewmodel",1, function() { + dom = $(''); + var viewModel = kendo.observable( { + foo: function() { + strictEqual(this, viewModel); + } + }); + + kendo.bind(dom, viewModel); + + dom.trigger("click"); +}); + +test("the context of the nested function call is the nested observable object", 1, function() { + expect(1); + + dom = $(''); + var viewModel = kendo.observable( { + nested: { + foo: function() { + strictEqual(this, viewModel.nested); + } + } + }); + + kendo.bind(dom, viewModel); +}); + +test("select binding", function() { + dom = $(''); + + kendo.bind(dom, { + foo: [ { + id: 1, + name: "foo" + }] + }); + + equal(dom.find("option").text(), "foo"); + equal(dom.find("option").val(), "1"); +}); + +test("select binding to data source", function() { + dom = $(''); + + kendo.bind(dom, { + foo: new kendo.data.DataSource( { + data: [ { + id: 1, + name: "foo" + }] + } ) + }); + + equal(dom.find("option").length, 0); +}); + +test("pushing items to array creates new option elements without destroying the existing ones", function() { + dom = $(''); + + var viewModel = kendo.observable( { + foo: new kendo.data.DataSource( { + data: [ + { id: 1, name: "foo" } + ] + } ) + }); + + kendo.bind(dom, viewModel); + + var option = dom.find("option")[0]; + + viewModel.foo.add({ id: 2, name: "bar" }); + + equal(dom.find("option").length, viewModel.foo.data().length); + equal(dom.find("option").eq(1).text(), "bar"); + equal(dom.find("option")[0], option); +}); + +test("value of private field is shown", function() { + dom = $(''); + + var viewModel = kendo.observable( { + _foo:"bar" + }); + + kendo.bind(dom, viewModel); + + equal(dom.text(), "bar"); +}); + +test("pushing items to array initializes child bindings", function() { + dom = $('
                                  '); + + var viewModel = kendo.observable( { + foo: [1, 2] + }); + + kendo.bind(dom, viewModel); + + viewModel.foo.push(3, 4); + + equal(dom.find("li:last").text(), "4"); +}); + +test("splicing items from array removes option elements without destroying the existing ones", function() { + dom = $(''); + + var viewModel = kendo.observable( { + foo: new kendo.data.DataSource( { + data: [ + { id: 1, name: "1" }, + { id: 2, name: "2" }, + { id: 3, name: "3" }, + { id: 4, name: "4" } + ] + } ) + }); + + kendo.bind(dom, viewModel); + + var firstOption = dom.find("option")[0]; + var lastOption = dom.find("option")[3]; + + viewModel.foo.remove(viewModel.foo.at(1)); + + equal(dom.find("option").length, viewModel.foo.data().length); + equal(dom.find("option")[0], firstOption); + equal(dom.find("option")[2], lastOption); +}); + +test("bind array to table appends table rows to the table body", function() { + dom = $('
                                  '); + + var viewModel = kendo.observable( { + foo: [1, 2] + }); + + kendo.bind(dom, viewModel); + equal(dom.find("tbody > tr").length, viewModel.foo.length); +}); + +test("bind array to table keeps thead", function() { + dom = $('
                                  '); + + var viewModel = kendo.observable( { + foo: [1, 2] + }); + + kendo.bind(dom, viewModel); + equal(dom.find("thead > tr").length, 1); +}); + +test("bind array to unordered list creates list item elements", function() { + dom = $('
                                    '); + + var viewModel = kendo.observable( { + foo: [1, 2] + }); + + kendo.bind(dom, viewModel); + equal(dom.find("li").length, viewModel.foo.length); +}); + +test("bind array to ordered list creates list item elements", function() { + dom = $('
                                      '); + + var viewModel = kendo.observable( { + foo: [1, 2] + }); + + kendo.bind(dom, viewModel); + equal(dom.find("li").length, viewModel.foo.length); +}); + +test("binding child elements of template to data item", function() { + dom = $('
                                        '); + + var viewModel = kendo.observable( { + foo: [{ name: "foo"}] + }); + + kendo.bind(dom, viewModel); + equal(dom.find("li").text(), viewModel.foo[0].name); +}); + +test("binding child elements of template to data item of primitive type", function() { + dom = $('
                                          '); + + var viewModel = kendo.observable( { + foo: [1] + }); + + kendo.bind(dom, viewModel); + equal(dom.find("li").text(), viewModel.foo[0]); +}); + +test("template binding without source", function() { + dom = $('
                                          '); + + kendo.bind(dom, { foo: "foo" }); + + equal($.trim(dom.text()), "Hello, foofoo"); +}); + +test("binding to nested field", function() { + dom = $('
                                          '); + + kendo.bind(dom, { foo: { bar: "baz" } }); + + equal(dom.text(), "baz"); +}); + +test("binding to array item", function() { + dom = $('
                                          '); + + kendo.bind(dom, { foo: ["baz"] }); + + equal(dom.text(), "baz"); +}); + +test("binding the style attribute", function() { + dom = $('
                                          '); + + kendo.bind(dom, { foo: "none", bar: "underline" }); + + equal(dom.css("display"), "none"); + equal(dom.css("text-decoration"), "underline"); +}); + +test("binding select value to object", function() { + dom = $(''); + + var viewModel = kendo.observable({ + items: [ { name: "foo" }, { name: "bar" } ], + selectedItem: {} + }); + + viewModel.set("selectedItem", viewModel.items[1]); + + kendo.bind(dom, viewModel); + ok(dom.find("option").last().is(":selected")); +}); + +test("binding select to array of objects", function() { + dom = $(''); + + var viewModel = kendo.observable({ + items: function() { return [ "foo","bar" ] }, + selectedItem: {} + }); + + viewModel.set("selectedItem", viewModel.items()[1]); + + kendo.bind(dom, viewModel); + equal(dom.find("option").length, 2); + equal(dom.find("option").first().text(), "foo"); + equal(dom.find("option").first().val(), "foo"); + equal(dom.find("option").last().text(), "bar"); + equal(dom.find("option").last().val(), "bar"); + + ok(dom.find("option").last().is(":selected")); +}); + +test("binding select value to object specifing only text-field", function() { + dom = $(''); + + var viewModel = kendo.observable({ + items: ["foo", "bar"], + selectedItem: "bar" + }); + + kendo.bind(dom, viewModel); + ok(dom.find("option").last().is(":selected")); +}); + +test("binding pre populated select value", function() { + dom = $(''); + + var viewModel = kendo.observable({ + items: [ { name: "foo" }, { name: "bar" }, { name: "baz" } ], + selectedItem: [] + }); + + viewModel.selectedItem.push(viewModel.items[1]); + viewModel.selectedItem.push(viewModel.items[2]); + + kendo.bind(dom, viewModel); + ok(dom.find("option").eq(1).is(":selected")); + ok(dom.find("option").eq(2).is(":selected")); +}); + +test("binding multi select is update if value is removed", function() { + dom = $(''); + + var viewModel = kendo.observable({ + selectedItem: "" + }); + + viewModel.set("selectedItem", "foo"); + + kendo.bind(dom, viewModel); + ok(dom.is(":checked")); +}); + +test("checked binding binds radiobutton to boolean value", function() { + dom = $(''); + + var viewModel = kendo.observable({ + selectedItem: true + }); + + kendo.bind(dom, viewModel); + ok(dom.is(":checked")); +}); + +test("checked binding binds radiobutton to number value", function() { + dom = $(''); + + var viewModel = kendo.observable({ + selectedItem: 1 + }); + + kendo.bind(dom, viewModel); + ok(dom.is(":checked")); +}); + +test("checked binding binds checkbox to boolean", function() { + dom = $(''); + + var viewModel = kendo.observable({ + selectedItem: false + }); + + viewModel.set("selectedItem", true); + + kendo.bind(dom, viewModel); + ok(dom.is(":checked")); +}); + +test("checked binding binds checkbox by value to array", function() { + dom = $(''); + + var viewModel = kendo.observable({ + selectedItems: [] + }); + + viewModel.selectedItems.push("foo"); + + kendo.bind(dom, viewModel); + ok(dom.is(":checked")); +}); + +test("checked binding checkbox is not checked if value does not exists", function() { + dom = $(''); + + var viewModel = kendo.observable({ + selectedItems: [] + }); + + kendo.bind(dom, viewModel); + ok(!dom.is(":checked")); +}); + +test("visible binding shows the element", function() { + dom = $(''); + + var viewModel = kendo.observable({ + show: true + }); + + kendo.bind(dom, viewModel); + ok(dom.css("display") != "none", "Display is not 'none'"); +}); + +test("visible binding hides the element", function() { + dom = $(''); + + var viewModel = kendo.observable({ + show: true + }); + + kendo.bind(dom, viewModel); + + viewModel.set("show", false); + + equal(dom.css("display"), "none"); +}); + +test("invisible binding hides the element", function() { + dom = $(''); + + var viewModel = kendo.observable({ + hide: true + }); + + kendo.bind(dom, viewModel); + equal(dom.css("display"), "none"); +}); + +test("invisible binding shows the element", function() { + dom = $(''); + + var viewModel = kendo.observable({ + hide: true + }); + + kendo.bind(dom, viewModel); + + viewModel.set("hide", false); + + ok(dom.css("display") != "none", "Display is not 'none'"); +}); + +test("enable binding enables the element", function() { + dom = $(''); + + var viewModel = kendo.observable({ + enable: true + }); + + kendo.bind(dom, viewModel); + ok(!dom.is(":disabled")); +}); + +test("enable binding disables the element if value is false", function() { + dom = $(''); + + var viewModel = kendo.observable({ + enable: false + }); + + kendo.bind(dom, viewModel); + ok(dom.is(":disabled")); +}); + +test("enable binding disables the element if value is changed to false", function() { + dom = $(''); + + var viewModel = kendo.observable({ + enable: true + }); + + kendo.bind(dom, viewModel); + viewModel.set("enable", false); + ok(dom.is(":disabled")); +}); + +test("enable binding enables the select element", function() { + dom = $(''); + + var viewModel = kendo.observable({ + disabled: true + }); + + kendo.bind(dom, viewModel); + ok(dom.is(":disabled")); +}); + +test("disable binding enables the element if value is false", function() { + dom = $(''); + + var viewModel = kendo.observable({ + disabled: false + }); + + kendo.bind(dom, viewModel); + ok(!dom.is(":disabled")); +}); + +test("disable binding disables the element if value is changed to true", function() { + dom = $(''); + + var viewModel = kendo.observable({ + disabled: false + }); + + kendo.bind(dom, viewModel); + viewModel.set("disabled", true); + ok(dom.is(":disabled")); +}); + +test("disable binding disables the select element", function() { + dom = $(''); + kendo.bind(dom, {}); + + equal(dom.val(), ""); +}); + +test("value binding displays null fields as empty string", function() { + dom = $(''); + kendo.bind(dom, { foo:null }); + + equal(dom.val(), ""); +}); + +test("visible binding to undefined hides the element", function() { + dom = $(''); + kendo.bind(dom, {}); + + equal(dom.css("display"), "none"); +}); + +test("visible binding to null hides the element", function() { + dom = $(''); + kendo.bind(dom, {show:null}); + + equal(dom.css("display"), "none"); +}); + +test("visible binding to zero hides the element", function() { + dom = $(''); + kendo.bind(dom, {show:0}); + + equal(dom.css("display"), "none"); +}); + +test("visible binding to empty string hides the element", function() { + dom = $(''); + kendo.bind(dom, {show:""}); + + equal(dom.css("display"), "none"); +}); + +test("invisible binding to undefined shows the element", function() { + dom = $(''); + kendo.bind(dom, {}); + + ok(dom.css("display") != "none"); +}); + +test("invisible binding to null shows the element", function() { + dom = $(''); + kendo.bind(dom, {show:null}); + + ok(dom.css("display") != "none"); +}); + +test("invisible binding to zero shows the element", function() { + dom = $(''); + kendo.bind(dom, {show:0}); + + ok(dom.css("display") != "none"); +}); + +test("invisible binding to empty string shows the element", function() { + dom = $(''); + kendo.bind(dom, {show:""}); + + ok(dom.css("display") != "none"); +}); + +test("readonly binding to true-ish value sets the readonly attribute", function() { + dom = $(''); + kendo.bind(dom, {readonly: true}); + + equal(dom.attr("readonly"), "readonly"); +}); + +test("readonly binding to false-ish value removes the readonly attribute", function() { + dom = $(''); + kendo.bind(dom, {readonly: false}); + + equal(dom[0].hasAttribute("readonly"), false); +}); + +test("mobile and desktop widgets are initialized in the correct priority", function() { + var TestWidget = kendo.ui.Widget.extend({ + options: { + name: "TestWidget" + } + }); + kendo.ui.plugin(TestWidget); + + var MobileTestWidget = kendo.mobile.ui.Widget.extend({ + options: { + name: "TestWidget" + } + }); + kendo.mobile.ui.plugin(MobileTestWidget); + + dom = $("
                                          "); + kendo.bind(dom, kendo.observable({foo: ["bar"]}), kendo.mobile.ui, kendo.ui); + ok(dom.find("span").data("kendoMobileTestWidget")); +}); + +test("bind to parent property with nested kendo.bind", function() { + var viewModel = kendo.observable({ + foo: { + bar: "baz" + }, + items: [1,2,3,4] + }); + + dom = $("
                                          "); + + kendo.bind(dom, viewModel); + + dom.append($('
                                          ')); + + kendo.bind(dom.find("div.nested"), viewModel.foo); + + equal(dom.find("select")[0].options.length, 4); +}); + +test("binding ignores text nodes", 1, function() { + dom = $('Foo Bar'); + + kendo.bind(dom); + ok(true); +}); + +test("source binding destroy unbinds other change handlers", 1, function() { + dom = $(''); + + kendo.bind(dom, { + date: new Date("2013/6/3") + }); + + equal(dom.val(), "2013-06-03"); + }); +} + +if (kendo.support.input.datetimelocal) { + test("input type datetime value binding", function() { + dom = $(''); + + kendo.bind(dom, { + date: new Date("2013/6/3 20:30:52") + }); + + equal(dom.val(), "2013-06-03T20:30:52"); + }); +} + +if (kendo.support.input.number) { + test("input type number value binding", function() { + dom = $(''); + + kendo.bind(dom, { + number: 3.14 + }); + + equal(dom.val(), "3.14"); + }); +} + +}()); diff --git a/tests/mvvm/changing.js b/tests/mvvm/changing.js new file mode 100644 index 00000000000..9e8bc2382ce --- /dev/null +++ b/tests/mvvm/changing.js @@ -0,0 +1,1135 @@ +(function(){ + +module("mvvm observing", { + setup: function() { + this.sourceBinder = kendo.data.binders.source; + QUnit.fixture.append( + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + ); + }, + teardown: function() { + kendo.data.binders.source = this.sourceBinder; + } +}); + +test("changing a view model field reflects UI", function() { + var viewModel = kendo.observable( { + foo: "foo" + }); + + var dom = $(''); + kendo.bind(dom, viewModel); + viewModel.set("foo", "bar"); + equal(dom.text(), "bar"); +}); + +test("changing a view model field reflects UI via array access", function() { + var viewModel = kendo.observable( { + "1": "foo" + }); + + var dom = $(''); + kendo.bind(dom, viewModel); + viewModel.set("['1']", "bar"); + equal(dom.text(), "bar"); +}); + +test("field name of nested view model remains the same", 1, function() { + var viewModel = kendo.observable({ + foo: { + bar: "bar" + } + }); + + viewModel.foo.bind("change", function(e) { + equal(e.field, "bar"); + }); + + viewModel.foo.set("bar", "baz"); +}); + +test("changing a view model field from a view model function bound to UI reflects UI", function() { + var viewModel = kendo.observable( { + foo: "foo", + bar: function() { + this.set("foo", "baz"); + } + }); + + var dom = $('
                                          '); + + kendo.bind(dom, viewModel); + + equal(dom.find("span").text(), "foo"); + + dom.find("button").trigger("click"); + + equal(dom.find("span").text(), "baz"); +}); + +test("removing item from view model array reflects UI", function() { + var viewModel = kendo.observable( { + foo: ["foo", "bar", "baz"], + bar: "boo" // needed to test closure value assignment + }); + + var dom = $('
                                          '); + + kendo.bind(dom, viewModel); + + dom.find("option:first").prop("selected", true); + dom.find("select").trigger("change"); + equal(dom.find("span").text(), "foo"); +}); + +test("the view model is updated when the change event is raised", 1, function() { + var viewModel = kendo.observable( { + foo: "", + change: function() { + equal(this.foo, "bar"); + } + }); + + var dom = $(''); + + kendo.bind(dom, viewModel); + + dom.val("bar").trigger("change"); +}); + +test("keyup event notifies value listeners", function() { + var viewModel = kendo.observable( { + foo: ["foo", "bar", "baz"], + bar: "bar" + }); + + var dom = $('
                                          '); + + kendo.bind(dom, viewModel); + + dom.find("input").val("foo").trigger("keyup"); + + equal(dom.find("span").text(), "foo"); +}); + +test("changing value when value update mode is keyup does not reset the input value", 1, function() { + var viewModel = kendo.observable( { + bar: "bar" + }); + + var dom = $('
                                          '); + + kendo.bind(dom, viewModel); + + viewModel.bind("get", function(e) { + ok(true, "Should be called only for the span"); + }); + + dom.find("input").val("foo") + .trigger("keyup"); +}); + +test("changing ui updates view model with array accessor", function() { + var viewModel = kendo.observable( { + "1": "bar" + }); + + var dom = $(''); + + kendo.bind(dom, viewModel); + + dom.val("foo").trigger("change"); + + equal(viewModel["1"], "foo"); +}); + +test("select of multi select updates the viewModel", function() { + var viewModel = kendo.observable( { + foo: ["foo", "bar", "baz"], + selectedItems: [] + }); + + var dom = $(''); + + kendo.bind(dom, viewModel); + + dom.find("option:first").attr("selected", "selected"); + dom.find("option:last").attr("selected", "selected"); + dom.trigger("change"); + + equal(viewModel.selectedItems[0], viewModel.foo[0]); + equal(viewModel.selectedItems[1], viewModel.foo[1]); +}); + +test("select tracks complex value", function() { + var viewModel = kendo.observable( { + foo: [ { text: "foo" }, { text: "bar" } ], + selectedItem: null + }); + + viewModel.selectedItem = viewModel.foo[0]; + + var dom = $(''); + + kendo.bind(dom, viewModel); + + dom.find("option:first")[0].selected = false; + dom.find("option:last")[0].selected = true; + + dom.trigger("change"); + dom.triggerHandler("change"); + + strictEqual(viewModel.selectedItem, viewModel.foo[1].text); +}); + +test("select tracks complex value if text-field is set", function() { + var viewModel = kendo.observable( { + foo: [ { text: "foo" }, { text: "bar" } ], + selectedItem: null + }); + + viewModel.selectedItem = viewModel.foo[0]; + + var dom = $(''); + + kendo.bind(dom, viewModel); + + dom.find("option:last").attr("selected", "selected"); + + dom.trigger("change"); + + strictEqual(viewModel.selectedItems[0], viewModel.foo[1]); +}); + +test("select bound to complex object updates simple value", function() { + var viewModel = kendo.observable( { + foo: [ { text: "foo" }, { text: "bar" } ], + selectedItem: "foo" + }); + + var dom = $(''); + + kendo.bind(dom, viewModel); + + dom.find("option:first").attr("selected", "selected"); + dom.trigger("change"); + dom.find("option:last").attr("selected", "selected"); + dom.trigger("change"); + + equal(dom.find("option").length, 3); +}); + +test("changing the value updates the view model", function() { + var dom = $(''); + + var viewModel = kendo.observable( { foo: "foo" }); + + kendo.bind(dom, viewModel); + + dom.val("bar"); + dom.trigger("change"); + + equal(viewModel.foo, "bar"); +}); + +test("changing the value of pre populated select updates the view model", function() { + var dom = $(''); + + var viewModel = kendo.observable( { foo: [] }); + + kendo.bind(dom, viewModel); + + dom.find("option:last").attr("selected", "selected"); + dom.trigger("change"); + + equal(viewModel.foo[0], "bar"); +}); + +test("changing radiobutton value updates the view model", function() { + var dom = $(''); + + var viewModel = kendo.observable( { foo: "" }); + + kendo.bind(dom, viewModel); + + dom.attr("checked", true); + dom.trigger("change"); + + equal(viewModel.foo, "bar"); +}); + +test("changing checkbox value updates the view model", function() { + var dom = $(''); + + var viewModel = kendo.observable( { foo: false }); + + kendo.bind(dom, viewModel); + + dom.prop("checked", true); + dom.trigger("change"); + + equal(viewModel.foo, true); +}); + +test("changing checkbox does not add the value updates the view model", function() { + var dom = $(''); + + var viewModel = kendo.observable( { foo: true }); + + kendo.bind(dom, viewModel); + + dom.prop("checked", false); + dom.trigger("change"); + + equal(viewModel.foo, false); +}); + +test("changing checkbox value updates the view model with the checked state", function() { + var dom = $(''); + + var viewModel = kendo.observable( { foo: false }); + + kendo.bind(dom, viewModel); + + dom.prop("checked", true); + dom.trigger("change"); + + equal(viewModel.foo, true); +}); + +test("checking checkbox adds the value to the view model", function() { + var dom = $(''); + + var viewModel = kendo.observable( { foo: [] }); + + kendo.bind(dom, viewModel); + + dom.attr("checked", true); + dom.trigger("change"); + + equal(viewModel.foo[0], "bar"); +}); + +test("unchecking checkbox removes the value from the view model", function() { + var dom = $(''); + + var viewModel = kendo.observable( { foo: ["bar"] }); + + kendo.bind(dom, viewModel); + + dom.attr("checked", false); + dom.trigger("change"); + + ok(!viewModel.foo.length); +}); + +test("value binding calls set once during select change", function() { + var viewModel = kendo.observable( { + foo: ["foo", "bar", "baz"], + bar: "bar" + }); + + var calls = 0; + + var dom = $(''); + + kendo.bind(dom, viewModel); + + viewModel.set("bar", "baz"); + + equal(dom[0].selectedIndex, -1); +}); + +test("tracking changes of observable items in array", function() { + var viewModel = kendo.observable( { + foo: [{ name: "foo" }] + }); + + var dom = $('
                                            '); + + kendo.bind(dom, viewModel); + + viewModel.foo[0].set("name", "bar"); + + equal(dom.find("li").text(), "bar"); +}); + +test("replacing the source array rebinds the element", function() { + var viewModel = kendo.observable( { + foo: [{ name: "foo" }] + }); + + var dom = $('
                                              '); + + kendo.bind(dom, viewModel); + + viewModel.set("foo", [{ name: "bar" }]); + + equal(dom.find("li").text(), "bar"); +}); + +test("tracking changes of fields bound to style", function() { + var viewModel = kendo.observable( { + foo: "1px", + bar: "10px" + }); + + var dom = $(''); + + kendo.bind(dom, viewModel); + + viewModel.set("foo", "2px"); + viewModel.set("bar", "20px"); + + equal(dom.css("left"), "2px"); + equal(dom.css("top"), "20px") +}); + +test("tracking changes of complex fields", function() { + var dom = $('
                                              '); + + var viewModel = kendo.observable({ + foo: { + bar: "bar" + }, + bar: "boo" + }); + + kendo.bind(dom, viewModel); + + viewModel.foo.set("bar", "baz"); + + equal(dom.text(), "baz"); + //check that parent field is not changed + equal(dom.attr("title"), "boo"); +}); + +test("tracking changes in templates", function() { + var dom = $('
                                              '); + + var viewModel = kendo.observable({ foo: "foo" }); + + kendo.bind(dom, viewModel); + + viewModel.set("foo", "bar"); + + equal($.trim(dom.text()), "bar"); +}); + +test("change event is fired once", 1, function() { + var dom = $('
                                              '); + + var viewModel = kendo.observable({ foo: "foo" }); + + kendo.bind(dom, viewModel); + + viewModel.bind("change", function() { + ok(true); + }); + + viewModel.set("foo", "bar"); +}); + +test("dependencies are reavaluated", function() { + var dom = $('
                                              '); + + var viewModel = kendo.observable({ foo: "foo", bar: "bar" }); + + kendo.bind(dom, viewModel); + + viewModel.set("foo", "baz"); + + viewModel.set("bar", "boo"); + + equal($.trim(dom.text()), "boo"); +}); + +test("does not attach more than one change handler when monitoring for dependency changes", function() { + var dom = $('
                                              '); + + var viewModel = kendo.observable({ foo: "foo" }); + + kendo.bind(dom, viewModel); + + viewModel.set("foo", "baz"); + + templateEvaluationCounter = 0; + + viewModel.set("foo", "boo"); + + equal(templateEvaluationCounter, 1); +}); + +test("refreshing the source destroys the binder objects", 1, function() { + var dom = $('
                                              '); + + var viewModel = kendo.observable({ foo: "foo" }); + + kendo.data.binders.custom = kendo.data.Binder.extend({ + refresh: function() { + }, + destroy: function() { + ok(true); + } + }); + + kendo.bind(dom, viewModel); + + viewModel.set("foo", "baz"); +}); + +test("removing an item from the source destroys the binder objects", 1, function() { + var dom = $('
                                              '); + + var viewModel = kendo.observable({ foo: [ {} ] }); + + kendo.data.binders.custom = kendo.data.Binder.extend({ + refresh: function() { + }, + destroy: function() { + ok(true); + } + }); + + kendo.bind(dom, viewModel); + + viewModel.foo.splice(0, 1); +}); + +test("does not attach multiple event handlers to nested object", function() { + var parent = kendo.observable({}); + var child = kendo.observable({}); + + parent.set("child", child); + parent.set("child", kendo.observable({})); + parent.set("child", child); + + equal(child._events["change"].length, 1); + equal(child._events["get"].length, 1); +}); + +test("does not attach multiple event handlers to nested array", function() { + var parent = kendo.observable({}); + var child = new kendo.data.ObservableArray([]); + + parent.set("child", child); + parent.set("child", kendo.observable({})); + parent.set("child", child); + + equal(child._events["change"].length, 1); +}); + +test("tracking changes when direct access and set are used", function() { + var dom = $('
                                              '); + + var viewModel = kendo.observable({ + foo: { + bar: "bar" + } + }); + + kendo.bind(dom, viewModel); + + viewModel.foo.set("bar", "baz"); + + equal($.trim(dom.text()), "baz"); +}); + +test("tracking changes when single set is used", function() { + var dom = $('
                                              '); + + var viewModel = kendo.observable({ + foo: { + bar: "bar" + } + }); + + kendo.bind(dom, viewModel); + + viewModel.set("foo.bar", "boo"); + + equal($.trim(dom.text()), "boo"); +}); + +test("tracking changes when direct access and set are used (multiple get template)", function() { + var dom = $('
                                              '); + + var viewModel = kendo.observable({ + foo: { + bar: "bar" + } + }); + + kendo.bind(dom, viewModel); + + viewModel.foo.set("bar", "baz"); + + equal($.trim(dom.text()), "baz"); +}); + +test("tracking changes when single set is used (multiple get template)", function() { + var dom = $('
                                              '); + + var viewModel = kendo.observable({ + foo: { + bar: "bar" + } + }); + + kendo.bind(dom, viewModel); + + viewModel.set("foo.bar", "boo"); + + equal($.trim(dom.text()), "boo"); +}); + +test("tracking changes in dependent fields", function() { + var dom = $('
                                              '); + + var viewModel = kendo.observable({ + foo: "foo", + bar: "bar", + computed: function() { + return this.get("foo") + this.get("bar"); + } + }); + + kendo.bind(dom, viewModel); + + viewModel.set("foo", "boo"); + + equal($.trim(dom.text()), "boobar"); +}); + +test("checked binding removing the item unchecks the checkbox", function() { + var dom = $(''); + + var viewModel = kendo.observable({ + selectedItems: ["foo"] + }); + + kendo.bind(dom, viewModel); + + viewModel.selectedItems.splice(0,1); + + ok(!dom.is(":checked")); +}); + +test("model is not updated after target is destoryed", function() { + var dom = $(''); + + var viewModel = kendo.observable( { foo: "foo" }); + + kendo.bind(dom, viewModel); + + kendo.unbind(dom); + + dom.val("bar"); + dom.trigger("change"); + + equal(viewModel.foo, "foo"); +}); + +test("UI element is not updated after unbind", function() { + var dom = $(''); + + var viewModel = kendo.observable( { foo: "foo" }); + + kendo.bind(dom, viewModel); + + kendo.unbind(dom); + + viewModel.set("foo", "bar"); + + equal(dom.val(), "foo"); +}); + +test("changing a field does not triger changing of another field starting with the same name", function() { + var viewModel = kendo.observable({ + foo1: [{ name: "foo" }, { name: "bar" }] + }); + + var calls = 0; + + kendo.data.binders.source = kendo.data.Binder.extend({ + refresh: function() { + calls ++; + } + }); + + var dom = $(''); + + kendo.bind(dom, viewModel); + + dom.val("foo").trigger("change"); + equal(viewModel.foo, "foo"); +}); + +test("tracks changes of template bound to parent field", function() { + var dom = $('
                                                '); + + var viewModel = kendo.observable({ + root: "foo", + items: [ {} ] + }); + + kendo.bind(dom, viewModel); + viewModel.set("root", "bar"); + equal(dom.find("li").text(), viewModel.root); +}); + +test("parent properties are invoked with the current item", 2, function() { + var dom = $('
                                                  '); + + var viewModel = kendo.observable({ + root: function(item) { + }, + rootAlias: function(item) { + equal(item, viewModel.items[0]); + return this.get("root"); + }, + items: [ {} ] + }); + + kendo.bind(dom, viewModel); + viewModel.set("root", "bar"); +}); + +test("tracks changes of parent field bound to dependent parent field", function() { + var dom = $('
                                                    '); + + var viewModel = kendo.observable({ + root: "foo", + rootAlias: function() { + return this.get("root"); + }, + items: [ {} ] + }); + + kendo.bind(dom, viewModel); + + viewModel.set("root", "bar"); + + equal(dom.find("li").text(), "bar"); +}); + +test("tracks changes of parent field bound to dependent parent field", function() { + var dom = $('
                                                      '); + + var viewModel = kendo.observable({ + root: "foo", + rootAlias: function(item) { + return item.get("foo"); + }, + items: [ {foo: "foo" } ] + }); + + kendo.bind(dom, viewModel); + + viewModel.items[0].set("foo", "bar"); + + equal(dom.find("li").text(), "bar"); +}); + +test("tracks changes of element bound to parent field within a child template", function() { + var dom = $('
                                                        '); + + var viewModel = kendo.observable({ + root: "foo", + items: [ { bar: "baz" } ] + }); + + kendo.bind(dom, viewModel); + + dom.find("input").val("moo").change(); + + equal(dom.find("span").text(), "moo"); +}); + +test("tracks changes of element bound to parent nested field within a child template", function() { + var dom = $('
                                                          '); + + var viewModel = kendo.observable({ + root: { child: "foo" }, + items: [ { bar: "baz" } ] + }); + + kendo.bind(dom, viewModel); + + dom.find("input").val("moo").change(); + + equal(dom.find("span").text(), "moo"); +}); + + +test("event handlers are detached when the binding is changed", function() { + var observable = kendo.observable({ + handler: { + } + }); + + stub(observable.handler, "method"); + + var dom = $(''); + + kendo.bind(dom, observable); + + var handler = observable.handler; + + var other = kendo.observable({ + method: function() { } + }); + + observable.set("handler", other); + + dom.trigger("click"); + + equal(handler.calls("method"), 0); +}); + +test("tracking changes of bindings containing function calls", function() { + var observable = kendo.observable({ + foo: { + bar: "foo" + }, + baz: function() { + return this.get("foo"); + } + }); + + var dom = $(''); + + kendo.bind(dom, observable); + + observable.set("baz().bar", "bar"); + + equal(dom.text(), "bar"); +}); + +var date = $(''); + +if (date[0].type == "date") { + test("changing the value of input type date updates the view model with a valid JavaScript Date", function() { + var observable = kendo.observable({ + date: new Date("2013/5/4") + }); + + var dom = $(''); + + kendo.bind(dom, observable); + + dom.val("2013-06-05").trigger("change"); + + equal(observable.date.getMonth(), 5); + equal(observable.date.getDate(), 5); + }); +} + +var datetime = $(''); + +if (datetime[0].type == "datetime-local") { + test("changing the value of input type datetime-local updates the view model with a valid JavaScript Date", function() { + var observable = kendo.observable({ + date: new Date("2013/5/4") + }); + + var dom = $(''); + + kendo.bind(dom, observable); + + dom.val("2013-06-05T23:13:40").trigger("change"); + + equal(observable.date.getMonth(), 5); + equal(observable.date.getDate(), 5); + equal(observable.date.getHours(), 23); + equal(observable.date.getMinutes(), 13); + equal(observable.date.getSeconds(), 40); + }); + + test("changing the value of input type datetime-local updates the view model with a valid JavaScript Date - date time without seconds", function() { + var observable = kendo.observable({ + date: new Date("2013/5/4") + }); + + var dom = $(''); + + kendo.bind(dom, observable); + + dom.val("2013-06-05T23:13").trigger("change"); + + equal(observable.date.getMonth(), 5); + equal(observable.date.getDate(), 5); + equal(observable.date.getHours(), 23); + equal(observable.date.getMinutes(), 13); + equal(observable.date.getSeconds(), 00); + }); +} + +var number = $(''); + +if (number[0].type == "number") { + test("changing the value of input type number updates the view model with a valid Number", function() { + var dom = $(''); + + var observable = kendo.observable({ + number: 0 + }); + + kendo.bind(dom, observable); + + dom.val("3.14").trigger("change"); + + strictEqual(observable.number, 3.14); + }); +} + + +}()); diff --git a/tests/mvvm/observablearray.js b/tests/mvvm/observablearray.js new file mode 100644 index 00000000000..39d07c74444 --- /dev/null +++ b/tests/mvvm/observablearray.js @@ -0,0 +1,406 @@ +(function(){ + +test("pushing items to array raises the change event", function() { + expect(1); + + var viewModel = kendo.observable({ foo: [{}] }); + + viewModel.foo.bind("change", function() { + ok(true, "change is raised"); + }); + + viewModel.foo.push({}); +}); + +test("pushing items to array raises the change event", function() { + expect(1); + + var viewModel = kendo.observable({ foo: [{}] }); + + viewModel.foo.bind("change", function() { + ok(true, "change is raised"); + }); + + viewModel.foo.push({}); +}); + +test("items pushed to observable array are converted to observable objects", function() { + var viewModel = kendo.observable({ foo: [] }); + viewModel.foo.push({}); + + ok(viewModel.foo[0] instanceof kendo.data.ObservableObject); +}); + +test("Object should be wrapped", function() { + var MyClass = kendo.Class.extend({}); + + var viewModel = kendo.observable({ foo: [new MyClass()] }); + + ok(viewModel.foo[0] instanceof kendo.data.ObservableObject); +}); + +test("ObservableObjects should be converted if type is set", function() { + var ModelType = kendo.data.Model.define({}); + + var array = new kendo.data.ObservableArray([new kendo.data.ObservableObject({})], ModelType); + + ok(array[0] instanceof kendo.data.ObservableObject); + ok(array[0] instanceof ModelType); +}); + +test("pushing items to array raises the change event and sets the action to add", function() { + expect(1); + + var viewModel = kendo.observable({ foo: [{}] }); + + viewModel.foo.bind("change", function(e) { + equal(e.action, "add"); + }); + + viewModel.foo.push({}); +}); + +test("pushing items to array raises the change event and sets the index", function() { + expect(1); + + var viewModel = kendo.observable({ foo: [{}] }); + + viewModel.foo.bind("change", function(e) { + equal(e.index, 1) + }); + + viewModel.foo.push({}); +}); + +test("pushing items to array raises the change event and provides the added items", function() { + expect(1); + + var viewModel = kendo.observable({ foo: [{}] }); + + viewModel.foo.bind("change", function(e) { + equal(e.items.length, 1) + }); + + viewModel.foo.push({}); +}); + +test("unshifting items to array raises the change event", function() { + expect(3); + + var viewModel = kendo.observable({ foo: [] }); + + viewModel.foo.bind("change", function(e) { + equal(e.action, "add"); + equal(e.index, 0); + equal(e.items.length, 1); + }); + + viewModel.foo.unshift({}); +}); + +test("items unshifted to array are converted to observable objects", 1, function() { + var viewModel = kendo.observable({ foo: [] }); + + viewModel.foo.bind("change", function(e) { + ok(e.items[0] instanceof kendo.data.ObservableObject, "Should be ObservableObject"); + }); + + viewModel.foo.unshift({}); +}); + +test("items spliced to array items are converted to observable objects", 2, function() { + var viewModel = kendo.observable({ foo: [] }); + + viewModel.foo.bind("change", function(e) { + ok(e.items[0] instanceof kendo.data.ObservableObject, "Should be ObservableObject"); + }); + + viewModel.foo.splice(0, 0, {}); + + ok(viewModel.foo[0] instanceof kendo.data.ObservableObject, "Should be ObservableObject"); +}); + +test("splicing array items raises the change event with remove action", function() { + expect(1); + + var viewModel = kendo.observable({ foo: [{}] }); + + viewModel.foo.bind("change", function(e) { + equal(e.action, "remove"); + }); + + viewModel.foo.splice(0, 1); +}); + +test("splicing array items raises the change event and provides index", function() { + expect(1); + + var viewModel = kendo.observable({ foo: [{}] }); + + viewModel.foo.bind("change", function(e) { + equal(e.index, 0); + }); + + viewModel.foo.splice(0, 1); +}); + +test("splicing array items raises the change event and provides the removed items", function() { + expect(1); + + var viewModel = kendo.observable({ foo: [{}] }); + + viewModel.foo.bind("change", function(e) { + equal(e.items.length, 1); + }); + + viewModel.foo.splice(0, 1); +}); + +test("splicing array items returns the removed items", function() { + var viewModel = kendo.observable({ foo: [{}] }); + + equal(viewModel.foo.splice(0, 1).length, 1); +}); + +test("splicing array items raises the change event with add action", function() { + expect(1); + + var viewModel = kendo.observable({ foo: [] }); + + viewModel.foo.bind("change", function(e) { + equal(e.action, "add"); + }); + + viewModel.foo.splice(0, 1, {}); +}); + +test("splicing array items raises the change event and sends the index and inserted items", function() { + expect(2); + + var viewModel = kendo.observable({ foo: [] }); + + viewModel.foo.bind("change", function(e) { + equal(e.index, 0); + equal(e.items.length, 1); + }); + + viewModel.foo.splice(0, 1, {}); +}); + +test("observable array items are observable", function() { + var viewModel = kendo.observable({ foo: [ {} ] }); + ok(viewModel.foo[0].bind); +}); + +test("change event is raised when child an item changes", 3, function() { + var viewModel = kendo.observable({ foo: [ {} ] }); + + viewModel.foo.bind("change", function(e) { + equal(e.items[0], viewModel.foo[0]); + equal(e.action, "itemchange"); + equal(e.field, "bar"); + }); + + viewModel.foo[0].set("bar", "baz"); +}); + +test("indexOf return index of the item", function() { + var viewModel = kendo.observable({ foo: [ { bar: 1 } ] }); + + equal(viewModel.foo.indexOf(viewModel.foo[0]), 0); +}); + +test("indexOf return -1 if item does not exists", function() { + var viewModel = kendo.observable({ foo: [ { bar: 1 } ] }); + + equal(viewModel.foo.indexOf({ bar: 42 }), -1); +}); + +test("pop raises the change event and removes the last item", 2, function() { + var viewModel = kendo.observable({ foo: [ { bar: 1 } ] }); + var last = viewModel.foo[0]; + + + viewModel.foo.bind("change", function(e) { + equal(e.items[0], last); + equal(e.index, 0); + }); + + viewModel.foo.pop(); +}); + +test("pop raises the change event and action is remove", 1, function() { + var viewModel = kendo.observable({ foo: [ { bar: 1 } ] }); + + viewModel.foo.bind("change", function(e) { + equal(e.action, "remove"); + }); + + viewModel.foo.pop(); +}); + +test("shift raises the change event and removes the first item", 2, function() { + var viewModel = kendo.observable({ foo: [ { bar: 1 }, { bar: 2} ] }); + var first = viewModel.foo[0]; + + + viewModel.foo.bind("change", function(e) { + equal(e.items[0], first); + equal(e.index, 0); + }); + + viewModel.foo.shift(); +}); + +test("shift raises the change event and action is remove", 1, function() { + var viewModel = kendo.observable({ foo: [ { bar: 1 } ] }); + + viewModel.foo.bind("change", function(e) { + equal(e.action, "remove"); + }); + + viewModel.foo.shift(); +}); + +test("shift does not raise the change event when the array is empty", 0, function() { + var viewModel = kendo.observable({ foo: [ ] }); + + viewModel.foo.bind("change", function(e) { + ok(false, "Should not raise the change event when empty"); + }); + + viewModel.foo.shift(); +}); + +test("pop does not raise the change event when the array is empty", 0, function() { + var viewModel = kendo.observable({ foo: [ ] }); + + viewModel.foo.bind("change", function(e) { + ok(false, "Should not raise the change event when empty"); + }); + + viewModel.foo.pop(); +}); + +test("private fields are not included in JSON serialization", function() { + var viewModel = kendo.observable({ foo: [1] }); + + equal(kendo.stringify(viewModel.foo), "[1]"); +}); + +test("parent returns undefined for new observable array", function() { + strictEqual((new kendo.data.ObservableArray([])).parent(), undefined); +}); + +test("adding item to nested array triggers change event of the parent", 1, function() { + var viewModel = kendo.observable({ foo: [{ + bar: { items: [] } + } ] }); + + viewModel.get("foo").bind("change", function(e) { + equal(e.action, "itemchange"); + }); + + viewModel.get("foo")[0].bar.items.push({ baz: "moo" }); +}); + +test("forEach calls callback for each item", 3, function() { + var viewModel = kendo.observable({ foo: ["foo"] }); + + viewModel.foo.forEach(function(value, index, item) { + equal(value, "foo"); + strictEqual(index, 0); + equal(item, viewModel.foo); + }); +}); + +test("map collects returned results from iteration", 2, function() { + var viewModel = kendo.observable({ foo: [2, 4] }); + + var result = viewModel.get("foo").map(function(value) { + return value * 2; + }); + + equal(result[0], 4); + equal(result[1], 8); +}); + +test("filter collects returned results from iteration", 2, function() { + var viewModel = kendo.observable({ foo: [2, 3, 4] }); + + var result = viewModel.get("foo").filter(function(value) { + return value % 2 === 0; + }); + + equal(result[0], 2); + equal(result[1], 4); +}); + +test("find returns the first item that matches the requirements", 1, function() { + var viewModel = kendo.observable({ foo: [2, 3, 4] }); + + var result = viewModel.get("foo").find(function(value) { + return value % 2 === 1; + }); + + equal(result, 3); +}); + +test("every returns true if all items satisfy the provided requirement", 1, function() { + var viewModel = kendo.observable({ foo: [2, 4] }); + + var result = viewModel.get("foo").every(function(value) { + return value % 2 === 0; + }); + + ok(result); +}); + +test("every returns false if one item does not satisfy the provided requirement", 1, function() { + var viewModel = kendo.observable({ foo: [2, 3, 4] }); + + var result = viewModel.get("foo").every(function(value) { + return value % 2 === 0; + }); + + ok(!result); +}); + +test("some returns true if some items satisfy the provided requirement", 1, function() { + var viewModel = kendo.observable({ foo: [2, 4] }); + + var result = viewModel.get("foo").some(function(value) { + return value % 2 === 0; + }); + + ok(result); +}); + +test("some returns false if no items satisfy the provided requirement", 1, function() { + var viewModel = kendo.observable({ foo: [3, 5] }); + + var result = viewModel.get("foo").some(function(value) { + return value % 2 === 0; + }); + + ok(!result); +}); + +test("remove removes the given item", 2, function() { + var viewModel = kendo.observable({ foo: [3, 5] }); + + viewModel.foo.remove(3); + + equal(viewModel.foo.length, 1); + equal(viewModel.foo[0], 5); +}); + +test("empty removes all items", function() { + var viewModel = kendo.observable({ foo: [3, 5] }); + + viewModel.foo.empty(); + + equal(viewModel.foo.length, 0); +}); + +}()); diff --git a/tests/mvvm/observableobject.js b/tests/mvvm/observableobject.js new file mode 100644 index 00000000000..339e386e433 --- /dev/null +++ b/tests/mvvm/observableobject.js @@ -0,0 +1,392 @@ +(function(){ + +test("set changes the value of the field", function() { + var viewModel = kendo.observable({ foo: "bar" }); + + viewModel.set("foo", "foo"); + + equal(viewModel.foo, "foo"); +}); + +test("copies all fields of the source object", function() { + var viewModel = kendo.observable({ foo: "bar" }); + + equal(viewModel.foo, "bar"); +}); + +test("context of methods is the view model", function() { + var viewModel = kendo.observable({ + foo: function() { + strictEqual(this, viewModel); + } + }); + + viewModel.foo(); +}); + +test("nested objects are observable as well", function() { + var viewModel = kendo.observable({ foo: { bar: "baz" } }); + + ok(viewModel.foo.get); +}); + +test("nested objects which are private are not observable", function() { + var viewModel = kendo.observable({ _foo: { bar: "baz" } }); + + ok(!(viewModel._foo instanceof kendo.data.ObservableObject)); +}); + +test("set triggers the change event", function() { + expect(1); + + var viewModel = kendo.observable({ foo: "bar" }); + + viewModel.bind("change", function() { + ok(true, "change is raised"); + }); + + viewModel.set("foo", "baz"); +}); + +test("set triggers only once the change event if value is the same", 1, function() { + var viewModel = kendo.observable({ foo: { foo: "bar" }}); + + viewModel.bind("change", function() { + ok(true, "change is raised"); + }); + + viewModel.set("foo.foo", "baz"); + viewModel.set("foo.foo", "baz"); +}); + +test("change event arguments provide the name of the field", function() { + expect(1); + + var viewModel = kendo.observable({ foo: "bar" }); + + viewModel.bind("change", function(e) { + equal(e.field, "foo"); + }); + + viewModel.set("foo", "baz"); +}); + +test("setting nested fields", function() { + var viewModel = kendo.observable({ foo: { bar: "bar" } }); + + viewModel.set("foo.bar", "baz"); + + equal(viewModel.foo.bar, "baz"); +}); + +test("nested arrays are extended", function() { + var viewModel = kendo.observable({ foo: [{}] }); + + equal(typeof viewModel.foo.bind, "function"); +}); + +asyncTest("getting field raises get event", function() { + expect(1); + + var viewModel = kendo.observable({ foo: "bar" }); + + viewModel.bind("get", function(e) { + start(); + + equal(e.field, "foo"); + }); + + viewModel.get("foo"); +}); + +asyncTest("setting a field raises set event", function() { + expect(2); + + var viewModel = kendo.observable({ foo: "bar" }); + + viewModel.bind("set", function(e) { + start(); + + equal(e.field, "foo"); + equal(e.value, "foo"); + }); + + viewModel.set("foo", "foo"); +}); + +asyncTest("cancelling the set event prevents setting the field value", function() { + expect(1); + + var viewModel = kendo.observable({ foo: "bar" }); + + viewModel.bind("set", function(e) { + start(); + e.preventDefault(); + }); + + viewModel.set("foo", "foo"); + equal(viewModel.foo, "bar"); +}); + +asyncTest("getting nested field raises get event of parent", function() { + expect(1); + + var viewModel = kendo.observable({ foo: { bar: "bar" } }); + + viewModel.bind("get", function(e) { + start(); + equal(e.field, "foo.bar"); + }); + + viewModel.foo.get("bar"); +}); + +test("toJSON serializes only public fields", function() { + var observable = kendo.observable({ foo: "bar", baz: function(){} }); + var json = observable.toJSON(); + var fields = []; + + for (var field in json) { + fields.push(field); + } + + equal(fields.length, 1); + equal(fields[0], "foo"); + equal(json.foo, "bar"); +}); + +test("toJSON is recursive", function() { + var observable = kendo.observable({ foo: { bar: "bar", baz: function(){} } }); + var json = observable.toJSON(); + var fields = []; + + for (var field in json.foo) { + fields.push(field); + } + + equal(fields.length, 1); + equal(fields[0], "bar"); +}); + +test("toJSON is recursive with arrays", function() { + var observable = kendo.observable({ foo: [{ bar: "bar" }] }); + var json = observable.toJSON(); + var fields = []; + + for (var field in json.foo[0]) { + fields.push(field); + } + + equal(fields.length, 1); + equal(fields[0], "bar"); +}); + +test("toJSON copies dates", function() { + var date = new Date(); + var observable = kendo.observable({ foo: date } ); + var json = observable.toJSON(); + var fields = []; + + for (var field in json) { + fields.push(field); + } + + equal(fields.length, 1); + equal(json.foo, date); +}); + +test("set uses the nested observable object set method", function() { + var observable = kendo.observable({ foo: "bar", baz: { moo: "moo" } }), + set = stub(observable.baz, "set"); + + observable.set("baz.moo", "42"); + equal(set.calls("set"), 1); +}); + +test("set uses the nested array with observable objects", function() { + var observable = kendo.observable({ foo: "bar", baz: [{ moo: "moo" }] }), + set = stub(observable.baz[0], "set"); + + observable.set("baz[0].moo", "42"); + equal(set.calls("set"), 1); +}); + +test("set object is wrapped", function() { + var observable = kendo.observable({ foo: {} }); + + observable.set("foo", { bar: "baz" }); + + ok(observable.foo instanceof kendo.data.ObservableObject); +}); + +test("change event is raised if wrapped object is modified", 1, function() { + var observable = kendo.observable({ foo: {} }); + + observable.set("foo", { bar: "baz" }); + + observable.bind("change", function() { + ok(true); + }); + + observable.foo.set("bar", "moo"); +}); + +test("ObservableObject are not wrapped if attached through set", function() { + var observable = kendo.observable({ foo: {} }); + var nested = new kendo.data.ObservableObject({ bar: "baz" }); + observable.set("foo", nested); + + strictEqual(observable.foo, nested); +}); + +test("change event is raised for wrapped ObservableObject", 1, function() { + var observable = kendo.observable({ foo: {} }); + var nested = new kendo.data.ObservableObject({ bar: "baz" }); + observable.set("foo", nested); + + observable.bind("change", function() { + ok(true); + }); + + observable.foo.set("bar", "moo"); +}); + + +test("set Array is wrapped", function() { + var observable = kendo.observable({ foo: [] }); + + observable.set("foo", [1,2,3]); + + ok(observable.foo instanceof kendo.data.ObservableArray); +}); + +test("change event is raised if wrapped array is modified", 1, function() { + var observable = kendo.observable({ foo: [] }); + + observable.set("foo", []); + + observable.bind("change", function() { + ok(true); + }); + + observable.foo.push(1); +}); + +test("DataSource is not wrapped if set as ViewModel property",function() { + var observable = kendo.observable({ dataSource: new kendo.data.DataSource() }); + + ok(!(observable.dataSource instanceof kendo.data.ObservableObject)) +}); + +test("ObservableArray is not wrapped if set as ViewModel property",function() { + var observable = kendo.observable({ items: new kendo.data.ObservableArray([1,2,3,4,5]) }); + + ok(observable.items instanceof kendo.data.ObservableArray) +}); + +test("listen for changes of ObservableArray set as ViewModel property", 1,function() { + var observable = kendo.observable({ items: new kendo.data.ObservableArray([1,2,3,4,5]) }); + + observable.bind("change", function() { ok(true); }); + + observable.get("items").push(6); +}); + +test("parent returns the parent observable object", function() { + var observable = kendo.observable( { + foo: { + } + }); + + strictEqual(observable.foo.parent(), observable); +}); + +test("parent returns the parent observable array", function() { + var observable = kendo.observable( { + foo: [{}] + }); + + strictEqual(observable.foo[0].parent(), observable.foo); +}); + +test("parent returns the parent of the observable array", function() { + var observable = kendo.observable( { + foo: [{}] + }); + + strictEqual(observable.foo.parent(), observable); +}); + +test("parent returns undefined for root observable object", function() { + strictEqual(kendo.observable({}).parent(), undefined); +}); + +test("setting object sets its parent", function() { + var observable = kendo.observable({ }); + observable.set("foo", { bar: "baz" }); + + strictEqual(observable.foo.parent(), observable); +}); + +test("datasource change event propagates to parent", 1, function() { + var observable = new kendo.observable( { + dataSource: new kendo.data.DataSource() + }); + + observable.bind("change", function(e) { + equal(e.action, "add"); + }); + + observable.dataSource.add({}); +}); + +test("change events fire from top to bottom", 3, function() { + var observable = kendo.observable({ + foo: { + bar: { + baz: "" + } + } + }); + + observable.bind("change", function(e) { + equal(e.field, "foo.bar.baz"); + }); + + observable.foo.bind("change", function(e) { + equal(e.field, "bar.baz"); + }); + + observable.foo.bar.bind("change", function(e) { + equal(e.field, "baz"); + }); + + observable.set("foo.bar.baz", "baz"); +}); + + +test("change event bubbles to top", 2, function() { + var observable = kendo.observable({ + foo: [ + { bar: "bar" } + ] + }); + + var expected = ["foo", "foo[0].bar"]; + + observable.bind("change", function(e) { + equal(e.field, expected.shift()); + }); + + observable.set("foo[0].bar", "foo"); +}); + +test("undefined is not wrapped", function() { + var observable = new kendo.observable( { + empty: undefined + }); + + ok(!(observable.get("empty") instanceof kendo.data.ObservableObject)); +}); + +}()); diff --git a/tests/mvvm/widget.js b/tests/mvvm/widget.js new file mode 100644 index 00000000000..d200fca1f32 --- /dev/null +++ b/tests/mvvm/widget.js @@ -0,0 +1,55 @@ +(function(){ + + +var TestWidget = kendo.ui.Widget.extend({ + init: function(element, options) { + kendo.ui.Widget.fn.init.call(this, element, options); + }, + + options: { + name: "TestWidget", + } +}); + + +var MobileTestWidget = kendo.mobile.ui.Widget.extend({ + init: function(element, options) { + kendo.mobile.ui.Widget.fn.init.call(this, element, options); + }, + + options: { + name: "TestWidget2", + } +}); + +var dom; + +module("mvvm widgets", { + setup: function() { + kendo.ui.plugin(TestWidget); + kendo.mobile.ui.plugin(MobileTestWidget); + }, + teardown: function() { + kendo.destroy(dom); + } +}) + +test("widgets are initialized", function() { + dom = $('
                                                          '); + kendo.bind(dom, {}, kendo.ui); + ok(dom.find("#foo").data("kendoTestWidget")); +}); + +test("full path widgets are initialized", function() { + dom = $('
                                                          '); + kendo.bind(dom, {}, kendo.ui); + ok(dom.find("#foo").data("kendoTestWidget")); +}); + +test("widgets are initialized from multiple namespaces", function() { + dom = $('
                                                          '); + kendo.bind(dom, {}, kendo.ui, kendo.mobile.ui); + ok(dom.find("#bar").data("kendoMobileTestWidget2")); +}); + +}()); diff --git a/tests/notification/api.js b/tests/notification/api.js new file mode 100644 index 00000000000..06fc45fa96e --- /dev/null +++ b/tests/notification/api.js @@ -0,0 +1,330 @@ +(function() { + module("api", { + setup: function() { + kendo.effects.disable(); + }, + teardown: function() { + if (notification) { + notification.destroy(); + } + + $(".k-notification").each(function(idx, element){ + var popup = $(element).data("kendoPopup"); + if (popup) { + popup.destroy(); + } + $(element).remove(); + }); + + kendo.effects.enable(); + } + }); + + test("show method adds internal stacking GUID to popup notification", function() { + createNotification(); + + var guid = notification._guid; + + notification.show("foo"); + + ok($(".k-notification").parent().hasClass(guid)); + }); + + test("show method adds internal stacking GUID to static notification", function() { + createNotification({ + appendTo: QUnit.fixture + }); + + var guid = notification._guid; + + notification.show("foo"); + + ok($(".k-notification").hasClass(guid)); + }); + + test("show method creates div.k-widget.k-notification element", function() { + createNotification(); + + notification.show("foo"); + + equal($(document.body).find("div.k-widget.k-notification").length, 1); + }); + + test("show method creates a Kendo UI Popup when appendTo is not set", function() { + createNotification(); + + notification.show("foo"); + + ok($(document.body).find(".k-notification").data("kendoPopup")); + }); + + test("show method creates a Kendo UI Popup with zero margin", function() { + createNotification(); + + notification.show("foo"); + + equal($(document.body).find(".k-notification").parent().css("margin"), "0px"); + }); + + test("show method creates a Kendo UI Popup with three zero paddings, except top by default", 3, function() { + createNotification(); + + notification.show("foo"); + + equal($(document.body).find(".k-notification").parent().css("paddingBottom"), "0px"); + equal($(document.body).find(".k-notification").parent().css("paddingLeft"), "0px"); + equal($(document.body).find(".k-notification").parent().css("paddingRight"), "0px"); + }); + + test("show method creates a Kendo UI Popup with three zero paddings, except top", 3, function() { + createNotification({ + stacking: "up" + }); + + notification.show("foo"); + + equal($(document.body).find(".k-notification").parent().css("paddingBottom"), "0px"); + equal($(document.body).find(".k-notification").parent().css("paddingLeft"), "0px"); + equal($(document.body).find(".k-notification").parent().css("paddingRight"), "0px"); + }); + + test("show method creates a Kendo UI Popup with three zero paddings, except bottom", 3, function() { + createNotification({ + stacking: "down" + }); + + notification.show("foo"); + + equal($(document.body).find(".k-notification").parent().css("paddingTop"), "0px"); + equal($(document.body).find(".k-notification").parent().css("paddingLeft"), "0px"); + equal($(document.body).find(".k-notification").parent().css("paddingRight"), "0px"); + }); + + test("show method creates a Kendo UI Popup with three zero paddings, except left", 3, function() { + createNotification({ + stacking: "left" + }); + + notification.show("foo"); + + equal($(document.body).find(".k-notification").parent().css("paddingTop"), "0px"); + equal($(document.body).find(".k-notification").parent().css("paddingBottom"), "0px"); + equal($(document.body).find(".k-notification").parent().css("paddingRight"), "0px"); + }); + + test("show method creates a Kendo UI Popup with three zero paddings, except right", 3, function() { + createNotification({ + stacking: "right" + }); + + notification.show("foo"); + + equal($(document.body).find(".k-notification").parent().css("paddingTop"), "0px"); + equal($(document.body).find(".k-notification").parent().css("paddingBottom"), "0px"); + equal($(document.body).find(".k-notification").parent().css("paddingLeft"), "0px"); + }); + + test("show method does not create a Kendo UI Popup when appendTo is set", function() { + createNotification({ + appendTo: QUnit.fixture + }); + + notification.show("foo"); + + var notificationElement = QUnit.fixture.children(".k-notification"); + + equal(notificationElement.length, 1); + ok(!notificationElement.data("kendoPopup")); + }); + + test("show method ignores empty content", function() { + createNotification(); + + notification.show(""); + notification.show(); + notification.show(null); + + equal($(document.body).find("div.k-widget.k-notification").length, 0); + }); + + test("show method supports empty object as content", function() { + createNotification(); + + notification.show({}); + + equal($(document.body).find("div.k-widget.k-notification").length, 1); + }); + + test("show method renders passed string content", function() { + createNotification(); + + notification.show(""); + + equal($(document.body).find("div.k-widget.k-notification").find("#foo").length, 1); + }); + + test("show method renders passed object content", function() { + createNotification({ + templates: { + info: "
                                                          " + } + }); + + notification.show({foo: "bar"}); + + equal($(document.body).find("div.k-widget.k-notification").find("#bar").length, 1); + }); + + test("show method renders passed function content", function() { + createNotification(); + + var html = '
                                                          '; + + notification.show(function(){ + return html; + }); + + ok($(document.body).find("div.k-widget.k-notification").html().indexOf(html) > -1); + }); + + test("show method renders passed function object content", function() { + createNotification({ + templates: { + info: "
                                                          " + } + }); + + notification.show(function(){ + return {foo: "bar"}; + }); + + equal($(document.body).find("div.k-widget.k-notification").find("#bar").length, 1); + }); + + test("show method adds notification type CSS class to popup and text to note icon", 2, function() { + createNotification(); + + notification.show("foo", "bar"); + + var notificationPopup = $(".k-notification.k-notification-bar"); + + equal(notificationPopup.length, 1); + equal(notificationPopup.find(".k-i-note").text(), "bar"); + }); + + test("show method adds notification type CSS class to static element and text to note icon", 2, function() { + createNotification({ + appendTo: QUnit.fixture + }); + + notification.show("foo", "bar"); + + var notificationElement = $(".k-notification.k-notification-bar"); + + equal(notificationElement.length, 1); + equal(notificationElement.find(".k-i-note").text(), "bar"); + }); + + test("shortcut show methods call show method with appropriate arguments", 8, function() { + var defaultArgs = [null, null], + methods = ["info", "success", "warning", "error"], + args, j; + + createNotification(); + + notification.show = function() { + args = arguments; + }; + + for (j = 0; j < methods.length; j++) { + args = defaultArgs; + notification[methods[j]]("foo"); + + equal(args[0], "foo"); + equal(args[1], methods[j]); + } + }); + + test("hide method hides all popup notifications", function() { + createNotification({ + autoHideAfter: 0 + }); + + notification.show("foo"); + notification.show("bar"); + notification.show("baz"); + + notification.hide(); + + equal($(".k-notification").length, 0); + }); + + test("hide method hides all static notifications", function() { + createNotification({ + autoHideAfter: 0, + appendTo: QUnit.fixture + }); + + notification.show("foo"); + notification.show("bar"); + notification.show("baz"); + + notification.hide(); + + equal($(".k-notification").length, 0); + }); + + test("setOptions updates popup stacking settings", 3, function() { + createNotification({ + stacking: "left" + }); + + notification.setOptions({ + stacking: "right" + }); + + equal(notification._popupOrigin, "top right"); + equal(notification._popupPosition, "top left"); + equal(typeof notification._popupPaddings.paddingRight, "undefined"); + }); + + test("setOptions recompiles templates", function() { + createNotification({ + templates: { + info: "foo" + } + }); + + notification.setOptions({ + templates: { + info: "bar" + } + }); + + equal(notification._compiled.info({}), "bar"); + }); + + test("getNotifications returns open popup notifications", function() { + createNotification({ + autoHideAfter: 0 + }); + + notification.show("foo"); + notification.show("bar"); + + equal(notification.getNotifications().length, 2); + }); + + test("getNotifications returns open static notifications", function() { + createNotification({ + autoHideAfter: 0, + appendTo: QUnit.fixture + }); + + notification.show("foo"); + notification.show("bar"); + + equal(notification.getNotifications().length, 2); + }); + +})(); \ No newline at end of file diff --git a/tests/notification/events.js b/tests/notification/events.js new file mode 100644 index 00000000000..9b23db68424 --- /dev/null +++ b/tests/notification/events.js @@ -0,0 +1,97 @@ +(function() { + module("events", { + setup: function() { + kendo.effects.disable(); + }, + teardown: function() { + if (notification) { + notification.destroy(); + } + + $(".k-notification").each(function(idx, element){ + var popup = $(element).data("kendoPopup"); + if (popup) { + popup.destroy(); + } + $(element).remove(); + }); + + kendo.effects.enable(); + } + }); + + test("show method triggers show event with popup element as argument", 2, function() { + var triggered = false; + var args = {}; + + createNotification({ + show: function(e) { + triggered = true; + args = e; + } + }); + + notification.show("foo"); + + ok(triggered); + ok(args.element && args.element.length && args.element.length == 1); + }); + + test("show method triggers show event with static element as argument", 2, function() { + var triggered = false; + var args = {}; + + createNotification({ + appendTo: QUnit.fixture, + show: function(e) { + triggered = true; + args = e; + } + }); + + notification.show("foo"); + + ok(triggered); + ok(args.element && args.element.length && args.element.length == 1); + }); + + test("notification hide triggers hide event with popup element as argument", 2, function() { + var triggered = false; + var args = {}; + + createNotification({ + hide: function(e) { + triggered = true; + args = e; + } + }); + + notification.show("foo"); + + notification.hide(); + + ok(triggered); + ok(args.element && args.element.length && args.element.length == 1); + }); + + test("notification hide triggers hide event with static element as argument", 2, function() { + var triggered = false; + var args = {}; + + createNotification({ + appendTo: QUnit.fixture, + hide: function(e) { + triggered = true; + args = e; + } + }); + + notification.show("foo"); + + notification.hide(); + + ok(triggered); + ok(args.element && args.element.length && args.element.length == 1); + }); + +})(); \ No newline at end of file diff --git a/tests/notification/helper.js b/tests/notification/helper.js new file mode 100644 index 00000000000..cc5bc430b7d --- /dev/null +++ b/tests/notification/helper.js @@ -0,0 +1,5 @@ +var notification; + +function createNotification(options) { + notification = $("").appendTo(QUnit.fixture).kendoNotification(options).data("kendoNotification"); +} \ No newline at end of file diff --git a/tests/notification/initialization.js b/tests/notification/initialization.js new file mode 100644 index 00000000000..c95d7b48e12 --- /dev/null +++ b/tests/notification/initialization.js @@ -0,0 +1,677 @@ +(function() { + module("initialization", { + setup: function() { + kendo.effects.disable(); + }, + teardown: function() { + if (notification) { + notification.destroy(); + } + $(".k-notification").each(function(idx, element){ + var popup = $(element).data("kendoPopup"); + if (popup) { + popup.destroy(); + } + $(element).remove(); + }); + + kendo.effects.enable(); + } + }); + + test("initialization creates an internal GUID", 3, function() { + createNotification(); + + var guid = notification._guid; + + equal(typeof guid, "string"); + equal(guid.length, 37); + equal(guid.substr(0, 1), "_"); + }); + + test("initialization compiles popup stacking settings", 4, function() { + createNotification(); + + var origin = notification._popupOrigin, + position = notification._popupPosition, + regex = /^[a-z]+ [a-z]+$/; + + equal(typeof origin, "string"); + equal(typeof position, "string"); + equal(regex.exec(origin), origin); + equal(regex.exec(position), position); + }); + + test("initialization compiles popup padding settings", 4, function() { + createNotification(); + + var paddings = notification._popupPaddings, + size = 0, + allZero = true, + key; + + for (key in paddings) { + if (paddings.hasOwnProperty(key)) { + size++; + } + if (paddings[key] != 0) { + allZero = false; + } + } + + equal(typeof paddings, "object"); + equal(size, 3); + ok(allZero); + ok(!paddings.hasOwnProperty("paddingTop")); + }); + + test("up stacking removes top popup padding", function() { + createNotification({ + stacking: "up" + }); + + var paddings = notification._popupPaddings; + + ok(!paddings.hasOwnProperty("paddingTop")); + }); + + test("down stacking removes bottom popup padding", function() { + createNotification({ + stacking: "down" + }); + + var paddings = notification._popupPaddings; + + ok(!paddings.hasOwnProperty("paddingBottom")); + }); + + test("right stacking removes right popup padding", function() { + createNotification({ + stacking: "right" + }); + + var paddings = notification._popupPaddings; + + ok(!paddings.hasOwnProperty("paddingRight")); + }); + + test("left stacking removes right popup padding", function() { + createNotification({ + stacking: "left" + }); + + var paddings = notification._popupPaddings; + + ok(!paddings.hasOwnProperty("paddingLeft")); + }); + + test("initialization compiles default template function", 2, function() { + createNotification(); + + var defaultFunc = notification._getCompiled(); + var params = {typeIcon: "info", content: "foo"}; + var defaultOutput = '
                                                          infofooHide
                                                          '; + + equal(typeof defaultFunc, "function"); + equal(defaultFunc(params), defaultOutput); + }); + + test("initialization compiles custom template function", 2, function() { + createNotification({ + templates: { + foo: "bar" + } + }); + + var fooFunc = notification._getCompiled("foo"); + + equal(typeof fooFunc, "function"); + equal(fooFunc({}), "bar"); + }); + + asyncTest("opened popup notifications are hidden after set autoHideAfter", function() { + var autoHideAfter = 10; + + createNotification({ + autoHideAfter: autoHideAfter + }); + + notification.show("foo"); + + setTimeout(function(){ + start(); + equal($(".k-notification").length, 0); + }, autoHideAfter + 10); + + }); + + asyncTest("opened static notifications are hidden after set autoHideAfter", function() { + var autoHideAfter = 10; + + createNotification({ + appendTo: QUnit.fixture, + autoHideAfter: autoHideAfter + }); + + notification.show("foo"); + + setTimeout(function(){ + start(); + equal($(".k-notification").length, 0); + }, autoHideAfter + 10); + + }); + + test("clicking on popup notification hides it when hideOnClick is true (default)", function() { + createNotification({ + autoHideAfter: 0 + }); + + notification.show("foo"); + + $(".k-notification").click(); + + equal($(".k-notification").length, 0); + }); + + test("clicking on static notification hides it when hideOnClick is true (default)", function() { + createNotification({ + appendTo: QUnit.fixture, + autoHideAfter: 0 + }); + + notification.show("foo"); + + $(".k-notification").click(); + + equal($(".k-notification").length, 0); + }); + + test("clicking on notification popup does not hide it when hideOnClick is false", function() { + createNotification({ + autoHideAfter: 0, + hideOnClick: false + }); + + notification.show("foo"); + + $(".k-notification").click(); + + equal($(".k-notification").length, 1); + }); + + test("clicking on static notification does not hide it when hideOnClick is false", function() { + createNotification({ + appendTo: QUnit.fixture, + autoHideAfter: 0, + hideOnClick: false + }); + + notification.show("foo"); + + $(".k-notification").click(); + + equal($(".k-notification").length, 1); + }); + + test("notification width and height are null by default", 2, function() { + createNotification({ + autoHideAfter: 0 + }); + + notification.show("foo"); + + var notificationElement = $(".k-notification")[0]; + + equal(notificationElement.style.width, ""); + equal(notificationElement.style.height, ""); + }); + + test("int width and height settings are applied as inline styles", 2, function() { + var size = 2; + + createNotification({ + width: size, + height: size, + autoHideAfter: 0 + }); + + notification.show("foo"); + + var notificationElement = $(".k-notification")[0]; + + equal(notificationElement.style.width, size + "px"); + equal(notificationElement.style.height, size + "px"); + }); + + test("string pixel width and height settings are applied as inline styles", 2, function() { + var size = "2px"; + + createNotification({ + width: size, + height: size, + autoHideAfter: 0 + }); + + notification.show("foo"); + + var notificationElement = $(".k-notification")[0]; + + equal(notificationElement.style.width, size); + equal(notificationElement.style.height, size); + }); + + test("string em width and height settings are applied as inline styles", 2, function() { + var size = "2em"; + + createNotification({ + width: size, + height: size, + autoHideAfter: 0 + }); + + notification.show("foo"); + + var notificationElement = $(".k-notification")[0]; + + equal(notificationElement.style.width, size); + equal(notificationElement.style.height, size); + }); + + test("hide button is by default hidden", function() { + createNotification(); + + notification.show("foo"); + ok(!$(".k-notification").find(".k-i-close").is(":visible")); + }); + + test("hide button is displayed if button property is set to true", function() { + createNotification({ + button: true + }); + + notification.show("foo"); + + ok($(".k-notification").find(".k-i-close").is(":visible")); + }); + + test("clicking on static notification hides it when button is pressed", function() { + createNotification({ + appendTo: QUnit.fixture, + autoHideAfter: 0, + hideOnClick: false, + button: true + }); + + notification.show("foo"); + + $(".k-notification").find(".k-i-close").click(); + + equal($(".k-notification").length, 0); + }); + + test("clicking on popup notification hides it when button is pressed", function() { + createNotification({ + autoHideAfter: 0, + hideOnClick: false, + button: true + }); + + notification.show("foo"); + + $(".k-notification").find(".k-i-close").click(); + + equal($(".k-notification").length, 0); + }); + + test("popup notifications have fixed position style by default", function() { + createNotification(); + + notification.show("foo"); + + equal($(".k-notification").closest(".k-animation-container").css("position"), "fixed"); + }); + + test("unpinned popup notifications have an absolute position style", function() { + createNotification({ + position: { + pinned: false + } + }); + + notification.show("foo"); + + equal($(".k-notification").closest(".k-animation-container").css("position"), "absolute"); + }); + + test("pinned popup notification is shown at specified int position", 2, function() { + createNotification({ + position: { + top: 1, + left: 2 + } + }); + + notification.show("foo"); + + var popupContainer = $(".k-notification").parent(); + + equal(popupContainer.css("top"), "1px"); + equal(popupContainer.css("left"), "2px"); + }); + + test("pinned popup notification is shown at specified string position", 2, function() { + createNotification({ + position: { + top: "1px", + left: "2px" + } + }); + + notification.show("foo"); + + var popupContainer = $(".k-notification").parent(); + + equal(popupContainer.css("top"), "1px"); + equal(popupContainer.css("left"), "2px"); + }); + + test("pinned popup notification is shown at zero position", 2, function() { + createNotification({ + position: { + top: 0, + left: 0 + } + }); + + notification.show("foo"); + + var popupContainer = $(".k-notification").parent(); + + equal(popupContainer.css("top"), "0px"); + equal(popupContainer.css("left"), "0px"); + }); + + test("unpinned popup notification is shown at specified int position", 2, function() { + createNotification({ + position: { + top: 1, + left: 2, + pinned: false + } + }); + + notification.show("foo"); + + var popupContainer = $(".k-notification").parent(); + + equal(popupContainer.css("top"), "1px"); + equal(popupContainer.css("left"), "2px"); + }); + + test("unpinned popup notification is shown at specified string position", 2, function() { + createNotification({ + position: { + top: "1px", + left: "2px", + pinned: false + } + }); + + notification.show("foo"); + + var popupContainer = $(".k-notification").parent(); + + equal(popupContainer.css("top"), "1px"); + equal(popupContainer.css("left"), "2px"); + }); + + test("unpinned popup notification is shown at zero position", 2, function() { + createNotification({ + position: { + top: 0, + left: 0, + pinned: false + } + }); + + notification.show("foo"); + + var popupContainer = $(".k-notification").parent(); + + equal(popupContainer.css("top"), "0px"); + equal(popupContainer.css("left"), "0px"); + }); + + test("pinned popup notification ignores page scroll offset", 2, function() { + QUnit.fixture.css({width: 4000, height: 4000}); + var scrollPosition = 1000; + + $(QUnit.fixture[0].ownerDocument).scrollTop(scrollPosition).scrollLeft(scrollPosition); + + createNotification({ + position: { + top: 1, + left: 2 + } + }); + + notification.show("foo"); + + var popupContainer = $(".k-notification").parent(); + + equal(popupContainer.css("top"), "1px"); + equal(popupContainer.css("left"), "2px"); + }); + + test("unpinned popup notification obeys page scroll offset", 2, function() { + QUnit.fixture.css({width: 4000, height: 4000}); + var scrollPosition = 1000; + + $(QUnit.fixture[0].ownerDocument).scrollTop(scrollPosition).scrollLeft(scrollPosition); + + createNotification({ + position: { + top: 1, + left: 2, + pinned: false + } + }); + + notification.show("foo"); + + var popupContainer = $(".k-notification").parent(); + + equal(popupContainer.css("top"), "1001px"); + equal(popupContainer.css("left"), "1002px"); + }); + + test("down static stacking is applied by default", 2, function() { + createNotification({ + appendTo: QUnit.fixture, + autoHideAfter: 0 + }); + + notification.show('foo'); + notification.show('bar'); + + equal(QUnit.fixture.children(".k-notification").first().find("#foo").length, 1); + equal(QUnit.fixture.children(".k-notification").last().find("#bar").length, 1); + }); + + test("right static stacking behaves as down stacking", 2, function() { + createNotification({ + appendTo: QUnit.fixture, + autoHideAfter: 0, + stacking: "right" + }); + + notification.show('foo'); + notification.show('bar'); + + equal(QUnit.fixture.children(".k-notification").first().find("#foo").length, 1); + equal(QUnit.fixture.children(".k-notification").last().find("#bar").length, 1); + }); + + test("up static stacking is applied", 2, function() { + createNotification({ + appendTo: QUnit.fixture, + autoHideAfter: 0, + stacking: "up" + }); + + notification.show('foo'); + notification.show('bar'); + + equal(QUnit.fixture.children(".k-notification").last().find("#foo").length, 1); + equal(QUnit.fixture.children(".k-notification").first().find("#bar").length, 1); + }); + + test("left static stacking behaves as up stacking", 2, function() { + createNotification({ + appendTo: QUnit.fixture, + autoHideAfter: 0, + stacking: "left" + }); + + notification.show('foo'); + notification.show('bar'); + + equal(QUnit.fixture.children(".k-notification").last().find("#foo").length, 1); + equal(QUnit.fixture.children(".k-notification").first().find("#bar").length, 1); + }); + + test("up popup stacking is applied by default", 2, function() { + createNotification({ + autoHideAfter: 0 + }); + + notification.show('foo'); + var fooNotificationWrapper = $("#foo").closest(".k-notification").parent(); + + notification.show('bar'); + var barNotificationWrapper = $("#bar").closest(".k-notification").parent(); + + ok(fooNotificationWrapper.css("top") > barNotificationWrapper.css("top")); + equal(fooNotificationWrapper.css("left"), barNotificationWrapper.css("left")); + }); + + test("down popup stacking is applied", 2, function() { + createNotification({ + autoHideAfter: 0, + stacking: "down" + }); + + notification.show('foo'); + var fooNotificationWrapper = $("#foo").closest(".k-notification").parent(); + + notification.show('bar'); + var barNotificationWrapper = $("#bar").closest(".k-notification").parent(); + + ok(fooNotificationWrapper.css("top") < barNotificationWrapper.css("top")); + equal(fooNotificationWrapper.css("left"), barNotificationWrapper.css("left")); + }); + + test("down popup stacking is applied by default if position.top is set", 2, function() { + createNotification({ + autoHideAfter: 0, + position: { + top: 1 + } + }); + + notification.show('foo'); + var fooNotificationWrapper = $("#foo").closest(".k-notification").parent(); + + notification.show('bar'); + var barNotificationWrapper = $("#bar").closest(".k-notification").parent(); + + ok(fooNotificationWrapper.css("top") < barNotificationWrapper.css("top")); + equal(fooNotificationWrapper.css("left"), barNotificationWrapper.css("left")); + }); + + test("right popup stacking is applied", 2, function() { + createNotification({ + autoHideAfter: 0, + stacking: "right" + }); + + notification.show('foo'); + var fooNotificationWrapper = $("#foo").closest(".k-notification").parent(); + + notification.show('bar'); + var barNotificationWrapper = $("#bar").closest(".k-notification").parent(); + + ok(fooNotificationWrapper.css("left") < barNotificationWrapper.css("left")); + equal(fooNotificationWrapper.css("top"), barNotificationWrapper.css("top")); + }); + + test("left popup stacking is applied", 2, function() { + createNotification({ + autoHideAfter: 0, + stacking: "left" + }); + + notification.show('foo'); + var fooNotificationWrapper = $("#foo").closest(".k-notification").parent(); + + notification.show('bar'); + var barNotificationWrapper = $("#bar").closest(".k-notification").parent(); + + ok(fooNotificationWrapper.css("left") > barNotificationWrapper.css("left")); + equal(fooNotificationWrapper.css("top"), barNotificationWrapper.css("top")); + }); + + test("clicking on popup notification before allowHideAfter does not hide it", 2, function() { + var allowHideAfter = 300; + + createNotification({ + autoHideAfter: 0, + allowHideAfter: allowHideAfter + }); + + notification.show("foo"); + + $(".k-notification").click(); + + equal($(".k-notification").length, 1); + + stop(); + + setTimeout(function(){ + start(); + + $(".k-notification").click(); + equal($(".k-notification").length, 0); + + }, allowHideAfter + 100); + }); + + test("clicking on popup notification button before allowHideAfter does not hide it", 2, function() { + var allowHideAfter = 300; + + createNotification({ + autoHideAfter: 0, + hideOnClick: false, + button: true, + allowHideAfter: allowHideAfter + }); + + notification.show("foo"); + + $(".k-notification").find(".k-i-close").click(); + + equal($(".k-notification").length, 1); + + stop(); + + setTimeout(function(){ + start(); + + $(".k-notification").find(".k-i-close").click(); + equal($(".k-notification").length, 0); + + }, allowHideAfter + 100); + }); + +})(); \ No newline at end of file diff --git a/tests/pager/mvvm.js b/tests/pager/mvvm.js new file mode 100644 index 00000000000..4ec2725f822 --- /dev/null +++ b/tests/pager/mvvm.js @@ -0,0 +1,50 @@ +(function() { + var DataSource = kendo.data.DataSource; + + module('pager MVVM', { + teardown: function() { + kendo.destroy(QUnit.fixture); + } + }); + + test("initializes a pager when data role is pager", function() { + var dom = $('
                                                          ').appendTo(QUnit.fixture); + + kendo.bind(dom); + + ok(dom.data("kendoPager") instanceof kendo.ui.Pager); + }); + + test("initalizes data source", function() { + var dom = $('
                                                          ').appendTo(QUnit.fixture); + + kendo.bind(dom, { items: DataSource.create(["foo", "bar"]) } ); + dom.data("kendoPager").dataSource.view(); + + equal(dom.data("kendoPager").dataSource.view()[0], "foo"); + }); + + test("binding pager initialized before binding", function() { + var dom = $('
                                                          ').appendTo(QUnit.fixture); + + var observable = kendo.observable({ items: DataSource.create([{text:"foo"}, {text:"bar"}])}); + + dom.kendoPager(); + + kendo.bind(dom, observable); + + equal(dom.data("kendoPager").dataSource.at(0).text, "foo"); + }); + + test("binding pager initialized after binding", function() { + var dom = $('
                                                          ').appendTo(QUnit.fixture); + + var observable = kendo.observable({ items: DataSource.create([{text:"foo"}, {text:"bar"}])}); + + kendo.bind(dom, observable); + + dom.kendoPager(); + + equal(dom.data("kendoPager").dataSource.at(0).text, "foo"); + }); +})(); diff --git a/tests/pager/pager.js b/tests/pager/pager.js new file mode 100644 index 00000000000..1ff55d3f205 --- /dev/null +++ b/tests/pager/pager.js @@ -0,0 +1,635 @@ +(function() { + var DataSource = kendo.data.DataSource, + pager, + dataSource; + + module('pager', { + setup: function() { + kendo.ns = "kendo-"; + }, + teardown: function() { + kendo.destroy(QUnit.fixture); + kendo.ns = ""; + } + }); + + function setup(dataOptions, options){ + dataOptions = $.extend({ + data: [1,2,3,4,5], + page: 1, + pageSize: 1 + }, dataOptions); + + dataSource = new DataSource(dataOptions); + options = $.extend({ + dataSource: dataSource, + previousNext: false + }, options); + var element = $("
                                                          ").appendTo(QUnit.fixture).kendoPager(options); + pager = element.data("kendoPager"); + return element; + } + + test("kendoPager attach pager to an element", function() { + var ul = setup(); + + ok(ul.data("kendoPager") instanceof kendo.ui.Pager); + ok(pager instanceof kendo.ui.Pager); + }); + + test("renders buttons for all pages", function() { + var ul = setup(); + + dataSource.read(); + + var links = ul.find("a").add(ul.find(".k-state-selected")); + equal(links.length, 5); + equal(links[0].innerHTML, "1"); + equal(links[1].innerHTML, "2"); + equal(links[2].innerHTML, "3"); + equal(links[3].innerHTML, "4"); + equal(links[4].innerHTML, "5"); + }); + + test("one button is rendered on init", function() { + var ul = setup(); + var links = ul.find("a").add(ul.find(".k-state-selected")); + + equal(links.length, 1); + equal(links[0].innerHTML, "0"); + }); + + test("buttons are rendered if read before init", function() { + var dataSource = new DataSource({ + pageSize: 1, + data: [1,2,3] + }); + + dataSource.read(); + + var ul = $("
                                                            ").appendTo(QUnit.fixture).kendoPager({ + dataSource: dataSource, + previousNext: false + }); + var links = ul.find("a").add(ul.find(".k-state-selected")); + + equal(links.length, 3); + equal(links[0].innerHTML, "1"); + equal(links[1].innerHTML, "2"); + equal(links[2].innerHTML, "3"); + }); + + test("page number buttons have data attribute assign exept for the current page index", function(){ + var ul = setup(); + + dataSource.read(); + + var links = ul.find("a"); + equal(ul.find(".k-state-selected").data("page"), undefined); + equal(links.eq(0).attr("data-kendo-page"), "2"); + equal(links.eq(1).attr("data-kendo-page"), "3"); + equal(links.eq(2).attr("data-kendo-page"), "4"); + equal(links.eq(3).attr("data-kendo-page"), "5"); + }); + + test("clear page number buttons on multiple datasource rebinds", function(){ + var ul = setup(); + + dataSource.read(); + dataSource.read(); + + var links = ul.find("a").add(ul.find(".k-state-selected")); + equal(links.length, 5); + equal(links[0].innerHTML, "1"); + equal(links[1].innerHTML, "2"); + equal(links[2].innerHTML, "3"); + equal(links[3].innerHTML, "4"); + equal(links[4].innerHTML, "5"); + }); + + test("does not render page numbers if total pages are zero", function(){ + var ul = setup({pageSize: -1}); + + dataSource.read(); + + equal(ul.find("a").length, 0); + }); + + test("currentPage css class is added to current page a", function(){ + var ul = setup(); + + dataSource.read(); + ok(ul.find("span").hasClass("k-state-selected")); + }); + + test("changing page raises change event passing the new index", function() { + var ul = setup(), + index; + + dataSource.read(); + pager.bind("change", function(){ + index = arguments[0].index; + }); + + ul.find("a:eq(0)").click(); + equal(index, 2); + }); + + test("change event is fired when clicking a page button", function() { + var index = 0, + changeHandler = function (e) { + index = parseInt(e.index, 10); + }, + ul = setup( { }, { change: changeHandler } ); + + dataSource.read(); + + ul.find("a:eq(0)").click(); + equal(index, 2); + }); + + test("clicking on the current page does not trigger change event", function(){ + var ul = setup(), + called = false; + + dataSource.read(); + pager.bind("change", function(){ + called = true; + }); + + ul.find("a.currentPage").click(); + ok(!called); + }); + + test("changing page is paging datasource", function() { + var ul = setup(); + + dataSource.read(); + ul.find("a:eq(0)").click(); + equal(dataSource.page(), 2); + }); + + test("show more button should be shown if page buttons are more than the threshold", function(){ + var ul = setup({},{ buttonCount: 3}); + + dataSource.read(); + equal(ul.find("a").add(ul.find(".k-state-selected")).length, 4); + equal(ul.find("a:last").attr("data-kendo-page"), "4"); + }); + + test("show less button should be shown if page buttons are more than the threshold", function(){ + var ul = setup({ page: 4 },{ buttonCount: 3}); + + dataSource.read(); + equal(ul.find("a").add(ul.find(".k-state-selected")).length, 3); + equal(ul.find("a:first").attr("data-kendo-page"), "3"); + }); + + test("clicking more button pages to next pages group", function() { + var ul = setup({},{ buttonCount: 3}); + + dataSource.read(); + ul.find("a:last").click(); + equal(dataSource.page(), 4); + }); + + test("totalPages", function() { + var ul = setup(); + + dataSource.read(); + equal(ul.data("kendoPager").totalPages(), 5); + }); + + test("pageSize returns the dataSource pageSize value", function() { + var ul = setup(); + dataSource.read(); + + equal(ul.data("kendoPager").pageSize(), dataSource.pageSize()); + }); + + test("page returns the current page", function(){ + var ul = setup(); + dataSource.read(); + ul.find("a:eq(0)").click(); + + equal(ul.data("kendoPager").page(), 2); + }); + + test("custom linkTemplate should be used instead of the default", function() { + var ul = setup({}, { linkTemplate: "foo" }); + dataSource.read(); + equal(ul.find("a:eq(1)").text(), "foo"); + }); + + test("custom selectTemplate should be used", function() { + var ul = setup({}, { selectTemplate: "foo" }); + dataSource.read(); + equal(ul.find("a:first").text(), "foo"); + }); + + test("single page is rendered if no pageSize is set", function() { + var data = new DataSource( { data: [1,2,3,4,5], page: 1 }), + ul = $("
                                                              ").appendTo(QUnit.fixture).kendoPager({ dataSource: data }); + + data.read(); + equal(ul.find(".k-state-selected").length, 1); + }); + + test("pager displays info", function(){ + var pager = setup(); + dataSource.read(); + + equal(pager.find(".k-pager-info").text(), "1 - 1 of 5 items"); + }); + + test("pager does not displays info if info is set to false", function(){ + var pager = setup({}, { info: false }); + dataSource.read(); + + equal(pager.find(".k-pager-info").length, 0); + }); + + test("pager displays empty message when total is zero", function(){ + var pager = setup({data: []}); + dataSource.read(); + + equal(pager.find(".k-pager-info").text(), "No items to display"); + }); + + test("pager displays input", function() { + var pager = setup({data: []}, { input: true }); + dataSource.read(); + + equal(pager.find(".k-pager-input").length, 1); + }); + + test("input pager changes the page", function() { + var pager = setup({}, { input: true }); + dataSource.read(); + + pager.find(".k-pager-input").find("input").val(2).trigger({ type: "keydown", keyCode: 13 }); + + equal(dataSource.page(), 2); + }); + + test("input pager stays on current page if the input value is less than one is specified", function() { + var pager = setup({}, { input: true }); + dataSource.read(); + + pager.find(".k-pager-input").find("input").val(0).trigger({ type: "keydown", keyCode: 13 }); + + equal(dataSource.page(), 1); + equal(pager.find(".k-pager-input").find("input").val(), "1"); + }); + + test("input pager stays on current page if the input value is more than the total number of pages", function() { + var pager = setup({}, { input: true }); + dataSource.read(); + + pager.find(".k-pager-input").find("input").val(10).trigger({ type: "keydown", keyCode: 13 }); + + equal(dataSource.page(), 1); + equal(pager.find(".k-pager-input").find("input").val(), "1"); + }); + + test("input pager stays on current page if the input value is not a number", function() { + var pager = setup({}, { input: true }); + dataSource.read(); + + pager.find(".k-pager-input").find("input").val("foo").trigger({ type: "keydown", keyCode: 13 }); + + equal(dataSource.page(), 1); + equal(pager.find(".k-pager-input").find("input").val(), "1"); + }); + + test("input pager is updated when the page is changed", function() { + var pager = setup({}, { input: true }); + dataSource.read(); + + dataSource.page(2); + equal(pager.find(".k-pager-input").find("input").val(), "2"); + }); + + test("input pager is disabled if the data source is empty", function() { + var pager = setup({data:[]}, { input: true }); + dataSource.read(); + + equal(pager.find(".k-pager-input").find("input").attr("disabled"), "disabled"); + }); + + test("input pager shows the available pages", function() { + var pager = setup({}, { input: true }); + + dataSource.read(); + + equal(pager.find(".k-pager-input").text(), "Pageof 5"); + }); + + test("pager localization", function() { + var pager = setup({}, { + input: true, + messages: { + display: "Showing {0} - {1} of {2}", + page: "Foo", + of: "bar{0}" + } + }); + + dataSource.read(); + + equal(pager.find(".k-pager-info").text(), "Showing 1 - 1 of 5"); + equal(pager.find(".k-pager-input").text(), "Foobar5"); + + pager = setup({ data: [] }, { + messages: { + empty: "zero" + } + }); + + dataSource.read(); + equal(pager.find(".k-pager-info").text(), "zero"); + }); + + test("shows prev button", function() { + var pager = setup({}, { previousNext: true }); + + equal(pager.find(".k-i-arrow-w").length, 1); + }); + + test("shows first button", function() { + var pager = setup({}, { previousNext: true }); + + equal(pager.find(".k-pager-first .k-i-seek-w").length, 1); + }); + + test("shows next button", function() { + var pager = setup({}, { previousNext: true }); + + equal(pager.find(".k-i-arrow-e").length, 1); + }); + + test("shows last button", function() { + var pager = setup({}, { previousNext: true }); + + equal(pager.find(".k-pager-last .k-i-seek-e").length, 1); + }); + + test("first button is disabled on the first page", function() { + var pager = setup({}, { previousNext: true }); + + ok(pager.find(".k-pager-first").hasClass("k-state-disabled")); + }); + + test("first button is enabled on any page but first", function() { + var pager = setup({}, { previousNext: true }); + dataSource.read(); + dataSource.page(2); + + ok(!pager.find(".k-pager-first").hasClass("k-state-disabled")); + }); + + test("prev button is disabled on the first page", function() { + var pager = setup({}, { previousNext: true }); + + ok(pager.find(".k-i-arrow-w").parent().hasClass("k-state-disabled")); + }); + + test("prev button is enabled on any page but first", function() { + var pager = setup({}, { previousNext: true }); + + dataSource.read(); + dataSource.page(2); + + ok(!pager.find(".k-i-arrow-w").parent().hasClass("k-state-disabled")); + }); + + test("prev button page data attribute is set to page minus one", function() { + var pager = setup({}, { previousNext: true }); + + dataSource.read(); + dataSource.page(3); + + equal(pager.find(".k-i-arrow-w").parent().data(kendo.ns + "page"), 2); + }); + + test("next button is disabled on the last page", function() { + var pager = setup({}, { previousNext: true }); + + dataSource.read(); + dataSource.page(5); + ok(pager.find(".k-i-arrow-e").parent().hasClass("k-state-disabled")); + }); + + test("next button is enabled on any page but last", function() { + var pager = setup({}, { previousNext: true }); + + dataSource.read(); + ok(!pager.find(".k-i-arrow-e").parent().hasClass("k-state-disabled")); + }); + + test("next button page data attribute is set to page plus one", function() { + var pager = setup({}, { previousNext: true }); + + dataSource.read(); + dataSource.page(3); + + equal(pager.find(".k-i-arrow-e").parent().data(kendo.ns + "page"), 4); + }); + + test("last button is disabled on the last page", function() { + var pager = setup({}, { previousNext: true }); + + dataSource.read(); + dataSource.page(5); + ok(pager.find(".k-pager-last").hasClass("k-state-disabled")); + }); + + test("last button is enabled on any page but last", function() { + var pager = setup({}, { previousNext: true }); + + dataSource.read(); + ok(!pager.find(".k-pager-last").hasClass("k-state-disabled")); + }); + + test("prev button page data attribute is set to total pages", function() { + var pager = setup({}, { previousNext: true }); + + dataSource.read(); + + equal(pager.find(".k-pager-last").data(kendo.ns + "page"), dataSource.totalPages()); + }); + + test("first is enabled if the data source is read before pager init", function() { + var dataSource = new DataSource({ + pageSize: 1, + data: [1,2,3] + }); + + dataSource.read(); + dataSource.page(2); + + var pager = $("
                                                              ").appendTo(QUnit.fixture).kendoPager({ + dataSource: dataSource, + autoBind: false + }); + + ok(!pager.find(".k-pager-first").hasClass("k-state-disabled")); + }); + + test("previous is enabled if the data source is read before pager init", function() { + var dataSource = new DataSource({ + pageSize: 1, + data: [1,2,3] + }); + + dataSource.read(); + dataSource.page(2); + + var pager = $("
                                                              ").appendTo(QUnit.fixture).kendoPager({ + dataSource: dataSource, + autoBind: false + }); + + ok(!pager.find(".k-i-arrow-w").parent().hasClass("k-state-disabled")); + }); + + test("next is enabled if the data source is read before pager init", function() { + var dataSource = new DataSource({ + pageSize: 1, + data: [1,2,3] + }); + + dataSource.read(); + dataSource.page(2); + + var pager = $("
                                                              ").appendTo(QUnit.fixture).kendoPager({ + dataSource: dataSource, + autoBind: false + }); + + ok(!pager.find(".k-i-arrow-e").parent().hasClass("k-state-disabled")); + }); + + test("last is enabled if the data source is read before pager init", function() { + var dataSource = new DataSource({ + pageSize: 1, + data: [1,2,3] + }); + + dataSource.read(); + dataSource.page(2); + + var pager = $("
                                                              ").appendTo(QUnit.fixture).kendoPager({ + dataSource: dataSource, + autoBind: false + }); + + ok(!pager.find(".k-pager-last").hasClass("k-state-disabled")); + }); + + test("creates a dropdown for the page sizes", function() { + var pager = setup({}, { pageSizes: true }); + + equal(pager.find(".k-pager-sizes select").length, 1); + }); + + test("default page sizes", function() { + var pager = setup({}, { pageSizes: true }); + + equal(pager.find(".k-pager-sizes select option").text(), "51020"); + }); + + test("pageSizes can be array with numbers specifying custom page sizes", function() { + var pager = setup({}, { pageSizes: [1,2] }); + + equal(pager.find(".k-pager-sizes select option").text(), "12"); + }); + + test("the page size of the data source is selected", function() { + var pager = setup({pageSize: 2}, { pageSizes: [1, 2] }); + + equal(pager.find(".k-pager-sizes select").val(), "2"); + }); + + test("changing the page size of the data source selects the corresponding option", function() { + var pager = setup({}, { pageSizes: [1, 2] }); + + dataSource.pageSize(2); + + equal(pager.find(".k-pager-sizes select").val(), "2"); + }); + + test("changing the page size of the data source selects the corresponding option", 2, function() { + var pager = setup({}, { pageSizes: [1, 2] }); + + dataSource.pageSize(2); + + equal(pager.find(".k-pager-sizes select").val(), "2"); + equal(pager.find(".k-pager-sizes select").kendoDropDownList("text"), 2); + }); + + test("changing the page size of the data source to a custom value is displayed", function() { + var pager = setup({}, { pageSizes: [1, 2] }); + + dataSource.pageSize(5); + + equal(pager.find(".k-pager-sizes select").kendoDropDownList("text"), 5); + }); + + + test("changing the page size from the select changes the page size in the data source", function() { + var pager = setup({}, { pageSizes: [1, 2] }); + + pager.find(".k-pager-sizes select").val(2).trigger("change"); + + equal(dataSource.pageSize(), 2); + }); + + test("displays refresh button", function() { + var pager = setup({}, { refresh: true }); + + equal(pager.find(".k-i-refresh").length, 1); + }); + + test("clicking the refresh button reads from the data source", function() { + var pager = setup({}, { refresh: true }); + + dataSource.read(); + + stub(dataSource, { + read: function() { + } + }); + + pager.find(".k-i-refresh").click(); + + equal(dataSource.calls("read"), 1); + }); + + test("does not render numeric pager if numeric is set to false", function() { + var pager = setup({}, { numeric: false }); + + dataSource.read(); + + equal(pager.find(".k-pager-numbers").length, 0); + }); + + test("dropdown is visible when pager is created multiple times", function() { + setup(); + + container = $("
                                                              ").appendTo(QUnit.fixture).kendoPager({ + dataSource: dataSource, + pageSizes: [10, 20] + }); + + container.data("kendoPager").destroy(); + + container.kendoPager({ + dataSource: dataSource, + pageSizes: [10, 20] + }); + + ok(container.find("select").data("kendoDropDownList") + .wrapper.css("display") !== "none"); + }); +})(); diff --git a/tests/panelbar/ajax-loading.js b/tests/panelbar/ajax-loading.js new file mode 100644 index 00000000000..6df2f899d7a --- /dev/null +++ b/tests/panelbar/ajax-loading.js @@ -0,0 +1,176 @@ +(function () { + var panelbar; + var ul; + + module("panelbar ajax loading", { + setup: function() { + kendo.effects.disable(); + + QUnit.fixture.append( + '' + ); + + $.mockjaxSettings.responseTime = 0; + + $.mockjax({ + url: "error.html", + response: function() { + this.responseText = 'foo'); + }, + teardown: function() { + kendo.destroy(dom); + } + }); + + test("initializes a panelbar when data role is panelbar", function() { + dom = $('
                                                              '); + + kendo.bind(dom); + + ok(dom.data("kendoPanelBar") instanceof kendo.ui.PanelBar); + }); + + test("initializes a options from data attributes", function() { + dom = $('
                                                              '); + + kendo.bind(dom); + + var panelbar = dom.data("kendoPanelBar"); + + equal(panelbar.options.expandMode, "single"); + }); + + test("binding panelbar initialized before binding", function() { + dom = $('
                                                              '); + + dom.kendoPanelBar(); + + kendo.bind(dom); + + equal(dom.data("kendoPanelBar").options.expandMode, "single"); + }); + + test("binding containing binding attributes", function() { + dom = $('
                                                              '); + + var observable = kendo.observable({ text:"foo" }); + + kendo.bind(dom, observable); + + equal($.trim(dom.find("span:first").html()), "foo"); + }); + + test("updating viewModel updates the content", function() { + dom = $('
                                                              '); + + var observable = kendo.observable({ text:"foo" }); + + kendo.bind(dom, observable); + + observable.set("text", "bar"); + + equal($.trim(dom.find("span:first").html()), "bar"); + }); + + test("source binding is skipped if set to target element", function() { + dom = $('
                                                                '); + + var observable = kendo.observable({ items: [{text: "foo"}, {text:"bar" }] }); + + kendo.bind(dom, observable); + dom.kendoPanelBar(); + equal(dom.children().length, 2) + }); + + test("event is raised if attached as option", 1, function() { + window.panelBarExpand = function() { + ok(true); + } + + dom = $('
                                                                '); + + kendo.bind(dom); + + dom.data("kendoPanelBar").trigger("expand"); + }); + + + test("binding visible to true shows the panelbar", function() { + dom = $('
                                                                '); + + kendo.bind(dom, { visible: true }); + + var panelbar = dom.data("kendoPanelBar"); + + ok(panelbar.wrapper.css("display") != "none", "panelbar is visible"); + }); + + test("binding visible to false hides the panelbar", function() { + dom = $('
                                                                '); + + kendo.bind(dom, { visible: false }); + + var panelbar = dom.data("kendoPanelBar"); + + ok(panelbar.wrapper.css("display") == "none", "panelbar is not visible"); + }); + + test("binding invisible to true hides the panelbar", function() { + dom = $('
                                                                '); + + kendo.bind(dom, { invisible: true }); + + var panelbar = dom.data("kendoPanelBar"); + + ok(panelbar.wrapper.css("display") == "none", "panelbar is invisible"); + }); + + test("binding invisible to false shows the panelbar", function() { + dom = $('
                                                                '); + + kendo.bind(dom, { invisible: false }); + + var panelbar = dom.data("kendoPanelBar"); + + ok(panelbar.wrapper.css("display") != "none", "panelbar is not invisible"); + }); +})(); diff --git a/tests/panelbar/navigation.js b/tests/panelbar/navigation.js new file mode 100644 index 00000000000..af117fe245c --- /dev/null +++ b/tests/panelbar/navigation.js @@ -0,0 +1,327 @@ +(function() { + var keys = kendo.keys; + var panelbar; + var ul; + + module("panelbar navigation", { + setup: function() { + kendo.effects.disable(); + + ul = $('
                                                                  ').appendTo(QUnit.fixture); + + panelbar = new kendo.ui.PanelBar(ul); + }, + teardown: function() { + kendo.destroy(QUnit.fixture); + + kendo.effects.enable(); + } + }); + + function addItems(count, parent) { + for (var i = 0; i < count; i++) { + panelbar.append({ + text: "Item" + i + }, parent); + } + } + + + test("PanelBar adds tabindex", function() { + equal(ul.attr("tabindex"), 0); + }); + + test("PanelBar selects first item on focus", function() { + addItems(2); + + ul.focus(); + + var first = ul.children(":first"); + ok(first.children(":first").hasClass("k-state-focused")); + }); + + test("PanelBar clears focused item on blur", function() { + addItems(2); + + ul.focus(); + ul.blur(); + + var first = ul.children(":first"); + ok(!first.children(":first").hasClass("k-state-focused")); + }); + + test("PanelBar selects next item on key DOWN", function() { + addItems(2); + + ul.focus(); + ul.trigger({ + type: "keydown", + keyCode: keys.DOWN + }); + + ok(ul.children(":last").children(".k-link").hasClass("k-state-focused")); + ok(!ul.children(":first").children(".k-link").hasClass("k-state-focused")); + }); + + test("PanelBar misses next item if disabled", function() { + addItems(3); + + panelbar.enable(ul.children().eq(1), false); + + ul.focus(); + + ul.trigger({ + type: "keydown", + keyCode: keys.DOWN + }); + + ok(ul.children(":last").children(".k-link").hasClass("k-state-focused")); + }); + + test("PanelBar selects first item of group", function() { + addItems(2); + addItems(2, ul.children(":first")); + + ul.focus(); + ul.data("kendoPanelBar").expand(ul.children(":first")); + ul.trigger({ + type: "keydown", + keyCode: keys.DOWN + }); + + ok(ul.children(":first").find("li:first > span.k-link").hasClass("k-state-focused")); + }); + + test("PanelBar selects next item if current is last in a group", function() { + addItems(2); + addItems(2, ul.children(":first")); + + ul.focus(); + panelbar.expand(ul.children(":first")); + panelbar._current(ul.children(":first").find("li:last")); + + ul.trigger({ + type: "keydown", + keyCode: keys.DOWN + }); + + ok(ul.children(":last").children("span.k-link").hasClass("k-state-focused")); + }); + + test("PanelBar selects first if last is selected", function() { + addItems(2); + addItems(2, ul.children(":first")); + + ul.focus(); + panelbar.expand(ul.children(":first")); + panelbar._current(ul.children(":last")); + + ul.trigger({ + type: "keydown", + keyCode: keys.DOWN + }); + + ok(ul.children(":first").children("span.k-link").hasClass("k-state-focused")); + }); + + test("PanelBar selects first on HOME key", function() { + addItems(2); + addItems(2, ul.children(":first")); + + ul.focus(); + panelbar.expand(ul.children(":first")); + panelbar._current(ul.children(":last")); + + ul.trigger({ + type: "keydown", + keyCode: keys.HOME + }); + + ok(ul.children(":first").children("span.k-link").hasClass("k-state-focused")); + }); + + test("PanelBar selects last on END key", function() { + addItems(2); + addItems(2, ul.children(":first")); + + ul.focus(); + panelbar.expand(ul.children(":first")); + + ul.trigger({ + type: "keydown", + keyCode: keys.END + }); + + ok(ul.children(":last").children("span.k-link").hasClass("k-state-focused")); + }); + + test("PanelBar selects prev item on key UP", function() { + addItems(2); + + ul.focus(); + ul.trigger({ + type: "keydown", + keyCode: keys.DOWN + }); + + ul.trigger({ + type: "keydown", + keyCode: keys.UP + }); + + ok(ul.children(":first").children(".k-link").hasClass("k-state-focused")); + ok(!ul.children(":last").children(".k-link").hasClass("k-state-focused")); + }); + + test("PanelBar selects prev parent item", function() { + addItems(2); + addItems(2, ul.children(":first")); + + ul.focus(); + panelbar.expand(ul.children(":first")); + panelbar._current(ul.children(":first").find("li:first")); + + ul.trigger({ + type: "keydown", + keyCode: keys.UP + }); + + ok(ul.children(":first").children(".k-link").hasClass("k-state-focused")); + }); + + test("PanelBar selects last if no prev", function() { + addItems(2); + addItems(2, ul.children(":first")); + + ul.focus(); + panelbar.expand(ul.children(":first")); + panelbar._current(ul.children(":first").find("li:first")); + + ul.trigger({ + type: "keydown", + keyCode: keys.UP + }); + + ul.trigger({ + type: "keydown", + keyCode: keys.UP + }); + + ok(ul.children(":last").children(".k-link").hasClass("k-state-focused")); + }); + + test("PanelBar selects prev nested and visible item", function() { + addItems(2); + addItems(2, ul.children(":first")); + addItems(2, ul.children(":first").children(".k-group").children(":last")); + + ul.focus(); + panelbar.expand(ul.children(":first")); + panelbar.expand(ul.children(":first").children(".k-group").children(":last")); + panelbar._current(ul.children(":last")); + + ul.trigger({ + type: "keydown", + keyCode: keys.UP + }); + + ok(ul.children(":first") + .children(".k-group").children(":last") + .children(".k-group").children(":last") + .children("span.k-link") + .hasClass("k-state-focused")); + }); + + test("PanelBar misses prev item if disabled", function() { + addItems(3); + + panelbar.enable(ul.children().eq(1), false); + + ul.focus(); + panelbar._current(ul.children(":last")); + + ul.trigger({ + type: "keydown", + keyCode: keys.UP + }); + + ok(ul.children(":first").children(".k-link").hasClass("k-state-focused")); + }); + + test("PanelBar moves focus to last element in the last expanded group", function() { + addItems(3); + addItems(2, ul.children(":last")); + + ul.focus(); + panelbar.expand(ul.children(":last")); + panelbar._current(ul.children(":first")); + + ul.trigger({ + type: "keydown", + keyCode: keys.UP + }); + + ok(ul.children(":last").children(".k-group").children(":last").children(".k-link").hasClass("k-state-focused")); + }); + + test("PanelBar expands current focused item on Enter", function() { + addItems(3); + addItems(2, ul.children(":first")); + + ul.focus(); + panelbar._current(ul.children(":first")); + + ul.trigger({ + type: "keydown", + keyCode: keys.ENTER + }); + + ok(ul.children(":first").children(".k-group:visible")[0]); + }); + + test("PanelBar selects item on Enter", function() { + addItems(3); + addItems(2, ul.children(":first")); + + ul.focus(); + panelbar._current(ul.children(":first")); + + ul.trigger({ + type: "keydown", + keyCode: keys.ENTER + }); + + ok(ul.children(":first").children(".k-link").hasClass("k-state-selected")); + }); + + test("PanelBar collapses expanded group", function() { + addItems(3); + addItems(2, ul.children(":first")); + + ul.focus(); + panelbar._current(ul.children(":first")); + + ul.trigger({ + type: "keydown", + keyCode: keys.ENTER + }); + + ul.trigger({ + type: "keydown", + keyCode: keys.ENTER + }); + + ok(!ul.children(":first").children(".k-group").is(":visible")); + }); + + test("PanelBar makes clicked element focused", function() { + addItems(3); + + var item = ul.children().eq(1); + + ul.focus(); + panelbar._click(item.find(".k-link")); + equal(panelbar._focused[0], item[0]); + }); + +})(); diff --git a/tests/panelbar/selection.js b/tests/panelbar/selection.js new file mode 100644 index 00000000000..2383f1bf4c8 --- /dev/null +++ b/tests/panelbar/selection.js @@ -0,0 +1,132 @@ +(function() { + var panelbar; + var ul; + + module("panelbar selection", { + setup: function() { + kendo.effects.disable(); + + QUnit.fixture.append( + '
                                                                    ' + + '
                                                                  • Mail' + + ' ' + + '
                                                                  • ' + + '
                                                                  • Contacts' + + ' ' + + '
                                                                  • ' + + '
                                                                  • Tasks' + + ' ' + + '
                                                                  • ' + + '
                                                                  • Notes' + + '
                                                                      ' + + '
                                                                    • My Notes' + + '
                                                                    • ' + + '
                                                                    • Notes List' + + '
                                                                    • ' + + '
                                                                    • Shared Notes' + + '
                                                                    • ' + + '
                                                                    • Archive' + + '
                                                                    • ' + + '
                                                                    ' + + '
                                                                  • ' + + '
                                                                  • Folders List' + + ' ' + + '
                                                                  • ' + + '
                                                                  ' + ); + + ul = $("#panelbar"); + + panelbar = new kendo.ui.PanelBar(ul); + }, + teardown: function() { + kendo.effects.enable(); + + panelbar.destroy(); + } + }); + + function getRootItem(index) { + return ul.find('.k-header').parent().eq(index) + } + + test('clicking root items selects them', function() { + var firstLink = getRootItem(0).find('> .k-link'); + + firstLink.trigger({ type: 'click' }); + + ok(firstLink.hasClass('k-state-selected')); + }); + + test('selecting root items deselects their siblings', function() { + var firstLink = getRootItem(0).find('> .k-link'); + var secondLink = getRootItem(1).find('> .k-link'); + + firstLink.trigger({ type: 'click' }); + secondLink.trigger({ type: 'click' }); + + equal(ul.find('.k-state-selected').length, 1); + }); +})(); diff --git a/tests/panelbar/single-expand-api.js b/tests/panelbar/single-expand-api.js new file mode 100644 index 00000000000..f6bedb3f6b9 --- /dev/null +++ b/tests/panelbar/single-expand-api.js @@ -0,0 +1,132 @@ +(function() { + var panelbar; + var ul; + + module('panelbar single expand api', { + setup: function() { + kendo.effects.disable(); + + QUnit.fixture.append( + '
                                                                    ' + + '
                                                                  • Mail' + + ' ' + + '
                                                                  • ' + + '
                                                                  • Contacts' + + ' ' + + '
                                                                  • ' + + '
                                                                  • Tasks' + + ' ' + + '
                                                                  • ' + + '
                                                                  • Notes' + + '
                                                                      ' + + '
                                                                    • My Notes' + + '
                                                                    • ' + + '
                                                                    • Notes List' + + '
                                                                    • ' + + '
                                                                    • Shared Notes' + + '
                                                                    • ' + + '
                                                                    • Archive' + + '
                                                                    • ' + + '
                                                                    ' + + '
                                                                  • ' + + '
                                                                  • Folders List' + + ' ' + + '
                                                                  • ' + + '
                                                                  ' + ); + + ul = $("#panelbar"); + + panelbar = new kendo.ui.PanelBar(ul, { expandMode: 0 }); + }, + teardown: function() { + kendo.effects.enable(); + + panelbar.destroy(); + } + }); + + function getRootItem(index) { + return ul.find('.k-header').parent().eq(index) + } + + test('expand should collapse other opened items', function() { + var item = getRootItem(0); + var item2 = getRootItem(2); + + panelbar.expand(item2); + + equal(item.find('> .k-group').css("display"), "none"); + }); + + test('expand should not collapse item which is already expanded', function() { + var item = getRootItem(2); + + panelbar.expand(item); + panelbar.expand(item); + + equal(item.find('> .k-group').css("display"), "block"); + }); +})(); diff --git a/tests/panelbar/single-expand-collapse.js b/tests/panelbar/single-expand-collapse.js new file mode 100644 index 00000000000..2321c0dd638 --- /dev/null +++ b/tests/panelbar/single-expand-collapse.js @@ -0,0 +1,158 @@ +(function() { + var panelbar; + var ul; + + module('panelbar single expand collapse', { + setup: function() { + kendo.effects.disable(); + + QUnit.fixture.append( + '
                                                                    ' + + '
                                                                  • Mail' + + ' ' + + '
                                                                  • ' + + '
                                                                  • Contacts' + + ' ' + + '
                                                                  • ' + + '
                                                                  • Tasks' + + ' ' + + '
                                                                  • ' + + '
                                                                  • Notes' + + '
                                                                      ' + + '
                                                                    • My Notes' + + '
                                                                    • ' + + '
                                                                    • Notes List' + + '
                                                                    • ' + + '
                                                                    • Shared Notes' + + '
                                                                    • ' + + '
                                                                    • Archive' + + '
                                                                    • ' + + '
                                                                    ' + + '
                                                                  • ' + + '
                                                                  • Folders List' + + ' ' + + '
                                                                  • ' + + '
                                                                  ' + ); + + ul = $("#panelbar"); + + panelbar = new kendo.ui.PanelBar(ul, { expandMode: "single" }); + }, + teardown: function() { + kendo.effects.enable(); + + panelbar.destroy(); + } + }); + + function getRootItem(index) { + return ul.find('.k-header').parent().eq(index) + } + + test('clicking not expandable item should not collapse expanded item', function() { + var item = getRootItem(3); + var item2 = getRootItem(1); + + item2.find('> .k-link').click(); + + equal(item.find('.k-group').css("display"), "block"); + }); + + test('clicking item should collapse other and fire collapse on it', function() { + + var item = getRootItem(3), + item2 = getRootItem(2), + collapseItem = false; + + panelbar.bind( "collapse", function(e) { + collapseItem = e.item; + }); + + item2.find('> .k-link').trigger('click'); + + equal(item.find('.k-group').css("display"), "none"); + equal(collapseItem, item[0]); + }); + + test('clicking item twice should not collapse it', function() { + var item = getRootItem(0); + + item.find('> .k-link').trigger('click'); + item.find('> .k-link').trigger('click'); + + equal(item.find('.k-group').css("display"), "block"); + }); + + test('clicking subItem should not collapse headerItem', function() { + var item = getRootItem(0); + item.find('> .k-link').trigger('click'); + var subItem = item.find('> .k-group').children()[0]; + + $(subItem).find('> .k-link').trigger('click'); + + equal(item.find('.k-group').css("display"), "block"); + }); +})(); diff --git a/tests/popup/popup.js b/tests/popup/popup.js new file mode 100644 index 00000000000..7a20be381e4 --- /dev/null +++ b/tests/popup/popup.js @@ -0,0 +1,711 @@ +(function() { + var Popup = kendo.ui.Popup, div, anchor, popup; + + function round100(value) { + return Math.round(value); + } + + module("kendo.ui.Popup", { + setup: function() { + kendo.effects.disable(); + div = $("
                                                                  popup
                                                                  "); + anchor = $("
                                                                  anchor
                                                                  ").appendTo(QUnit.fixture); + }, + teardown: function() { + if (popup) { + popup.destroy(); + } + div.add(anchor).remove(); + kendo.effects.enable(); + } + }); + + test("updates zIndex based on anchor container property", function() { + QUnit.fixture.css({ zIndex: 2, position: 'relative' }); + popup = new Popup(div, { anchor: anchor }); + + popup.open(); + equal(div.parent().css("zIndex"), "3"); + }); + + asyncTest("mousedown outside the element should close it", function(){ + div.kendoPopup( { + anchor: anchor, + close: function() { + ok(true); + start(); + } + }).data("kendoPopup").open(); + + popup = div.data("kendoPopup"); + + $(document.documentElement).mousedown(); + }); + + test("mousedown inside toggleTarget should not close the popup", function() { + var closed = false; + var MyPopup = Popup.extend( { + close: function() { + closed = true; + } + }); + + popup = new MyPopup(div, { + toggleTarget: anchor + }); + + anchor.mousedown(); + ok(!closed); + }); + + test("window.scroll does not close popup when focused", function() { + expect(1); + popup = new Popup(div, { + close: function() { + ok(false); + } + }); + + popup.open(); + div.mouseenter(); + + $(window).scroll(); + + ok(popup.visible()); + }); + + + test("popup appends element to body", function() { + div.kendoPopup(); + + popup = div.data('kendoPopup'); + + ok(div.parent().is("body")); + }); + + test("popup hides the element", function() { + div.kendoPopup(); + + popup = div.data('kendoPopup'); + + ok(!div.is(":visible")); + }); + + asyncTest("open raises the open event", function() { + div.kendoPopup( { + open: function() { + ok(true); + start(); + } + }); + + popup = div.data('kendoPopup'); + div.data("kendoPopup").open(); + }); + + test("open shows the element", function() { + div.kendoPopup(); + popup = div.data('kendoPopup'); + + div.data("kendoPopup").open(); + + ok(div.is(":visible")); + }); + + test("open with coordinates skips alignment", function() { + popup = div.kendoPopup().data("kendoPopup"); + + popup.open(50, 50); + + ok(popup.wrapper.css("left") == "50px"); + ok(popup.wrapper.css("top") == "50px"); + }); + + asyncTest("close triggers the close event", function() { + div.kendoPopup( { + close: function() { + ok(true); + start(); + } + }); + popup = div.data('kendoPopup'); + + div.show().data("kendoPopup").close(); + }); + + asyncTest("close closes the element", function() { + div.kendoPopup(); + popup = div.data('kendoPopup'); + + div.show().data("kendoPopup").close(); + + setTimeout(function(){ + start(); + ok(!div.is(":visible")); + }, 400); + }); + + test("popup is made absolute", function() { + div.kendoPopup(); + popup = div.data('kendoPopup'); + equal(div.css("position"), "absolute"); + }); + + test("default popup origin is bottom left", function() { + popup = new Popup(div, { + animation: false, + collision: "flip", + anchor: anchor + }); + + equal(popup.options.origin, "bottom left"); + }); + + test("default popup position is top left", function() { + popup = new Popup(div, { + animation: false, + collision: "flip", + anchor: anchor + }); + + equal(popup.options.position, "top left"); + }); + + test("origin bottom and position top", function() { + popup = new Popup(div, { + animation: false, + anchor: anchor, + origin: "bottom left", + collision: "none" + }); + + popup.open(); + equal(round100(div.parent().offset().top), round100(anchor.offset().top + anchor.outerHeight())); + }); + + test("origin bottom and position bottom", function() { + popup = new Popup(div, { + animation: false, + collision: "flip", + anchor: anchor, + origin: "bottom left", + position: "bottom left" + }); + + popup.open(); + equal(round100(div.parent().offset().top + div.outerHeight()), round100(anchor.offset().top + anchor.outerHeight())); + }); + + test("origin bottom and position center", function() { + popup = new Popup(div, { + animation: false, + collision: "flip", + anchor: anchor, + origin: "bottom left", + position: "center left" + }); + + popup.open(); + equal(round100(div.parent().offset().top + Math.round(div.outerHeight() / 2)), round100(anchor.offset().top + anchor.outerHeight())); + }); + + test("origin top and position top", function() { + popup = new Popup(div, { + animation: false, + collision: "flip", + anchor: anchor, + origin: "top left" + }); + + popup.open(); + equal(round100(div.parent().offset().top), round100(anchor.offset().top), 2); + }); + + test("origin top and position bottom", function() { + popup = new Popup(div, { + animation: false, + collision: "flip", + anchor: anchor, + origin: "top left", + position: "bottom left" + }); + + scrollTo(0, anchor.offset().top); + popup.open(); + scrollTo(0, 0); + equal(round100(div.parent().offset().top) + Math.round(div.outerHeight()), round100(anchor.offset().top), 8); + }); + + test("origin top and position center", function() { + popup = new Popup(div, { + animation: false, + collision: "flip", + anchor: anchor, + origin: "top left", + position: "center left" + }); + + popup.open(); + equal(round100(div.parent().offset().top + Math.round(div.outerHeight() / 2)), round100(anchor.offset().top), 2); + }); + + test("origin center and position top", function() { + popup = new Popup(div, { + animation: false, + collision: "flip", + anchor: anchor, + origin: "center left" + }); + + popup.open(); + equal(round100(div.parent().offset().top), Math.round(anchor.offset().top + round100(anchor.outerHeight() / 2 )), 2); + }); + + test("origin center and position bottom", function() { + popup = new Popup(div, { + animation: false, + collision: "flip", + anchor: anchor, + origin: "center left", + position: "bottom left" + }); + + popup.open(); + equal(round100(div.parent().offset().top + div.outerHeight()), round100(anchor.offset().top + Math.round(anchor.outerHeight() / 2 )), 2); + }); + + test("origin center and position center", function() { + popup = new Popup(div, { + animation: false, + collision: "flip", + anchor: anchor, + origin: "center left", + position: "center left" + }); + + popup.open(); + equal(round100(div.parent().offset().top + Math.round(div.outerHeight() / 2)), round100(anchor.offset().top + Math.round(anchor.outerHeight() / 2 )), 2); + }); + + test("origin left and position left", function() { + popup = new Popup(div, { + animation: false, + collision: "flip", + anchor: anchor, + origin: "center left", + position: "center left" + }); + + popup.open(); + + equal(div.parent().offset().left, anchor.offset().left); + }); + + test("origin left and position right", function() { + popup = new Popup(div, { + animation: false, + anchor: anchor, + origin: "center left", + position: "center right", + collision: "none" + }); + + popup.open(); + + equal(div.parent().offset().left + div.outerWidth(), anchor.offset().left); + }); + + test("origin left and position center", function() { + popup = new Popup(div, { + animation: false, + collision: "flip", + anchor: anchor, + origin: "center left", + position: "center center" + }); + + popup.open(); + + equal(div.parent().offset().left + Math.round(div.outerWidth() / 2), anchor.offset().left); + }); + + test("origin right and position left", function() { + popup = new Popup(div, { + animation: false, + collision: "none", + anchor: anchor, + origin: "center right", + position: "center left" + }); + + popup.open(); + + equal(div.parent().offset().left, anchor.offset().left + anchor.outerWidth()); + }); + + test("origin right and position right", function() { + popup = new Popup(div, { + animation: false, + collision: "flip", + anchor: anchor, + origin: "center right", + position: "center right" + }); + + popup.open(); + + equal(div.parent().offset().left + div.outerWidth(), anchor.offset().left + anchor.outerWidth()); + }); + + test("origin right and position center", function() { + popup = new Popup(div, { + animation: false, + collision: "flip", + anchor: anchor, + origin: "center right", + position: "center center" + }); + + popup.open(); + + equal(div.parent().offset().left + Math.round(div.outerWidth() / 2), anchor.offset().left + anchor.outerWidth()); + }); + + test("origin center and position left", function() { + popup = new Popup(div, { + animation: false, + collision: "flip", + anchor: anchor, + origin: "center center", + position: "center left" + }); + + popup.open(); + + equal(div.parent().offset().left, anchor.offset().left + Math.round(anchor.outerWidth() / 2)); + }); + + test("origin center and position right", function() { + popup = new Popup(div, { + animation: false, + collision: "flip", + anchor: anchor, + origin: "center center", + position: "center right" + }); + + popup.open(); + + equal(div.parent().offset().left + div.outerWidth(), anchor.offset().left + Math.round(anchor.outerWidth() / 2)); + }); + + test("origin center and position center", function() { + popup = new Popup(div, { + animation: false, + collision: "flip", + anchor: anchor, + origin: "center center", + position: "center center" + }); + + popup.open(); + + equal(div.parent().offset().left + Math.round(div.outerWidth() / 2), anchor.offset().left + Math.round(anchor.outerWidth() / 2)); + }); + + test("toggleEvent is click by default", function() { + popup = new Popup(div); + + equal(popup.options.toggleEvent, "click"); + }); + + test("toggle opens closed popup", function() { + popup = new Popup(div); + + popup.toggle(); + ok(div.is(":visible")); + }); + + asyncTest("toggle closes opened popup", function() { + popup = new Popup(div, { + close: function() { + ok(true); + start(); + } + }); + + div.show(); + popup.toggle(); + }); + + asyncTest("triggering the toggleEvent on the toggleTarget toggles the popup", function() { + var toggleTarget = $("
                                                                  ").appendTo(QUnit.fixture); + popup = new Popup(div, { + open: function() { + ok(true); + start(); + }, + toggleTarget: toggleTarget + }); + + toggleTarget.click(); + }); + + test("update position of the popup on window.onresize", function() { + var toggleTarget = $("
                                                                  ").appendTo(QUnit.fixture); + + var called = false, + MyPopup = Popup.extend({ + _position: function() { + called = true; + } + }); + + popup = new MyPopup(div, { + animation: false, + toggleTarget: toggleTarget + }); + popup.open(); + $(window).trigger("resize"); + + ok(called); + }); + + test("fit returns inverted position if position is negative", function() { + popup = new Popup(div); + equal(popup._fit(-42, 42, 42), 42); + }); + + test("fit returns offset if element does not fit in original position", function() { + popup = new Popup(div); + equal(popup._fit(42, 42, 42), -42); + }); + + test("fit if element does not fit in the original and new position", function() { + popup = new Popup(div); + equal(popup._fit(42, 24, 42), -24); // should return offset from the current position - in this case its size + }); + + test("collision is \"flip fit\" by default", function() { + popup = new Popup(div); + + equal(popup.options.collision, "flip fit"); + }); + + test("setting collision to false stops boundary detection", function() { + popup = new Popup(div, { collision: false }); + + ok($.isArray(popup.collisions)); + equal(popup.collisions.length, 0); + }); + + test("collision fit calls fit strategy when opened", function() { + var argsCount, + MyPopup = Popup.extend({ + _fit: function() { + argsCount = arguments.length; + } + }); + + var toggleTarget = $("
                                                                  ").appendTo(QUnit.fixture); + + popup = new MyPopup(div, { + animation: false, + collision: "fit", + toggleTarget: toggleTarget + }); + popup.open(); + + equal(argsCount, 3); + }); + + test("collision fit calls fit strategy for each settings", function() { + var calledCount = 0, + MyPopup = Popup.extend({ + _fit: function() { + calledCount++ + } + }); + + var toggleTarget = $("
                                                                  ").appendTo(QUnit.fixture); + + popup = new MyPopup(div, { + animation: false, + collision: "fit fit", + toggleTarget: toggleTarget + }); + popup.open(); + + equal(calledCount, 2); + }); + + test("collision flip calls flip strategy when opened", function() { + var argsCount, + MyPopup = Popup.extend({ + _flip: function() { + argsCount = arguments.length; + return {top:0, left:0}; + } + }); + + var toggleTarget = $("
                                                                  ").appendTo(QUnit.fixture); + popup = new MyPopup(div, { + animation: false, + collision: "flip", + toggleTarget: toggleTarget + }); + popup.open(); + + equal(argsCount, 7); + }); + + test("collision flip calls flip strategy when opened horizontal", function() { + var argsCount, + MyPopup = Popup.extend({ + _flip: function() { + argsCount = arguments.length; + return {top:0, left:0}; + } + }); + + var toggleTarget = $("
                                                                  ").appendTo(QUnit.fixture); + popup = new MyPopup(div, { + animation: false, + collision: "flip flip", + toggleTarget: toggleTarget, + origin: "top left", + position: "top right" + + }); + popup.open(); + + equal(argsCount, 7); + }); + + test("flip when element does not fit right should be position left", function() { + popup = new Popup(div, { + animation: false, + collision: "flip" + }); + + var result = popup._flip(82, 42, 20, 100, "right", "left"); + + equal(result, -62); + }); + + test("flip when element does not fit right and does not fit left should be position right", function() { + + popup = new Popup(div, { + animation: false, + collision: "flip" + }); + + var result = popup._flip(42, 42, 42, 60, "right", "left"); + + equal(result, 0); + }); + + test("flip offset is not modified if position is center", function() { + popup = new Popup(div, { + animation: false, + collision: "flip" + }); + + var result = popup._flip(30, 35, 35, 60, "center", "left"); + + equal(result, 0); + }); + + test("flip offset is not modified if origin is center", function() { + popup = new Popup(div, { + animation: false, + collision: "flip" + }); + + var result = popup._flip(30, 35, 35, 60, "left", "center"); + + equal(result, 0); + }); + + test("flip offset is not modified if origin and position have same value", function() { + popup = new Popup(div, { + animation: false, + collision: "flip" + }); + + var result = popup._flip(30, 35, 35, 60, "left", "left"); + + equal(result, 0); + }); + + test("flip when element does not fit bellow should be position at the top", function() { + + popup = new Popup(div, { + animation: false, + collision: "flip" + }); + + var result = popup._flip(82, 42, 20, 100, "bottom", "top"); + + equal(result, -62); + }); + + test("flip when element does not fit bellow and above should be position bellow", function() { + popup = new Popup(div, { + animation: false, + collision: "flip" + }); + + var result = popup._flip(42, 42, 42, 60, "bottom", "top"); + + equal(result, 0); + }); + + test("open adds active state to parent state changers", function() { + anchor.append("
                                                                  "); + popup = new Popup(div, { + anchor: anchor + }); + + popup.open(); + ok(anchor.children().hasClass("k-state-active")); + }); + + test("gets biggest zindex if sibling container does not have zIndex", function() { + var anchor = $("
                                                                  anchor
                                                                  ").appendTo($("
                                                                  ").appendTo(QUnit.fixture)); + anchor.wrap('
                                                                  '); + + popup = new Popup(div, { anchor: anchor }); + popup.open(); + + ok(div.parent().css("zIndex") > 2); + }); + + test("copy font styles from anchor", function() { + anchor.css("font-size", "1rem"); + anchor.css("font-family", "Serif"); + anchor.css("font-style", "italic"); + + popup = new Popup(div, { anchor: anchor }); + popup.open(); + + equal(anchor.css("font-size"), div.css("font-size")); + equal(anchor.css("font-family"), div.css("font-family")); + equal(anchor.css("font-style"), div.css("font-style")); + }); + + asyncTest("re-position on resize", function() { + popup = new Popup(div, { anchor: anchor }); + popup.open(); + + stub(popup, { + _position: popup._position + }); + + $(window).trigger("resize"); + setTimeout(function() { + start(); + equal(popup.calls("_position"), 1); + }, 100); + }); +})(); diff --git a/tests/progressbar/api.js b/tests/progressbar/api.js new file mode 100644 index 00000000000..06245d5ffa0 --- /dev/null +++ b/tests/progressbar/api.js @@ -0,0 +1,960 @@ +(function(){ +var pb; + +function createPbHtml(){ + var html = "
                                                                  " + + "
                                                                  " + + "
                                                                  "; + + $(html).appendTo(QUnit.fixture); +} + +function createProgressbar(options){ + createPbHtml(); + + $("#progressbar").kendoProgressBar(options); + return $("#progressbar").data("kendoProgressBar"); +} + +function moduleSetup() { + //pb = createProgressbar(); +} + +function moduleTeardown() { + kendo.destroy(QUnit.fixture); +} + +// ----------------------------------------------------------------------------------- +// ----------------------------------------------------------------------------------- +module("value", { + setup: moduleSetup, + teardown: moduleTeardown +}); + +test("value method returns the actual initial value", function () { + pb = createProgressbar({ + value: 50 + }); + + equal(pb.value(), 50); +}); + +test("value method sets indeterminate state correctly when false is passed", function () { + pb = createProgressbar({ + value: 50 + }); + + pb.value(false); + + equal(pb.value(), false); +}); + +test("value method does not set indeterminate state when true is passed", function () { + pb = createProgressbar({ + value: 50 + }); + + pb.value(true); + + equal(pb.value(), 50); +}); + +test("value method sets value correctly when the value is between min and max", function () { + pb = createProgressbar({ + value: 50, + min: 20, + max: 60 + }); + + pb.value(40); + + equal(pb.value(), 40); +}); + +test("value method sets value equal to max value when it is bigger than max", function () { + pb = createProgressbar({ + value: 50, + min: 20, + max: 60 + }); + + pb.value(100); + + equal(pb.value(), pb.options.max); +}); + +test("value method sets value equal to min value when it is smaller than min", function () { + pb = createProgressbar({ + value: 50, + min: 20, + max: 60 + }); + + pb.value(10); + + equal(pb.value(), pb.options.min); +}); + +test("value method sets the value when it is equal to min", function () { + pb = createProgressbar({ + value: 50, + min: 20, + max: 60 + }); + + pb.value(20); + + equal(pb.value(), 20); +}); + +test("value method sets the value when it is equal to max", function () { + pb = createProgressbar({ + value: 50, + min: 20, + max: 60 + }); + + pb.value(60); + + equal(pb.value(), 60); +}); + +asyncTest("Change event is fired only once per value (type='chunk')", function() { + var changeFiredCounter = 0; + + pb = createProgressbar({ + min: 20, + max: 60, + value: 20, + type: "chunk", + change: function(){ + changeFiredCounter++; + }, + animation: false + }); + + pb.value(30); + pb.value(30); + + setTimeout(function(){ + equal(changeFiredCounter, 1); + start(); + }, 30); +}); + +asyncTest("Change event is fired only once per value (type='value')", function() { + var changeFiredCounter = 0; + + pb = createProgressbar({ + min: 20, + max: 60, + value: 20, + type: "value", + change: function(){ + changeFiredCounter++; + }, + animation: false + }); + + pb.value(30); + pb.value(30); + + setTimeout(function(){ + equal(changeFiredCounter, 1); + start(); + }, 30); +}); + +asyncTest("Change event is fired only once per value (type='percent')", function() { + var changeFiredCounter = 0; + + pb = createProgressbar({ + min: 20, + max: 60, + value: 20, + type: "percent", + change: function(){ + changeFiredCounter++; + }, + animation: false + }); + + pb.value(30); + pb.value(30); + + setTimeout(function(){ + equal(changeFiredCounter, 1); + start(); + }, 30); +}); + +asyncTest("Change event is fired only once per value when trying to set value bigger than max (type='percent')", function() { + var changeFiredCounter = 0; + + pb = createProgressbar({ + min: 20, + max: 60, + value: 20, + type: "percent", + change: function(){ + changeFiredCounter++; + }, + animation: false + }); + + pb.value(60); + pb.value(65); + + setTimeout(function(){ + equal(changeFiredCounter, 1); + start(); + }, 30); +}); + +asyncTest("Change event is fired only once per value when trying to set value bigger than max (type='value')", function() { + var changeFiredCounter = 0; + + pb = createProgressbar({ + min: 20, + max: 60, + value: 20, + type: "value", + change: function(){ + changeFiredCounter++; + }, + animation: false + }); + + pb.value(60); + pb.value(65); + + setTimeout(function(){ + equal(changeFiredCounter, 1); + start(); + }, 30); +}); + +asyncTest("Change event is fired only once per value when trying to set value bigger than max (type='chunk')", function() { + var changeFiredCounter = 0; + + pb = createProgressbar({ + min: 20, + max: 60, + value: 20, + type: "chunk", + change: function(){ + changeFiredCounter++; + }, + animation: false + }); + + pb.value(60); + pb.value(65); + + setTimeout(function(){ + equal(changeFiredCounter, 1); + start(); + }, 30); +}); + +asyncTest("Change event is fired only once per value when trying to set value smaller than min (type='percent')", function() { + var changeFiredCounter = 0; + + pb = createProgressbar({ + min: 20, + max: 60, + value: 30, + type: "percent", + change: function(){ + changeFiredCounter++; + }, + animation: false + }); + + pb.value(20); + pb.value(15); + + setTimeout(function(){ + equal(changeFiredCounter, 1); + start(); + }, 30); +}); + +asyncTest("Change event is fired only once per value when trying to set value smaller than min (type='value')", function() { + var changeFiredCounter = 0; + + pb = createProgressbar({ + min: 20, + max: 60, + value: 30, + type: "value", + change: function(){ + changeFiredCounter++; + }, + animation: false + }); + + pb.value(20); + pb.value(15); + + setTimeout(function(){ + equal(changeFiredCounter, 1); + start(); + }, 30); +}); + +asyncTest("Change event is fired only once per value when trying to set value smaller than min (type='chunk')", function() { + var changeFiredCounter = 0; + + pb = createProgressbar({ + min: 20, + max: 60, + value: 30, + type: "chunk", + change: function(){ + changeFiredCounter++; + }, + animation: false + }); + + pb.value(20); + pb.value(15); + + setTimeout(function(){ + equal(changeFiredCounter, 1); + start(); + }, 30); +}); + +asyncTest("Complete event is not fired before max is reached (type='value')", function(){ + var completeFired = false; + + pb = createProgressbar({ + min: 20, + max: 60, + value: 20, + type: "value", + complete: function(){ + completeFired = true; + }, + animation: false + }); + + pb.value(30); + pb.value(50); + pb.value(59); + + setTimeout(function(){ + ok(!completeFired); + start(); + }, 30); +}); + +asyncTest("Complete event is fired when max is reached (type='value')", function(){ + var completeFired = false; + + pb = createProgressbar({ + min: 20, + max: 60, + value: 20, + type: "value", + complete: function(){ + completeFired = true; + }, + animation: false + }); + + pb.value(50); + pb.value(59); + pb.value(60); + + setTimeout(function(){ + ok(completeFired); + start(); + }, 30); +}); + +asyncTest("Complete event is fired each time when max is reached (type='value')", function(){ + var completeFiredCounter = 0; + + pb = createProgressbar({ + min: 20, + max: 60, + value: 20, + type: "value", + complete: function(){ + completeFiredCounter++; + }, + animation: false + }); + + pb.value(60); + pb.value(50); + pb.value(65); + + setTimeout(function(){ + equal(completeFiredCounter, 2); + start(); + }, 30); +}); + +asyncTest("Complete event is not fired before max is reached (type='percent')", function(){ + var completeFired = false; + + pb = createProgressbar({ + min: 20, + max: 60, + value: 20, + type: "percent", + complete: function(){ + completeFired = true; + }, + animation: false + }); + + pb.value(30); + pb.value(50); + pb.value(59); + + setTimeout(function(){ + ok(!completeFired); + start(); + }, 30); +}); + +asyncTest("Complete event is fired when max is reached (type='percent')", function(){ + var completeFired = false; + + pb = createProgressbar({ + min: 20, + max: 60, + value: 20, + type: "percent", + complete: function(){ + completeFired = true; + }, + animation: false + }); + + pb.value(50); + pb.value(59); + pb.value(60); + + setTimeout(function(){ + ok(completeFired); + start(); + }, 30); +}); + +asyncTest("Complete event is fired each time when max is reached (type='percent')", function(){ + var completeFiredCounter = 0; + + pb = createProgressbar({ + min: 20, + max: 60, + value: 20, + type: "percent", + complete: function(){ + completeFiredCounter++; + }, + animation: false + }); + + pb.value(60); + pb.value(50); + pb.value(65); + + setTimeout(function(){ + equal(completeFiredCounter, 2); + start(); + }, 30); +}); + +asyncTest("Complete event is not fired before max is reached (type='chunk')", function(){ + var completeFired = false; + + pb = createProgressbar({ + min: 20, + max: 60, + value: 20, + type: "chunk", + complete: function(){ + completeFired = true; + }, + animation: false + }); + + pb.value(30); + pb.value(50); + pb.value(59); + + setTimeout(function(){ + ok(!completeFired); + start(); + }, 30); +}); + +asyncTest("Complete event is fired when max is reached (type='chunk')", function(){ + var completeFired = false; + + pb = createProgressbar({ + min: 20, + max: 60, + value: 20, + type: "chunk", + complete: function(){ + completeFired = true; + }, + animation: false + }); + + pb.value(50); + pb.value(59); + pb.value(60); + + setTimeout(function(){ + ok(completeFired); + start(); + }, 30); +}); + +asyncTest("Complete event is fired each time when max is reached (type='chunk')", function(){ + var completeFiredCounter = 0; + + pb = createProgressbar({ + min: 20, + max: 60, + value: 20, + type: "chunk", + complete: function() { + completeFiredCounter++; + }, + animation: false + }); + + pb.value(60); + pb.value(50); + pb.value(65); + + setTimeout(function() { + equal(completeFiredCounter, 2); + start(); + }, 30); +}); + +asyncTest("Complete event is not fired max is set multiple times in a row (type='value')", function(){ + var completeFiredCounter = 0; + + pb = createProgressbar({ + min: 20, + max: 60, + value: 20, + type: "value", + complete: function() { + completeFiredCounter++; + }, + animation: false + }); + + pb.value(60); + pb.value(65); + + setTimeout(function() { + equal(completeFiredCounter, 1); + start(); + }, 30); +}); + +asyncTest("Complete event is not fired max is set multiple times in a row (type='percent')", function(){ + var completeFiredCounter = 0; + + pb = createProgressbar({ + min: 20, + max: 60, + value: 20, + type: "percent", + complete: function() { + completeFiredCounter++; + }, + animation: false + }); + + pb.value(60); + pb.value(65); + + setTimeout(function() { + equal(completeFiredCounter, 1); + start(); + }, 30); +}); + +asyncTest("Complete event is not fired max is set multiple times in a row (type='chunk')", function(){ + var completeFiredCounter = 0; + + pb = createProgressbar({ + min: 20, + max: 60, + value: 20, + type: "chunk", + complete: function() { + completeFiredCounter++; + }, + animation: false + }); + + pb.value(60); + pb.value(65); + + setTimeout(function() { + equal(completeFiredCounter, 1); + start(); + }, 30); +}); + +asyncTest("k-progressbar-indeterminate class is set correctly when passed value is false", function(){ + pb = createProgressbar({ + min: 20, + max: 60, + value: 20, + animation: false + }); + + pb.value(false); + + setTimeout(function() { + ok(pb.wrapper.hasClass("k-progressbar-indeterminate")); + start(); + }, 30); +}); + +asyncTest("k-progressbar-indeterminate class is removed when previous value was false", function(){ + pb = createProgressbar({ + min: 20, + max: 60, + value: 20, + animation: false + }); + + pb.value(false); + pb.value(40); + + setTimeout(function() { + ok(!pb.wrapper.hasClass("k-progressbar-indeterminate")); + start(); + }, 30); +}); + +asyncTest("k-progressbar-indeterminate class is removed when initial value was false", function(){ + pb = createProgressbar({ + min: 20, + max: 60, + value: false, + animation: false + }); + + pb.value(40); + + setTimeout(function() { + ok(!pb.wrapper.hasClass("k-progressbar-indeterminate")); + start(); + }, 30); +}); + +asyncTest("One percent is calculated correctly", function(){ + pb = createProgressbar({ + min: 0, + max: 300, + value: 0, + animation: false + }); + + pb.value(40); + + setTimeout(function() { + equal(pb._onePercent, 3); + + start(); + }, 30); +}); + +// ----------------------------------------------------------------------------------- +// ----------------------------------------------------------------------------------- +module("enable", { + setup: moduleSetup, + teardown: moduleTeardown +}); + +test("enable method renders k-state-disabled class when false is passed", function () { + pb = createProgressbar(); + + pb.enable(false); + + ok(pb.wrapper.hasClass("k-state-disabled")); +}); + +test("enable method removes k-state-disabled class when no parameter is passed", function () { + pb = createProgressbar(); + + pb.enable(false); + pb.enable(); + + ok(!pb.wrapper.hasClass("k-state-disabled")); +}); + +test("enable method removes k-state-disabled class when true is passed", function () { + pb = createProgressbar(); + + pb.enable(false); + pb.enable(true); + + ok(!pb.wrapper.hasClass("k-state-disabled")); +}); + +test("enable method does not add k-state-disabled class if not needed", function () { + pb = createProgressbar(); + + pb.enable(); + pb.enable(true); + + ok(!pb.wrapper.hasClass("k-state-disabled")); +}); + +test("enable method does not removes k-state-disabled class if not needed", function () { + pb = createProgressbar(); + + pb.enable(false); + pb.enable(false); + + ok(pb.wrapper.hasClass("k-state-disabled")); +}); + +test("enable does not disable progressbar", function(){ + pb = createProgressbar(); + pb.enable(); + + ok(!pb.wrapper.hasClass("k-state-disabled")); +}); + +test("initially disabled state is applied", function() { + pb = createProgressbar({ + enable: false + }); + + ok(pb.wrapper.hasClass("k-state-disabled")); +}); + +test("ProgressBar does change value when disabled", function(){ + pb = createProgressbar({ + animation: false + }); + pb.value(30); + pb.enable(false); + pb.value(40); + + equal(pb.value(), 40); +}); + +test("ProgressBar does change value when initially disabled", function(){ + pb = createProgressbar({ + animation: false, + enable: false, + value: 0 + }); + pb.value(30); + + equal(pb.value(), 30); +}); + +test("ProgressBar does change value when enabled after initially disabled", function(){ + pb = createProgressbar({ + animation: false, + enable: false + }); + pb.enable(); + pb.value(30); + + equal(pb.value(), 30); +}); + +test("ProgressBar does change value when reenabled", function(){ + pb = createProgressbar({ + animation: false + }); + + pb.enable(false); + pb.value(30); + pb.enable(); + pb.value(40); + + equal(pb.value(), 40); +}); + +test("ProgressBar does not indeterminate state when disabled", 2, function(){ + pb = createProgressbar({ + animation: false, + value: 30 + }); + + pb.enable(false); + pb.value(false); + + equal(pb.value(), false); + ok(pb.wrapper.hasClass("k-progressbar-indeterminate")); +}); + +test("ProgressBar is disabled correctly when in indeterminate state", function(){ + pb = createProgressbar({ + animation: false, + value: 30 + }); + + pb.value(false); + pb.enable(false); + + ok(pb.wrapper.hasClass("k-state-disabled")); +}); + + +// ----------------------------------------------------------------------------------- +// ----------------------------------------------------------------------------------- +module("setOptions", { + setup: moduleSetup, + teardown: moduleTeardown +}); + +test("Animation is set to false in options", function(){ + pb = createProgressbar({ + animation: { + duration: 500 + }, + value: 30 + }); + + pb.setOptions({animation: false}); + + equal(pb.options.animation, false); +}); + +test("Private animation object duration is set to 0", function() { + pb = createProgressbar({ + animation: { + duration: 500 + }, + value: 30 + }); + + pb.setOptions({animation: false}); + + var expectedAnimation = {duration: 0}; + + deepEqual(pb._animation, expectedAnimation); +}); + +test("Animation duration is set correctly in options", function(){ + pb = createProgressbar({ + animation: false, + value: 30 + }); + + var newAnimation = { + duration: 550 + }; + + pb.setOptions({animation: newAnimation}); + + deepEqual(pb.options.animation, newAnimation); +}); + +test("Private animation object duration is set correctly", function(){ + pb = createProgressbar({ + animation: false, + value: 30 + }); + + var newAnimation = { + duration: 550 + }; + + pb.setOptions({animation: newAnimation}); + + deepEqual(pb._animation, newAnimation); +}); + +test("Type is changed correctly from value to percent", 2, function() { + pb = createProgressbar({ + animation: false, + value: 150, + min: 0, + max: 300, + type: "value" + }); + + pb.setOptions({type: "percent"}); + + equal(pb.wrapper.find(".k-progress-status:first").text(), "50%"); + equal(pb.wrapper.find(".k-progress-status:last").text(), "50%"); +}); + +test("Type is changed correctly from percent to value", 2, function() { + pb = createProgressbar({ + animation: false, + value: 150, + min: 0, + max: 300, + type: "percent" + }); + + pb.setOptions({type: "value"}); + + equal(pb.wrapper.find(".k-progress-status:first").text(), "150"); + equal(pb.wrapper.find(".k-progress-status:last").text(), "150"); +}); + +test("Value is changed correctly (type='value')", 3, function(){ + pb = createProgressbar({ + animation: false, + value: 20, + min: 0, + max: 300, + type: "value" + }); + + pb.setOptions({ value: 150 }); + + equal(pb.value(), 150); + equal(pb.wrapper.find(".k-progress-status:first").text(), "150"); + equal(pb.wrapper.find(".k-progress-status:last").text(), "150"); +}); + +test("Value is changed correctly (type='percent')", 3, function(){ + pb = createProgressbar({ + animation: false, + value: 20, + min: 0, + max: 300, + type: "percent" + }); + + pb.setOptions({ value: 150 }); + + equal(pb.value(), 150); + equal(pb.wrapper.find(".k-progress-status:first").text(), "50%"); + equal(pb.wrapper.find(".k-progress-status:last").text(), "50%"); +}); + +test("Value is changed correctly (type='chunk')", 2, function(){ + pb = createProgressbar({ + animation: false, + value: 20, + min: 0, + max: 300, + type: "chunk", + chunkCount: 4 + }); + + pb.setOptions({ value: 150 }); + + equal(pb.value(), 150); + equal(pb.wrapper.find(".k-state-selected").length, 2); +}); +})(); \ No newline at end of file diff --git a/tests/progressbar/initialization.js b/tests/progressbar/initialization.js new file mode 100644 index 00000000000..b24440be415 --- /dev/null +++ b/tests/progressbar/initialization.js @@ -0,0 +1,659 @@ +(function(){ +var ProgressBar = kendo.ui.ProgressBar, + container; + +function moduleSetup() { + container = document.createElement("div"); + $(container).appendTo(QUnit.fixture); +} + +function moduleTeardown() { + kendo.destroy(QUnit.fixture); +} + +// ----------------------------------------------------------------------------------- +// ----------------------------------------------------------------------------------- +module("Initialization", { + setup: moduleSetup, + teardown: moduleTeardown +}); + +test("kendoProgressBar attaches a progressbar object to target", function() { + var dom = $('
                                                                  '); + dom.appendTo(QUnit.fixture); + + var pb = dom.kendoProgressBar(); + + ok(pb.data("kendoProgressBar") instanceof ProgressBar); +}); + +test("The element of the progressbar is set to the target from which it was initialized", function() { + var pb = new ProgressBar(container); + + equal(pb.element[0], container); +}); + +test("Wrapper field is initialized", function() { + var pb = new ProgressBar(container); + + equal(pb.wrapper[0], container); +}); + +test("Css classes are added to the wrapper", function() { + var pb = new ProgressBar(container); + + ok(pb.wrapper.hasClass("k-widget")); + ok(pb.wrapper.hasClass("k-progressbar")); +}); + +test("Correct css classes for horizontal progressbar are added to the wrapper", function() { + var pb = new ProgressBar(container, { + orientation: "horizontal" + }); + + ok(pb.wrapper.hasClass("k-progressbar-horizontal")); +}); + +test("Correct css classes for vertical progressbar are added to the wrapper", function() { + var pb = new ProgressBar(container, { + orientation: "vertical" + }); + + ok(pb.wrapper.hasClass("k-progressbar-vertical")); +}); + +test("Correct css classes for horizontal reverse progressbar are added to the wrapper", function() { + var pb = new ProgressBar(container, { + reverse: true + }); + + ok(pb.wrapper.hasClass("k-progressbar-horizontal")); + ok(pb.wrapper.hasClass("k-progressbar-reverse")); +}); + +test("Correct css classes for vertical reverse progressbar are added to the wrapper", function() { + var pb = new ProgressBar(container, { + reverse: true, + orientation: "vertical" + }); + + ok(pb.wrapper.hasClass("k-progressbar-vertical")); + ok(pb.wrapper.hasClass("k-progressbar-reverse")); +}); + +test("Initial value is normalized correctly when it is less than min", function() { + var pb = new ProgressBar(container, { + min: 10, + max: 100, + value: 0 + }); + + equal(pb.options.value, pb.options.min); +}); + +test("Initial value is normalized correctly when it is more than max", function() { + var pb = new ProgressBar(container, { + min: 10, + max: 100, + value: 1000 + }); + + equal(pb.options.value, pb.options.max); +}); + +asyncTest("Start event is not fired on initialization when value is more than min", function() { + var startFired = false, + pb = new ProgressBar(container, { + min: 10, + max: 100, + value: 30, + start: function(){ + startFired = true; + } + }); + + setTimeout(function() { + ok(!startFired); + start(); + }, 50); +}); + +test("Progress property is set to width when orientation is horizontal", function() { + var pb = new ProgressBar(container, { + orientation: "horizontal" + }); + + equal(pb._progressProperty, "width"); +}); + +test("Progress property is set to height when orientation is vertical", function() { + var pb = new ProgressBar(container, { + orientation: "vertical" + }); + + equal(pb._progressProperty, "height"); +}); + + +test("Animation duration is equal to default animation duration when not specified", function() { + var pb = new ProgressBar(container, { }), + defaultAnimationDuration = 400; + + equal(pb._animation.duration, defaultAnimationDuration); +}); + +test("Animation is correctly set to false", function() { + var pb = new ProgressBar(container, { + animation: false + }); + + ok(!pb.options.animation); +}); + +test("Animation duration is overriden when specified by user", function() { + var pb = new ProgressBar(container, { + animation: { + duration: 789 + } + }); + + equal(pb.options.animation.duration, 789); +}); + +test("k-progressbar-indeterminate class is set correctly when initial value is false (type='value')", function() { + var pb = new ProgressBar(container, { + value: false, + type: "value" + }); + + ok(pb.wrapper.hasClass("k-progressbar-indeterminate")); +}); + +test("k-progressbar-indeterminate class is set correctly when initial value is false (type='percent')", function() { + var pb = new ProgressBar(container, { + value: false, + type: "percent" + }); + + ok(pb.wrapper.hasClass("k-progressbar-indeterminate")); +}); + +test("k-progressbar-indeterminate class is set correctly when initial value is false (type='chunk')", function() { + var pb = new ProgressBar(container, { + value: false, + type: "chunk" + }); + + ok(pb.wrapper.hasClass("k-progressbar-indeterminate")); +}); + +test("k-progressbar-indeterminate class is not set when initial value is not false (type='value')", function() { + var pb = new ProgressBar(container, { + value: 20, + type: "value" + }); + + ok(!pb.wrapper.hasClass("k-progressbar-indeterminate")); +}); + +test("k-progressbar-indeterminate class is not set when initial value is not false (type='percent')", function() { + var pb = new ProgressBar(container, { + value: 20, + type: "percent" + }); + + ok(!pb.wrapper.hasClass("k-progressbar-indeterminate")); +}); + +test("k-progressbar-indeterminate class is not set when initial value is not false (type='chunk')", function() { + var pb = new ProgressBar(container, { + value: 20, + type: "chunk" + }); + + ok(!pb.wrapper.hasClass("k-progressbar-indeterminate")); +}); + +test("k-state-disabled class is added when ProgressBar is disabled initially", function() { + var pb = new ProgressBar(container, { + enable: false + }); + + ok(pb.wrapper.hasClass("k-state-disabled")); +}); + +test("Initial value is set correctly to false", function() { + var pb = new ProgressBar(container, { + value: false + }); + + equal(pb.value(), false); +}); + +test("Initial value false correctly sets status holder text to min (type='value')", function() { + var pb = new ProgressBar(container, { + value: false, + type: "value" + }); + + equal(pb.wrapper.children(".k-progress-status-wrap").text(), pb.options.min); +}); + +test("Initial value false correctly sets status holder text to min (type='percent')", function() { + var pb = new ProgressBar(container, { + value: false, + type: "percent" + }); + + equal(pb.wrapper.children(".k-progress-status-wrap").text(), pb.options.min + "%"); +}); + +test("Progress wrapper is not added when initial value is false", function() { + var pb = new ProgressBar(container, { + value: false + }); + + equal(pb.wrapper.find(".k-state-selected").length, 0); +}); + +test("ProgressBar is correctly disabled and initial value is set to false (type='value')", 3, function() { + var pb = new ProgressBar(container, { + value: false, + enable: false, + type: "value" + }); + + ok(pb.wrapper.hasClass("k-progressbar-indeterminate")); + ok(pb.wrapper.hasClass("k-state-disabled")); + equal(pb.options.value, false); +}); + +test("ProgressBar is correctly disabled and initial value is set to false (type='percent')", 3, function() { + var pb = new ProgressBar(container, { + value: false, + enable: false, + type: "percent" + }); + + ok(pb.wrapper.hasClass("k-progressbar-indeterminate")); + ok(pb.wrapper.hasClass("k-state-disabled")); + equal(pb.options.value, false); +}); + +test("ProgressBar is correctly disabled and initial value is set to false (type='chunk')", 3, function() { + var pb = new ProgressBar(container, { + value: false, + enable: false, + type: "chunk" + }); + + ok(pb.wrapper.hasClass("k-progressbar-indeterminate")); + ok(pb.wrapper.hasClass("k-state-disabled")); + equal(pb.options.value, false); +}); + +test("_isStarted is set to false initially when value is equal to min", function(){ + var pb = new ProgressBar(container, { + value: 0, + min: 0 + }); + + equal(pb._isStarted, false); +}); + +test("_isStarted is set to false initially when value is not equal to min", function(){ + var pb = new ProgressBar(container, { + value: 10, + min: 0 + }); + + equal(pb._isStarted, false); +}); + +test("ProgressBar is initialized correctly via data attribute", function() { + var dom = $("
                                                                  "); + $(container).append(dom); + + kendo.init($(container)); + + ok($(container.firstChild).data("kendoProgressBar") instanceof ProgressBar); +}); + +test("ProgressBar value is set correctly via data attribute", function() { + var dom = $("
                                                                  "); + $(container).append(dom); + + kendo.init($(container)); + + equal($(container.firstChild).data("kendoProgressBar").value(), 25); +}); + +test("ProgressBar type is set correctly via data attribute", function() { + var dom = $("
                                                                  "); + $(container).append(dom); + + kendo.init($(container)); + + equal($(container.firstChild).data("kendoProgressBar").options.type, "chunk"); +}); + +test("ProgressBar events are raised when set via data attribute", function() { + var dom = $("
                                                                  "); + var fired = false; + + $(container).append(dom); + + var observable = kendo.observable({ + onPbChange: function(e){ + ok(true); + } + }); + + kendo.bind($(container), observable); + + dom.data("kendoProgressBar").value(10); +}); + +test("Error is thrown when invalid type is passed", function() { + throws(function() { + var pb = new ProgressBar(container, { + type: "invalid" + }); + }); +}); + +test("Error is not thrown when type is 'value'", function() { + var pb = new ProgressBar(container, { + type: "value" + }); + + ok(true); +}); + +test("Error is not thrown when type is 'percent'", function() { + var pb = new ProgressBar(container, { + type: "percent" + }); + + ok(true); +}); + +test("Error is not thrown when type is 'chunk'", function() { + var pb = new ProgressBar(container, { + type: "chunk" + }); + + ok(true); +}); + +test("progressStatus field is set when showStatus is true and value is equal to min (type='value')", function() { + var pb = new ProgressBar(container, { + type: "value" + }); + + equal(pb.progressStatus.length, 1); +}); + +test("progressStatus field is set when showStatus is true and value is equal to min (type='percent')", function() { + var pb = new ProgressBar(container, { + type: "percent" + }); + + equal(pb.progressStatus.length, 1); +}); + +test("progressStatus field is set when showStatus is true and value is not equal to min (type='value')", function() { + var pb = new ProgressBar(container, { + type: "value", + min: 0, + max: 10, + value: 5 + }); + + equal(pb.progressStatus.length, 2); +}); + +test("progressStatus field is set when showStatus is true and value is not equal to min (type='percent')", function() { + var pb = new ProgressBar(container, { + type: "percent", + min: 0, + max: 10, + value: 5 + }); + + equal(pb.progressStatus.length, 2); +}); + + +test("progressStatus field is set to empty jQuery object when type is 'chunk'", function() { + var pb = new ProgressBar(container, { + type: "chunk" + }); + + ok(pb.progressStatus instanceof jQuery); +}); + +test("progressWrapper field is set to empty jQuery object when type is 'chunk'", function() { + var pb = new ProgressBar(container, { + type: "chunk" + }); + + ok(pb.progressWrapper instanceof jQuery); +}); + +test("progressWrapper field is set to empty jQuery object when value is equal to min (type='value')", function() { + var pb = new ProgressBar(container, { + type: "value", + min: 5, + value: 5 + }); + + ok(pb.progressWrapper instanceof jQuery); +}); + +test("progressWrapper field is set to empty jQuery object when value is equal to min (type='percent')", function() { + var pb = new ProgressBar(container, { + type: "percent", + min: 5, + value: 5 + }); + + ok(pb.progressWrapper instanceof jQuery); +}); + +test("progressWrapper field is set when value is not equal to min (type='value')", function() { + var pb = new ProgressBar(container, { + type: "value", + min: 5, + value: 10 + }); + + ok(pb.hasOwnProperty("progressWrapper")); +}); + +test("progressWrapper field is set when value is not equal to min (type='percent')", function() { + var pb = new ProgressBar(container, { + type: "percent", + min: 5, + value: 10 + }); + + ok(pb.hasOwnProperty("progressWrapper")); +}); + + +//----------------------------------------------------------------------- +//----------------------------------------------------------------------- +module("Initialization / Regular ProgressBar", { + setup: moduleSetup, + teardown: moduleTeardown +}); + +test("ProgressBar wrapper is empty when value is equal to min and showStatus is false", function() { + var pb = new ProgressBar(container, { + min: 10, + value: 10, + showStatus: false + }); + + ok(pb.wrapper.is(":empty")); +}); + +test("ProgressBar contains empty div for progress wrapper when value is not equal to min and showStatus is false", function() { + var pb = new ProgressBar(container, { + min: 10, + value: 20, + showStatus: false + }); + + var progressWrapper = pb.wrapper.find(".k-state-selected"); + + equal(progressWrapper.length, 1); + ok(progressWrapper.is(":empty")); +}); + +test("Size of progress wrapper div reflects value when value is not equal to min and showStatus is false", function() { + var pb = new ProgressBar(container, { + min: 0, + max: 1000, + value: 200, + showStatus: false + }); + + var progressWrapperExpectedSize = pb._calculatePercentage().toFixed(2); + var actualProgressWrapperSize = parseFloat(pb.wrapper.find(".k-state-selected")[0].style.width).toFixed(2); + + equal(actualProgressWrapperSize, progressWrapperExpectedSize); +}); + +test("ProgressBar wrapper contains progress status holder when value is equal to min and showStatus is true", function() { + var pb = new ProgressBar(container, { + showStatus: true + }); + + var progressStatusHolder = pb.wrapper.children("span.k-progress-status-wrap"); + + equal(progressStatusHolder.length, 1); +}); + +test("ProgressBar wrapper contains progress status holder and progress wrapper when value is not equal to min and showStatus is true", 3, function() { + var pb = new ProgressBar(container, { + min: 10, + max: 200, + value: 50, + showStatus: true + }); + + var progressStatusHolder = pb.wrapper.children("span.k-progress-status-wrap"); + var progressWrapper = pb.wrapper.find(".k-state-selected"); + var progressWrapperStatusHolder = $("span.k-progress-status-wrap", progressWrapper); + + equal(progressStatusHolder.length, 1); + equal(progressWrapper.length, 1); + equal(progressWrapperStatusHolder.length, 1); +}); + +test("Status holder text is set correctly when value is not equal to min and showStatus is true", function() { + var pb = new ProgressBar(container, { + min: 10, + max: 200, + value: 50, + showStatus: true + }); + + equal(pb.wrapper.children("span.k-progress-status-wrap").text(), pb.options.value); +}); + + +//----------------------------------------------------------------------- +//----------------------------------------------------------------------- +module("Initialization / Chunk ProgressBar", { + setup: moduleSetup, + teardown: moduleTeardown +}); + +test("Chunk ProgressBar contains a single ul element to hold the chunks", function() { + var pb = new ProgressBar(container, { + type: "chunk" + }); + + equal(pb.wrapper.find("ul.k-reset").length, 1); +}); + +test("Chunk ProgressBar contains a li element for each chunk", function() { + var pb = new ProgressBar(container, { + type: "chunk" + }); + + equal(pb.wrapper.find("li.k-item").length, pb.options.chunkCount); +}); + +test("Correct css class is added to each upcoming chunk", function() { + var pb = new ProgressBar(container, { + type: "chunk" + }); + + ok(pb.wrapper.find("li.k-item").hasClass("k-state-default")); +}); + +test("Correct css class is added to the first chunk", function() { + var pb = new ProgressBar(container, { + type: "chunk" + }); + + ok(pb.wrapper.find("li.k-item:first").hasClass("k-first")); +}); + +test("Correct css class is added to the last chunk", function() { + var pb = new ProgressBar(container, { + type: "chunk" + }); + + ok(pb.wrapper.find("li.k-item:last").hasClass("k-last")); +}); + +test("Correct css class is added to the completed chunks", function() { + var pb = new ProgressBar(container, { + type: "chunk", + value: 45 + }); + + var completedChunks = pb.wrapper.find("li.k-item:lt(2)"); + + equal(pb.wrapper.find("li.k-item.k-state-selected").length, completedChunks.length); +}); + +test("Chunk size is calculated correctly according to chunk count", function() { + var pb = new ProgressBar(container, { + type: "chunk", + chunkCount: 17 + }); + + var chunkCount = pb.options.chunkCount; + var chunkWrapperSize = pb.wrapper.find("ul.k-reset").width(); + var expectedChunkSize = parseFloat(pb.wrapper.find("ul.k-reset li.k-item:first")[0].style.width).toFixed(2); + var actualChunkSize = (100 / pb.options.chunkCount).toFixed(2); + + equal(actualChunkSize, expectedChunkSize); +}); + +test("Chunk count is reset to default if negative chunk count is passed", function() { + var pb = new ProgressBar(container, { + type: "chunk", + chunkCount: -5 + }); + + var chunkCount = pb.options.chunkCount; + equal(chunkCount, 5); +}); + +test("Chunk count is reset to default if chunk count is less than two", function() { + var pb = new ProgressBar(container, { + type: "chunk", + chunkCount: 1 + }); + + var chunkCount = pb.options.chunkCount; + equal(chunkCount, 5); +}); +})(); diff --git a/tests/progressbar/progress.js b/tests/progressbar/progress.js new file mode 100644 index 00000000000..fbfeea7cfea --- /dev/null +++ b/tests/progressbar/progress.js @@ -0,0 +1,1013 @@ +(function(){ +var pb; + +function createPbHtml(){ + var html = "
                                                                  " + + "
                                                                  " + + "
                                                                  "; + + $(html).appendTo(QUnit.fixture); +} + +function createProgressbar(options){ + createPbHtml(); + + $("#progressbar").kendoProgressBar(options); + return $("#progressbar").data("kendoProgressBar"); +} + +function moduleSetup() { + //pb = createProgressbar(); +} + +function moduleTeardown() { + kendo.destroy(QUnit.fixture); +} + +// ----------------------------------------------------------------------------------- +// ----------------------------------------------------------------------------------- +module("Rendering", { + setup: moduleSetup, + teardown: moduleTeardown +}); + +asyncTest("k-complete is added when the progress width is more than 98%", function() { + var progressCompleted = false; + + pb = createProgressbar({ + animation: false, + complete: function(e){ + progressCompleted = true; + } + }); + + pb.value(99); + + setTimeout(function(){ + equal(pb.wrapper.find(".k-complete").length, 1); + start(); + }, 30); +}); + +asyncTest("k-complete is removed when the progress width becomes less than 98%", function() { + var progressCompleted = false; + + pb = createProgressbar({ + animation: false, + complete: function(e){ + progressCompleted = true; + } + }); + + pb.value(99); + pb.value(90); + + setTimeout(function(){ + equal(pb.wrapper.find(".k-complete").length, 0); + start(); + }, 30); +}); + +asyncTest("k-complete is not added when the progress width is less than or equal to 98%", function() { + var progressCompleted = false; + + pb = createProgressbar({ + animation: false, + complete: function(e){ + progressCompleted = true; + } + }); + + pb.value(98); + + setTimeout(function(){ + equal(pb.wrapper.find(".k-complete").length, 0); + start(); + }, 50); +}); + +asyncTest("Complete event has correct value parameter (type='value')", function() { + var value; + + pb = createProgressbar({ + min: -50, + max: 165, + value: -50, + animation: false, + type: "value", + complete: function(e){ + value = e.value; + } + }); + + pb.value(165); + + setTimeout(function() { + equal(value, pb.options.max); + start(); + }, 30); +}); + +asyncTest("Complete event has correct value parameter (type='percent')", function() { + var value; + + pb = createProgressbar({ + min: -50, + max: 165, + value: -50, + animation: false, + type: "percent", + complete: function(e){ + value = e.value; + } + }); + + pb.value(165); + + setTimeout(function() { + equal(value, pb.options.max); + start(); + }, 30); +}); + +asyncTest("Complete event has correct value parameter (type='chunk')", function() { + var value; + + pb = createProgressbar({ + min: -50, + max: 165, + value: -50, + animation: false, + type: "chunk", + complete: function(e){ + value = e.value; + } + }); + + pb.value(165); + + setTimeout(function() { + equal(value, pb.options.max); + start(); + }, 30); +}); + +asyncTest("Change event has correct value parameter (type='value')", function() { + var value; + var expected = 120; + + pb = createProgressbar({ + min: -50, + max: 165, + value: -50, + animation: false, + type: "value", + change: function(e){ + value = e.value; + } + }); + + pb.value(120); + + setTimeout(function() { + equal(value, expected); + start(); + }, 30); +}); + +asyncTest("Change event has correct value parameter (type='percent')", function() { + var value; + var expected = 120; + + pb = createProgressbar({ + min: -50, + max: 165, + value: -50, + animation: false, + type: "percent", + change: function(e){ + value = e.value; + } + }); + + pb.value(120); + + setTimeout(function() { + equal(value, expected); + start(); + }, 30); +}); + +asyncTest("Change event has correct value parameter (type='chunk')", function() { + var value; + var expected = 120; + + pb = createProgressbar({ + min: -50, + max: 165, + value: -50, + animation: false, + type: "chunk", + change: function(e){ + value = e.value; + } + }); + + pb.value(120); + + setTimeout(function() { + equal(value, expected); + start(); + }, 30); +}); + +asyncTest("Context is correctly set in complete event (type='value')", function() { + var context; + + pb = createProgressbar({ + min: -50, + max: 165, + value: -50, + animation: false, + type: "value", + complete: function(e){ + context = this; + } + }); + + pb.value(165); + + setTimeout(function() { + equal(context, pb); + start(); + }, 30); +}); + +asyncTest("Context is correctly set in complete event (type='percent')", function() { + var context; + + pb = createProgressbar({ + min: -50, + max: 130, + value: -50, + animation: false, + type: "percent", + complete: function(e){ + context = this; + } + }); + + pb.value(130); + + setTimeout(function() { + equal(context, pb); + start(); + }, 30); +}); + +asyncTest("Context is correctly set in complete event (type='chunk')", function() { + var context; + + pb = createProgressbar({ + min: -50, + max: 130, + value: -50, + animation: false, + type: "chunk", + complete: function(e){ + context = this; + } + }); + + pb.value(130); + + setTimeout(function() { + equal(context, pb); + start(); + }, 30); +}); + +asyncTest("Context is correctly set in change event (type='value')", function() { + var context; + + pb = createProgressbar({ + min: -50, + max: 165, + value: -50, + animation: false, + type: "value", + change: function(e){ + context = this; + } + }); + + pb.value(150); + + setTimeout(function() { + equal(context, pb); + start(); + }, 30); +}); + +asyncTest("Context is correctly set in change event (type='percent')", function() { + var context; + + pb = createProgressbar({ + min: -50, + max: 165, + value: -50, + animation: false, + type: "percent", + change: function(e){ + context = this; + } + }); + + pb.value(150); + + setTimeout(function() { + equal(context, pb); + start(); + }, 30); +}); + +asyncTest("Context is correctly set in change event (type='chunk')", function() { + var context; + + pb = createProgressbar({ + min: -50, + max: 165, + value: -50, + animation: false, + type: "chunk", + change: function(e){ + context = this; + } + }); + + pb.value(150); + + setTimeout(function() { + equal(context, pb); + start(); + }, 30); +}); + +asyncTest("Complete event is fired after change event", 2, function() { + var events = []; + + pb = createProgressbar({ + min: -50, + max: 165, + value: -50, + animation: false, + complete: function(e){ + events.push("complete"); + }, + change: function(e){ + events.push("change"); + } + }); + + pb.value(165); + + setTimeout(function(){ + equal(events[0], "change"); + equal(events[1], "complete"); + start(); + }, 30); +}); + +// ----------------------------------------------------------------------------------- +// ----------------------------------------------------------------------------------- +module("Rendering / Chunk progressbar", { + setup: moduleSetup, + teardown: moduleTeardown +}); + +test("k-progressbar-reverse class is added to progressbar (type='chunk')", function() { + pb = createProgressbar({ + type: "chunk", + reverse: true + }); + + ok(pb.wrapper.hasClass("k-progressbar-reverse")); +}); + +test("Correct chunks are updated when progressbar is orientation:horizontal and reverse: false", function() { + pb = createProgressbar({ + type: "chunk", + orientation: "horizontal", + reverse: false, + min: 0, + max: 5, + value: 0, + chunkCount: 5 + }); + + pb.value(2); + + equal(pb.wrapper.find("li:lt(2)").filter(".k-state-selected").length, 2); +}); + +test("Correct chunks are updated when progressbar is orientation:horizontal and reverse: true", function() { + pb = createProgressbar({ + type: "chunk", + orientation: "horizontal", + reverse: true, + min: 0, + max: 5, + value: 0, + chunkCount: 5 + }); + + pb.value(2); + + equal(pb.wrapper.find("li:gt(2)").filter(".k-state-selected").length, 2); +}); + +test("Correct chunks are updated when progressbar is orientation:vertical and reverse: false", function() { + pb = createProgressbar({ + type: "chunk", + orientation: "vertical", + reverse: false, + min: 0, + max: 5, + value: 0, + chunkCount: 5 + }); + + pb.value(2); + + equal(pb.wrapper.find("li:gt(2)").filter(".k-state-selected").length, 2); +}); + +test("Correct chunks are updated when progressbar is orientation:vertical and reverse: true", function() { + pb = createProgressbar({ + type: "chunk", + orientation: "vertical", + reverse: true, + min: 0, + max: 5, + value: 0, + chunkCount: 5 + }); + + pb.value(2); + + equal(pb.wrapper.find("li:lt(2)").filter(".k-state-selected").length, 2); +}); + +test("Correct chunks are updated when progressbar is orientation:horizontal and reverse: false and value was decreased", 2, function() { + pb = createProgressbar({ + type: "chunk", + orientation: "horizontal", + reverse: false, + min: 0, + max: 5, + value: 0, + chunkCount: 5 + }); + + pb.value(4); + pb.value(2); + + equal(pb.wrapper.find("li:lt(2)").filter(".k-state-selected").length, 2); + equal(pb.wrapper.find(".k-state-default").length, 3); +}); + +test("Correct chunks are updated when progressbar is orientation:horizontal and reverse: true and value was decreased", 2, function() { + pb = createProgressbar({ + type: "chunk", + orientation: "horizontal", + reverse: true, + min: 0, + max: 5, + value: 0, + chunkCount: 5 + }); + + pb.value(4); + pb.value(2); + + equal(pb.wrapper.find("li:gt(2)").filter(".k-state-selected").length, 2); + equal(pb.wrapper.find(".k-state-default").length, 3); +}); + +test("Correct chunks are updated when progressbar is orientation:vertical and reverse: false and value was decreased", 2, function() { + pb = createProgressbar({ + type: "chunk", + orientation: "vertical", + reverse: false, + min: 0, + max: 5, + value: 0, + chunkCount: 5 + }); + + pb.value(4); + pb.value(2); + + equal(pb.wrapper.find("li:gt(2)").filter(".k-state-selected").length, 2); + equal(pb.wrapper.find(".k-state-default").length, 3); +}); + +test("Correct chunks are updated when progressbar is orientation:vertical and reverse: true and value was decreased", 2, function() { + pb = createProgressbar({ + type: "chunk", + orientation: "vertical", + reverse: true, + min: 0, + max: 5, + value: 0, + chunkCount: 5 + }); + + pb.value(4); + pb.value(2); + + equal(pb.wrapper.find("li:lt(2)").filter(".k-state-selected").length, 2); + equal(pb.wrapper.find(".k-state-default").length, 3); +}); + +asyncTest("isStarted is set to true when the value is changed for the first time", function() { + pb = createProgressbar({ + min: 0, + max: 130, + value: 10, + type: "chunk", + showStatus: true + }); + + pb.value(50); + + setTimeout(function() { + ok(pb._isStarted); + + start(); + }, 30); +}); + +asyncTest("isStarted remains true when the value has been changed and then set to the initial value", function() { + pb = createProgressbar({ + min: 0, + max: 130, + value: 0, + type: "chunk", + showStatus: true + }); + + pb.value(50); + pb.value(0); + + setTimeout(function() { + ok(pb._isStarted); + + start(); + }, 30); +}); + +asyncTest("Correct chunk count is updated when range is more than chunkCount", function() { + pb = createProgressbar({ + min: 0, + max: 300, + value: 0, + type: "chunk", + chunkCount: 10 + }); + + pb.value(150); + + setTimeout(function() { + equal(pb.wrapper.find(".k-state-selected").length, 5); + + start(); + }, 30); +}); + +asyncTest("Correct chunk count is updated when range is less than chunkCount", function() { + pb = createProgressbar({ + min: 0, + max: 10, + value: 0, + type: "chunk", + chunkCount: 20 + }); + + pb.value(2); + + setTimeout(function() { + equal(pb.wrapper.find(".k-state-selected").length, 4); + + start(); + }, 30); +}); + +asyncTest("The last chunk is not filled until max value is reached", function() { + pb = createProgressbar({ + min: 0, + max: 10000, + value: 0, + type: "chunk", + chunkCount: 20 + }); + + pb.value(9999); + + setTimeout(function() { + equal(pb.wrapper.find(".k-state-selected").length, 19); + + start(); + }, 30); +}); + + +// ----------------------------------------------------------------------------------- +// ----------------------------------------------------------------------------------- +module("Rendering / Regular progressbar", { + setup: moduleSetup, + teardown: moduleTeardown +}); + +asyncTest("Progress status wrapper is hidden when value is set to min and showStatus is true (type: 'value')", function() { + pb = createProgressbar({ + min: -50, + max: 130, + value: 100, + animation: false, + type: "value", + showStatus: true + }); + + pb.value(-50); + + setTimeout(function() { + equal(pb.wrapper.find(".k-state-selected:hidden").length, 1); + start(); + }, 30); +}); + +asyncTest("Progress status wrapper is hidden when value is set to min and showStatus is true (type: 'percent')", function() { + pb = createProgressbar({ + min: -50, + max: 130, + value: 100, + animation: false, + type: "percent", + showStatus: true + }); + + pb.value(-50); + + setTimeout(function() { + equal(pb.wrapper.find(".k-state-selected:hidden").length, 1); + start(); + }, 30); +}); + +asyncTest("Progress status wrapper is hidden when value is set to min and showStatus is false (type: 'value')", function() { + pb = createProgressbar({ + min: -50, + max: 130, + value: 100, + animation: false, + type: "value", + showStatus: false + }); + + pb.value(-50); + + setTimeout(function() { + equal(pb.wrapper.find(".k-state-selected:hidden").length, 1); + start(); + }, 30); +}); + +asyncTest("Progress status wrapper is hidden when value is set to min and showStatus is false (type: 'percent')", function() { + pb = createProgressbar({ + min: -50, + max: 130, + value: 100, + animation: false, + type: "percent", + showStatus: false + }); + + pb.value(-50); + + setTimeout(function() { + equal(pb.wrapper.find(".k-state-selected:hidden").length, 1); + start(); + }, 30); +}); + +asyncTest("Progress status wrapper is appended when initial value is set to min and then changed, showStatus is true (type: 'value')", function() { + pb = createProgressbar({ + min: -50, + max: 130, + value: -50, + animation: false, + type: "value", + showStatus: true + }); + + pb.value(-20); + + setTimeout(function() { + equal(pb.wrapper.find(".k-state-selected:visible").length, 1); + start(); + }, 30); +}); + +asyncTest("Progress status wrapper is appended when initial value is set to min and then changed, showStatus is true (type: 'percent')", function() { + pb = createProgressbar({ + min: -50, + max: 130, + value: -50, + animation: false, + type: "percent", + showStatus: true + }); + + pb.value(-20); + + setTimeout(function() { + equal(pb.wrapper.find(".k-state-selected:visible").length, 1); + start(); + }, 30); +}); + +asyncTest("Progress status wrapper is appended when initial value is set to min and then changed, showStatus is false (type: 'value')", function() { + pb = createProgressbar({ + min: -50, + max: 130, + value: -50, + animation: false, + type: "value", + showStatus: false + }); + + pb.value(-20); + + setTimeout(function() { + equal(pb.wrapper.find(".k-state-selected:visible").length, 1); + start(); + }, 30); +}); + +asyncTest("Progress status wrapper is appended when initial value is set to min and then changed, showStatus is false (type: 'percent')", function() { + pb = createProgressbar({ + min: -50, + max: 130, + value: -50, + animation: false, + type: "percent", + showStatus: false + }); + + pb.value(-20); + + setTimeout(function() { + equal(pb.wrapper.find(".k-state-selected:visible").length, 1); + start(); + }, 30); +}); + +asyncTest("Progress status wrapper is shown again when hidden once, showStatus is true (type: 'value')", function() { + pb = createProgressbar({ + min: 0, + max: 130, + value: 0, + animation: false, + type: "value", + showStatus: true + }); + + pb.value(20); + pb.value(0); + pb.value(50); + + setTimeout(function() { + equal(pb.wrapper.find(".k-state-selected:visible").length, 1); + start(); + }, 30); +}); + +asyncTest("Progress status wrapper is shown again when hidden once, showStatus is true (type: 'percent')", function() { + pb = createProgressbar({ + min: 0, + max: 130, + value: 0, + animation: false, + type: "percent", + showStatus: true + }); + + pb.value(20); + pb.value(0); + pb.value(50); + + setTimeout(function() { + equal(pb.wrapper.find(".k-state-selected:visible").length, 1); + start(); + }, 30); +}); + +asyncTest("Progress status wrapper is shown again when hidden once, showStatus is false (type: 'value')", function() { + pb = createProgressbar({ + min: 0, + max: 130, + value: 0, + animation: false, + type: "value", + showStatus: false + }); + + pb.value(20); + pb.value(0); + pb.value(50); + + setTimeout(function() { + equal(pb.wrapper.find(".k-state-selected:visible").length, 1); + start(); + }, 30); +}); + +asyncTest("Progress status wrapper is shown again when hidden once, showStatus is false (type: 'percent')", function() { + pb = createProgressbar({ + min: 0, + max: 130, + value: 0, + animation: false, + type: "percent", + showStatus: false + }); + + pb.value(20); + pb.value(0); + pb.value(50); + + setTimeout(function() { + equal(pb.wrapper.find(".k-state-selected:visible").length, 1); + start(); + }, 30); +}); + +asyncTest("Progress wrapper width stays the same when the ProgressBar wrapper is resized and showStatus is false", function() { + pb = createProgressbar({ + min: 0, + max: 130, + value: 50, + animation: false, + type: "percent", + showStatus: false + }); + + var prevWidth = pb.wrapper.find(".k-state-selected")[0].style.width; + pb.wrapper.width(700); + var currentWidth = pb.wrapper.find(".k-state-selected")[0].style.width; + + setTimeout(function() { + equal(prevWidth, currentWidth); + start(); + }, 30); +}); + +asyncTest("Progress wrapper width stays the same when the ProgressBar wrapper is resized and showStatus is true", function() { + pb = createProgressbar({ + min: 0, + max: 130, + value: 50, + animation: false, + type: "percent", + showStatus: true + }); + + var prevWidth = pb.wrapper.find(".k-state-selected")[0].style.width; + pb.wrapper.width(700); + var currentWidth = pb.wrapper.find(".k-state-selected")[0].style.width; + + setTimeout(function() { + equal(prevWidth, currentWidth); + start(); + }, 30); +}); + +asyncTest("Progress status holder wrapper width stays the same when the ProgressBar wrapper is resized (type='percent')", function() { + pb = createProgressbar({ + min: 0, + max: 130, + value: 50, + animation: false, + type: "percent", + showStatus: true + }); + + var prevWidth = pb.wrapper.find(".k-state-selected .k-progress-status-wrap")[0].style.width; + pb.wrapper.width(700); + var currentWidth = pb.wrapper.find(".k-state-selected .k-progress-status-wrap")[0].style.width; + + setTimeout(function() { + equal(prevWidth, currentWidth); + start(); + }, 30); +}); + +asyncTest("Progress status holder wrapper width stays the same when the ProgressBar wrapper is resized (type='value')", function() { + pb = createProgressbar({ + min: 0, + max: 130, + value: 50, + animation: false, + type: "value", + showStatus: true + }); + + var prevWidth = pb.wrapper.find(".k-state-selected .k-progress-status-wrap")[0].style.width; + pb.wrapper.width(700); + var currentWidth = pb.wrapper.find(".k-state-selected .k-progress-status-wrap")[0].style.width; + + setTimeout(function() { + equal(prevWidth, currentWidth); + start(); + }, 30); +}); + +asyncTest("isStarted is set to true when the value is changed for the first time (type='value')", function() { + pb = createProgressbar({ + min: 0, + max: 130, + value: 10, + type: "value", + showStatus: true, + animation: false + }); + + pb.value(50); + + setTimeout(function() { + ok(pb._isStarted); + + start(); + }, 30); +}); + +asyncTest("isStarted remains true when the value has been changed and then set to the initial value (type='value')", function() { + pb = createProgressbar({ + min: 0, + max: 130, + value: 0, + type: "value", + showStatus: true, + animation: false + }); + + pb.value(50); + pb.value(0); + + setTimeout(function() { + ok(pb._isStarted); + + start(); + }, 30); +}); + +asyncTest("isStarted is set to true when the value is changed for the first time (type='percent')", function() { + pb = createProgressbar({ + min: 0, + max: 130, + value: 10, + type: "percent", + showStatus: true, + animation: false + }); + + pb.value(50); + + setTimeout(function() { + ok(pb._isStarted); + + start(); + }, 30); +}); + +asyncTest("isStarted remains true when the value has been changed and then set to the initial value (type='percent')", function() { + pb = createProgressbar({ + min: 0, + max: 130, + value: 0, + type: "percent", + showStatus: true, + animation: false + }); + + pb.value(50); + pb.value(0); + + setTimeout(function() { + ok(pb._isStarted); + + start(); + }, 30); +}); +})(); \ No newline at end of file diff --git a/tests/resizable/resizable.js b/tests/resizable/resizable.js new file mode 100644 index 00000000000..1dadac6fe5f --- /dev/null +++ b/tests/resizable/resizable.js @@ -0,0 +1,269 @@ +(function() { + var Resizable = kendo.ui.Resizable, + handle, + div; + + module("kendo.ui.Resizable", { + setup: function() { + div = $("
                                                                  ").appendTo(QUnit.fixture); + handle = div.find("span"); + }, + teardown: function() { + kendo.destroy(QUnit.fixture); + div.remove(); + } + }); + + function setup(options) { + return new Resizable(div, options); + } + + function ev(options) { + return new $.Event(options.type, options); + } + + function dragEvent(x, y, handle) { + return { + x: { location: x, startLocation: x }, + y: { location: y, startLocation: y }, + currentTarget: handle + }; + } + + test("start is raised when element is dragged", function() { + var called, + resizable = setup({ + handle: "span", + start: function() { + called = true; + } + }); + handle.trigger(ev({ type: "mousedown", pageX:0, pageY: 0 })); + handle.trigger(ev({ type: "mousemove", pageX: 10, pageY: 0 })); + ok(called); + }); + + test("resize is raised when element is dragged", function() { + var called, + resizable = setup({ + handle: "span", + resize: function() { + called = true; + } + }); + handle.trigger(ev({ type: "mousedown", pageX:0, pageY: 0 })); + handle.trigger(ev({ type: "mousemove", pageX: 10, pageY: 0 })); + handle.trigger(ev({ type: "mousemove", pageX: 11, pageY: 0 })); + ok(called); + }); + + test("resize is raised only if the handle is dragged", function() { + var called, + resizable = setup({ + handle: "span", + resize: function() { + called = true; + } + }); + handle = div.find("b"); + handle.trigger(ev({ type: "mousedown", pageX:0, pageY: 0 })); + handle.trigger(ev({ type: "mousemove", pageX: 10, pageY: 0 })); + handle.trigger(ev({ type: "mousemove", pageX: 11, pageY: 0 })); + ok(!called); + }); + + test("resize is raised if the vertical handle is dragged vertically", function() { + var called, + resizable = setup({ + orientation: "vertical", + handle: "span", + resize: function() { + called = true; + } + }); + handle.trigger(ev({ type: "mousedown", pageX:1, pageY: 1 })); + handle.trigger( ev( { type: "mousemove", pageX: 1, pageY: 10 } ) ); + handle.trigger( ev( { type: "mousemove", pageX: 1, pageY: 11 } ) ); + ok(called); + }); + + test("resizeend is raised when user release the mouse", function() { + var called, + resizable = setup({ + handle: "span", + resizeend: function() { + called = true; + } + }); + handle.trigger(ev({ type: "mousedown", pageX:1, pageY: 1 })); + handle.trigger( ev( { type: "mousemove", pageX: 10, pageY: 1 } ) ); + handle.trigger( ev( { type: "mousemove", pageX: 11, pageY: 1 } ) ); + $(document.documentElement).trigger( { type: "mouseup" } ); + ok(called); + }); + + test("hint is moved during horizontal dragging", function() { + var resizable = setup({ + handle: "span", + hint: $("
                                                                  ") + }); + + resizable._start(dragEvent(0, 0, handle)); + resizable._resize(dragEvent(10, 0, handle)); + + equal(parseInt(div.find(".hint").offset().left), 10); + }); + + test("hint is not moved during horizontal dragging with vertical orientation", function() { + var resizable = setup({ + handle: "span", + orientation: "vertical", + hint: $("
                                                                  ") + }); + + resizable._start(dragEvent(0, 0, handle)); + resizable._resize(dragEvent(10, 10, handle)); + + ok(!parseInt(div.find(".hint").offset().left)); + }); + + test("hint is not moved during vertical dragging with horizontal orientation", function() { + var resizable = setup({ + handle: "span", + orientation: "horizontal", + hint: $("
                                                                  ") + }); + + resizable._start(dragEvent(0, 0, handle)); + resizable._resize(dragEvent(0, 10, handle)); + + ok(!parseInt(div.find(".hint").offset().top)); + }); + + test("hint is moved during vertical dragging", function() { + var resizable = setup({ + handle: "span", + orientation: "vertical", + hint: $("
                                                                  ") + }); + + resizable._start(dragEvent(0, 0, handle)); + resizable._resize(dragEvent(0, 10, handle)); + + equal(parseInt(div.find(".hint").offset().top), 10); + }); + + test("hint is removed", function() { + var resizable = setup({ + handle: "span", + hint: $("
                                                                  ") + }); + + resizable._start(dragEvent(0, 0, handle)); + resizable._resize(dragEvent(10, 0, handle)); + resizable._stop(dragEvent(10, 0, handle)); + + equal(div.find(".hint").length, 0); + }); + + test("hint is create if function", function() { + var el, + resizable = setup({ + handle: "span", + hint: function(e) { + el = e; + return $("
                                                                  "); + } + }); + resizable._start(dragEvent(0, 0, handle)); + + ok(resizable.hint); + ok(el); + }); + test("hint is not moved over the max value", function() { + var resizable = setup({ + handle:"span", + hint: $("
                                                                  "), + max: 30 + }); + resizable._start(dragEvent(0, 0, handle)); + resizable._resize(dragEvent(60, 0, handle)); + + equal(parseInt(div.find(".hint").offset().left), 30); + }); + + test("hint is not moved out of the min value", function() { + var resizable = setup({ + handle:"span", + hint: $("
                                                                  "), + min: 30 + }); + resizable._start(dragEvent(60, 0, handle)); + resizable._resize(dragEvent(20, 0, handle)); + + equal(parseInt(div.find(".hint").offset().left), 30); + }); + + test("hint is not moved out of the min value if min is function", function() { + var el, + resizable = setup({ + handle:"span", + hint: $("
                                                                  "), + min: function(e) { + el = e; + return 30; + } + }); + resizable._start(dragEvent(60, 0, handle)); + resizable._resize(dragEvent(20, 0, handle)); + + equal(parseInt(div.find(".hint").offset().left), 30); + ok(el); + }); + + test("hint is not moved out of the max value if max is function", function() { + var el, + resizable = setup({ + handle:"span", + hint: $("
                                                                  "), + max: function(e) { + el = e; + return 30; + } + }); + resizable._start(dragEvent(0, 0, handle)); + resizable._resize(dragEvent(40, 0, handle)); + + equal(parseInt(div.find(".hint").offset().left), 30); + ok(el); + }); + + test("hint invalid class is applied if outsize of the max value", function() { + var el, + resizable = setup({ + handle:"span", + hint: $("
                                                                  "), + max: function(e) { + el = e; + return 30; + }, + invalidClass: "foo" + }); + resizable._start(dragEvent(0, 0, handle)); + resizable._resize(dragEvent(40, 0, handle)); + + ok(div.find(".hint").hasClass("foo")); + }); + + test("kendo.resize does not trigger resize event", 0, function() { + var resizable = setup({ + resize: function() { + ok(true); + } + }); + + div.css({ width:10 }); + + kendo.resize(div); + }); +})(); diff --git a/tests/router/history.js b/tests/router/history.js new file mode 100644 index 00000000000..cda11311d12 --- /dev/null +++ b/tests/router/history.js @@ -0,0 +1,341 @@ +(function() { + var win, + kendoHistory, + _history, + initial, + win, + loc, + root, + pushStateSupported = kendo.support.pushState; + + module("History", { + setup: function() { + location.hash = ""; + QUnit.stop(); + QUnit.fixture.html(''); + win = window.frames[0].window; + + $(win).one('load', function() { + loc = win.location; + root = loc.pathname; + initial = loc.href.replace(/#.*$/, ''); + kendoHistory = win.kendo.history; + _history = win.history; + QUnit.start(); + }); + }, + + teardown: function() { + if (win.kendo) { + win.kendo.support.pushState = pushStateSupported; + kendoHistory.stop(); + } + } + }); + + function url(expected) { + equal(loc.href.replace(/#$/, ''), expected); + } + + function startWithHash() { + kendoHistory.start({root: root}); + } + + function startWithPushState() { + kendoHistory.start({pushState: true, root: root}); + } + + test("uses hashbang by default", function() { + startWithHash(); + kendoHistory.navigate("/new-location"); + url(initial + "#/new-location"); + }); + + test("keeps track of locations", 2, function() { + startWithHash(); + equal(kendoHistory.locations.length, 1); + equal(kendoHistory.locations[0], ""); + }); + + test("uses pushState if possible and asked to", function() { + startWithPushState(); + kendoHistory.navigate("/new-location"); + if (!!pushStateSupported) { + url(initial + "/new-location"); + } + else { + url(initial + "#/new-location"); + } + }); + + test("does not pushState if identical", function() { + startWithPushState(); + kendoHistory.navigate("/new-location"); + var length = history.length; + kendoHistory.navigate("/new-location"); + equal(history.length, length); + }); + + asyncTest("transforms pushState to non-push state when needed", 1, function() { + if (!pushStateSupported) { + start(); + ok(true); + return; + } + + startWithPushState(); + + kendoHistory.navigate("/new-location"); + + var currentLocation = loc.href; + + var check = function() { + var newLocation = frames[0].window.location.href; + if (newLocation != currentLocation) { + start(); + equal(newLocation, initial + "#/new-location"); + } else { + setTimeout(check, 100); + } + } + + kendoHistory.stop(); + win.kendo.support.pushState = false; + startWithPushState(); + check(); + }); + + asyncTest("transforms hash to push state on start", function() { + expect(1); + + if (!pushStateSupported) { + start(); + ok(true); + return; + } + + startWithHash(); + kendoHistory.navigate("/new-location"); + + var currentLocation = loc.href; + + var check = function() { + var newLocation = frames[0].window.location.href; + if (newLocation != currentLocation) { + start(); + equal(newLocation, initial + "/new-location"); + } else { + setTimeout(check, 100); + } + } + + kendoHistory.stop(); + startWithPushState(); + check(); + }); + + test("allows setting of root", function() { + if (!pushStateSupported) { + return; + } + kendoHistory.start({root: root + "/subdir/", pushState: true}); + kendoHistory.navigate('/new-location'); + url(initial + "/subdir/new-location"); + }); + + test("triggers events when history changed", function() { + expect(1); + startWithHash(); + + kendoHistory.change(function(e) { + equal(e.url, "/new-location"); + }); + + kendoHistory.navigate("/new-location"); + }); + + test("Allows prevention of hash change if preventDefault called", 1, function() { + startWithHash(); + + kendoHistory.change(function(e) { + e.preventDefault(); + }); + + kendoHistory.navigate("/new-location"); + url(initial); + }); + + asyncTest("Allows prevention of back if preventDefault called", 1, function() { + startWithHash(); + + kendoHistory.navigate("/initial-location"); + kendoHistory.navigate("/new-location"); + + kendoHistory.change(function(e) { + e.preventDefault(); + }); + + _history.back(); + + setTimeout(function() { + start(); + url(initial + "#/new-location"); + }, 300); + }); + + asyncTest("Allows prevention of navigating to previous URL (not back) if preventDefault called", 1, function() { + startWithHash(); + + kendoHistory.navigate("/initial-location"); + kendoHistory.navigate("/new-location"); + + kendoHistory.change(function(e) { + e.preventDefault(); + }); + + setTimeout(function() { + loc.href = initial + "#/initial-location"; + }, 300); + + setTimeout(function() { + start(); + url(initial + "#/new-location"); + }, 600); + }); + + asyncTest("Triggers back", 2, function() { + startWithHash(); + + kendoHistory.navigate("/initial-location"); + kendoHistory.navigate("/new-location"); + + kendoHistory.bind("back", function(e) { + equal(e.url, "/new-location"); + equal(e.to, "/initial-location"); + }); + + _history.back(); + + setTimeout(function() { + start(); + }, 300); + }); + + asyncTest("Allows prevention of back if preventDefault in back event called", 1, function() { + startWithHash(); + + kendoHistory.navigate("/initial-location"); + kendoHistory.navigate("/new-location"); + + kendoHistory.bind("back", function(e) { + e.preventDefault(); + }); + + _history.back(); + + setTimeout(function() { + start(); + url(initial + "#/new-location"); + }, 300); + }); + + asyncTest("Allows prevention of hash change by clicked link if preventDefault called", 1, function() { + startWithHash(); + + kendoHistory.navigate("/bar") + kendoHistory.change(function(e) { + e.preventDefault(); + }); + + loc.href = loc.href + "#foo"; + + setTimeout(function() { + start(); + url(initial + "#/bar"); + }, 300); + }); + + test("strips hash from passed urls", function() { + startWithHash(); + kendoHistory.navigate('#/new-location'); + equal(kendoHistory.current, '/new-location'); + }); + + test("accepts event handlers passed as options", function() { + expect(1); + + kendoHistory.start({root: root, change: function(e) { equal(e.url, "/new-location"); }}); + + kendoHistory.navigate("/new-location"); + }); + + test("triggers ready with the initial location", function() { + expect(1); + + win.location.hash = "/initial-location"; + kendoHistory.start({root: root }); + equal(kendoHistory.current, "/initial-location"); + }); + + asyncTest("listens for outside url changes (hashChange)", function() { + expect(1); + startWithHash(); + + kendoHistory.change(function(e) { + start(); + equal(e.url, "/outside-location"); + }); + + win.location.hash = "/outside-location"; + }); + + test("passes parameters if any present", function() { + expect(1); + startWithHash(); + + kendoHistory.change(function(e) { + equal(e.url, "/new-location?foo=bar"); + }); + + kendoHistory.navigate("/new-location?foo=bar"); + }); + + asyncTest("supports #:back pseudo url for going back", 1, function() { + startWithHash(); + kendoHistory.navigate("/new-location"); + kendoHistory.navigate("#:back"); + setTimeout(function() { + start(); + equal(loc.hash, ''); + }, 300); + }); + + asyncTest("stays in sync after back is called", 2, function() { + startWithHash(); + kendoHistory.navigate("/initial-location"); + kendoHistory.navigate("/new-location"); + kendoHistory.navigate("#:back"); + + setTimeout(function() { + start(); + equal(kendoHistory.locations.length, 2); + equal(kendoHistory.locations[0], ""); + }, 300); + }); + + asyncTest("handles back in push state", 1, function() { + startWithPushState(); + kendoHistory.navigate("/foo"); + kendoHistory.navigate("/bar"); + kendoHistory.navigate("/baz"); + _history.back(); + + setTimeout(function() { + _history.back(); + setTimeout(function() { + start(); + equal(kendoHistory.locations.length, 2); + }, 200); + }, 200); + }); +})(); diff --git a/tests/router/router.js b/tests/router/router.js new file mode 100644 index 00000000000..d7dbe04a753 --- /dev/null +++ b/tests/router/router.js @@ -0,0 +1,284 @@ +var router; + +function navigate(to) { + kendo.history.navigate(to); +} + +module("Router", { + setup: function() { + location.hash = ''; + }, + + teardown: function() { + router.destroy(); + } +}); + +test("raises init when started", 1, function(){ + router = new kendo.Router({ + init: function(e) { + equal(e.url, "/"); + } + }) + + router.start(); +}); + +test("navigates to / by default", 1, function(){ + router = new kendo.Router(); + + router.route("/", function() { + ok(true); + }); + + router.start(); +}); + +test("supports multiple instances", 2, function(){ + router = new kendo.Router(); + + router.route("/", function() { ok(true); }); + + router.start(); + + router2 = new kendo.Router(); + router2.route("/", function() { ok(true); }); + router2.start(); +}); + +module("Router params", { + setup: function() { + location.hash = ''; + router = new kendo.Router(); + router.start(); + }, + + teardown: function() { + kendo.history.stop(); + location.hash = ''; + router.destroy(); + } +}) + +test("recognizes an url", 1, function(){ + var router = new kendo.Router(); + + router.route("/foo", function() { + ok(true); + }); + + router.start(); + navigate("/foo"); +}); + +test("parses params", 1, function(){ + var router = new kendo.Router(); + + router.route("/:foo", function(foo) { + equal(foo, "foo"); + }); + + router.start(); + navigate("/foo"); +}); + +test("parses query string params", 2, function(){ + var router = new kendo.Router(); + + router.route("/:foo", function(foo, params) { + equal(foo, "foo"); + equal(params.baz, "Q"); + }); + + router.start(); + navigate("/foo?baz=Q"); +}); + +test("handles complex query string parameters", 6, function(){ + var router = new kendo.Router(); + + router.route("/:foo", function(foo, params) { + equal(foo, "foo"); + equal(params.key1, ""); + equal(params.key2, "value"); + equal(params.key3, "Rock & Roll"); + equal(params["rock&roll"], "here to stay"); + equal(params.key4, "baz"); + }); + + router.start(); + navigate("/foo?key1=&key2=value&key3=Rock%20%26%20Roll&rock%26roll=here%20to%20stay&key4=foo&key4=bar&key4=baz"); +}); + +test("no exception is rised when invalid query string parameters are passed", 2, function(){ + var router = new kendo.Router(); + + router.route("/:foo", function(foo, params) { + equal(foo, "foo"); + ok(true); + }); + + router.start(); + try { + navigate("/foo?key1&value"); + } catch(e) { + ok(false, "Error should not be thrown"); + } +}); + +test("parses optional params", 4, function() { + var router = new kendo.Router(); + + router.route("/:foo(/:bar)", function(foo, bar) { + equal(foo, "foo"); + + if (bar) { + equal(bar, "bar"); + } else { + ok(true); + } + }); + + router.start(); + navigate("/foo/bar"); + navigate("/foo"); +}); + +test("parses optional params when query string is present", 2, function() { + var router = new kendo.Router(); + + router.route("/items(/:foo)", function(foo) { + if (foo) { + equal(foo, "foo"); + } else { + ok(true); + } + }); + + router.start(); + navigate("/items/foo?a=2"); + navigate("/items?a=2"); +}); + +test("parses optional params and query string params", 7, function() { + var router = new kendo.Router(); + + router.route("/:foo(/:bar)", function(foo, bar, params) { + equal(foo, "foo"); + + if (bar) { + equal(bar, "bar"); + equal(params.baz, "Q"); + } else { + equal(params.baz, "Q"); + equal(params.qux, "qux"); + ok(true); + } + }); + + router.start(); + navigate("/foo/bar?baz=Q"); + navigate("/foo?baz=Q&qux=qux"); +}); + +test("parses splat params", 2, function() { + var router = new kendo.Router(); + + router.route("/:foo/*bar", function(foo, bar) { + equal(foo, "foo"); + + equal(bar, "bar/baz"); + }); + + router.start(); + navigate("/foo/bar/baz"); +}); + +test("triggers change on url change", 2, function(){ + var router = new kendo.Router(); + + + router.one("change", function(e) { equal(e.url, "/") }); + router.start(); + router.one("change", function(e) { equal(e.url, "/foo") }); + navigate("/foo"); +}); + +test("triggers change on query string params change", 2, function(){ + var router = new kendo.Router(); + + router.start(); + router.one("change", function(e) { equal(e.url, "/foo?bar=A") }); + navigate("/foo?bar=A"); + router.one("change", function(e) { equal(e.url, "/foo?bar=B") }); + navigate("/foo?bar=B"); +}); + +test("query string parameters are available in change event", 2, function(){ + var router = new kendo.Router(); + + router.start(); + router.bind("change", function(e) { + equal(e.params.bar, "A"); + equal(e.params.baz, "B"); + }); + navigate("/foo?bar=A&baz=B"); +}); + +test("preventing default does not hit the route", 0, function(){ + var router = new kendo.Router(); + + router.start(); + + router.route("/foo", function(url) { + ok(false); + }); + + router.one("change", function(e) { + e.preventDefault(); + }); + + navigate("/foo"); +}); + +test("triggers route missing if no route found", 2, function(){ + var router = new kendo.Router(); + + router.route("/", function() { + ok(true); + }); + + router.bind("routeMissing", function(e) { + equal(e.url, "/foo") + }); + + router.start(); + navigate("/foo"); +}); + +test("query string parameters are available in the route missing event", 3, function() { + var router = new kendo.Router(); + + router.route("/", function() { + ok(true); + }); + + router.bind("routeMissing", function(e) { + equal(e.params.bar, "A"); + equal(e.params.baz, "B"); + }); + + router.start(); + navigate("/foo?bar=A&baz=B"); +}) + +test("navigate method navigates to a given url", 1, function(){ + var router = new kendo.Router(); + + router.route("/foo", function() { + ok(true); + }); + + router.start(); + router.navigate("/foo"); +}); diff --git a/tests/router/sandbox.html b/tests/router/sandbox.html new file mode 100644 index 00000000000..8d3e86ce07b --- /dev/null +++ b/tests/router/sandbox.html @@ -0,0 +1,10 @@ + + + diff --git a/tests/selectable/selectable.js b/tests/selectable/selectable.js new file mode 100644 index 00000000000..f04e572bc59 --- /dev/null +++ b/tests/selectable/selectable.js @@ -0,0 +1,601 @@ +(function() { + var Selectable = kendo.ui.Selectable, + ul, + SELECTED = "k-state-selected", + ACTIVE = "k-state-selecting", + SELECTABLE = "k-selectable", + UNSELECTING = "k-state-unselecting"; + + module("kendo.ui.Selectable", { + setup: function() { + ul = $("
                                                                  • 1
                                                                  • 2
                                                                  • 3
                                                                  ").appendTo(QUnit.fixture); + + $.fn.press = function(x, y, ctrlKey, metaKey) { + return triggerEvent(this, "mousedown", { + pageX: x, + pageY: y, + ctrlKey: ctrlKey, + metaKey: metaKey + }); + } + + $.fn.move = function(x, y, ctrlKey, metaKey) { + return triggerEvent(this, "mousemove", { + pageX: x, + pageY: y, + ctrlKey: ctrlKey, + metaKey: metaKey + }); + } + + $.fn.release = function(info) { + info = $.extend({}, info); + return triggerEvent(this, "mouseup", info); + } + + $.fn.tap = function(info) { + return this.press().release(info); + } + }, + teardown: function() { + ul.kendoSelectable("destroy"); + ul.remove(); + $(".k-marquee").remove(); + } + }); + + function triggerEvent(element, type, info) { + element.trigger($.Event(type, info)); + + return element; + }; + + test("selectable class is applied on the element when initialized", function() { + var selectable = new Selectable(ul); + ok(ul.hasClass(SELECTABLE)); + }); + + test("single selection does not attach the marquee", function() { + var selectable = new Selectable(ul); + + ul.children().eq(0).press(); + equal($(".k-marquee").length, 0); + }); + + test("multiple selection attach the marquee to the document", function() { + var selectable = new Selectable(ul, { multiple: true }); + + ul.children().eq(0).press().move(10, 10); + equal($(".k-marquee").length, 1); + }); + + test("element get selected on mouseup", function() { + var selectable = new Selectable(ul); + var selectee = $(ul.find(">li")[0]); + + selectee.tap(); + + ok(selectee.hasClass(SELECTED)); + }); + + test("unselect all previosly selected when select new element", function() { + var selectable = new Selectable(ul); + var selectees = ul.find(">li"); + + selectees.eq(0).tap(); + selectees.eq(1).tap(); + + equal(selectees.eq(0).hasClass(SELECTED), false); + equal(selectees.eq(1).hasClass(SELECTED), true); + }); + + test("item is marked for selection on start", function() { + var selectable = new Selectable(ul, { multiple: true }); + var selectee = ul.find(">li:first"); + var position = selectee.offset(); + + selectee.press(0, 0).move(position.left, position.top).move(position.left + 1, position.top); + + ok(selectee.hasClass(ACTIVE)); + }); + + test("moving over item marks it for selection", function() { + var selectable = new Selectable(ul, { multiple: true }); + var selectees = ul.find(">li"); + var position = selectees.eq(1).offset(); + + selectees.eq(0).press().move(position.left, position.top); + + ok(selectees.eq(0).hasClass(ACTIVE)); + ok(selectees.eq(1).hasClass(ACTIVE)); + }); + + test("moving away from selectable item removes selection mark", function() { + var selectable = new Selectable(ul, { multiple: true }); + var selectees = ul.find(">li"); + var position = selectees.eq(1).offset(); + + selectees.eq(0).press(0, 0).move(position.left, position.top).move(position.left, position.top - 1); + + ok(selectees.eq(0).hasClass(ACTIVE)); + ok(!selectees.eq(1).hasClass(ACTIVE)); + }); + + test("value returns all selected items", function() { + var selectable = new Selectable(ul); + var selectees = ul.find(">li"); + + selectees.eq(0).tap(); + + var values = selectable.value(); + + equal(values.length, 1); + ok(values[0], selectees[0]); + }); + + test("multiple selection ctrlKey click on selected items does not unselects it", function() { + var selectable = new Selectable(ul, { multiple: true }); + var selectees = ul.find(">li"); + + selectees.eq(0).tap(); + selectees.eq(1).tap({ ctrlKey: true }); + + ok(selectees.eq(0).hasClass(SELECTED)); + ok(selectees.eq(1).hasClass(SELECTED)); + }); + + test("multiple selection metaKey click on selected items does not unselects it", function() { + var selectable = new Selectable(ul, { multiple: true }); + var selectees = ul.find(">li"); + + selectees.eq(0).tap(); + selectees.eq(1).tap({ metaKey: true }); + + ok(selectees.eq(0).hasClass(SELECTED)); + ok(selectees.eq(1).hasClass(SELECTED)); + }); + + test("single selection ctrlKey click on item when another is selected", function() { + var selectable = new Selectable(ul); + var selectees = ul.find(">li"); + + selectees.eq(0).tap(); + selectees.eq(1).tap({ ctrlKey: true }); + + ok(!selectees.eq(0).hasClass(SELECTED)); + ok(selectees.eq(1).hasClass(SELECTED)); + }); + + test("single selection metaKey click on item when another is selected", function() { + var selectable = new Selectable(ul); + var selectees = ul.find(">li"); + + selectees.eq(0).tap(); + selectees.eq(1).tap({ metaKey: true }); + + ok(!selectees.eq(0).hasClass(SELECTED)); + ok(selectees.eq(1).hasClass(SELECTED)); + }); + + test("single selection ctrlKey click on selected item unselects it", function() { + var selectable = new Selectable(ul); + var selectee = $(ul.find(">li")[0]); + + selectee.tap(); + selectee.tap({ ctrlKey: true }); + + ok(!selectee.hasClass(SELECTED)); + ok(!selectee.hasClass(ACTIVE)); + }); + + test("single selection metaKey click on selected item unselects it", function() { + var selectable = new Selectable(ul); + var selectee = $(ul.find(">li")[0]); + + selectee.tap(); + selectee.tap({ metaKey: true }); + + ok(!selectee.hasClass(SELECTED)); + ok(!selectee.hasClass(ACTIVE)); + }); + + test("multiple selection mousedown with ctrlKey on selected item persist selection", function() { + var selectable = new Selectable(ul, { multiple: true }); + var selectee = $(ul.find(">li")[0]); + + selectee.tap(); + selectee.press(0, 0, true); + + ok(selectee.hasClass(SELECTED)); + ok(!selectee.hasClass(ACTIVE)); + }); + + test("multiple selection mousedown with metaKey on selected item persist selection", function() { + var selectable = new Selectable(ul, { multiple: true }); + var selectee = $(ul.find(">li")[0]); + + selectee.tap(); + selectee.press(0, 0, false, true); + + ok(selectee.hasClass(SELECTED)); + ok(!selectee.hasClass(ACTIVE)); + }); + + test("multiple selection click on selected item with ctrlKey pressed unselect it", function() { + var selectable = new Selectable(ul, { multiple: true }); + var selectee = $(ul.find(">li")[0]); + + selectee.addClass(SELECTED); + selectee.tap({ ctrlKey: true }); + + ok(!selectee.hasClass(SELECTED)); + ok(!selectee.hasClass(ACTIVE)); + }); + + test("multiple selection click on selected item with metaKey pressed unselect it", function() { + var selectable = new Selectable(ul, { multiple: true }); + var selectee = $(ul.find(">li")[0]); + + selectee.addClass(SELECTED); + selectee.tap({ metaKey: true }); + + ok(!selectee.hasClass(SELECTED)); + ok(!selectee.hasClass(ACTIVE)); + }); + + test("moving after selected item with ctrlKey pressed", function() { + var selectable = new Selectable(ul, { multiple: true }), + firstSelectee = $(ul.find(">li")[0]), + secondSelectee = $(ul.find(">li")[1]), + position = secondSelectee.offset(); + + firstSelectee.addClass(SELECTED); + secondSelectee.addClass(SELECTED); + + firstSelectee.press(0, 0, true).move(position.left, position.top, true).move(position.left, position.top + 1, true); + + ok(firstSelectee.hasClass(SELECTED)); + ok(!secondSelectee.hasClass(ACTIVE)); + ok(!secondSelectee.hasClass(SELECTED)); + }); + + test("moving after selected item with metaKey pressed", function() { + var selectable = new Selectable(ul, { multiple: true }), + firstSelectee = $(ul.find(">li")[0]), + secondSelectee = $(ul.find(">li")[1]), + position = secondSelectee.offset(); + + firstSelectee.addClass(SELECTED); + secondSelectee.addClass(SELECTED); + + firstSelectee.press(0, 0, false, true).move(position.left, position.top, false, true).move(position.left, position.top + 1, false, true); + + ok(firstSelectee.hasClass(SELECTED)); + ok(!secondSelectee.hasClass(ACTIVE)); + ok(!secondSelectee.hasClass(SELECTED)); + }); + + test("moving back from selected item with ctrlKey pressed", function() { + var selectable = new Selectable(ul, {multiple: true}), + firstSelectee = $(ul.find(">li")[0]), + secondSelectee = $(ul.find(">li")[1]), + position = secondSelectee.offset(); + + firstSelectee.addClass(SELECTED); + secondSelectee.addClass(SELECTED); + + + firstSelectee.press(0, 0, true).move(position.left, position.top, true).move(position.left, position.top - 1, true); + + + ok(firstSelectee.hasClass(SELECTED)); + ok(!secondSelectee.hasClass(ACTIVE)); + ok(secondSelectee.hasClass(SELECTED)); + ok(!secondSelectee.hasClass(UNSELECTING)); + }); + + test("moving back from selected item with metaKey pressed", function() { + var selectable = new Selectable(ul, {multiple: true}), + firstSelectee = $(ul.find(">li")[0]), + secondSelectee = $(ul.find(">li")[1]), + position = secondSelectee.offset(); + + firstSelectee.addClass(SELECTED); + secondSelectee.addClass(SELECTED); + + + firstSelectee.press(0, 0, false, true).move(position.left, position.top, false, true).move(position.left, position.top - 1, false, true); + + + ok(firstSelectee.hasClass(SELECTED)); + ok(!secondSelectee.hasClass(ACTIVE)); + ok(secondSelectee.hasClass(SELECTED)); + ok(!secondSelectee.hasClass(UNSELECTING)); + }); + + test("select range between two selected elements when shift key is pressed", function() { + var selectable = new Selectable(ul, { multiple: true }), + firstSelectee = $(ul.find(">li")[0]), + secondSelectee = $(ul.find(">li")[2]); + + firstSelectee.addClass(SELECTED); + secondSelectee.tap({ shiftKey: true }); + + var selected = selectable.value(); + equal(selected.length, 3); + }); + + test("select range when no item selected with shift key pressed select from first selectable", function() { + var selectable = new Selectable(ul, { multiple: true }), + selectee = $(ul.find(">li")[2]); + + selectee.tap({ shiftKey: true }); + + var selected = selectable.value(); + equal(selected.length, 3); + }); + + test("selectRange when start element is in oposite order in the DOM", function() { + var selectable = new Selectable(ul, {multiple: true}), + start = ul.find(">li")[1], + end = ul.find(">li")[0]; + + selectable.selectRange(start, end); + var selected = selectable.value(); + equal(selected.length, 2); + }); + + test("shift and click clears selected items outside the selected range", function() { + var selectable = new Selectable(ul, { multiple: true }), + selectees = ul.find(">li"); + + selectees.eq(0).addClass(SELECTED); + selectees.eq(1).tap(); + selectees.eq(2).tap({ shiftKey: true }); + + var selected = selectable.value(); + equal(selected.length, 2); + ok(selectees[1] === selected[0]); + ok(selectees[2] === selected[1]); + }); + + test("selecting range with equal start and end element", function() { + var selectable = new Selectable(ul, { multiple: true }), + selectee = $(ul.find(">li")[0]); + + ul.children().addClass(SELECTED); + selectee.tap({ shiftKey: true }); + + var selected = selectable.value(); + equal(selected.length, 1); + equal(selected[0], selectee[0]); + }); + + test("selecting element fires select event", function() { + var selectable = new Selectable(ul), + selectee = $(ul.find(">li")[0]), + selectWasCalled = false; + + selectable.bind("select", function () { selectWasCalled = true; }); + selectee.tap(); + + ok(selectWasCalled); + }); + + test("select event recieve as argument element to be selected", function() { + var selectable = new Selectable(ul), + selectee = $(ul.find(">li")[0]), + elementToSelect; + + selectable.bind("select", function (arg) { + elementToSelect = arg.element; + }); + selectee.tap(); + + equal(elementToSelect, selectee[0]); + }); + + test("cancel select event will prevent element selection", function() { + var selectable = new Selectable(ul), + selectee = $(ul.find(">li")[0]); + + selectable.bind("select", function (arg) { + arg.preventDefault(); + }); + selectee.tap(); + + var selected = selectable.value(); + equal(selected.length, 0); + ok(!selectee.hasClass(SELECTED)); + ok(!selectee.hasClass(ACTIVE)); + }); + + test("change fires when elements are selected", function() { + var selectable = new Selectable(ul), + selectee = $(ul.find(">li")[0]), + changetWasCalled = false; + + selectable.bind("change", function () { changetWasCalled = true; }); + selectee.tap(); + + ok(changetWasCalled); + ok(selectee.hasClass(SELECTED)); + }); + + test("ctrlKey click on selected triggers change event", function() { + var wasCalled = false, + selectable = new Selectable(ul, { + change: function() { + wasCalled = true; + } + }); + + ul.children().first().addClass(SELECTED).tap({ ctrlKey: true }); + + ok(wasCalled); + ok(!ul.children().first().hasClass(SELECTED)); + }); + + test("metaKey click on selected triggers change event", function() { + var wasCalled = false, + selectable = new Selectable(ul, { + change: function() { + wasCalled = true; + } + }); + + ul.children().first().addClass(SELECTED).tap({ metaKey: true }); + + ok(wasCalled); + ok(!ul.children().first().hasClass(SELECTED)); + }); + + test("selectRange accept arguments as jQuery object", function() { + var selectable = new Selectable(ul, {multiple: true}), + start = $(ul.find(">li")[1]), + end = $(ul.find(">li")[0]); + + selectable.selectRange(start, end); + var selected = selectable.value(); + equal(selected.length, 2); + }); + + test("selectRange accept arguments as jQuery selectors", function() { + var selectable = new Selectable(ul, {multiple: true}); + + selectable.selectRange("ul>li", "ul>li"); + var selected = selectable.value(); + equal(selected.length, 1); + }); + + test("clear unselect all selected elements", function() { + var selectable = new Selectable(ul, {multiple: true}); + $(ul.find(">li")).addClass(SELECTED); + + selectable.clear(); + + var selected = selectable.value(); + equal(selected.length, 0); + }); + + test("set values to select through value method selects the elements", function() { + var selectable = new Selectable(ul, {multiple: true}), + selectees = $(ul.find(">li")); + + selectable.value(selectees); + + var selected = selectable.value(); + equal(selected.length, 3); + ok(selected.first().hasClass(SELECTED)); + }); + + test("set values to select through value method triggers select event", function() { + var selectable = new Selectable(ul, {multiple: true}), + selectees = $(ul.find(">li")), + selectWasFired = false; + + selectable.bind("select", function () { + selectWasFired = true; + }); + selectable.value(selectees); + + ok(selectWasFired); + }); + + test("set null as value to select", function() { + var selectable = new Selectable(ul), + selectees = null; + + selectable.value(selectees); + + ok(true); + }); + + test("set values to select through value method triggers change event", function() { + var selectable = new Selectable(ul, {multiple: true}), + selectees = $(ul.find(">li")), + changeWasFired = false; + + selectable.bind("change", function () { + changeWasFired = true; + }); + selectable.value(selectees); + + ok(changeWasFired); + }); + + test("selectRange with shift key pressed triggers select event", function() { + var selectable = new Selectable(ul, {multiple: true}), + start = $(ul.find(">li")[1]), + end = $(ul.find(">li")[0]), + selectWasFired = false; + + selectable.bind("select", function () { + selectWasFired = true; + }); + selectable.selectRange(start, end); + + equal(selectable.value().length, 2); + ok(selectWasFired); + }); + + test("selectRange with shift key pressed triggers change event", function() { + var selectable = new Selectable(ul, {multiple: true}), + start = $(ul.find(">li")[1]), + end = $(ul.find(">li")[0]), + changeWasFired = false; + + selectable.bind("change", function () { + changeWasFired = true; + }); + selectable.selectRange(start, end); + + equal(selectable.value().length, 2); + ok(changeWasFired); + }); + + test("select element adds aria attribute", function() { + new Selectable(ul, { aria: true }); + + ul.children().first().tap(); + + equal(ul.children().first().attr("aria-selected"), "true"); + }); + + test("unselecting element sets aria attribute to false", function() { + new Selectable(ul, { aria: true }); + + ul.children().first().tap().tap({ ctrlKey: true }); + + equal(ul.children().first().attr("aria-selected"), "false"); + }); + + test("multiple selection unselecting element sets aria attribute to false", function() { + new Selectable(ul, { aria: true, multiple: true}); + + ul.children().first().tap().tap({ ctrlKey: true }); + + equal(ul.children().first().attr("aria-selected"), "false"); + }); + + test("select another element invalidates aria attribute", function() { + new Selectable(ul, { aria: true }); + + ul.children().first().tap(); + ul.children().eq(1).tap(); + + equal(ul.children().first().attr("aria-selected"), "false"); + equal(ul.children().eq(1).attr("aria-selected"), "true"); + }); + + test("moving over item sets aria attribute", function() { + var selectable = new Selectable(ul, { aria:true, multiple: true }); + var selectees = ul.find(">li"); + var position = selectees.eq(1).offset(); + + selectees.eq(0).tap().press().move(position.left, position.top).release(); + + equal(selectees.eq(0).attr("aria-selected"), "true"); + equal(selectees.eq(1).attr("aria-selected"), "true"); + }); +})(); diff --git a/tests/slider/clientsideapi.js b/tests/slider/clientsideapi.js new file mode 100644 index 00000000000..b03efa8f9de --- /dev/null +++ b/tests/slider/clientsideapi.js @@ -0,0 +1,473 @@ +(function(){ + +var Slider = kendo.ui.Slider; + +module("slider api", { + teardown: function() { + kendo.destroy(QUnit.fixture); + } +}); + +function newSlider(options, sliderInput) { + var input = $(sliderInput || "").appendTo(QUnit.fixture)[0]; + return new Slider(input, options); +} + +test("value should set slider value", function() { + var slider = newSlider(); + + slider.value(9); + + equal(slider.value(), 9); +}); + +test("value should not be null or empty string and should return old value", function() { + var slider = newSlider(); + + slider.value(2) + + slider.value(" "); + + equal(slider.value(), 2); + + slider.value(null); + + equal(slider.value(), 2); +}); + +test("value should be in range", function() { + var slider = newSlider(); + $.extend(slider.options, { showButtons: false }); + + slider.value(11); + + equal(slider.value(), 0); + + slider.value(-1); + + equal(slider.value(), 0); +}); + +test("value should update slider selectionDiv", function () { + var slider = newSlider(); + + var selectionDiv = slider.wrapper.find(".k-slider-selection"); + + slider.value(10); + + equal(selectionDiv.width(), 130); +}); + +test("value should be in range", function() { + var slider = newSlider(); + + var selectionDiv = slider.wrapper.find(".k-slider-selection"); + + slider.value(11); + + equal(selectionDiv.width(), 0); + + slider.value(-1); + + equal(selectionDiv.width(), 0); +}); + +test("when value is string slider should set slider value", function() { + var slider = newSlider(); + + slider.value("1"); + + equal(1, slider.value()); +}); + +test("value should not trigger change event", function() { + var result = true; + var change = function (e) { + result = false; + }; + + var slider = newSlider({ "change": change }); + + slider.value(5); + + ok(result); +}); + +test("slider init should not trigger change event", function() { + var result = true; + var change = function (e) { + result = false; + }; + + newSlider({ "change": change, min: 2 }); + + ok(result); +}); + +test("value should set value to the input", function() { + var slider = newSlider({ value: 1 }); + + var value = 2; + + slider.value(value); + + equal(slider.element.val(), value); +}); + +test("enabled with false should disable slider", function () { + var slider = newSlider({ enabled: false }); + + ok(slider.element.is("[disabled]")); + ok(!slider.options.enabled); + + equal(slider.wrapper.find(".k-draghandle").attr("tabindex"), -1); +}); + +test("disabled attribute should disable slider", function () { + var slider = newSlider({}, ""); + + ok(slider.element.is("[disabled]")); + ok(!slider.options.enabled); +}); + +test("enable method with false should disable slider", function () { + var slider = newSlider(); + + slider.disable(false); + + ok(slider.element.is("[disabled]")); + ok(!slider.options.enabled); +}); + +test("enable method with true should enable slider", function () { + var slider = newSlider(); + + slider.enable(true); + + ok(!slider.element.attr("disabled")); + ok(slider.options.enabled); + + equal(slider.wrapper.find(".k-draghandle").attr("tabindex"), 0); +}); + +test("disable method should disable slider", function () { + var slider = newSlider(); + + slider.disable(); + + ok(slider.element.is("[disabled]")); + ok(!slider.options.enabled); +}); + +test("enable method should enable slider", function () { + var slider = newSlider(); + + slider.enable(); + + ok(!slider.element.attr("disabled")); + ok(slider.options.enabled); +}); + +test("disable method should add state disabled to the slider", function () { + var slider = newSlider(); + + slider.disable(); + + ok(slider.wrapper.hasClass("k-state-disabled")); +}); + +test("enable method should remove state disabled from the slider", function () { + var slider = newSlider(); + + slider.enable(); + + ok(!slider.wrapper.hasClass("k-state-disabled")); +}); + +test("refresh method should not select minimum when slider increase his value from -1 to 0", function () { + var slider = newSlider({ showButtons: true, min: -5, value: -1 }); + + slider.value(0) + + ok(slider.value, 0); +}); + +test('slider should not trigger change if we decrease value with 1 step and value is equal to min value', function () { + var downArrow = kendo.keys.DOWN, + leftArrow = kendo.keys.LEFT, + result = true; + + var change = function (e) { + result = false; + }; + + var slider = newSlider({ "change": change, value: 0 }), + dragHandle = slider.wrapper.find(".k-draghandle").focus(); + + dragHandle.trigger({ type: "keydown", keyCode: downArrow }); + dragHandle.trigger({ type: "keydown", keyCode: leftArrow }); + + ok(result); +}); + +var slider; + +module("slider destroy", { + setup: function() { + slider = newSlider(); + slider.destroy(); + } +}); + +test("removes data", function() { + ok(!$("#slider").data("kendoSlider")); +}); + +test("unbinds events", function() { + ok(!(slider._events || {}).slide); +}); + +test("unbinds mousedown", function() { + ok(!($(".k-slider").data("events") || {}).mousedown); +}); + +// ------------------------------------------------------------ +var RangeSlider = kendo.ui.RangeSlider; + +module("rangeslider api", { + teardown: function() { + kendo.destroy(QUnit.fixture); + } +}); + +function newRangeSlider(options, sliderDiv) { + var div = $(sliderDiv || "
                                                                  ").appendTo(QUnit.fixture); + return new RangeSlider(div, options); +} + +test("values should set rangeSlider selectionStart and selectionEnd", function () { + var rangeSlider = newRangeSlider(), + values = [ 0, 9 ]; + + rangeSlider.values(values); + + deepEqual(rangeSlider.value(), values); +}); + +test("value should set rangeSlider selectionStart and selectionEnd", function () { + var rangeSlider = newRangeSlider(), + values = [ 0, 9 ]; + + rangeSlider.value(values); + + deepEqual(rangeSlider.value(), values); +}); + +test("values should return array of selectionStart and selectionEnd", function () { + var rangeSlider = newRangeSlider(), + values = [ 0, 9 ]; + + rangeSlider.values(values); + + ok(values instanceof Array); +}); + +test("values should not be null or empty string and should return old values", function () { + var selectionStart = 1, + selectionEnd = 3, + rangeSlider = newRangeSlider({ selectionStart: selectionStart, selectionEnd: selectionEnd }); + + rangeSlider.values(" "); + + deepEqual(rangeSlider.values(), [selectionStart, selectionEnd]); + + rangeSlider.values(null); + + deepEqual(rangeSlider.values(), [selectionStart, selectionEnd]); +}); + +test("values should be in range", function () { + var selectionStart = 1, + selectionEnd = 3, + rangeSlider = newRangeSlider({ selectionStart: selectionStart, selectionEnd: selectionEnd }); + + rangeSlider.values(-1, 11); + + deepEqual(rangeSlider.values(), [selectionStart, selectionEnd]); +}); + +test("values should set rangeSlider position selectionDiv", function () { + var rangeSlider = newRangeSlider(); + + var selectionDiv = rangeSlider.wrapper.find(".k-slider-selection"); + + rangeSlider.values(0, 10); + + equal(selectionDiv.width(), 198); +}); + +test("values should not trigger change event", function () { + var result = true; + var change = function (e) { + result = false; + }; + + var rangeSlider = newRangeSlider({ "change": change }); + + rangeSlider.values(1, 3); + ok(result); +}); + +test("init should not trigger change event", function () { + var result = true; + var change = function (e) { + result = false; + }; + + newRangeSlider({ "change": change, min: -1, max: 20 }); + ok(result); +}); + +test("values should set values to the inputs", function () { + var rangeSlider = newRangeSlider(), + selectionStart = 2, + selectionEnd = 5; + + rangeSlider.values(selectionStart, selectionEnd); + + var inputs = rangeSlider.element.find("input"); + + equal(inputs.eq(0).val(), selectionStart); + equal(inputs.eq(1).val(), selectionEnd); +}); + +test("values should set selectionStart and selectionEnd values from string parameters", function() { + var rangeSlider = newRangeSlider(); + + rangeSlider.values("1", "2"); + + deepEqual(rangeSlider.values(), [ 1, 2 ]); +}); + +test("values should set z-index to first handle", function() { + var rangeSlider = newRangeSlider(), + dragHandles = rangeSlider.wrapper.find(".k-draghandle"), + firstDragHandle = dragHandles.eq(0); + + rangeSlider.values(10, 10); + + equal(firstDragHandle.css("z-index"), 1); +}); + +test("enabled with false should disable range slider", function () { + var rangeSlider = newRangeSlider({ enabled: false }); + + ok(rangeSlider.element.find("input").is("[disabled]")); + ok(!rangeSlider.options.enabled); + + equal(rangeSlider.wrapper.find(".k-draghandle").eq(0).attr("tabindex"), -1); + equal(rangeSlider.wrapper.find(".k-draghandle").eq(1).attr("tabindex"), -1); +}); + +test("disabled attribute should disable range slider", function () { + var rangeSlider = newRangeSlider({}, "
                                                                  "); + + ok(rangeSlider.element.find("input").is("[disabled]")); + ok(!rangeSlider.options.enabled); +}); + +test("enable method with false should disable range slider", function () { + var rangeSlider = newRangeSlider(); + + rangeSlider.disable(false); + + ok(rangeSlider.element.find("input").is("[disabled]")); + ok(!rangeSlider.options.enabled); +}); + +test("enable method with true should enable range slider", function () { + var rangeSlider = newRangeSlider(); + + rangeSlider.enable(true); + + ok(!rangeSlider.element.find("input").attr("disabled")); + ok(rangeSlider.options.enabled); +}); + +test("disable method should disable range slider", function () { + var rangeSlider = newRangeSlider(); + + rangeSlider.disable(); + + ok(rangeSlider.element.find("input").is(":disabled")); + ok(!rangeSlider.options.enabled); +}); + +test("enable method should enable range slider", function () { + var rangeSlider = newRangeSlider(); + + rangeSlider.enable(); + + ok(!rangeSlider.wrapper.attr("disabled")); + ok(rangeSlider.options.enabled); +}); + +test("disable method should add state disabled to the range slider", function () { + var rangeSlider = newRangeSlider(); + + rangeSlider.disable(); + + ok(rangeSlider.wrapper.hasClass("k-state-disabled")); +}); + +test("enable method should remove state disabled from the range slider", function () { + var rangeSlider = newRangeSlider(); + + rangeSlider.enable(); + + ok(!rangeSlider.wrapper.hasClass("k-state-disabled")); + + equal(rangeSlider.wrapper.find(".k-draghandle").eq(0).attr("tabindex"), 0); + equal(rangeSlider.wrapper.find(".k-draghandle").eq(1).attr("tabindex"), 0); +}); + +test('range slider should not trigger change if we decrease selectionStart with 1 step and selectionStart is equal to min value', function () { + var downArrow = kendo.keys.down, + leftArrow = kendo.keys.left, + result = true; + + var change = function (e) { + result = false; + }; + + var rangeSlider = newRangeSlider({ change: change, selectionStart: 10, selectionEnd: 10 }), + dragHandles = rangeSlider.wrapper.find(".k-draghandle"); + + dragHandles.eq(0).trigger({ type: "keydown", keyCode: downArrow }); + dragHandles.eq(0).trigger({ type: "keydown", keyCode: leftArrow }); + + ok(result); +}); + +var rangeSider; + +module("rangeslider destroy", { + setup: function() { + rangeSider = newRangeSlider(); + rangeSider.destroy(); + } +}); + +test("removes data", function() { + ok(!$("#rangeslider").data("kendoRangeSlider")); +}); + +test("unbinds events", function() { + ok(!(rangeSider._events || {}).slide); +}); + +test("unbinds mousedown", function() { + ok(!($(".k-slider").data("events") || {}).mousedown); +}); + +}()); diff --git a/tests/slider/mvvm.js b/tests/slider/mvvm.js new file mode 100644 index 00000000000..dec7b5f156b --- /dev/null +++ b/tests/slider/mvvm.js @@ -0,0 +1,615 @@ +(function(){ + +var dom; + +module("slider mvvm", { + setup: function() { + window.change = function() { + ok(true); + }; + }, + teardown: function() { + kendo.destroy(dom); + delete window.change; + } +}); + +test("initializes a slider when data role is slider", function() { + dom = $(''); + + kendo.bind(dom); + + ok(dom.data("kendoSlider") instanceof kendo.ui.Slider); +}); + +test("initializes a options from data attributes", function() { + dom = $(''); + + kendo.bind(dom); + + var slider = dom.data("kendoSlider"); + + slider.value(80); + + equal(slider.options.max, 100); + equal(slider.value(), 80); +}); + +test("initializes value from view model", function() { + dom = $(''); + + kendo.bind(dom, { value: 10 } ); + + equal(dom.data("kendoSlider").value(), 10); +}); + +test("changing a value updates the view model", function() { + dom = $(''); + + var observable = kendo.observable({ value: null }); + + kendo.bind(dom, observable); + + dom.data("kendoSlider").value(10); + dom.data("kendoSlider").trigger("change"); + + equal(observable.value, 10); +}); + +test("binding slider initialized before binding", function() { + dom = $(''); + + var observable = kendo.observable({ value: null }); + observable.value = 10; + + dom.kendoSlider(); + + kendo.bind(dom, observable); + + equal(dom.data("kendoSlider").value(), 10); +}); + +test("binding slider initialized after binding", function() { + dom = $(''); + + var observable = kendo.observable({ value: null }); + observable.value = 10; + + kendo.bind(dom, observable); + + dom.kendoSlider(); + + equal(dom.data("kendoSlider").value(), 10); +}); + +test("updating model value updates the UI", function() { + dom = $(''); + + var observable = kendo.observable({ value: null }); + + kendo.bind(dom, observable); + + dom.kendoSlider(); + + observable.set("value", 10) + equal(dom.data("kendoSlider").value(), 10); +}); + +test("bindings are removed if element is rebind", 1, function() { + dom = $(''); + + var observable = kendo.observable({ value: 10 }); + + kendo.bind(dom, observable); + + var destroy = stub(dom[0].kendoBindingTarget, "destroy"); + + kendo.bind(dom, observable); + + equal(destroy.calls("destroy"), 1); +}); + +test("binding target is destroyed", 1, function() { + dom = $(''); + + var observable = kendo.observable({ value: null }); + + kendo.bind(dom, observable); + + var destroy = stub(dom[0].kendoBindingTarget, "destroy"); + + kendo.bind(dom, observable); + + equal(destroy.calls("destroy"), 1); +}); + +test("change event is raised if attached as option", 1, function() { + dom = $(''); + + var observable = kendo.observable({ + items: [{text:"foo"}, {text:"bar"}] + }); + + kendo.bind(dom, observable); + dom.data("kendoSlider").trigger("change"); +}); + +test("change event is raised if attached as option to a already initialized slider", 1, function() { + dom = $('').kendoSlider(); + + var observable = kendo.observable({ + items: [{text:"foo"}, {text:"bar"}] + }); + + kendo.bind(dom, observable); + dom.data("kendoSlider").trigger("change"); +}); + +test("binding enabled to false disables the widget", function() { + dom = $(''); + + var observable = kendo.observable({ + enabled: false + }); + + kendo.bind(dom, observable); + + ok(dom.is(":disabled")); +}); + +test("binding enabled to true enables the widget", function() { + dom = $(''); + + var observable = kendo.observable({ + enabled: true + }); + + kendo.bind(dom, observable); + + ok(!dom.is(":disabled")); +}); + +test("binding disable to true disables the widget", function() { + dom = $(''); + + var observable = kendo.observable({ + disabled: false + }); + + kendo.bind(dom, observable); + + ok(!dom.is(":disabled")); +}); + +test("binding disabled to false enables the widget", function() { + dom = $(''); + + var observable = kendo.observable({ + disabled: true + }); + + kendo.bind(dom, observable); + + ok(dom.is(":disabled")); +}); + +test("binding visible to false hides the widget", function() { + dom = $(''); + + var observable = kendo.observable({ + visible: false + }); + + kendo.bind(dom, observable); + + ok(dom.data("kendoSlider").wrapper.css("display") == "none", "Display is 'none'"); +}); + +test("binding visible to true shows the widget", function() { + dom = $(''); + + var observable = kendo.observable({ + visible: true + }); + + kendo.bind(dom, observable); + + ok(dom.data("kendoSlider").wrapper.css("display") != "none", "Display is not 'none'"); +}); + +test("changing visible to false hides the widget", function() { + dom = $(''); + + var observable = kendo.observable({ + visible: true + }); + + kendo.bind(dom, observable); + observable.set("visible", false); + + ok(dom.data("kendoSlider").wrapper.css("display") == "none", "Display is 'none'"); +}); + +test("changing visible to true shows the widget", function() { + dom = $(''); + + var observable = kendo.observable({ + visible: false + }); + + kendo.bind(dom, observable); + observable.set("visible", true); + + ok(dom.data("kendoSlider").wrapper.css("display") != "none", "Display is not 'none'"); +}); + +test("binding invisible to true hides the widget", function() { + dom = $(''); + + var observable = kendo.observable({ + invisible: true + }); + + kendo.bind(dom, observable); + + ok(dom.data("kendoSlider").wrapper.css("display") == "none", "display is 'none'"); +}); + +test("binding invisible to false shows the widget", function() { + dom = $(''); + + var observable = kendo.observable({ + invisible: false + }); + + kendo.bind(dom, observable); + + ok(dom.data("kendoSlider").wrapper.css("display") != "none", "display is not 'none'"); +}); + +test("changing invisible to true hides the widget", function() { + dom = $(''); + + var observable = kendo.observable({ + invisible: false + }); + + kendo.bind(dom, observable); + observable.set("invisible", true); + + ok(dom.data("kendoSlider").wrapper.css("display") == "none", "display is 'none'"); +}); + +test("changing invisible to false shows the widget", function() { + dom = $(''); + + var observable = kendo.observable({ + invisible: true + }); + + kendo.bind(dom, observable); + observable.set("invisible", false); + + ok(dom.data("kendoSlider").wrapper.css("display") != "none", "display is not 'none'"); +}); + +test("slider should have value 10", function() { + dom = $(''); + + kendo.bind(dom); + + ok(dom.data("kendoSlider").options.value == 10, "value is not equal to 10"); +}); + +module("rangeslider mvvm", { + setup: function() { + window.change = function() { + ok(true); + }; + }, + teardown: function() { + kendo.destroy(dom); + delete window.change; + } +}); + +test("initializes a rangeslider when data role is rangeslider", function() { + dom = $('
                                                                  '); + + kendo.bind(dom); + + ok(dom.data("kendoRangeSlider") instanceof kendo.ui.RangeSlider); +}); + +test("initializes a options from data attributes", function() { + dom = $('
                                                                  '); + + kendo.bind(dom); + + var rangeSlider = dom.data("kendoRangeSlider"); + + rangeSlider.value([40, 80]); + + equal(rangeSlider.options.max, 100); + deepEqual(rangeSlider.value(), [40, 80]); +}); + +test("initializes value from view model", function() { + dom = $('
                                                                  '); + + kendo.bind(dom, { value: [1, 2] } ); + + deepEqual(dom.data("kendoRangeSlider").value(), [1, 2]); +}); + +test("changing a value updates the view model", function() { + dom = $('
                                                                  '); + + var observable = kendo.observable({ value: [1, 1] }); + + kendo.bind(dom, observable); + + dom.data("kendoRangeSlider").value([1, 2]); + dom.data("kendoRangeSlider").trigger("change"); + + ok(observable.value[0], 1); + ok(observable.value[1], 2); +}); + +test("binding rangeslider initialized before binding", function() { + dom = $('
                                                                  '); + + var observable = kendo.observable({ value: null }); + observable.value = [1, 2]; + + dom.kendoRangeSlider(); + + kendo.bind(dom, observable); + + deepEqual(dom.data("kendoRangeSlider").value(), [1, 2]); +}); + +test("binding slider initialized after binding", function() { + dom = $('
                                                                  '); + + var observable = kendo.observable({ value: null }); + observable.value = [1, 2]; + + kendo.bind(dom, observable); + + dom.kendoRangeSlider(); + + deepEqual(dom.data("kendoRangeSlider").value(), [1, 2]); +}); + +test("updating model value updates the UI", function() { + dom = $('
                                                                  '); + + var observable = kendo.observable({ value: null }); + + kendo.bind(dom, observable); + + dom.kendoRangeSlider(); + + observable.set("value", [1, 3]) + deepEqual(dom.data("kendoRangeSlider").value(), [1, 3]); +}); + +test("bindings are removed if element is rebind", 1, function() { + dom = $('
                                                                  '); + + var observable = kendo.observable({ value: [1, 4] }); + + kendo.bind(dom, observable); + + var destroy = stub(dom[0].kendoBindingTarget, "destroy"); + + kendo.bind(dom, observable); + + equal(destroy.calls("destroy"), 1); +}); + +test("binding target is destroyed", 1, function() { + dom = $('
                                                                  '); + + var observable = kendo.observable({ value: null }); + + kendo.bind(dom, observable); + + var destroy = stub(dom[0].kendoBindingTarget, "destroy"); + + kendo.bind(dom, observable); + + equal(destroy.calls("destroy"), 1); +}); + +test("change event is raised if attached as option", 1, function() { + dom = $('
                                                                  '); + + var observable = kendo.observable({ + items: [{text:"foo"}, {text:"bar"}] + }); + + kendo.bind(dom, observable); + dom.data("kendoRangeSlider").trigger("change"); +}); + +test("change event is raised if attached as option to a already initialized slider", 1, function() { + dom = $('
                                                                  ').kendoRangeSlider(); + + var observable = kendo.observable({ + items: [{text:"foo"}, {text:"bar"}] + }); + + kendo.bind(dom, observable); + dom.data("kendoRangeSlider").trigger("change"); +}); + +test("binding enabled to false disables the widget", function() { + dom = $('
                                                                  '); + + var observable = kendo.observable({ + enabled: false + }); + + kendo.bind(dom, observable); + + ok($(dom.find("input")[0]).is(":disabled")); + ok($(dom.find("input")[1]).is(":disabled")); +}); + +test("binding enabled to true enables the widget", function() { + dom = $('
                                                                  '); + + var observable = kendo.observable({ + enabled: true + }); + + kendo.bind(dom, observable); + + ok(!$(dom.find("input")[0]).is(":disabled")); + ok(!$(dom.find("input")[1]).is(":disabled")); +}); + +test("binding disable to true disables the widget", function() { + dom = $('
                                                                  '); + + var observable = kendo.observable({ + disabled: false + }); + + kendo.bind(dom, observable); + + ok(!$(dom.find("input")[0]).is(":disabled")); + ok(!$(dom.find("input")[1]).is(":disabled")); +}); + +test("binding disabled to false enables the widget", function() { + dom = $('
                                                                  '); + + var observable = kendo.observable({ + disabled: true + }); + + kendo.bind(dom, observable); + + ok($(dom.find("input")[0]).is(":disabled")); + ok($(dom.find("input")[1]).is(":disabled")); +}); + +test("binding visible to false hides the widget", function() { + dom = $('
                                                                  '); + + var observable = kendo.observable({ + visible: false + }); + + kendo.bind(dom, observable); + + ok(dom.data("kendoRangeSlider").wrapper.css("display") == "none", "Display is 'none'"); +}); + +test("binding visible to true shows the widget", function() { + dom = $('
                                                                  '); + + var observable = kendo.observable({ + visible: true + }); + + kendo.bind(dom, observable); + + ok(dom.data("kendoRangeSlider").wrapper.css("display") != "none", "Display is not 'none'"); +}); + +test("changing visible to false hides the widget", function() { + dom = $('
                                                                  '); + + var observable = kendo.observable({ + visible: true + }); + + kendo.bind(dom, observable); + observable.set("visible", false); + + ok(dom.data("kendoRangeSlider").wrapper.css("display") == "none", "Display is 'none'"); +}); + +test("changing visible to true shows the widget", function() { + dom = $('
                                                                  '); + + var observable = kendo.observable({ + visible: false + }); + + kendo.bind(dom, observable); + observable.set("visible", true); + + ok(dom.data("kendoRangeSlider").wrapper.css("display") != "none", "Display is not 'none'"); +}); + +test("binding invisible to true hides the widget", function() { + dom = $('
                                                                  '); + + var observable = kendo.observable({ + invisible: true + }); + + kendo.bind(dom, observable); + + ok(dom.data("kendoRangeSlider").wrapper.css("display") == "none", "display is 'none'"); +}); + +test("binding invisible to false shows the widget", function() { + dom = $('
                                                                  '); + + var observable = kendo.observable({ + invisible: false + }); + + kendo.bind(dom, observable); + + ok(dom.data("kendoRangeSlider").wrapper.css("display") != "none", "display is not 'none'"); +}); + +test("changing invisible to true hides the widget", function() { + dom = $('
                                                                  '); + + var observable = kendo.observable({ + invisible: false + }); + + kendo.bind(dom, observable); + observable.set("invisible", true); + + ok(dom.data("kendoRangeSlider").wrapper.css("display") == "none", "display is 'none'"); +}); + +test("changing invisible to false shows the widget", function() { + dom = $('
                                                                  '); + + var observable = kendo.observable({ + invisible: true + }); + + kendo.bind(dom, observable); + observable.set("invisible", false); + + ok(dom.data("kendoRangeSlider").wrapper.css("display") != "none", "display is not 'none'"); +}); + +test("rangeslider should have selection start 10", function() { + dom = $('
                                                                  '); + + kendo.bind(dom); + + ok(dom.data("kendoRangeSlider").options.selectionStart == 10, "selectionStart is not equal to 10"); +}); + +test("rangeslider should have selection end 10", function() { + dom = $('
                                                                  '); + + kendo.bind(dom); + + ok(dom.data("kendoRangeSlider").options.selectionEnd == 10, "selectionEnd is not equal to 10"); +}); +}()); diff --git a/tests/slider/rangeslider.js b/tests/slider/rangeslider.js new file mode 100644 index 00000000000..13c311f8e9a --- /dev/null +++ b/tests/slider/rangeslider.js @@ -0,0 +1,319 @@ +(function(){ + +var RangeSlider = kendo.ui.RangeSlider; +var div = {}; +var isDefaultPrevent; + +module("rangeslider", { + setup: function () { + div = $("
                                                                  "); + isDefaultPrevent = false; + }, + teardown: function() { + kendo.destroy(QUnit.fixture); + } +}); + +function newRangeSlider(options, newDiv) { + return new RangeSlider((newDiv || div).appendTo(QUnit.fixture)[0], options); +} + +test('range slider should decrease value with a small step when down and left arrow keyboard is clicked', function () { + var downArrow = "40"; // down arrow + leftArrow = "37", // left arrow + rangeSlider = newRangeSlider({ tooltip: { enabled: false }, selectionStart: 3, selectionEnd: 6 }), + dragHandles = rangeSlider.wrapper.find(".k-draghandle"); + + //left drag handle + dragHandles.eq(0).focus().trigger({ type: "keydown", + keyCode: downArrow, + preventDefault: function () { + isDefaultPrevent = true; + } + }); + + ok(isDefaultPrevent); + deepEqual(rangeSlider.values(), [ 2, 6 ]); + + rangeSlider.values(3, 6); + isDefaultPrevent = false; + + dragHandles.eq(0).focus().trigger({ type: "keydown", + keyCode: leftArrow, + preventDefault: function () { + isDefaultPrevent = true; + } + }); + + ok(isDefaultPrevent); + deepEqual(rangeSlider.values(), [ 2, 6 ]); + + rangeSlider.values(3, 6); + + //right drag handle + isDefaultPrevent = false; + dragHandles.eq(1).focus().trigger({ type: "keydown", + keyCode: downArrow, + preventDefault: function () { + isDefaultPrevent = true; + } + }); + + ok(isDefaultPrevent); + deepEqual(rangeSlider.values(), [ 3, 5 ]); + + rangeSlider.values(3, 6); + isDefaultPrevent = false; + + dragHandles.eq(1).focus().trigger({ type: "keydown", + keyCode: leftArrow, + preventDefault: function () { + isDefaultPrevent = true; + } + }); + + ok(isDefaultPrevent); + deepEqual(rangeSlider.values(), [ 3, 5 ]); +}); + +test('range slider should increase value with a small step when down and left arrow keyboard is clicked', function () { + var upArrow = "38", // up arrow + rightArrow = "39", // right arrow + rangeSlider = newRangeSlider({ tooltip: { enabled: false }, selectionStart: 3, selectionEnd: 6 }), + dragHandles = rangeSlider.wrapper.find(".k-draghandle"); + + // left drag handle + dragHandles.eq(0).focus().trigger({ type: "keydown", + keyCode: upArrow, + preventDefault: function () { + isDefaultPrevent = true; + } + }); + + ok(isDefaultPrevent); + deepEqual(rangeSlider.values(), [ 4, 6 ]); + + rangeSlider.values(3, 6); + isDefaultPrevent = false; + + dragHandles.eq(0).focus().trigger({ type: "keydown", + keyCode: rightArrow, + preventDefault: function () { + isDefaultPrevent = true; + } + }); + + ok(isDefaultPrevent); + deepEqual(rangeSlider.values(), [ 4, 6 ]); + + rangeSlider.values(3, 6); + + // right drag handle + isDefaultPrevent = false; + dragHandles.eq(1).focus().trigger({ type: "keydown", + keyCode: upArrow, + preventDefault: function () { + isDefaultPrevent = true; + } + }); + + ok(isDefaultPrevent); + deepEqual(rangeSlider.values(), [ 3, 7 ]); + + rangeSlider.values(3, 6); + isDefaultPrevent = false; + + dragHandles.eq(1).focus().trigger({ type: "keydown", + keyCode: rightArrow, + preventDefault: function () { + isDefaultPrevent = true; + } + }); + + ok(isDefaultPrevent); + deepEqual(rangeSlider.values(), [ 3, 7 ]); +}); + +test('range slider should increase value with a large step when page up keyboard is clicked', function () { + var pageUp = "33", // page up + rangeSlider = newRangeSlider({ tooltip: { enabled: false }, selectionStart: 3, selectionEnd: 6, largeStep: 3 }), + dragHandles = rangeSlider.wrapper.find(".k-draghandle"); + + // left drag handle + dragHandles.eq(0).focus().trigger({ type: "keydown", + keyCode: pageUp, + preventDefault: function () { + isDefaultPrevent = true; + } + }); + + ok(isDefaultPrevent); + deepEqual(rangeSlider.values(), [ 6, 6 ]); + + rangeSlider.values(3, 6); + + // right drag handle + isDefaultPrevent = false; + dragHandles.eq(1).focus().trigger({ type: "keydown", + keyCode: pageUp, + preventDefault: function () { + isDefaultPrevent = true; + } + }); + + ok(isDefaultPrevent); + deepEqual(rangeSlider.values(), [ 3, 9 ]); +}); + +test('range slider should decrease value with a large step when page down keyboard is clicked', function () { + var pageDown = "34", // page down + rangeSlider = newRangeSlider({ tooltip: { enabled: false }, selectionStart: 3, selectionEnd: 6, largeStep: 3 }), + dragHandles = rangeSlider.wrapper.find(".k-draghandle"); + + //left drag handle + dragHandles.eq(0).focus().trigger({ type: "keydown", + keyCode: pageDown, + preventDefault: function () { + isDefaultPrevent = true; + } + }); + + ok(isDefaultPrevent); + deepEqual(rangeSlider.values(), [ 0, 6 ]); + + rangeSlider.values(3, 6); + + //right drag handle + isDefaultPrevent = false; + dragHandles.eq(1).focus().trigger({ type: "keydown", + keyCode: pageDown, + preventDefault: function () { + isDefaultPrevent = true; + } + }); + + ok(isDefaultPrevent); + deepEqual(rangeSlider.values(), [ 3, 3 ]); +}); + +test('range slider should increase value to maximum value when end keyboard is clicked', function () { + var end = "35", // end + rangeSlider = newRangeSlider({ tooltip: { enabled: false }, selectionStart: 3, selectionEnd: 6 }), + dragHandles = rangeSlider.wrapper.find(".k-draghandle"); + + // left drag hangle + dragHandles.eq(0).focus().trigger({ type: "keydown", + keyCode: end, + preventDefault: function () { + isDefaultPrevent = true; + } + }); + + ok(isDefaultPrevent); + deepEqual(rangeSlider.values(), [ 10, 10 ]); + + rangeSlider.values(6, 6); + + //right drag handle + isDefaultPrevent = false; + dragHandles.eq(1).focus().trigger({ type: "keydown", + keyCode: end, + preventDefault: function () { + isDefaultPrevent = true; + } + }); + + ok(isDefaultPrevent); + deepEqual(rangeSlider.values(), [ 6, 10 ]); +}); + +test('range slider should decrease value to minimum value when home keyboard is clicked', function () { + var home = "36", // home + rangeSlider = newRangeSlider({ tooltip: { enabled: false }, selectionStart: 3, selectionEnd: 6 }), + dragHandles = rangeSlider.wrapper.find(".k-draghandle"); + + //left drag handle + dragHandles.eq(0).focus().trigger({ type: "keydown", + keyCode: home, + preventDefault: function () { + isDefaultPrevent = true; + } + }); + + ok(isDefaultPrevent); + deepEqual(rangeSlider.values(), [ 0, 6 ]); + + rangeSlider.values(3, 6); + + //right drag handle + dragHandles.eq(1).focus().trigger({ type: "keydown", + keyCode: home, + preventDefault: function () { + isDefaultPrevent = true; + } + }); + + ok(isDefaultPrevent); + deepEqual(rangeSlider.values(), [ 0, 0 ]); +}); + +test("rangeSlider should get values from the inputs", function () { + var rangeSlider = newRangeSlider(); + + equal(rangeSlider.options.selectionStart, 1); + equal(rangeSlider.options.selectionEnd, 5); +}); + +test("rangeSlider should get step from the input", function () { + var rangeSlider = newRangeSlider({}, $("
                                                                  ")); + + equal(rangeSlider.options.smallStep, 2); +}); + +test("rangeSlider should get min from the input", function () { + var rangeSlider = newRangeSlider({}, $("
                                                                  ")); + + equal(rangeSlider.options.min, 4); +}); + +test("rangeSlider should get max from the input", function () { + var rangeSlider = newRangeSlider({}, $("
                                                                  ")); + + equal(rangeSlider.options.max, 5); +}); + +test("rangeSlider should set default value to the inputs", function () { + var rangeSlider = newRangeSlider({}, $("
                                                                  ")), + inputs = rangeSlider.element.find("input"); + + equal(inputs.eq(0).val(), 0); + equal(inputs.eq(1).val(), 10); +}); + +test("rangeSlider should not have default values", function () { + var rangeSlider = newRangeSlider({ min: -2, max: 40 }, $("
                                                                  ")), + inputs = rangeSlider.element.find("input"); + + equal(inputs.eq(0).val(), -2); + equal(inputs.eq(1).val(), 40); +}); + +test("rangeSlider should get values from the inputs", function () { + var rangeSlider = newRangeSlider({ min: -2, max: 40 }, $("
                                                                  ")), + inputs = rangeSlider.element.find("input"); + + equal(inputs.eq(0).val(), 0); + equal(inputs.eq(1).val(), 0); +}); + +test("rangeSlider resize should resize", function () { + var rangeSlider = newRangeSlider({ min: -2, max: 40 }, $("
                                                                  ")); + + var initialWidth = rangeSlider._trackDiv.width(); + rangeSlider.wrapper.width(400); + rangeSlider.resize(); + var currentWidth = rangeSlider._trackDiv.width(); + ok(initialWidth != currentWidth); +}); + +}()); diff --git a/tests/slider/rendering.js b/tests/slider/rendering.js new file mode 100644 index 00000000000..f368a92ec2f --- /dev/null +++ b/tests/slider/rendering.js @@ -0,0 +1,59 @@ +(function(){ + +var Slider = kendo.ui.Slider; +var input; + +module("slider rendering", { + setup: function () { + input = $(""); + }, + teardown: function() { + kendo.destroy(QUnit.fixture); + } +}); + +function newSlider(options) { + options = $.extend({}, { tooltip: {enabled:false}}, options); + return new Slider(input.appendTo(QUnit.fixture)[0], options); +} + +test("horizontal slider should apply max value", function () { + var slider = newSlider({ value: 10 }), + trackDivWidth = slider.wrapper.find(".k-slider-track").width(), + selectionDivWidth = slider.wrapper.find(".k-slider-selection").width(); + + equal(trackDivWidth, selectionDivWidth); +}); + +test("height slider should apply max value", function () { + var slider = newSlider({ value: 10, orientation: "vertical" }), + trackDivHeight = slider.wrapper.find(".k-slider-track").height(), + selectionDivHeight = slider.wrapper.find(".k-slider-selection").height(); + + equal(trackDivHeight, selectionDivHeight); +}); + +test("slider should apply style", function () { + var style = "width: 200px; height: 30px;", + slider = newSlider({ value: 10, style: style }); + + equal("200px", slider.wrapper.css("width")); + equal("30px", slider.wrapper.css("height")); +}); + +test("slider should apply option value to the input", function() { + var value = 10, + slider = newSlider({ value: value }); + + equal(slider.element.val(), value); +}); + +test("getValueFromPosition should increase value", function () { + var slider = newSlider({ value: 1, smallStep: 2 }), + dragableArea = slider._getDraggableArea(), + step = 2 * (144 / 10); + + equal(slider._getValueFromPosition(dragableArea.startPoint + step, dragableArea), 2); +}); + +}()); diff --git a/tests/slider/slider.js b/tests/slider/slider.js new file mode 100644 index 00000000000..010049c87f0 --- /dev/null +++ b/tests/slider/slider.js @@ -0,0 +1,287 @@ +var Slider = kendo.ui.Slider; +var input; +var isDefaultPrevent; + +module("slider", { + setup: function () { + input = $(""); + isDefaultPrevent = false; + }, + teardown: function() { + kendo.destroy(QUnit.fixture) + } +}); + +function newSlider(options, newInput) { + options = $.extend({}, { tooltip: { enabled: false } }, options); + + return new Slider((newInput || input).appendTo(QUnit.fixture)[0], options); +} + +test('slider should decrease value with a small step when down and left arrow keyboard is clicked', function () { + var downArrow = "40", // down arrow + leftArrow = "37", // left arrow + slider = newSlider({ value: 5, smallStep: 2 }), + dragHandle = slider.wrapper.find(".k-draghandle"); + + dragHandle.focus().trigger({ type: "keydown", + keyCode: downArrow, + preventDefault: function () { + isDefaultPrevent = true; + } + }); + + ok(isDefaultPrevent); + equal(3, slider.value()); + + slider.value(5); + + dragHandle.focus().trigger({ type: "keydown", + keyCode: leftArrow, + preventDefault: function () { + isDefaultPrevent = true; + } + }); + + ok(isDefaultPrevent); + equal(3, slider.value()); + + slider.value(5); +}); + +test('slider should increase value with a small step when down and left arrow keyboard is clicked', function () { + var upArrow = "38"; // up arrow + rightArrow = "39", // right arrow + slider = newSlider({ value: 5, smallStep: 2 }), + dragHandle = slider.wrapper.find(".k-draghandle"); + + dragHandle.focus().trigger({ type: "keydown", + keyCode: upArrow, + preventDefault: function () { + isDefaultPrevent = true; + } + }); + + ok(isDefaultPrevent); + equal(7, slider.value()); + + slider.value(5); + + dragHandle.focus().trigger({ type: "keydown", + keyCode: rightArrow, + preventDefault: function () { + isDefaultPrevent = true; + } + }); + + ok(isDefaultPrevent); + equal(7, slider.value()); + + slider.value(5); +}); + +test('slider should increase value with a large step when page up keyboard is clicked', function () { + var end = "33", // page up + slider = newSlider({ value: 5, largeStep: 3 }), + dragHandle = slider.wrapper.find(".k-draghandle"); + + dragHandle.focus().trigger({ type: "keydown", + keyCode: end, + preventDefault: function () { + isDefaultPrevent = true; + } + }); + + ok(isDefaultPrevent); + equal(8, slider.value()); + + slider.value(5); +}); + +test('slider should decrease value with a large step when page down keyboard is clicked', function () { + var home = "34", // page down + slider = newSlider({ value: 5, largeStep: 3 }), + dragHandle = slider.wrapper.find(".k-draghandle"); + + dragHandle.focus().trigger({ type: "keydown", + keyCode: home, + preventDefault: function () { + isDefaultPrevent = true; + } + }); + + ok(isDefaultPrevent); + equal(2, slider.value()); + + slider.value(5); +}); + +test('slider should increase value to maximum value when end keyboard is clicked', function () { + var end = "35", // end + slider = newSlider({ value: 5 }), + dragHandle = slider.wrapper.find(".k-draghandle"); + + dragHandle.focus().trigger({ type: "keydown", + keyCode: end, + preventDefault: function () { + isDefaultPrevent = true; + } + }); + + ok(isDefaultPrevent); + equal(10, slider.value()); + + slider.value(5); +}); + +test('slider should increase value to minimum value when home keyboard is clicked', function () { + var home = "36", // home + slider = newSlider({ value: 5 }), + dragHandle = slider.wrapper.find(".k-draghandle"); + + dragHandle.focus().trigger({ type: "keydown", + keyCode: home, + preventDefault: function () { + isDefaultPrevent = true; + } + }); + + ok(isDefaultPrevent); + equal(0, slider.value()); + + slider.value(5); +}); + +test('getValueFromPosition with small step 3 and mouse position 100 should return max value', function () { + var slider = newSlider({ value: 0, smallStep: 3, style: "width: 156px;" }), + mousePosition = 100, + dragableArea = { startPoint: 0, endPoint: slider._maxSelection }, + value = slider._getValueFromPosition(mousePosition, dragableArea); + + equal(value, 10); +}); + +test('getValueFromPosition with small step 2 and mouse position 78 should return 8', function () { + var slider = newSlider({ value: 0, smallStep: 2, style: "width: 156px;" }), + mousePosition = 78, + dragableArea = { startPoint: 0, endPoint: slider._maxSelection }, + value = slider._getValueFromPosition(mousePosition, dragableArea); + + equal(value, 8); +}); + +test('getValueFromPosition with small step 3 and mouse position 80 should return 9', function () { + var slider = newSlider({ value: 0, smallStep: 3, style: "width: 156px;" }), + mousePosition = 80, + dragableArea = { startPoint: 0, endPoint: slider._maxSelection }, + value = slider._getValueFromPosition(mousePosition, dragableArea); + + equal(value, 9); +}); + +test('getValueFromPosition with small step 2 and mouse position 60 should return 3', function () { + var slider = newSlider({ value: 0, smallStep: 2, style: "width: 156px;" }), + mousePosition = 60, + dragableArea = { startPoint: 0, endPoint: slider._maxSelection }, + value = slider._getValueFromPosition(mousePosition, dragableArea); + + equal(value, 6); +}); + +test('getValueFromPosition with small step 2 and mouse position 95 should return 10', function () { + var slider = newSlider({ value: 0, smallStep: 2, style: "width: 156px;" }), + mousePosition = 95, + dragableArea = { startPoint: 0, endPoint: slider._maxSelection }, + value = slider._getValueFromPosition(mousePosition, dragableArea); + + equal(value, 10); +}); + +test('getValueFromPosition with small step 2 and mouse position 9 should return 0', function () { + var slider = newSlider({ value: 0, smallStep: 2, style: "width: 156px;" }), + mousePosition = 9, + dragableArea = { startPoint: 0, endPoint: slider._maxSelection }, + value = slider._getValueFromPosition(mousePosition, dragableArea); + + equal(value, 0); +}); + +test('getValueFromPosition with small step 0.1 mouse position 39 should return 0.4', function () { + var slider = newSlider({ value: 0, smallStep: 0.1, max: 1, style: "width: 156px;" }), + mousePosition = 39, + dragableArea = { startPoint: 0, endPoint: slider._maxSelection }, + value = slider._getValueFromPosition(mousePosition, dragableArea); + + equal(value, 0.4); +}); + +test('getValueFromPosition with small step 0.1 mouse position 30 should return 0.3', function () { + var slider = newSlider({ value: 0, smallStep: 0.1, max: 1, style: "width: 156px;" }), + mousePosition = 30, + dragableArea = { startPoint: 0, endPoint: slider._maxSelection }, + value = slider._getValueFromPosition(mousePosition, dragableArea); + + equal(value, 0.3); +}); + +test('getValueFromPosition with small step 0.1 mouse position 48 should return 0.5', function () { + var slider = newSlider({ value: 0, smallStep: 0.1, max: 1, style: "width: 156px;" }), + mousePosition = 48, + dragableArea = { startPoint: 0, endPoint: slider._maxSelection }, + value = slider._getValueFromPosition(mousePosition, dragableArea); + + equal(value, 0.5); +}); + +test("slider should get value from the input", function () { + var slider = newSlider(); + + equal(slider.value(), 1); +}); + +test("slider should get step from the input", function () { + var slider = newSlider({}, $("")); + + equal(slider.options.smallStep, 2); +}); + +test("slider should get min from the input", function () { + var slider = newSlider({}, $("")); + + equal(slider.options.min, 4); +}); + +test("slider should get max from the input", function () { + var slider = newSlider({}, $("")); + + equal(slider.options.max, 5); +}); + +test("slider should have default input value", function () { + var slider = newSlider({}, $("")); + + equal(slider.element.val(), 0); +}); + +test("slider should not have default value", function () { + var slider = newSlider({ min: -20 }, $("")); + + equal(slider.element.val(), -20); +}); + +test("slider should have get value from the input", function () { + var slider = newSlider({ min: -20 }, $("")); + + equal(slider.element.val(), 0); +}); + +test("slider resize should resize", function () { + var slider = newSlider({}, $("")); + + var initialWidth = slider._trackDiv.width(); + slider.wrapper.width(400); + slider.resize(); + var currentWidth = slider._trackDiv.width(); + ok(initialWidth != currentWidth); +}); + diff --git a/tests/sortable/sortable.js b/tests/sortable/sortable.js new file mode 100644 index 00000000000..65a03f93e83 --- /dev/null +++ b/tests/sortable/sortable.js @@ -0,0 +1,226 @@ +(function() { + var DataSource = kendo.data.DataSource, + Sortable = kendo.ui.Sortable, + button, + dataSource; + + function setup(element, options) { + return new Sortable(element || button.attr("data-field", "foo"), options || { dataSource: dataSource }); + } + + module("kendo.ui.Sortable", { + setup: function() { + dataSource = DataSource.create( { data: [ { foo: 2, bar: 2 }, { foo: 1, bar: 1 } ] } ); + button = $("