diff --git a/.jshintrc b/.jshintrc index 28a5891..29b6850 100644 --- a/.jshintrc +++ b/.jshintrc @@ -16,9 +16,9 @@ "trailing": true, "white": false, "indent": 2, - "quotmark": "single", + "quotmark": "double", - "maxparams": 3, + "maxparams": 5, "maxdepth": 3, "maxcomplexity": 10 } diff --git a/example/input-datetime-local.html b/example/input-datetime-local.html new file mode 100644 index 0000000..b2b19c4 --- /dev/null +++ b/example/input-datetime-local.html @@ -0,0 +1,51 @@ + + + + + Examples of polyformfill for input[type=datetime-local] + + + + + + + +
+ +

+ + +

+ +

+ + +

+ +

+ + +

+ +

+ + +

+ +

+ + +

+ +

+ + +

+ +

+ +

+
+ + + diff --git a/example/style.css b/example/style.css index fd79402..fa9dd4d 100644 --- a/example/style.css +++ b/example/style.css @@ -4,6 +4,11 @@ input[type=datetime-local], input[type=time] { font-family: monospace; } + +input[type=datetime-local] { + width: 15em; +} + input:invalid { border-color: red; } diff --git a/example/test.js b/example/test.js index b1367e5..054c670 100644 --- a/example/test.js +++ b/example/test.js @@ -1,15 +1,15 @@ -void function (window, document) { - 'use strict'; +(function (window, document) { + "use strict"; - if (document.readyState === 'interactive' || document.readyState === 'complete') { + if ("interactive" === document.readyState || "complete" === document.readyState) { init(); } else { - document.addEventListener('DOMContentLoaded', init); + document.addEventListener("DOMContentLoaded", init); } function init() { - var input = document.getElementsByTagName('INPUT'); + var input = document.getElementsByTagName("INPUT"); for (var i = 0; i < input.length; i++) { console.log( @@ -19,40 +19,40 @@ void function (window, document) { ); } - document.getElementById('example-date-1-button').addEventListener('click', updateExampleDate1); + document.getElementById("example-date-1-button").addEventListener("click", updateExampleDate1); - document.getElementById('example-date-4').addEventListener('input', function() { - document.getElementById('example-date-4-output').value = this.value; + document.getElementById("example-date-4").addEventListener("input", function() { + document.getElementById("example-date-4-output").value = this.value; }); - document.getElementById('example-date-4-output').value = document.getElementById('example-date-4').value; + document.getElementById("example-date-4-output").value = document.getElementById("example-date-4").value; } function updateExampleDate1() { - var input = document.getElementById('example-date-1'); + var input = document.getElementById("example-date-1"); input.focus(); - input.dispatchEvent(window.crossBrowser_initKeyboardEvent('keydown', { key: 'Right', bubbles: true })); - input.dispatchEvent(window.crossBrowser_initKeyboardEvent('keydown', { key: 'Up', bubbles: true })); + input.dispatchEvent(window.crossBrowser_initKeyboardEvent("keydown", { key: "Right", bubbles: true })); + input.dispatchEvent(window.crossBrowser_initKeyboardEvent("keydown", { key: "Up", bubbles: true })); } - /*window.addEventListener('blur', function(e) { + /*window.addEventListener("blur", function(e) { console.log(e); }); - window.addEventListener('focus', function(e) { + window.addEventListener("focus", function(e) { console.log(e); }); - window.addEventListener('focusin', function(e) { + window.addEventListener("focusin", function(e) { console.log(e); }); - window.addEventListener('keydown', function(e) { + window.addEventListener("keydown", function(e) { console.log(e); }); - window.addEventListener('keypress', function(e) { + window.addEventListener("keypress", function(e) { console.log(e); });*/ -}(window, document); +}(window, document)); diff --git a/gulpfile.js b/gulpfile.js index 42eaa44..f4cb1e2 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,23 +1,23 @@ -'use strict'; +"use strict"; /* global require */ -var gulp = require('gulp'), - concat = require('gulp-concat'), - preprocess = require('gulp-preprocess'), - rename = require('gulp-rename'), - replace = require('gulp-replace'), - sourcemaps = require('gulp-sourcemaps'), - uglify = require('gulp-uglify'); +var gulp = require("gulp"), + concat = require("gulp-concat"), + preprocess = require("gulp-preprocess"), + rename = require("gulp-rename"), + replace = require("gulp-replace"), + sourcemaps = require("gulp-sourcemaps"), + uglify = require("gulp-uglify"); -gulp.task('default', function () { +gulp.task("default", function () { // place code for your default task here }); -gulp.task('compress', function () { - gulp.src(['src/polyformfill.js.prefix', 'src/**/base.js', 'src/**/*.js', 'src/polyformfill.js.suffix']) - .pipe(concat('polyformfill.js')) - .pipe(replace("'use strict';", '')) +gulp.task("compress", function () { + gulp.src(["src/polyformfill.js.prefix", "src/**/!(init).js", "src/init.js", "src/polyformfill.js.suffix"]) + .pipe(concat("polyformfill.js")) + .pipe(replace('"use strict";', "")) .pipe(preprocess({ context: { FEATURES: { @@ -37,13 +37,33 @@ gulp.task('compress', function () { semicolons: false, width: 120 }, - compress: false, - preserveComments: 'some' + compress: { + sequences : false, // join consecutive statements with the “comma operator” + properties : false, // optimize property access: a["foo"] → a.foo + dead_code : true, // discard unreachable code + drop_debugger : true, // discard “debugger” statements + unsafe : false, // some unsafe optimizations (see below) + conditionals : false, // optimize if-s and conditional expressions + comparisons : false, // optimize comparisons + evaluate : false, // evaluate constant expressions + booleans : false, // optimize boolean expressions + loops : false, // optimize loops + unused : true, // drop unused variables/functions + hoist_funs : true, // hoist function declarations + hoist_vars : true, // hoist variable declarations + if_return : false, // optimize if-s followed by return/continue + join_vars : true, // join var declarations + cascade : false, // try to cascade `right` into `left` in sequences + side_effects : false, // drop side-effect-free statements + warnings : true, // warn about potentially dangerous optimizations/code + global_defs : {} // global definitions + }, + preserveComments: "some" })) - .pipe(gulp.dest('./')) + .pipe(gulp.dest("./")) .pipe(sourcemaps.init()) .pipe(uglify()) - .pipe(rename('polyformfill.min.js')) - .pipe(sourcemaps.write('./')) - .pipe(gulp.dest('./')); + .pipe(rename("polyformfill.min.js")) + .pipe(sourcemaps.write("./")) + .pipe(gulp.dest("./")); }); diff --git a/karma.conf-ci.js b/karma.conf-ci.js index a5d2ab1..c63775b 100644 --- a/karma.conf-ci.js +++ b/karma.conf-ci.js @@ -1,4 +1,4 @@ -'use strict'; +"use strict"; /* global module, require, process */ @@ -7,87 +7,86 @@ * Karma configuration for Travis. */ -var fs = require('fs'); +var fs = require("fs"); module.exports = function(config) { // Use ENV vars on Travis and sauce.json locally to get credentials if (!process.env.SAUCE_USERNAME) { - if (!fs.existsSync('sauce.json')) { - console.log('Create a sauce.json with your credentials based on the sauce-sample.json file.'); + if (!fs.existsSync("sauce.json")) { + console.log("Create a sauce.json with your credentials based on the sauce-sample.json file."); process.exit(1); } else { - process.env.SAUCE_USERNAME = require('./sauce').username; - process.env.SAUCE_ACCESS_KEY = require('./sauce').accessKey; + process.env.SAUCE_USERNAME = require("./sauce").username; + process.env.SAUCE_ACCESS_KEY = require("./sauce").accessKey; } } // Browsers to run on Sauce Labs var customLaunchers = { sl_chrome: { - base: 'SauceLabs', - browserName: 'chrome', - version: '39', + base: "SauceLabs", + browserName: "chrome", + version: "39", // Sweden uses ISO 8601 for date and time representation. And while chrome localizes date input elements using // the browser language this makes testing easier. chromeOptions: { - args: ['--lang=sv-SE'] + args: ["--lang=sv-SE"] }, - platform: 'Windows 7' + platform: "Windows 7" }, sl_firefox: { - base: 'SauceLabs', - browserName: 'firefox', - version: '33' + base: "SauceLabs", + browserName: "firefox", + version: "33" }, sl_ie_9: { - base: 'SauceLabs', - browserName: 'internet explorer', - version: '9' + base: "SauceLabs", + browserName: "internet explorer", + version: "9" }, sl_ie_10: { - base: 'SauceLabs', - browserName: 'internet explorer', - version: '10' + base: "SauceLabs", + browserName: "internet explorer", + version: "10" }, sl_ie_11: { - base: 'SauceLabs', - browserName: 'internet explorer', - version: '11' + base: "SauceLabs", + browserName: "internet explorer", + version: "11" } }; config.set({ // base path that will be used to resolve all patterns (eg. files, exclude) - basePath: '', + basePath: "", // frameworks to use // available frameworks: https://npmjs.org/browse/keyword/karma-adapter - frameworks: ['jasmine'], + frameworks: ["jasmine"], // list of files / patterns to load in the browser files: [ - 'test/helpers/*.js', - 'src/**/!(base).js', - 'src/*/base.js', - 'src/base.js', - 'test/**/*.js', + "test/helpers/*.js", + "src/**/!(init).js", + "src/init.js", + "test/**/*.js", - {pattern: 'test/popup.html', watched: true, served: true, included: false} + {pattern: "test/popup.html", watched: true, served: true, included: false} ], // test results reporter to use - // possible values: 'dots', 'progress' + // possible values: "dots", "progress" // available reporters: https://npmjs.org/browse/keyword/karma-reporter - reporters: ['dots', 'saucelabs', 'coverage', 'coveralls'], + reporters: ["dots", "saucelabs", "coverage", "coveralls"], coverageReporter: { - type: 'lcov', - dir: 'coverage/' + type: "lcov", + dir: "coverage/" }, // web server port @@ -100,7 +99,8 @@ module.exports = function(config) { logLevel: config.LOG_INFO, sauceLabs: { - testName: 'polyformfill' + testName: "polyformfill", + takeScreenshots: false }, captureTimeout: 120000, customLaunchers: customLaunchers, diff --git a/karma.conf.js b/karma.conf.js index ca4bc32..6ffb822 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -1,4 +1,4 @@ -'use strict'; +"use strict"; /* global module */ @@ -11,23 +11,22 @@ module.exports = function(config) { config.set({ // base path that will be used to resolve all patterns (eg. files, exclude) - basePath: '', + basePath: "", // frameworks to use // available frameworks: https://npmjs.org/browse/keyword/karma-adapter - frameworks: ['jasmine'], + frameworks: ["jasmine"], // list of files / patterns to load in the browser files: [ - 'test/helpers/*.js', - 'src/**/!(base).js', - 'src/*/base.js', - 'src/base.js', - 'test/**/*.js', + "test/helpers/*.js", + "src/**/!(init).js", + "src/init.js", + "test/**/*.js", - {pattern: 'test/popup.html', watched: true, served: true, included: false} + {pattern: "test/popup.html", watched: true, served: true, included: false} ], @@ -39,18 +38,18 @@ module.exports = function(config) { // preprocess matching files before serving them to the browser // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor preprocessors: { - 'src/**/*.js': ['coverage'] + "src/**/*.js": ["coverage"] }, // test results reporter to use - // possible values: 'dots', 'progress' + // possible values: "dots", "progress" // available reporters: https://npmjs.org/browse/keyword/karma-reporter - reporters: ['progress', 'coverage'], + reporters: ["progress", "coverage"], coverageReporter: { - type : 'lcov', - dir : 'coverage/' + type : "lcov", + dir : "coverage/" }, // web server port @@ -73,27 +72,27 @@ module.exports = function(config) { // start these browsers // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher browsers: [ - 'Chrome_lang_svSE', - 'Firefox', - 'IE', - 'IE10', - 'IE9' + "Chrome_lang_svSE", + "Firefox", + "IE", + "IE10", + "IE9" ], customLaunchers: { Chrome_lang_svSE: { - base: 'Chrome', + base: "Chrome", // Sweden uses ISO 8601 for date and time representation. And while chrome localizes date input elements using // the browser language this makes testing easier. - flags: ['--lang=sv-SE'] + flags: ["--lang=sv-SE"] }, IE10: { - base: 'IE', - 'x-ua-compatible': 'IE=EmulateIE10' + base: "IE", + "x-ua-compatible": "IE=EmulateIE10" }, IE9: { - base: 'IE', - 'x-ua-compatible': 'IE=EmulateIE9' + base: "IE", + "x-ua-compatible": "IE=EmulateIE9" } }, diff --git a/package.json b/package.json index 388b483..f526561 100644 --- a/package.json +++ b/package.json @@ -24,16 +24,16 @@ "gulp-preprocess": "^1.2.0", "gulp-rename": "^1.2.0", "gulp-replace": "^0.5.0", - "gulp-sourcemaps": "^1.2.8", + "gulp-sourcemaps": "^1.3.0", "gulp-uglify": "^1.0.2", "jasmine-core": "^2.1.3", - "karma": "^0.12.28", + "karma": "^0.12.31", "karma-chrome-launcher": "^0.1.7", "karma-coverage": "^0.2.7", "karma-coveralls": "^0.1.4", - "karma-firefox-launcher": "^0.1.3", + "karma-firefox-launcher": "^0.1.4", "karma-ie-launcher": "^0.1.5", - "karma-jasmine": "^0.3.2", + "karma-jasmine": "^0.3.3", "karma-sauce-launcher": "^0.2.10" } } diff --git a/polyformfill.js b/polyformfill.js index 78d6f00..787ff17 100644 --- a/polyformfill.js +++ b/polyformfill.js @@ -1,263 +1,21 @@ -(function(window, document, undefined) { +!function(window, document, undefined) { "use strict"; - var INPUT_ATTR_TYPE = "type"; function init() { var testInput = document.createElement("input"); - if (!("valueAsDate" in testInput)) { + if (!(INPUT_PROPERTY_VALUEASDATE in testInput)) { initInput(testInput); initInputDate(); + initInputDatetimeLocal(); initInputTime(); } } - init(); - function initInput(testInput) { - initInputDom(testInput); - initInputAccessibility(); - initInputNormalization(); - } - var DATECOMPONENT_YEAR = 1, DATECOMPONENT_MONTH = 2, DATECOMPONENT_DAY = 4; - var INPUT_DATE_YEAR_EMPTY = 0, INPUT_DATE_MONTH_EMPTY = -1, INPUT_DATE_DAY_EMPTY = 0; - var INPUT_DATE_YEAR_MIN = 1, INPUT_DATE_YEAR_MAX = 275760; - var INPUT_DATE_MONTH_MIN = 0, INPUT_DATE_MONTH_MAX = 11; - var INPUT_DATE_DAY_MIN = 1, INPUT_DATE_DAY_MAX = 31; - var rfc3999FullDateRegExp = /^([0-9]{4,})-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/; - var inputDateValueFormatter; - var inputDateFormatOrderGetter; - var inputDateFormatSeparatorGetter; - function initInputDate() { - inputDateValueFormatter = inputDateFuzzyRfc3339ValueFormatter; - inputDateFormatOrderGetter = inputDateRfc3339FormatOrder; - inputDateFormatSeparatorGetter = inputDateRfc3339FormatSeparator; - initInputDateLocalization(); - } - function inputDateComponentsSet(input, year, month, day) { - var formattedValue; - input.__polyformfillInputDate = { - year: year, - month: month, - day: day - }; - formattedValue = inputDateValueFormatter(input, year, month, day); - inputDomOriginalValueSetter.call(input, formattedValue); - return formattedValue; - } - function inputDateComponentsGet(input) { - if (input.__polyformfillInputDate === undefined) { - inputDateInitInternalValue(input); - } - return input.__polyformfillInputDate; - } - function inputDateFuzzyRfc3339ValueFormatter(input, year, month, day) { - if (year === INPUT_DATE_YEAR_EMPTY) { - year = "yyyy"; - } else { - if (year <= 9999) { - year = ("000" + year).slice(-4); - } - } - if (month === INPUT_DATE_MONTH_EMPTY) { - month = "mm"; - } else { - month = ("00" + (month + 1)).slice(-2); - } - if (day === INPUT_DATE_DAY_EMPTY) { - day = "dd"; - } else { - day = ("00" + day).slice(-2); - } - return year + "-" + month + "-" + day; - } - function inputDateRfc3339FormatOrder() { - return [ DATECOMPONENT_YEAR, DATECOMPONENT_MONTH, DATECOMPONENT_DAY ]; - } - function inputDateRfc3339FormatSeparator() { - return [ "-" ]; - } - function getDateFromRfc3339FullDateString(str) { - var date, dateComponents; - if (str && rfc3999FullDateRegExp.test(str)) { - dateComponents = str.split("-"); - if (dateComponents.join("") < 2757600914) { - date = new Date(0); - date.setUTCFullYear(dateComponents[0], dateComponents[1] - 1, dateComponents[2]); - if (date.getUTCMonth() != dateComponents[1] - 1 || date.getUTCDate() != dateComponents[2]) { - return null; - } - return date; - } - } - return null; - } - function inputDateInitInternalValue(input) { - var value = input.getAttribute("value"), date; - if (value !== "") { - date = getDateFromRfc3339FullDateString(value); - } - if (date) { - input.__polyformfillInputDate = { - year: date.getUTCFullYear(), - month: date.getUTCMonth(), - day: date.getUTCDate() - }; - } else { - input.__polyformfillInputDate = { - year: INPUT_DATE_YEAR_EMPTY, - month: INPUT_DATE_MONTH_EMPTY, - day: INPUT_DATE_DAY_EMPTY - }; - } - } - function inputDateGetRfc3339(input) { - var date = inputDateGetDate(input), value; - if (date) { - value = date.toISOString().replace("+0", "").replace("+", ""); - value = value.substr(0, value.indexOf("T")); - } else { - value = ""; - } - return value; - } - function inputDateGetDate(input) { - var dateComponents = inputDateComponentsGet(input), date = null; - if (dateComponents.year !== INPUT_DATE_YEAR_EMPTY && dateComponents.month !== INPUT_DATE_MONTH_EMPTY && dateComponents.day !== INPUT_DATE_DAY_EMPTY) { - date = new Date(0); - date.setUTCFullYear(dateComponents.year, dateComponents.month, dateComponents.day); - } - return date; - } - var INPUT_TIME_COMPONENT_HOUR = 1, INPUT_TIME_COMPONENT_MINUTE = 2, INPUT_TIME_COMPONENT_SECOND = 4, INPUT_TIME_COMPONENT_MILISECOND = 8; - var INPUT_TIME_COMPONENT_EMPTY = -1; - var INPUT_TIME_COMPONENT_HIDDEN = -2; - var INPUT_TIME_COMPONENT_HOUR_MIN = 0; - var INPUT_TIME_COMPONENT_HOUR_MAX = 23; - var INPUT_TIME_COMPONENT_MINUTE_MIN = 0; - var INPUT_TIME_COMPONENT_MINUTE_MAX = 59; - var INPUT_TIME_COMPONENT_SECOND_MIN = 0; - var INPUT_TIME_COMPONENT_SECOND_MAX = 59; - var INPUT_TIME_COMPONENT_MILISECOND_MIN = 0; - var INPUT_TIME_COMPONENT_MILISECOND_MAX = 999; - var inputTimeValidTimeStringRegExp = /^(([0-1][0-9])|(2[0-3])):[0-5][0-9](:[0-5][0-9](\.[0-9]{1,3})?)?$/; - var inputTimeValueFormatter; - var inputTimeFormatOrderGetter; - var inputTimeFormatSeparatorGetter; - function initInputTime() { - inputTimeValueFormatter = inputTimeDefaultValueFormatter; - inputTimeFormatOrderGetter = inputTimeDefaultFormatOrder; - inputTimeFormatSeparatorGetter = inputTimeDefaultFormatSeparator; - } - function inputTimeComponentsGet(input) { - if (input.__polyformfillInputTime === undefined) { - inputTimeInitInternalValue(input); - } - return input.__polyformfillInputTime; - } - function inputTimeComponentsSet(input, hour, minute, second, milisecond) { - var formattedValue; - input.__polyformfillInputTime = { - hour: hour, - minute: minute, - second: second, - milisecond: milisecond - }; - formattedValue = inputTimeValueFormatter(input, hour, minute, second, milisecond); - inputDomOriginalValueSetter.call(input, formattedValue); - return formattedValue; - } - function inputTimeInitInternalValue(input) { - var value = input.getAttribute("value"), components; - if (value !== "") { - components = inputTimeValidTimeStringToComponents(value); - } - if (components) { - input.__polyformfillInputTime = components; - } else { - input.__polyformfillInputTime = { - hour: INPUT_TIME_COMPONENT_EMPTY, - minute: INPUT_TIME_COMPONENT_EMPTY, - second: INPUT_TIME_COMPONENT_HIDDEN, - milisecond: INPUT_TIME_COMPONENT_HIDDEN - }; - } - } - function inputTimeValidTimeStringToComponents(str) { - var components; - if (str && inputTimeValidTimeStringRegExp.test(str)) { - components = str.split(/[:.]/); - if (components[2] === undefined) { - components[2] = INPUT_TIME_COMPONENT_HIDDEN; - } - if (components[3] === undefined) { - components[3] = INPUT_TIME_COMPONENT_HIDDEN; - } else { - components[3] = (components[3] + "000").slice(0, 3); - } - return { - hour: parseInt(components[0], 10), - minute: parseInt(components[1], 10), - second: parseInt(components[2], 10), - milisecond: parseInt(components[3], 10) - }; - } - return null; - } - function inputTimeGetRfc3339(element) { - var components = inputTimeComponentsGet(element); - if (components.hour > INPUT_TIME_COMPONENT_EMPTY && components.minute > INPUT_TIME_COMPONENT_EMPTY) { - if (components.second === INPUT_TIME_COMPONENT_EMPTY) { - components.second = INPUT_TIME_COMPONENT_HIDDEN; - } - if (components.milisecond === INPUT_TIME_COMPONENT_EMPTY) { - components.milisecond = INPUT_TIME_COMPONENT_HIDDEN; - } - return inputTimeDefaultValueFormatter(element, components.hour, components.minute, components.second, components.milisecond); - } else { - return ""; - } - } - function inputTimeDefaultValueFormatter(input, hour, minute, second, milisecond) { - var formatted; - if (hour === INPUT_TIME_COMPONENT_EMPTY) { - formatted = "--"; - } else { - formatted = ("00" + hour).slice(-2); - } - formatted += ":"; - if (minute === INPUT_TIME_COMPONENT_EMPTY) { - formatted += "--"; - } else { - formatted += ("00" + minute).slice(-2); - } - if (second !== INPUT_TIME_COMPONENT_HIDDEN) { - formatted += ":"; - if (second === INPUT_TIME_COMPONENT_EMPTY) { - formatted += "--"; - } else { - formatted += ("00" + second).slice(-2); - } - if (milisecond !== INPUT_TIME_COMPONENT_HIDDEN) { - formatted += "."; - if (milisecond === INPUT_TIME_COMPONENT_EMPTY) { - formatted += "---"; - } else { - formatted += ("000" + milisecond).slice(-3); - } - } - } - return formatted; - } - function inputTimeDefaultFormatOrder() { - return [ INPUT_TIME_COMPONENT_HOUR, INPUT_TIME_COMPONENT_MINUTE, INPUT_TIME_COMPONENT_SECOND, INPUT_TIME_COMPONENT_MILISECOND ]; - } - function inputTimeDefaultFormatSeparator() { - return [ ":", "." ]; - } - function initInputAccessibility() { - window.addEventListener("keydown", inputAccessibilityOnKeydownHandleNavigation); - window.addEventListener("keypress", inputAccessibilityOnKeyPressHandleUserInput); - window.addEventListener("focus", inputAccessibilityOnFocusHandleInputSelection, true); - window.addEventListener("focusin", inputAccessibilityOnFocusHandleInputSelection); - window.addEventListener("click", inputAccessibilityOnFocusHandleInputSelection); - window.addEventListener("blur", inputAccessibilityOnBlurHandleInputNormalization, true); + function initInputAccessibility(addEventListener) { + addEventListener("keydown", inputAccessibilityOnKeydownHandleNavigation); + addEventListener("keypress", inputAccessibilityOnKeyPressHandleUserInput); + addEventListener("focus", inputAccessibilityOnFocusHandleInputSelection, true); + addEventListener("focusin", inputAccessibilityOnFocusHandleInputSelection); + addEventListener("click", inputAccessibilityOnFocusHandleInputSelection); + addEventListener("blur", inputAccessibilityOnBlurHandleInputNormalization, true); } function inputAccessibilityOnKeydownHandleNavigation(event) { if (event.defaultPrevented) { @@ -268,16 +26,16 @@ } if (event.target instanceof HTMLInputElement) { switch (event.target.getAttribute(INPUT_ATTR_TYPE)) { - case "date": + case INPUT_TYPE_DATE: inputDateAccessibilityOnKeydownHandleNavigation(event.target, event); break; - case "time": - inputTimeAccessibilityOnKeydownHandleNavigation(event.target, event); + case INPUT_TYPE_DATETIME_LOCAL: + inputDatetimeLocalAccessibilityOnKeydownHandleNavigation(event.target, event); break; - default: - break; + case INPUT_TYPE_TIME: + inputTimeAccessibilityOnKeydownHandleNavigation(event.target, event); } } } @@ -290,48 +48,48 @@ } if (event.target instanceof HTMLInputElement) { switch (event.target.getAttribute(INPUT_ATTR_TYPE)) { - case "date": + case INPUT_TYPE_DATE: inputDateAccessibilityOnKeyPressHandleUserInput(event.target, event); break; - case "time": - inputTimeAccessibilityOnKeyPressHandleUserInput(event.target, event); + case INPUT_TYPE_DATETIME_LOCAL: + inputDatetimeLocalAccessibilityOnKeyPressHandleUserInput(event.target, event); break; - default: - break; + case INPUT_TYPE_TIME: + inputTimeAccessibilityOnKeyPressHandleUserInput(event.target, event); } } } function inputAccessibilityOnFocusHandleInputSelection(event) { if (event.target instanceof HTMLInputElement) { switch (event.target.getAttribute(INPUT_ATTR_TYPE)) { - case "date": + case INPUT_TYPE_DATE: inputDateAccessibilityOnFocusHandleInputSelection(event.target, event); break; - case "time": - inputTimeAccessibilityOnFocusHandleInputSelection(event.target, event); + case INPUT_TYPE_DATETIME_LOCAL: + inputDatetimeLocalAccessibilityOnFocusHandleInputSelection(event.target, event); break; - default: - break; + case INPUT_TYPE_TIME: + inputTimeAccessibilityOnFocusHandleInputSelection(event.target, event); } } } function inputAccessibilityOnBlurHandleInputNormalization(event) { if (event.target instanceof HTMLInputElement) { switch (event.target.getAttribute(INPUT_ATTR_TYPE)) { - case "date": + case INPUT_TYPE_DATE: inputDateAccessibilityOnBlurHandleInputNormalization(event.target); break; - case "time": - inputTimeAccessibilityOnBlurHandleInputNormalization(event.target); + case INPUT_TYPE_DATETIME_LOCAL: + inputDatetimeLocalAccessibilityOnBlurHandleInputNormalization(event.target); break; - default: - break; + case INPUT_TYPE_TIME: + inputTimeAccessibilityOnBlurHandleInputNormalization(event.target); } } } @@ -349,11 +107,11 @@ function inputAccessibilityComplementComponent(value, addition, min, max, limit) { if (value > limit) { value = parseInt(addition, 10); - if (min === 0) { + if (0 === min) { value -= 1; } } else { - if (min === 0) { + if (0 === min) { value = parseInt("" + (value + 1) + addition, 10) - 1; } else { value = parseInt("" + value + addition, 10); @@ -365,7 +123,7 @@ return value; } function inputAccessibilityPreviousSeparator(value, position, componentSeparators) { - var previous = 0, test, i, componentSeparatorsCount = componentSeparators.length; + var test, i, previous = 0, componentSeparatorsCount = componentSeparators.length; for (i = 0; i < componentSeparatorsCount; i++) { test = value.lastIndexOf(componentSeparators[i], position - 1) + 1; if (test > previous) { @@ -375,7 +133,7 @@ return previous; } function inputAccessibilityNextSeparator(value, position, componentSeparators) { - var next = value.length, test, i, componentSeparatorsCount = componentSeparators.length; + var test, i, next = value.length, componentSeparatorsCount = componentSeparators.length; for (i = 0; i < componentSeparatorsCount; i++) { test = value.indexOf(componentSeparators[i], position); if (test < next && test !== -1) { @@ -391,11 +149,11 @@ function inputAccessibilityGetPreviousComponentRange(value, position, componentSeparators) { var start, end; end = inputAccessibilityPreviousSeparator(value, position, componentSeparators); - if (end === 0) { + if (0 === end) { start = end; end = inputAccessibilityNextSeparator(value, position, componentSeparators); } else { - end = end - 1; + end -= 1; start = inputAccessibilityPreviousSeparator(value, end, componentSeparators); } return [ start, end ]; @@ -407,51 +165,105 @@ end = start; start = inputAccessibilityPreviousSeparator(value, position, componentSeparators); } else { - start = start + 1; + start += 1; end = inputAccessibilityNextSeparator(value, start, componentSeparators); } return [ start, end ]; } function inputAccessibilityGetSelectedComponentNumber(value, position, componentSeparators) { - var number = 0, test, i, componentSeparatorsCount = componentSeparators.length; - while (position > 0) { - test = -1; - for (i = 0; i < componentSeparatorsCount; i++) { - test = Math.max(test, value.lastIndexOf(componentSeparators[i], position)); - } - position = test - 1; - if (position > -2) { + var number = 0; + while (0 < position) { + position = inputAccessibilityPreviousSeparator(value, position, componentSeparators) - 1; + if (0 < position) { number++; } } return number; } - var inputDomOriginalTypeGetter, inputDomOriginalValueGetter, inputDomOriginalValueSetter, inputDomOriginalValueAsNumberGetter, inputDomOriginalValueAsNumberSetter, inputDomOriginalStepUp, inputDomOriginalStepDown; + function inputAccessibilityGetSelectedComponent(value, selectionStart, componentOrder, componentSeparator) { + return componentOrder[inputAccessibilityGetSelectedComponentNumber(value, selectionStart, componentSeparator)]; + } + function initInput(testInput) { + initInputDom(testInput); + initInputAccessibility(window.addEventListener); + initInputNormalization(window.addEventListener); + } + function inputComponentGetMinimum(element, selectedComponent) { + if (element.hasAttribute("min")) {} + switch (selectedComponent) { + case INPUT_COMPONENT_YEAR: + return INPUT_DATE_YEAR_MIN; + + case INPUT_COMPONENT_MONTH: + return INPUT_DATE_MONTH_MIN; + + case INPUT_COMPONENT_DAY: + return INPUT_DATE_DAY_MIN; + + case INPUT_COMPONENT_HOUR: + return INPUT_TIME_COMPONENT_HOUR_MIN; + + case INPUT_COMPONENT_MINUTE: + return INPUT_TIME_COMPONENT_MINUTE_MIN; + + case INPUT_COMPONENT_SECOND: + return INPUT_TIME_COMPONENT_SECOND_MIN; + + case INPUT_COMPONENT_MILISECOND: + return INPUT_TIME_COMPONENT_MILISECOND_MIN; + } + } + function inputComponentGetMaximum(element, selectedComponent) { + if (element.hasAttribute("max")) {} + switch (selectedComponent) { + case INPUT_COMPONENT_YEAR: + return INPUT_DATE_YEAR_MAX; + + case INPUT_COMPONENT_MONTH: + return INPUT_DATE_MONTH_MAX; + + case INPUT_COMPONENT_DAY: + return INPUT_DATE_DAY_MAX; + + case INPUT_COMPONENT_HOUR: + return INPUT_TIME_COMPONENT_HOUR_MAX; + + case INPUT_COMPONENT_MINUTE: + return INPUT_TIME_COMPONENT_MINUTE_MAX; + + case INPUT_COMPONENT_SECOND: + return INPUT_TIME_COMPONENT_SECOND_MAX; + + case INPUT_COMPONENT_MILISECOND: + return INPUT_TIME_COMPONENT_MILISECOND_MAX; + } + } function initInputDom(testInput) { - var descriptor; + var descriptor, HTMLInputElementPrototype; if (HTMLInputElement && Object.isExtensible(HTMLInputElement.prototype)) { - descriptor = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "type"); + HTMLInputElementPrototype = HTMLInputElement.prototype; + descriptor = Object.getOwnPropertyDescriptor(HTMLInputElementPrototype, INPUT_ATTR_TYPE); if (descriptor === undefined) { - descriptor = Object.getOwnPropertyDescriptor(testInput, "type"); + descriptor = Object.getOwnPropertyDescriptor(testInput, INPUT_ATTR_TYPE); } inputDomOriginalTypeGetter = descriptor.get; if (descriptor.configurable) { - Object.defineProperty(HTMLInputElement.prototype, "type", { + Object.defineProperty(HTMLInputElementPrototype, INPUT_ATTR_TYPE, { get: inputDomTypeGet }); } - descriptor = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value"); + descriptor = Object.getOwnPropertyDescriptor(HTMLInputElementPrototype, INPUT_PROPERTY_VALUE); if (descriptor.configurable) { - Object.defineProperty(HTMLInputElement.prototype, "value", { + Object.defineProperty(HTMLInputElementPrototype, INPUT_PROPERTY_VALUE, { get: inputDomValueGet, set: inputDomValueSet }); inputDomOriginalValueGetter = descriptor.get; inputDomOriginalValueSetter = descriptor.set; } - descriptor = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "valueAsNumber"); + descriptor = Object.getOwnPropertyDescriptor(HTMLInputElementPrototype, INPUT_PROPERTY_VALUEASNUMBER); if (descriptor === undefined || descriptor.configurable) { - Object.defineProperty(HTMLInputElement.prototype, "valueAsNumber", { + Object.defineProperty(HTMLInputElementPrototype, INPUT_PROPERTY_VALUEASNUMBER, { get: inputDomValueAsNumberGet, set: inputDomValueAsNumberSet }); @@ -460,14 +272,15 @@ inputDomOriginalValueAsNumberSetter = descriptor.set; } } - Object.defineProperty(HTMLInputElement.prototype, "valueAsDate", { + Object.defineProperty(HTMLInputElementPrototype, INPUT_PROPERTY_VALUEASDATE, { get: inputDomValueAsDateGet, set: inputDomValueAsDateSet }); - inputDomOriginalStepUp = HTMLInputElement.prototype.stepUp; - HTMLInputElement.prototype.stepUp = inputDomStepUp; - inputDomOriginalStepDown = HTMLInputElement.prototype.stepDown; - HTMLInputElement.prototype.stepDown = inputDomStepDown; + inputDomOriginalStepUp = HTMLInputElementPrototype.stepUp; + HTMLInputElementPrototype.stepUp = inputDomStepUp; + inputDomOriginalStepDown = HTMLInputElementPrototype.stepDown; + HTMLInputElementPrototype.stepDown = inputDomStepDown; + inputDomOriginalSetSelectionRange = HTMLInputElementPrototype.setSelectionRange; } } function inputDomException(code, message) { @@ -475,11 +288,12 @@ } function inputDomTypeGet() { var attr, type = inputDomOriginalTypeGetter.call(this); - if (type === "text") { + if (INPUT_TYPE_TEXT === type) { attr = this.getAttribute(INPUT_ATTR_TYPE); switch (attr) { - case "date": - case "time": + case INPUT_TYPE_DATE: + case INPUT_TYPE_DATETIME_LOCAL: + case INPUT_TYPE_TIME: return attr; default: @@ -489,12 +303,14 @@ return type; } function inputDomValueGet() { - var inputType = this.getAttribute(INPUT_ATTR_TYPE); - switch (inputType) { - case "date": + switch (this.getAttribute(INPUT_ATTR_TYPE)) { + case INPUT_TYPE_DATE: return inputDateDomValueGet(this); - case "time": + case INPUT_TYPE_DATETIME_LOCAL: + return inputDatetimeLocalDomValueGet(this); + + case INPUT_TYPE_TIME: return inputTimeDomValueGet(this); default: @@ -502,12 +318,14 @@ } } function inputDomValueSet(value) { - var inputType = this.getAttribute(INPUT_ATTR_TYPE); - switch (inputType) { - case "date": + switch (this.getAttribute(INPUT_ATTR_TYPE)) { + case INPUT_TYPE_DATE: return inputDateDomValueSet(this, value); - case "time": + case INPUT_TYPE_DATETIME_LOCAL: + return inputDatetimeLocalDomValueSet(this, value); + + case INPUT_TYPE_TIME: return inputTimeDomValueSet(this, value); default: @@ -515,17 +333,17 @@ } } function inputDomValueAsNumberGet() { - var inputType = this.getAttribute(INPUT_ATTR_TYPE); - switch (inputType) { - case "date": - case "time": + switch (this.getAttribute(INPUT_ATTR_TYPE)) { + case INPUT_TYPE_DATE: + case INPUT_TYPE_DATETIME_LOCAL: + case INPUT_TYPE_TIME: return inputDomValueAsNumberGetFromDate.call(this); default: if (inputDomOriginalValueAsNumberGetter) { return inputDomOriginalValueAsNumberGetter.call(this); } - return NaN; + return 0/0; } } function inputDomValueAsNumberGetFromDate() { @@ -533,19 +351,18 @@ if (date) { return date.getTime(); } - return NaN; + return 0/0; } function inputDomValueAsNumberSet(value) { - var inputType = this.getAttribute(INPUT_ATTR_TYPE); - switch (inputType) { - case "date": - case "time": + switch (this.getAttribute(INPUT_ATTR_TYPE)) { + case INPUT_TYPE_DATE: + case INPUT_TYPE_DATETIME_LOCAL: + case INPUT_TYPE_TIME: inputDomValueAsNumberSetFromDate.call(this, value); break; default: inputDomOriginalValueSetter.call(this); - break; } } function inputDomValueAsNumberSetFromDate(value) { @@ -555,12 +372,14 @@ } } function inputDomValueAsDateGet() { - var inputType = this.getAttribute(INPUT_ATTR_TYPE); - switch (inputType) { - case "date": + switch (this.getAttribute(INPUT_ATTR_TYPE)) { + case INPUT_TYPE_DATE: return inputDateDomValueAsDateGet(this); - case "time": + case INPUT_TYPE_DATETIME_LOCAL: + return inputDatetimeLocalDomValueAsDateGet(this); + + case INPUT_TYPE_TIME: return inputTimeDomValueAsDateGet(this); default: @@ -568,13 +387,15 @@ } } function inputDomValueAsDateSet(value) { - var inputType = this.getAttribute(INPUT_ATTR_TYPE); if (value instanceof Date) {} - switch (inputType) { - case "date": + switch (this.getAttribute(INPUT_ATTR_TYPE)) { + case INPUT_TYPE_DATE: return inputDateDomValueAsDateSet(this, value); - case "time": + case INPUT_TYPE_DATETIME_LOCAL: + return inputDatetimeLocalDomValueAsDateSet(this, value); + + case INPUT_TYPE_TIME: return inputTimeDomValueAsDateSet(this, value); default: @@ -582,13 +403,15 @@ } } function inputDomStepUp(n) { - var inputType = this.getAttribute(INPUT_ATTR_TYPE); n = n || 1; - switch (inputType) { - case "date": + switch (this.getAttribute(INPUT_ATTR_TYPE)) { + case INPUT_TYPE_DATE: return inputDomStepUpOrDown(this, n, INPUT_DATE_STEP_DEFAULT, INPUT_DATE_STEP_SCALE_FACTOR); - case "time": + case INPUT_TYPE_DATETIME_LOCAL: + return inputDomStepUpOrDown(this, n, INPUT_TIME_STEP_DEFAULT, INPUT_TIME_STEP_SCALE_FACTOR); + + case INPUT_TYPE_TIME: return inputDomStepUpOrDown(this, n, INPUT_TIME_STEP_DEFAULT, INPUT_TIME_STEP_SCALE_FACTOR); default: @@ -596,13 +419,15 @@ } } function inputDomStepDown(n) { - var inputType = this.getAttribute(INPUT_ATTR_TYPE); n = n || 1; - switch (inputType) { - case "date": + switch (this.getAttribute(INPUT_ATTR_TYPE)) { + case INPUT_TYPE_DATE: return inputDomStepUpOrDown(this, -n, INPUT_DATE_STEP_DEFAULT, INPUT_DATE_STEP_SCALE_FACTOR); - case "time": + case INPUT_TYPE_DATETIME_LOCAL: + return inputDomStepUpOrDown(this, -n, INPUT_TIME_STEP_DEFAULT, INPUT_TIME_STEP_SCALE_FACTOR); + + case INPUT_TYPE_TIME: return inputDomStepUpOrDown(this, -n, INPUT_TIME_STEP_DEFAULT, INPUT_TIME_STEP_SCALE_FACTOR); default: @@ -610,10 +435,9 @@ } } function inputDomStepUpOrDown(element, n, defaultStep, stepScaleFactor) { - var allowedValueStep, delta, value; - allowedValueStep = inputDomGetAllowedValueStep(element, defaultStep, stepScaleFactor); - if (allowedValueStep === null) { - throw inputDomException(DOMException.INVALID_STATE_ERR); + var delta, value, allowedValueStep = inputDomGetAllowedValueStep(element, defaultStep, stepScaleFactor); + if (null === allowedValueStep) { + throw inputDomException(DOMEXCEPTION_INVALID_STATE_ERR); } value = element.valueAsNumber; delta = allowedValueStep * n; @@ -624,11 +448,11 @@ var step; if (element.hasAttribute("step")) { step = element.getAttribute("step"); - if (step === "any") { + if ("any" === step) { return null; } step = parseInt(step, 10); - if (step < 1) { + if (1 > step) { step = defaultStep; } } else { @@ -636,41 +460,41 @@ } return step * stepScaleFactor; } - function initInputNormalization() { - window.addEventListener("submit", inputNormalizationOnSubmitNormalizeInput); - window.addEventListener("load", inputNormalizationOnLoadFormatInputElements); + function initInputNormalization(addEventListener) { + addEventListener("load", inputNormalizationOnLoadFormatInputElements); + addEventListener("submit", inputNormalizationOnSubmitNormalizeInput); } function inputNormalizationOnLoadFormatInputElements(event) { - var elements = event.target.getElementsByTagName("INPUT"), i; + var i, elements = event.target.getElementsByTagName("INPUT"); for (i = 0; i < elements.length; i++) { switch (elements[i].getAttribute(INPUT_ATTR_TYPE)) { - case "date": - inputDateNormalizationOnLoadFormatInputDateElements(elements[i]); + case INPUT_TYPE_DATE: + inputDateNormalizationOnLoadFormatInputElements(elements[i]); break; - case "time": - inputTimeNormalizationOnLoadFormatInputElements(elements[i]); + case INPUT_TYPE_DATETIME_LOCAL: + inputDatetimeLocalNormalizationOnLoadFormatInputElements(elements[i]); break; - default: - break; + case INPUT_TYPE_TIME: + inputTimeNormalizationOnLoadFormatInputElements(elements[i]); } } } function inputNormalizationOnSubmitNormalizeInput(event) { - var elements = event.target.elements, i; + var i, elements = event.target.elements; for (i = 0; i < elements.length; i++) { switch (elements[i].getAttribute(INPUT_ATTR_TYPE)) { - case "date": - inputDateNormalizationOnSubmitNormalizeDateInput(elements[i]); + case INPUT_TYPE_DATE: + inputDateNormalizationOnSubmitNormalizeInput(elements[i]); break; - case "time": - inputTimeNormalizationOnSubmitNormalizeInput(elements[i]); + case INPUT_TYPE_DATETIME_LOCAL: + inputDatetimeLocalNormalizationOnSubmitNormalizeInput(elements[i]); break; - default: - break; + case INPUT_TYPE_TIME: + inputTimeNormalizationOnSubmitNormalizeInput(elements[i]); } } } @@ -680,46 +504,30 @@ case "Backspace": case "U+0008": case "Del": - inputDateClearDateComponent(element, selectionStart); + inputDateAccessibilityClearComponent(element, selectionStart); break; case "Tab": case "U+0009": - inputDateAccessibilityNormalizeSelectedComponent(element, selectionStart); - if (event.altKey || event.ctrlKey || event.metaKey) { - return; - } - if (event.shiftKey) { - if (inputAccessibilityGetSelectedComponentNumber(inputDomOriginalValueGetter.call(element), selectionStart, inputDateFormatSeparatorGetter(element)) !== 0) { - inputDateAccessibilitySelectPreviousDateComponent(element, selectionStart); - } else { - return; - } - } else { - if (inputAccessibilityGetSelectedComponentNumber(inputDomOriginalValueGetter.call(element), selectionStart, inputDateFormatSeparatorGetter(element)) !== 2) { - inputDateAccessibilitySelectNextDateComponent(element, selectionStart); - } else { - return; - } - } - break; + inputDateAccessibilityOnTabKeydownHandleNavigation(element, event, selectionStart); + return; case "Left": inputDateAccessibilityNormalizeSelectedComponent(element, selectionStart); - inputDateAccessibilitySelectPreviousDateComponent(element, selectionStart); + inputDateAccessibilitySelectPreviousComponent(element, selectionStart); break; case "Up": - inputDateAccessibilityIncreaseDateComponent(element, selectionStart, 1); + inputDateAccessibilityIncreaseComponent(element, selectionStart, 1); break; case "Right": inputDateAccessibilityNormalizeSelectedComponent(element, selectionStart); - inputDateAccessibilitySelectNextDateComponent(element, selectionStart); + inputDateAccessibilitySelectNextComponent(element, selectionStart); break; case "Down": - inputDateAccessibilityIncreaseDateComponent(element, selectionStart, -1); + inputDateAccessibilityIncreaseComponent(element, selectionStart, -1); break; default: @@ -727,39 +535,44 @@ } event.preventDefault(); } - function inputDateAccessibilityOnKeyPressHandleUserInput(element, event) { - if (event.charCode > 47 && event.charCode < 58) { - var selectionStart = element.selectionStart; - var selectNext = false; - var value = inputDomOriginalValueGetter.call(element), components = inputDateComponentsGet(element), componentOrder = inputDateFormatOrderGetter(element), componentSeparator = inputDateFormatSeparatorGetter(element), selectedComponent = inputDateAccessibilityGetSelectedComponent(value, selectionStart, componentOrder, componentSeparator); - switch (selectedComponent) { - case DATECOMPONENT_YEAR: - components.year = parseInt((components.year + event.key).substr(-6), 10); - break; - - case DATECOMPONENT_MONTH: - components.month = inputAccessibilityComplementComponent(components.month, event.key, INPUT_DATE_MONTH_MIN, INPUT_DATE_MONTH_MAX, 0); - if (components.month > 0) { - selectNext = true; - } - break; - - case DATECOMPONENT_DAY: - components.day = inputAccessibilityComplementComponent(components.day, event.key, INPUT_DATE_DAY_MIN, INPUT_DATE_DAY_MAX, 3); - if (components.day > 3) { - selectNext = true; - } - break; - - default: + function inputDateAccessibilityOnTabKeydownHandleNavigation(element, event, selectionStart) { + inputDateAccessibilityNormalizeSelectedComponent(element, selectionStart); + if (event.altKey || event.ctrlKey || event.metaKey) { + return; + } + if (event.shiftKey) { + if (0 !== inputAccessibilityGetSelectedComponentNumber(inputDomOriginalValueGetter.call(element), selectionStart, inputDateFormatSeparatorGetter(element))) { + inputDateAccessibilitySelectPreviousComponent(element, selectionStart); + } else { + return; + } + } else { + if (2 !== inputAccessibilityGetSelectedComponentNumber(inputDomOriginalValueGetter.call(element), selectionStart, inputDateFormatSeparatorGetter(element))) { + inputDateAccessibilitySelectNextComponent(element, selectionStart); + } else { return; } - value = inputDateComponentsSet(element, components.year, components.month, components.day); - var selection = inputAccessibilityGetComponentRange(value, selectionStart, componentSeparator); - if (selectNext) { - inputDateAccessibilitySelectNextDateComponent(element, selection[0], selection[1]); + } + event.preventDefault(); + } + function inputDateAccessibilityOnKeyPressHandleUserInput(element, event) { + var selectionStart, value, components, componentOrder, componentSeparator, selectedComponent, componentMin, componentMax, componentLimit; + if (47 < event.charCode && 58 > event.charCode) { + selectionStart = element.selectionStart; + value = inputDomOriginalValueGetter.call(element); + components = inputDateComponentsGet(element); + componentOrder = inputDateFormatOrderGetter(element); + componentSeparator = inputDateFormatSeparatorGetter(element); + selectedComponent = inputAccessibilityGetSelectedComponent(value, selectionStart, componentOrder, componentSeparator); + componentMin = inputComponentGetMinimum(element, selectedComponent); + componentMax = inputComponentGetMaximum(element, selectedComponent); + componentLimit = componentMax / 10; + components[selectedComponent] = inputAccessibilityComplementComponent(components[selectedComponent], event.key, componentMin, componentMax, componentLimit); + value = inputDateComponentsSet(element, components); + if (components[selectedComponent] > componentLimit) { + inputDateAccessibilitySelectNextComponent(element, selectionStart); } else { - element.setSelectionRange.apply(element, selection); + inputDomOriginalSetSelectionRange.apply(element, inputAccessibilityGetComponentRange(value, selectionStart, componentSeparator)); } } event.preventDefault(); @@ -769,111 +582,186 @@ value = inputDomOriginalValueGetter.call(element); componentSeparator = inputDateFormatSeparatorGetter(element); if (!value) { - value = inputDateComponentsSet(element, INPUT_DATE_YEAR_EMPTY, INPUT_DATE_MONTH_EMPTY, INPUT_DATE_DAY_EMPTY); + value = inputDateComponentsSet(element, { + yy: INPUT_DATE_YEAR_EMPTY, + mm: INPUT_DATE_MONTH_EMPTY, + dd: INPUT_DATE_DAY_EMPTY + }); selectionStart = 0; } else { selectionStart = element.selectionStart; } componentRange = inputAccessibilityGetComponentRange(value, selectionStart, componentSeparator); - element.setSelectionRange.apply(element, componentRange); + inputDomOriginalSetSelectionRange.apply(element, componentRange); event.preventDefault(); } function inputDateAccessibilityOnBlurHandleInputNormalization(element) { inputDateAccessibilityNormalizeSelectedComponent(element, element.selectionStart); } - function inputDateAccessibilityGetSelectedComponent(value, selectionStart, componentOrder, componentSeparator) { - return componentOrder[inputAccessibilityGetSelectedComponentNumber(value, selectionStart, componentSeparator)]; - } - function inputDateClearDateComponent(input, selectionStart) { - var value = inputDomOriginalValueGetter.call(input), components = inputDateComponentsGet(input), componentOrder = inputDateFormatOrderGetter(input), componentSeparator = inputDateFormatSeparatorGetter(input), selectedComponent = inputDateAccessibilityGetSelectedComponent(value, selectionStart, componentOrder, componentSeparator); + function inputDateAccessibilityClearComponent(element, selectionStart) { + var value = inputDomOriginalValueGetter.call(element), components = inputDateComponentsGet(element), componentOrder = inputDateFormatOrderGetter(element), componentSeparator = inputDateFormatSeparatorGetter(element), selectedComponent = inputAccessibilityGetSelectedComponent(value, selectionStart, componentOrder, componentSeparator); switch (selectedComponent) { - case DATECOMPONENT_YEAR: - components.year = INPUT_DATE_YEAR_EMPTY; + case INPUT_COMPONENT_YEAR: + components.yy = INPUT_DATE_YEAR_EMPTY; break; - case DATECOMPONENT_MONTH: - components.month = INPUT_DATE_MONTH_EMPTY; + case INPUT_COMPONENT_MONTH: + components.mm = INPUT_DATE_MONTH_EMPTY; break; - case DATECOMPONENT_DAY: - components.day = INPUT_DATE_DAY_EMPTY; + case INPUT_COMPONENT_DAY: + components.dd = INPUT_DATE_DAY_EMPTY; break; default: return; } - value = inputDateComponentsSet(input, components.year, components.month, components.day); - input.setSelectionRange.apply(input, inputAccessibilityGetComponentRange(value, selectionStart, componentSeparator)); + value = inputDateComponentsSet(element, components); + inputDomOriginalSetSelectionRange.apply(element, inputAccessibilityGetComponentRange(value, selectionStart, componentSeparator)); } - function inputDateAccessibilityNormalizeSelectedComponent(input, selectionStart) { - var value = inputDomOriginalValueGetter.call(input), components = inputDateComponentsGet(input), componentOrder = inputDateFormatOrderGetter(input), componentSeparator = inputDateFormatSeparatorGetter(input), selectedComponent = inputDateAccessibilityGetSelectedComponent(value, selectionStart, componentOrder, componentSeparator); - switch (selectedComponent) { - case DATECOMPONENT_YEAR: - if (components.year > INPUT_DATE_YEAR_MAX) { - components.year = INPUT_DATE_YEAR_MAX; - } - break; - - case DATECOMPONENT_MONTH: - if (components.month > INPUT_DATE_MONTH_MAX) { - components.month = INPUT_DATE_MONTH_MAX; - } - break; - - case DATECOMPONENT_DAY: - if (components.day > INPUT_DATE_DAY_MAX) { - components.day = INPUT_DATE_DAY_MAX; - } - break; - - default: - return; + function inputDateAccessibilityNormalizeSelectedComponent(element, selectionStart) { + var value = inputDomOriginalValueGetter.call(element), components = inputDateComponentsGet(element), componentOrder = inputDateFormatOrderGetter(element), componentSeparator = inputDateFormatSeparatorGetter(element), selectedComponent = inputAccessibilityGetSelectedComponent(value, selectionStart, componentOrder, componentSeparator), componentMax = inputComponentGetMaximum(element, selectedComponent); + if (components[selectedComponent] > componentMax) { + components[selectedComponent] = componentMax; } - inputDateComponentsSet(input, components.year, components.month, components.day); + inputDateComponentsSet(element, components); } - function inputDateAccessibilitySelectPreviousDateComponent(input, selectionStart) { - var value = inputDomOriginalValueGetter.call(input), componentSeparator = inputDateFormatSeparatorGetter(input), selection = inputAccessibilityGetPreviousComponentRange(value, selectionStart, componentSeparator); - input.setSelectionRange(selection[0], selection[1]); + function inputDateAccessibilitySelectPreviousComponent(element, selectionStart) { + var value = inputDomOriginalValueGetter.call(element), componentSeparator = inputDateFormatSeparatorGetter(element), selection = inputAccessibilityGetPreviousComponentRange(value, selectionStart, componentSeparator); + inputDomOriginalSetSelectionRange.apply(element, selection); } - function inputDateAccessibilitySelectNextDateComponent(input, selectionStart) { - var value = inputDomOriginalValueGetter.call(input), componentSeparator = inputDateFormatSeparatorGetter(input), selection = inputAccessibilityGetNextComponentRange(value, selectionStart, componentSeparator); - input.setSelectionRange(selection[0], selection[1]); + function inputDateAccessibilitySelectNextComponent(element, selectionStart) { + var value = inputDomOriginalValueGetter.call(element), componentSeparator = inputDateFormatSeparatorGetter(element), selection = inputAccessibilityGetNextComponentRange(value, selectionStart, componentSeparator); + inputDomOriginalSetSelectionRange.apply(element, selection); } - function inputDateAccessibilityIncreaseDateComponent(input, selectionStart, amount) { - var value = inputDomOriginalValueGetter.call(input), components = inputDateComponentsGet(input), componentOrder = inputDateFormatOrderGetter(input), componentSeparator = inputDateFormatSeparatorGetter(input), selectedComponent = inputDateAccessibilityGetSelectedComponent(value, selectionStart, componentOrder, componentSeparator); - switch (selectedComponent) { - case DATECOMPONENT_YEAR: - components.year = inputAccessibilityIncreaseComponent(components.year, amount, INPUT_DATE_YEAR_MIN, INPUT_DATE_YEAR_MAX); - break; - - case DATECOMPONENT_MONTH: - components.month = inputAccessibilityIncreaseComponent(components.month, amount, INPUT_DATE_MONTH_MIN, INPUT_DATE_MONTH_MAX); - break; - - case DATECOMPONENT_DAY: - components.day = inputAccessibilityIncreaseComponent(components.day, amount, INPUT_DATE_DAY_MIN, INPUT_DATE_DAY_MAX); - break; - - default: - return; + function inputDateAccessibilityIncreaseComponent(element, selectionStart, amount) { + var value = inputDomOriginalValueGetter.call(element), components = inputDateComponentsGet(element), componentOrder = inputDateFormatOrderGetter(element), componentSeparator = inputDateFormatSeparatorGetter(element), selectedComponent = inputAccessibilityGetSelectedComponent(value, selectionStart, componentOrder, componentSeparator), componentMin = inputComponentGetMinimum(element, selectedComponent), componentMax = inputComponentGetMaximum(element, selectedComponent); + components[selectedComponent] = inputAccessibilityIncreaseComponent(components[selectedComponent], amount, componentMin, componentMax); + value = inputDateComponentsSet(element, components); + inputDomOriginalSetSelectionRange.apply(element, inputAccessibilityGetComponentRange(value, selectionStart, componentSeparator)); + } + function initInputDate() { + inputDateValueFormatter = inputDateFuzzyRfc3339ValueFormatter; + inputDateFormatOrderGetter = inputDateRfc3339FormatOrder; + inputDateFormatSeparatorGetter = inputDateRfc3339FormatSeparator; + initInputDateLocalization(); + } + function inputDateComponentsGet(input) { + if (input[INPUT_PROPERTY_COMPONENTS] === undefined) { + input[INPUT_PROPERTY_COMPONENTS] = inputDateComponentsFromValue(input.getAttribute(INPUT_PROPERTY_VALUE)); + } + return input[INPUT_PROPERTY_COMPONENTS]; + } + function inputDateComponentsSet(element, components) { + var formattedValue; + element[INPUT_PROPERTY_COMPONENTS] = { + yy: components[INPUT_COMPONENT_YEAR], + mm: components[INPUT_COMPONENT_MONTH], + dd: components[INPUT_COMPONENT_DAY] + }; + formattedValue = inputDateValueFormatter(element[INPUT_PROPERTY_COMPONENTS], element); + inputDomOriginalValueSetter.call(element, formattedValue); + return formattedValue; + } + function inputDateFuzzyRfc3339ValueFormatter(components) { + var year, month, day; + if (components.yy === INPUT_DATE_YEAR_EMPTY) { + year = "yyyy"; + } else { + if (9999 >= components.yy) { + year = ("000" + components.yy).slice(-4); + } + } + if (components.mm === INPUT_DATE_MONTH_EMPTY) { + month = "mm"; + } else { + month = ("00" + (components.mm + 1)).slice(-2); + } + if (components.dd === INPUT_DATE_DAY_EMPTY) { + day = "dd"; + } else { + day = ("00" + components.dd).slice(-2); + } + return year + "-" + month + "-" + day; + } + function inputDateRfc3339FormatOrder() { + return [ INPUT_COMPONENT_YEAR, INPUT_COMPONENT_MONTH, INPUT_COMPONENT_DAY ]; + } + function inputDateRfc3339FormatSeparator() { + return [ "-" ]; + } + function getDateFromRfc3339FullDateString(str) { + var date, dateComponents; + if (str && rfc3999FullDateRegExp.test(str)) { + dateComponents = str.split("-"); + if (2757600914 > dateComponents.join("")) { + date = new Date(0); + date.setUTCFullYear(dateComponents[0], dateComponents[1] - 1, dateComponents[2]); + if (date.getUTCMonth() != dateComponents[1] - 1 || date.getUTCDate() != dateComponents[2]) { + return null; + } + return date; + } } - value = inputDateComponentsSet(input, components.year, components.month, components.day); - input.setSelectionRange.apply(input, inputAccessibilityGetComponentRange(value, selectionStart, componentSeparator)); + return null; + } + function inputDateComponentsFromValue(value) { + var date; + if ("" !== value) { + date = getDateFromRfc3339FullDateString(value); + } + if (date) { + return { + yy: date.getUTCFullYear(), + mm: date.getUTCMonth(), + dd: date.getUTCDate() + }; + } else { + return { + yy: INPUT_DATE_YEAR_EMPTY, + mm: INPUT_DATE_MONTH_EMPTY, + dd: INPUT_DATE_DAY_EMPTY + }; + } + } + function inputDateGetRfc3339(input) { + var value, date = inputDateGetDate(input); + if (date) { + value = date.toISOString().replace("+0", "").replace("+", ""); + value = value.substr(0, value.indexOf("T")); + } else { + value = ""; + } + return value; + } + function inputDateGetDate(input) { + var dateComponents = inputDateComponentsGet(input), date = null; + if (dateComponents.yy !== INPUT_DATE_YEAR_EMPTY && dateComponents.mm !== INPUT_DATE_MONTH_EMPTY && dateComponents.dd !== INPUT_DATE_DAY_EMPTY) { + date = new Date(0); + date.setUTCFullYear(dateComponents.yy, dateComponents.mm, dateComponents.dd); + } + return date; } - var INPUT_DATE_STEP_DEFAULT = 1; - var INPUT_DATE_STEP_SCALE_FACTOR = 864e5; function inputDateDomValueGet(element) { return inputDateGetRfc3339(element); } function inputDateDomValueSet(element, value) { var date; - if (value !== "") { + if ("" !== value) { date = getDateFromRfc3339FullDateString(value); } if (date) { - inputDateComponentsSet(element, date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()); + inputDateComponentsSet(element, { + yy: date.getUTCFullYear(), + mm: date.getUTCMonth(), + dd: date.getUTCDate() + }); } else { - inputDateComponentsSet(element, INPUT_DATE_YEAR_EMPTY, INPUT_DATE_MONTH_EMPTY, INPUT_DATE_DAY_EMPTY); + inputDateComponentsSet(element, { + yy: INPUT_DATE_YEAR_EMPTY, + mm: INPUT_DATE_MONTH_EMPTY, + dd: INPUT_DATE_DAY_EMPTY + }); } return value; } @@ -881,35 +769,40 @@ return inputDateGetDate(element); } function inputDateDomValueAsDateSet(element, value) { - inputDateComponentsSet(element, value.getUTCFullYear(), value.getUTCMonth(), value.getUTCDate()); + inputDateComponentsSet(element, { + yy: value.getUTCFullYear(), + mm: value.getUTCMonth(), + dd: value.getUTCDate() + }); } function initInputDateLocalization() { inputDateValueFormatter = inputDateLocalizationValueFormatter; inputDateFormatOrderGetter = inputDateLocalizationFormatOrder; inputDateFormatSeparatorGetter = inputDateLocalizationFormatSeparator; } - function inputDateLocalizationValueFormatter(input, year, month, day) { - var separator = inputDateFormatSeparatorGetter(input), value; - if (year === INPUT_DATE_YEAR_EMPTY) { + function inputDateLocalizationValueFormatter(components, element) { + var year, month, day, value, lang, separator = inputDateFormatSeparatorGetter(element); + if (components.yy === INPUT_DATE_YEAR_EMPTY) { year = "yyyy"; } else { - if (year <= 9999) { - year = ("000" + year).slice(-4); + if (9999 >= components.yy) { + year = ("000" + components.yy).slice(-4); + } else { + year = components.yy; } } - if (month === INPUT_DATE_MONTH_EMPTY) { + if (components.mm === INPUT_DATE_MONTH_EMPTY) { month = "mm"; } else { - month = ("00" + (month + 1)).slice(-2); + month = ("00" + (components.mm + 1)).slice(-2); } - if (day === INPUT_DATE_DAY_EMPTY) { + if (components.dd === INPUT_DATE_DAY_EMPTY) { day = "dd"; } else { - day = ("00" + day).slice(-2); + day = ("00" + components.dd).slice(-2); } - var lang; - if (input.hasAttribute("lang")) { - lang = input.getAttribute("lang").toLowerCase(); + if (element.hasAttribute(INPUT_ATTR_LANG)) { + lang = element.getAttribute(INPUT_ATTR_LANG).toLowerCase(); } switch (lang) { case "en": @@ -925,37 +818,35 @@ default: value = year + separator + month + separator + day; - break; } return value; } function inputDateLocalizationFormatOrder(input) { var lang, order; - if (input.hasAttribute("lang")) { - lang = input.getAttribute("lang").toLowerCase(); + if (input.hasAttribute(INPUT_ATTR_LANG)) { + lang = input.getAttribute(INPUT_ATTR_LANG).toLowerCase(); } switch (lang) { case "en": case "en-us": - order = [ DATECOMPONENT_MONTH, DATECOMPONENT_DAY, DATECOMPONENT_YEAR ]; + order = [ INPUT_COMPONENT_MONTH, INPUT_COMPONENT_DAY, INPUT_COMPONENT_YEAR ]; break; case "en-gb": case "de": case "nl": - order = [ DATECOMPONENT_DAY, DATECOMPONENT_MONTH, DATECOMPONENT_YEAR ]; + order = [ INPUT_COMPONENT_DAY, INPUT_COMPONENT_MONTH, INPUT_COMPONENT_YEAR ]; break; default: - order = [ DATECOMPONENT_YEAR, DATECOMPONENT_MONTH, DATECOMPONENT_DAY ]; - break; + order = [ INPUT_COMPONENT_YEAR, INPUT_COMPONENT_MONTH, INPUT_COMPONENT_DAY ]; } return order; } function inputDateLocalizationFormatSeparator(input) { var lang, separator; - if (input.hasAttribute("lang")) { - lang = input.getAttribute("lang").toLowerCase(); + if (input.hasAttribute(INPUT_ATTR_LANG)) { + lang = input.getAttribute(INPUT_ATTR_LANG).toLowerCase(); } switch (lang) { case "en": @@ -971,64 +862,44 @@ default: separator = "-"; - break; } return [ separator ]; } - function inputDateNormalizationOnLoadFormatInputDateElements(element) { + function inputDateNormalizationOnLoadFormatInputElements(element) { var components = inputDateComponentsGet(element); - inputDateComponentsSet(element, components.year, components.month, components.day); + inputDateComponentsSet(element, components); } - function inputDateNormalizationOnSubmitNormalizeDateInput(element) { + function inputDateNormalizationOnSubmitNormalizeInput(element) { inputDomOriginalValueSetter.call(element, inputDateGetRfc3339(element)); } - function inputTimeAccessibilityOnKeydownHandleNavigation(element, event) { + function inputDatetimeLocalAccessibilityOnKeydownHandleNavigation(element, event) { var selectionStart = element.selectionStart; switch (event.key) { case "Backspace": case "U+0008": case "Del": - inputTimeClearComponent(element, selectionStart); + inputDatetimeLocalClearComponent(element, selectionStart); break; case "Tab": case "U+0009": - if (event.altKey || event.ctrlKey || event.metaKey) { - return; - } else { - if (event.shiftKey) { - if (selectionStart === 0) { - inputTimeAccessibilityNormalizeSelectedComponent(element, selectionStart); - return; - } - } else { - if (element.selectionEnd === inputDomOriginalValueGetter.call(element).length) { - inputTimeAccessibilityNormalizeSelectedComponent(element, selectionStart); - return; - } - } - } - if (event.shiftKey) { - inputTimeAccessibilitySelectPreviousComponent(element, selectionStart); - } else { - inputTimeAccessibilitySelectNextComponent(element, selectionStart); - } - break; + inputDatetimeLocalAccessibilityOnTabKeydownHandleNavigation(element, event, selectionStart); + return; case "Left": - inputTimeAccessibilitySelectPreviousComponent(element, selectionStart); + inputDatetimeLocalAccessibilitySelectPreviousComponent(element, selectionStart); break; case "Up": - inputTimeAccessibilityIncreaseComponent(element, selectionStart, 1); + inputDatetimeLocalAccessibilityIncreaseComponent(element, selectionStart, 1); break; case "Right": - inputTimeAccessibilitySelectNextComponent(element, selectionStart); + inputDatetimeLocalAccessibilitySelectNextComponent(element, selectionStart); break; case "Down": - inputTimeAccessibilityIncreaseComponent(element, selectionStart, -1); + inputDatetimeLocalAccessibilityIncreaseComponent(element, selectionStart, -1); break; default: @@ -1036,203 +907,577 @@ } event.preventDefault(); } - function inputTimeAccessibilityOnKeyPressHandleUserInput(element, event) { - if (event.charCode > 47 && event.charCode < 58) { - var selectionStart = element.selectionStart, selectNext = false, value = inputDomOriginalValueGetter.call(element), components = inputTimeComponentsGet(element), componentOrder = inputTimeFormatOrderGetter(element), componentSeparator = inputTimeFormatSeparatorGetter(element), selectedComponent = inputTimeAccessibilityGetSelectedComponent(value, selectionStart, componentOrder, componentSeparator); - switch (selectedComponent) { - case INPUT_TIME_COMPONENT_HOUR: - components.hour = inputAccessibilityComplementComponent(components.hour, event.key, INPUT_TIME_COMPONENT_HOUR_MIN, INPUT_TIME_COMPONENT_HOUR_MAX, 2); - if (components.hour > 2) { - selectNext = true; - } - break; - - case INPUT_TIME_COMPONENT_MINUTE: - components.minute = inputAccessibilityComplementComponent(components.minute, event.key, INPUT_TIME_COMPONENT_MINUTE_MIN, INPUT_TIME_COMPONENT_MINUTE_MAX, 5); - if (components.minute > 5) { - selectNext = true; - } - break; - - case INPUT_TIME_COMPONENT_SECOND: - components.second = inputAccessibilityComplementComponent(components.second, event.key, INPUT_TIME_COMPONENT_SECOND_MIN, INPUT_TIME_COMPONENT_SECOND_MAX, 5); - if (components.second > 5) { - selectNext = true; + function inputDatetimeLocalAccessibilityOnTabKeydownHandleNavigation(element, event, selectionStart) { + if (event.altKey || event.ctrlKey || event.metaKey) { + return; + } else { + if (event.shiftKey) { + if (0 === selectionStart) { + inputDatetimeLocalAccessibilityNormalizeSelectedComponent(element, selectionStart); + return; } - break; - - case INPUT_TIME_COMPONENT_MILISECOND: - components.milisecond = inputAccessibilityComplementComponent(components.second, event.key, INPUT_TIME_COMPONENT_MILISECOND_MIN, INPUT_TIME_COMPONENT_MILISECOND_MAX, 99); - if (components.milisecond > 99) { - selectNext = true; + } else { + if (element.selectionEnd === inputDomOriginalValueGetter.call(element).length) { + inputDatetimeLocalAccessibilityNormalizeSelectedComponent(element, selectionStart); + return; } - break; - - default: - return; } - value = inputTimeComponentsSet(element, components.hour, components.minute, components.second, components.milisecond); - var selection = inputAccessibilityGetComponentRange(value, selectionStart, componentSeparator); - if (selectNext) { - inputTimeAccessibilitySelectNextComponent(element, selection[0]); + } + if (event.shiftKey) { + inputDatetimeLocalAccessibilitySelectPreviousComponent(element, selectionStart); + } else { + inputDatetimeLocalAccessibilitySelectNextComponent(element, selectionStart); + } + event.preventDefault(); + } + function inputDatetimeLocalAccessibilityOnKeyPressHandleUserInput(element, event) { + var selectionStart, value, components, componentOrder, componentSeparator, selectedComponent, componentMin, componentMax, componentLimit; + if (47 < event.charCode && 58 > event.charCode) { + selectionStart = element.selectionStart; + value = inputDomOriginalValueGetter.call(element); + components = inputDateComponentsGet(element); + componentOrder = inputDateFormatOrderGetter(element); + componentSeparator = inputDateFormatSeparatorGetter(element); + selectedComponent = inputAccessibilityGetSelectedComponent(value, selectionStart, componentOrder, componentSeparator); + componentMin = inputComponentGetMinimum(element, selectedComponent); + componentMax = inputComponentGetMaximum(element, selectedComponent); + componentLimit = componentMax / 10; + components[selectedComponent] = inputAccessibilityComplementComponent(components[selectedComponent], event.key, componentMin, componentMax, componentLimit); + value = inputDatetimeLocalComponentsSet(element, components); + if (components[selectedComponent] > componentLimit) { + inputDatetimeLocalAccessibilitySelectNextComponent(element, selectionStart); } else { - element.setSelectionRange.apply(element, selection); + inputDomOriginalSetSelectionRange.apply(element, inputAccessibilityGetComponentRange(value, selectionStart, componentSeparator)); } } event.preventDefault(); } - function inputTimeAccessibilityOnFocusHandleInputSelection(element, event) { + function inputDatetimeLocalAccessibilityOnFocusHandleInputSelection(element, event) { var componentRange, value, selectionStart, componentSeparator; value = inputDomOriginalValueGetter.call(element); - componentSeparator = inputTimeFormatSeparatorGetter(element); + componentSeparator = inputDatetimeLocalFormatSeparatorGetter(element); if (!value) { - value = inputTimeComponentsSet(element, INPUT_TIME_COMPONENT_EMPTY, INPUT_TIME_COMPONENT_EMPTY, INPUT_TIME_COMPONENT_HIDDEN, INPUT_TIME_COMPONENT_HIDDEN); + value = inputDatetimeLocalComponentsSet(element, { + yy: INPUT_DATE_YEAR_EMPTY, + mm: INPUT_DATE_MONTH_EMPTY, + dd: INPUT_DATE_DAY_EMPTY, + hh: INPUT_TIME_COMPONENT_EMPTY, + ii: INPUT_TIME_COMPONENT_EMPTY, + ss: INPUT_TIME_COMPONENT_HIDDEN, + ms: INPUT_TIME_COMPONENT_HIDDEN + }); selectionStart = 0; } else { selectionStart = element.selectionStart; } componentRange = inputAccessibilityGetComponentRange(value, selectionStart, componentSeparator); - element.setSelectionRange.apply(element, componentRange); + inputDomOriginalSetSelectionRange.apply(element, componentRange); event.preventDefault(); } - function inputTimeAccessibilityOnBlurHandleInputNormalization(element) { - inputTimeAccessibilityNormalizeSelectedComponent(element, element.selectionStart); - } - function inputTimeAccessibilityGetSelectedComponent(value, selectionStart, componentOrder, componentSeparator) { - return componentOrder[inputAccessibilityGetSelectedComponentNumber(value, selectionStart, componentSeparator)]; + function inputDatetimeLocalAccessibilityOnBlurHandleInputNormalization(element) { + inputDatetimeLocalAccessibilityNormalizeSelectedComponent(element, element.selectionStart); } - function inputTimeClearComponent(input, selectionStart) { - var value = inputDomOriginalValueGetter.call(input), components = inputTimeComponentsGet(input), componentOrder = inputTimeFormatOrderGetter(input), componentSeparator = inputTimeFormatSeparatorGetter(input), selectedComponent = inputTimeAccessibilityGetSelectedComponent(value, selectionStart, componentOrder, componentSeparator); + function inputDatetimeLocalClearComponent(element, selectionStart) { + var value = inputDomOriginalValueGetter.call(element), components = inputDatetimeLocalComponentsGet(element), componentOrder = inputDatetimeLocalFormatOrderGetter(element), componentSeparator = inputDatetimeLocalFormatSeparatorGetter(element), selectedComponent = inputAccessibilityGetSelectedComponent(value, selectionStart, componentOrder, componentSeparator); switch (selectedComponent) { - case INPUT_TIME_COMPONENT_HOUR: - components.hour = INPUT_TIME_COMPONENT_EMPTY; + case INPUT_COMPONENT_YEAR: + components.yy = INPUT_DATE_YEAR_EMPTY; break; - case INPUT_TIME_COMPONENT_MINUTE: - components.minute = INPUT_TIME_COMPONENT_EMPTY; + case INPUT_COMPONENT_MONTH: + components.mm = INPUT_DATE_MONTH_EMPTY; break; - case INPUT_TIME_COMPONENT_SECOND: - components.second = INPUT_TIME_COMPONENT_EMPTY; + case INPUT_COMPONENT_DAY: + components.dd = INPUT_DATE_DAY_EMPTY; break; - case INPUT_TIME_COMPONENT_MILISECOND: - components.milisecond = INPUT_TIME_COMPONENT_EMPTY; + case INPUT_COMPONENT_HOUR: + components.hh = INPUT_TIME_COMPONENT_EMPTY; + break; + + case INPUT_COMPONENT_MINUTE: + components.ii = INPUT_TIME_COMPONENT_EMPTY; + break; + + case INPUT_COMPONENT_SECOND: + components.ss = INPUT_TIME_COMPONENT_EMPTY; + break; + + case INPUT_COMPONENT_MILISECOND: + components.ms = INPUT_TIME_COMPONENT_EMPTY; break; default: return; } - value = inputTimeComponentsSet(input, components.hour, components.minute, components.second, components.milisecond); - input.setSelectionRange.apply(input, inputAccessibilityGetComponentRange(value, selectionStart, componentSeparator)); + value = inputDatetimeLocalComponentsSet(element, components); + inputDomOriginalSetSelectionRange.apply(element, inputAccessibilityGetComponentRange(value, selectionStart, componentSeparator)); } - function inputTimeAccessibilityNormalizeSelectedComponent(input, selectionStart) { - var value = inputDomOriginalValueGetter.call(input), components = inputTimeComponentsGet(input), componentOrder = inputTimeFormatOrderGetter(input), componentSeparator = inputTimeFormatSeparatorGetter(input), selectedComponent = inputTimeAccessibilityGetSelectedComponent(value, selectionStart, componentOrder, componentSeparator); - switch (selectedComponent) { - case INPUT_TIME_COMPONENT_HOUR: - if (components.hour > INPUT_TIME_COMPONENT_HOUR_MAX) { - components.hour = INPUT_TIME_COMPONENT_HOUR_MAX; + function inputDatetimeLocalAccessibilityNormalizeSelectedComponent(element, selectionStart) { + var value = inputDomOriginalValueGetter.call(element), components = inputDatetimeLocalComponentsGet(element), componentOrder = inputDatetimeLocalFormatOrderGetter(element), componentSeparator = inputDatetimeLocalFormatSeparatorGetter(element), selectedComponent = inputAccessibilityGetSelectedComponent(value, selectionStart, componentOrder, componentSeparator), componentMax = inputComponentGetMaximum(element, selectedComponent); + if (components[selectedComponent] > componentMax) { + components[selectedComponent] = componentMax; + } + inputDatetimeLocalComponentsSet(element, components); + } + function inputDatetimeLocalAccessibilitySelectPreviousComponent(element, selectionStart) { + inputDatetimeLocalAccessibilityNormalizeSelectedComponent(element, selectionStart); + var value = inputDomOriginalValueGetter.call(element), componentSeparator = inputDatetimeLocalFormatSeparatorGetter(element), selection = inputAccessibilityGetPreviousComponentRange(value, selectionStart, componentSeparator); + inputDomOriginalSetSelectionRange.apply(element, selection); + } + function inputDatetimeLocalAccessibilitySelectNextComponent(element, selectionStart) { + inputDatetimeLocalAccessibilityNormalizeSelectedComponent(element, selectionStart); + var value = inputDomOriginalValueGetter.call(element), componentSeparator = inputDatetimeLocalFormatSeparatorGetter(element), selection = inputAccessibilityGetNextComponentRange(value, selectionStart, componentSeparator); + inputDomOriginalSetSelectionRange.apply(element, selection); + } + function inputDatetimeLocalAccessibilityIncreaseComponent(element, selectionStart, amount) { + var value = inputDomOriginalValueGetter.call(element), components = inputDatetimeLocalComponentsGet(element), componentOrder = inputDatetimeLocalFormatOrderGetter(element), componentSeparator = inputDatetimeLocalFormatSeparatorGetter(element), selectedComponent = inputAccessibilityGetSelectedComponent(value, selectionStart, componentOrder, componentSeparator), componentMin = inputComponentGetMinimum(element, selectedComponent), componentMax = inputComponentGetMaximum(element, selectedComponent); + components[selectedComponent] = inputAccessibilityIncreaseComponent(components[selectedComponent], amount, componentMin, componentMax); + value = inputDatetimeLocalComponentsSet(element, components); + inputDomOriginalSetSelectionRange.apply(element, inputAccessibilityGetComponentRange(value, selectionStart, componentSeparator)); + } + function initInputDatetimeLocal() { + inputDatetimeLocalValueFormatter = inputDatetimeLocalDefaultValueFormatter; + inputDatetimeLocalFormatOrderGetter = inputDatetimeLocalDefaultFormatOrder; + inputDatetimeLocalFormatSeparatorGetter = inputDatetimeLocalDefaultFormatSeparator; + } + function inputDatetimeLocalComponentsGet(input) { + if (input[INPUT_PROPERTY_COMPONENTS] === undefined) { + input[INPUT_PROPERTY_COMPONENTS] = inputDatetimeLocalComponentsFromValue(input.getAttribute(INPUT_PROPERTY_VALUE)); + } + return input[INPUT_PROPERTY_COMPONENTS]; + } + function inputDatetimeLocalComponentsSet(element, components) { + var formattedValue; + element[INPUT_PROPERTY_COMPONENTS] = { + yy: components[INPUT_COMPONENT_YEAR], + mm: components[INPUT_COMPONENT_MONTH], + dd: components[INPUT_COMPONENT_DAY], + hh: components[INPUT_COMPONENT_HOUR], + ii: components[INPUT_COMPONENT_MINUTE], + ss: components[INPUT_COMPONENT_SECOND], + ms: components[INPUT_COMPONENT_MILISECOND] + }; + formattedValue = inputDatetimeLocalValueFormatter(element[INPUT_PROPERTY_COMPONENTS], element); + inputDomOriginalValueSetter.call(element, formattedValue); + return formattedValue; + } + function inputDatetimeLocalComponentsFromValue(value) { + var components; + if (value) { + components = inputDatetimeLocalValidValueStringToComponents(value); + } + if (components) { + return components; + } else { + return { + yy: INPUT_DATE_YEAR_EMPTY, + mm: INPUT_DATE_MONTH_EMPTY, + dd: INPUT_DATE_DAY_EMPTY, + hh: INPUT_TIME_COMPONENT_EMPTY, + ii: INPUT_TIME_COMPONENT_EMPTY, + ss: INPUT_TIME_COMPONENT_HIDDEN, + ms: INPUT_TIME_COMPONENT_HIDDEN + }; + } + } + function inputDatetimeLocalValidValueStringToComponents(str) { + var date, time; + str = str.split("T"); + if (2 === str.length) { + date = getDateFromRfc3339FullDateString(str[0]); + if (null === date) { + return null; + } + time = inputTimeValidTimeStringToComponents(str[1]); + if (null === time) { + return null; + } + return { + yy: date.getUTCFullYear(), + mm: date.getUTCMonth(), + dd: date.getUTCDate(), + hh: time.hh, + ii: time.ii, + ss: time.ss, + ms: time.ms + }; + } + return null; + } + function inputDatetimeLocalGetRfc3339(element) { + var components = inputDatetimeLocalComponentsGet(element); + if (components.hh > INPUT_TIME_COMPONENT_EMPTY && components.ii > INPUT_TIME_COMPONENT_EMPTY) { + if (components.ss === INPUT_TIME_COMPONENT_EMPTY) { + components.ss = INPUT_TIME_COMPONENT_HIDDEN; + } + if (components.ms === INPUT_TIME_COMPONENT_EMPTY) { + components.ms = INPUT_TIME_COMPONENT_HIDDEN; } + return inputDateFuzzyRfc3339ValueFormatter(components) + "T" + inputTimeDefaultValueFormatter(components); + } else { + return ""; + } + } + function inputDatetimeLocalDefaultValueFormatter(components) { + return inputDateFuzzyRfc3339ValueFormatter(components) + " " + inputTimeDefaultValueFormatter(components); + } + function inputDatetimeLocalDefaultFormatOrder() { + return [ INPUT_COMPONENT_YEAR, INPUT_COMPONENT_MONTH, INPUT_COMPONENT_DAY, INPUT_COMPONENT_HOUR, INPUT_COMPONENT_MINUTE, INPUT_COMPONENT_SECOND, INPUT_COMPONENT_MILISECOND ]; + } + function inputDatetimeLocalDefaultFormatSeparator() { + return [ "-", " ", ":", "." ]; + } + function inputDatetimeLocalDomValueGet(element) { + return inputDatetimeLocalGetRfc3339(element); + } + function inputDatetimeLocalDomValueSet(element, value) { + var components; + if ("" !== value) { + components = inputDatetimeLocalValidValueStringToComponents(value + ""); + } + if (components) { + inputDatetimeLocalComponentsSet(element, components); + } else { + inputDatetimeLocalComponentsSet(element, { + yy: INPUT_DATE_YEAR_EMPTY, + mm: INPUT_DATE_MONTH_EMPTY, + dd: INPUT_DATE_DAY_EMPTY, + hh: INPUT_TIME_COMPONENT_EMPTY, + ii: INPUT_TIME_COMPONENT_EMPTY, + ss: INPUT_TIME_COMPONENT_HIDDEN, + ms: INPUT_TIME_COMPONENT_HIDDEN + }); + } + return value; + } + function inputDatetimeLocalDomValueAsDateGet(element) { + var components = inputDatetimeLocalComponentsGet(element), date = null; + if (components.hh !== INPUT_TIME_COMPONENT_EMPTY && components.ii !== INPUT_TIME_COMPONENT_EMPTY) { + date = inputDateGetDate(element); + if (date) { + date.setUTCHours(components.hh); + date.setUTCMinutes(components.ii); + if (components.ss > INPUT_TIME_COMPONENT_EMPTY) { + date.setUTCSeconds(components.ss); + } + if (components.ms > INPUT_TIME_COMPONENT_EMPTY) { + date.setUTCMilliseconds(components.ms); + } + } + } + return date; + } + function inputDatetimeLocalDomValueAsDateSet(element, value) { + inputDatetimeLocalComponentsSet(element, { + yy: value.getUTCFullYear(), + mm: value.getUTCMonth(), + dd: value.getUTCDate(), + hh: value.getUTCHours(), + ii: value.getUTCMinutes(), + ss: value.getUTCSeconds(), + ms: value.getUTCMilliseconds() + }); + } + function inputDatetimeLocalNormalizationOnLoadFormatInputElements(element) { + var components = inputDatetimeLocalComponentsGet(element); + inputDatetimeLocalComponentsSet(element, components); + } + function inputDatetimeLocalNormalizationOnSubmitNormalizeInput(element) { + inputDomOriginalValueSetter.call(element, inputDatetimeLocalGetRfc3339(element)); + } + function inputTimeAccessibilityOnKeydownHandleNavigation(element, event) { + var selectionStart = element.selectionStart; + switch (event.key) { + case "Backspace": + case "U+0008": + case "Del": + inputTimeAccessibilityClearComponent(element, selectionStart); break; - case INPUT_TIME_COMPONENT_MINUTE: - if (components.minute > INPUT_TIME_COMPONENT_MINUTE_MAX) { - components.minute = INPUT_TIME_COMPONENT_MINUTE_MAX; - } + case "Tab": + case "U+0009": + inputTimeAccessibilityOnTabKeydownHandleNavigation(element, event, selectionStart); + return; + + case "Left": + inputTimeAccessibilitySelectPreviousComponent(element, selectionStart); break; - case INPUT_TIME_COMPONENT_SECOND: - if (components.second > INPUT_TIME_COMPONENT_SECOND_MAX) { - components.second = INPUT_TIME_COMPONENT_SECOND_MAX; - } + case "Up": + inputTimeAccessibilityIncreaseComponent(element, selectionStart, 1); break; - case INPUT_TIME_COMPONENT_MILISECOND: - if (components.milisecond > INPUT_TIME_COMPONENT_MILISECOND_MAX) { - components.milisecond = INPUT_TIME_COMPONENT_MILISECOND_MAX; - } + case "Right": + inputTimeAccessibilitySelectNextComponent(element, selectionStart); + break; + + case "Down": + inputTimeAccessibilityIncreaseComponent(element, selectionStart, -1); break; default: return; } - inputTimeComponentsSet(input, components.hour, components.minute, components.second, components.milisecond); + event.preventDefault(); + } + function inputTimeAccessibilityOnTabKeydownHandleNavigation(element, event, selectionStart) { + if (event.altKey || event.ctrlKey || event.metaKey) { + return; + } else { + if (event.shiftKey) { + if (0 === selectionStart) { + inputTimeAccessibilityNormalizeSelectedComponent(element, selectionStart); + return; + } + } else { + if (element.selectionEnd === inputDomOriginalValueGetter.call(element).length) { + inputTimeAccessibilityNormalizeSelectedComponent(element, selectionStart); + return; + } + } + } + if (event.shiftKey) { + inputTimeAccessibilitySelectPreviousComponent(element, selectionStart); + } else { + inputTimeAccessibilitySelectNextComponent(element, selectionStart); + } + event.preventDefault(); + } + function inputTimeAccessibilityOnKeyPressHandleUserInput(element, event) { + var selectionStart, value, components, componentOrder, componentSeparator, selectedComponent, componentMin, componentMax, componentLimit; + if (47 < event.charCode && 58 > event.charCode) { + selectionStart = element.selectionStart; + value = inputDomOriginalValueGetter.call(element); + components = inputTimeComponentsGet(element); + componentOrder = inputTimeFormatOrderGetter(element); + componentSeparator = inputTimeFormatSeparatorGetter(element); + selectedComponent = inputAccessibilityGetSelectedComponent(value, selectionStart, componentOrder, componentSeparator); + componentMin = inputComponentGetMinimum(element, selectedComponent); + componentMax = inputComponentGetMaximum(element, selectedComponent); + componentLimit = componentMax / 10; + components[selectedComponent] = inputAccessibilityComplementComponent(components[selectedComponent], event.key, componentMin, componentMax, componentLimit); + value = inputTimeComponentsSet(element, components); + if (components[selectedComponent] > componentLimit) { + inputTimeAccessibilitySelectNextComponent(element, selectionStart); + } else { + inputDomOriginalSetSelectionRange.apply(element, inputAccessibilityGetComponentRange(value, selectionStart, componentSeparator)); + } + } + event.preventDefault(); + } + function inputTimeAccessibilityOnFocusHandleInputSelection(element, event) { + var value, selectionStart, componentSeparator; + value = inputDomOriginalValueGetter.call(element); + componentSeparator = inputTimeFormatSeparatorGetter(element); + if (!value) { + value = inputTimeComponentsSet(element, { + hh: INPUT_TIME_COMPONENT_EMPTY, + ii: INPUT_TIME_COMPONENT_EMPTY, + ss: INPUT_TIME_COMPONENT_HIDDEN, + ms: INPUT_TIME_COMPONENT_HIDDEN + }); + selectionStart = 0; + } else { + selectionStart = element.selectionStart; + } + inputDomOriginalSetSelectionRange.apply(element, inputAccessibilityGetComponentRange(value, selectionStart, componentSeparator)); + event.preventDefault(); + } + function inputTimeAccessibilityOnBlurHandleInputNormalization(element) { + inputTimeAccessibilityNormalizeSelectedComponent(element, element.selectionStart); + } + function inputTimeAccessibilityClearComponent(element, selectionStart) { + var value = inputDomOriginalValueGetter.call(element), components = inputTimeComponentsGet(element), componentOrder = inputTimeFormatOrderGetter(element), componentSeparator = inputTimeFormatSeparatorGetter(element), selectedComponent = inputAccessibilityGetSelectedComponent(value, selectionStart, componentOrder, componentSeparator); + components[selectedComponent] = INPUT_TIME_COMPONENT_EMPTY; + value = inputTimeComponentsSet(element, components); + inputDomOriginalSetSelectionRange.apply(element, inputAccessibilityGetComponentRange(value, selectionStart, componentSeparator)); + } + function inputTimeAccessibilityNormalizeSelectedComponent(element, selectionStart) { + var value = inputDomOriginalValueGetter.call(element), components = inputTimeComponentsGet(element), componentOrder = inputTimeFormatOrderGetter(element), componentSeparator = inputTimeFormatSeparatorGetter(element), selectedComponent = inputAccessibilityGetSelectedComponent(value, selectionStart, componentOrder, componentSeparator), componentMax = inputComponentGetMaximum(element, selectedComponent); + if (components[selectedComponent] > componentMax) { + components[selectedComponent] = componentMax; + } + inputTimeComponentsSet(element, components); } function inputTimeAccessibilitySelectPreviousComponent(element, selectionStart) { inputTimeAccessibilityNormalizeSelectedComponent(element, selectionStart); - var value = inputDomOriginalValueGetter.call(element), componentSeparator = inputTimeFormatSeparatorGetter(element), selection = inputAccessibilityGetPreviousComponentRange(value, selectionStart, componentSeparator); - element.setSelectionRange(selection[0], selection[1]); + var value = inputDomOriginalValueGetter.call(element), componentSeparator = inputTimeFormatSeparatorGetter(element); + inputDomOriginalSetSelectionRange.apply(element, inputAccessibilityGetPreviousComponentRange(value, selectionStart, componentSeparator)); } function inputTimeAccessibilitySelectNextComponent(element, selectionStart) { inputTimeAccessibilityNormalizeSelectedComponent(element, selectionStart); - var value = inputDomOriginalValueGetter.call(element), componentSeparator = inputTimeFormatSeparatorGetter(element), selection = inputAccessibilityGetNextComponentRange(value, selectionStart, componentSeparator); - element.setSelectionRange(selection[0], selection[1]); + var value = inputDomOriginalValueGetter.call(element), componentSeparator = inputTimeFormatSeparatorGetter(element); + inputDomOriginalSetSelectionRange.apply(element, inputAccessibilityGetNextComponentRange(value, selectionStart, componentSeparator)); } - function inputTimeAccessibilityIncreaseComponent(input, selectionStart, amount) { - var value = inputDomOriginalValueGetter.call(input), components = inputTimeComponentsGet(input), componentOrder = inputTimeFormatOrderGetter(input), componentSeparator = inputTimeFormatSeparatorGetter(input), selectedComponent = inputTimeAccessibilityGetSelectedComponent(value, selectionStart, componentOrder, componentSeparator); - switch (selectedComponent) { - case INPUT_TIME_COMPONENT_HOUR: - components.hour = inputAccessibilityIncreaseComponent(components.hour, amount, INPUT_TIME_COMPONENT_HOUR_MIN, INPUT_TIME_COMPONENT_HOUR_MAX); - break; - - case INPUT_TIME_COMPONENT_MINUTE: - components.minute = inputAccessibilityIncreaseComponent(components.minute, amount, INPUT_TIME_COMPONENT_MINUTE_MIN, INPUT_TIME_COMPONENT_MINUTE_MAX); - break; - - case INPUT_TIME_COMPONENT_SECOND: - components.second = inputAccessibilityIncreaseComponent(components.second, amount, INPUT_TIME_COMPONENT_SECOND_MIN, INPUT_TIME_COMPONENT_SECOND_MAX); - break; - - case INPUT_TIME_COMPONENT_MILISECOND: - components.milisecond = inputAccessibilityIncreaseComponent(components.milisecond, amount, INPUT_TIME_COMPONENT_MILISECOND_MIN, INPUT_TIME_COMPONENT_MILISECOND_MAX); - break; - - default: - return; + function inputTimeAccessibilityIncreaseComponent(element, selectionStart, amount) { + var value = inputDomOriginalValueGetter.call(element), components = inputTimeComponentsGet(element), componentOrder = inputTimeFormatOrderGetter(element), componentSeparator = inputTimeFormatSeparatorGetter(element), selectedComponent = inputAccessibilityGetSelectedComponent(value, selectionStart, componentOrder, componentSeparator), componentMin = inputComponentGetMinimum(element, selectedComponent), componentMax = inputComponentGetMaximum(element, selectedComponent); + components[selectedComponent] = inputAccessibilityIncreaseComponent(components[selectedComponent], amount, componentMin, componentMax); + value = inputTimeComponentsSet(element, components); + inputDomOriginalSetSelectionRange.apply(element, inputAccessibilityGetComponentRange(value, selectionStart, componentSeparator)); + } + function initInputTime() { + inputTimeValueFormatter = inputTimeDefaultValueFormatter; + inputTimeFormatOrderGetter = inputTimeDefaultFormatOrder; + inputTimeFormatSeparatorGetter = inputTimeDefaultFormatSeparator; + } + function inputTimeComponentsGet(input) { + if (input[INPUT_PROPERTY_COMPONENTS] === undefined) { + input[INPUT_PROPERTY_COMPONENTS] = inputTimeComponentsFromValue(input.getAttribute(INPUT_PROPERTY_VALUE)); + } + return input[INPUT_PROPERTY_COMPONENTS]; + } + function inputTimeComponentsSet(element, components) { + var formattedValue; + element[INPUT_PROPERTY_COMPONENTS] = { + hh: components[INPUT_COMPONENT_HOUR], + ii: components[INPUT_COMPONENT_MINUTE], + ss: components[INPUT_COMPONENT_SECOND], + ms: components[INPUT_COMPONENT_MILISECOND] + }; + formattedValue = inputTimeValueFormatter(element[INPUT_PROPERTY_COMPONENTS], element); + inputDomOriginalValueSetter.call(element, formattedValue); + return formattedValue; + } + function inputTimeComponentsFromValue(value) { + var components; + if ("" !== value) { + components = inputTimeValidTimeStringToComponents(value); + } + if (components) { + return components; + } else { + return { + hh: INPUT_TIME_COMPONENT_EMPTY, + ii: INPUT_TIME_COMPONENT_EMPTY, + ss: INPUT_TIME_COMPONENT_HIDDEN, + ms: INPUT_TIME_COMPONENT_HIDDEN + }; } - value = inputTimeComponentsSet(input, components.hour, components.minute, components.second, components.milisecond); - input.setSelectionRange.apply(input, inputAccessibilityGetComponentRange(value, selectionStart, componentSeparator)); } - var INPUT_TIME_STEP_DEFAULT = 60; - var INPUT_TIME_STEP_SCALE_FACTOR = 1e3; + function inputTimeValidTimeStringToComponents(str) { + var components; + if (str && inputTimeValidTimeStringRegExp.test(str)) { + components = str.split(/[:.]/); + if (components[2] === undefined) { + components[2] = INPUT_TIME_COMPONENT_HIDDEN; + } + if (components[3] === undefined) { + components[3] = INPUT_TIME_COMPONENT_HIDDEN; + } else { + components[3] = (components[3] + "000").slice(0, 3); + } + return { + hh: parseInt(components[0], 10), + ii: parseInt(components[1], 10), + ss: parseInt(components[2], 10), + ms: parseInt(components[3], 10) + }; + } + return null; + } + function inputTimeGetRfc3339(element) { + var components = inputTimeComponentsGet(element); + if (components.hh > INPUT_TIME_COMPONENT_EMPTY && components.ii > INPUT_TIME_COMPONENT_EMPTY) { + if (components.ss === INPUT_TIME_COMPONENT_EMPTY) { + components.ss = INPUT_TIME_COMPONENT_HIDDEN; + } + if (components.ms === INPUT_TIME_COMPONENT_EMPTY) { + components.ms = INPUT_TIME_COMPONENT_HIDDEN; + } + return inputTimeDefaultValueFormatter(components); + } else { + return ""; + } + } + function inputTimeDefaultValueFormatter(components) { + var formatted; + if (components.hh === INPUT_TIME_COMPONENT_EMPTY) { + formatted = "--"; + } else { + formatted = ("00" + components.hh).slice(-2); + } + formatted += ":"; + if (components.ii === INPUT_TIME_COMPONENT_EMPTY) { + formatted += "--"; + } else { + formatted += ("00" + components.ii).slice(-2); + } + if (components.ss !== INPUT_TIME_COMPONENT_HIDDEN) { + formatted += ":"; + if (components.ss === INPUT_TIME_COMPONENT_EMPTY) { + formatted += "--"; + } else { + formatted += ("00" + components.ss).slice(-2); + } + if (components.ms !== INPUT_TIME_COMPONENT_HIDDEN) { + formatted += "."; + if (components.ms === INPUT_TIME_COMPONENT_EMPTY) { + formatted += "---"; + } else { + formatted += ("000" + components.ms).slice(-3); + } + } + } + return formatted; + } + function inputTimeDefaultFormatOrder() { + return [ INPUT_COMPONENT_HOUR, INPUT_COMPONENT_MINUTE, INPUT_COMPONENT_SECOND, INPUT_COMPONENT_MILISECOND ]; + } + function inputTimeDefaultFormatSeparator() { + return [ ":", "." ]; + } function inputTimeDomValueGet(element) { return inputTimeGetRfc3339(element); } function inputTimeDomValueSet(element, value) { var components; - if (value !== "") { + if ("" !== value) { components = inputTimeValidTimeStringToComponents(value); } if (components) { - inputTimeComponentsSet(element, components.hour, components.minute, components.second, components.milisecond); + inputTimeComponentsSet(element, components); } else { - inputTimeComponentsSet(element, INPUT_TIME_COMPONENT_EMPTY, INPUT_TIME_COMPONENT_EMPTY, INPUT_TIME_COMPONENT_EMPTY, INPUT_TIME_COMPONENT_EMPTY); + inputTimeComponentsSet(element, { + hh: INPUT_TIME_COMPONENT_EMPTY, + ii: INPUT_TIME_COMPONENT_EMPTY, + ss: INPUT_TIME_COMPONENT_EMPTY, + ms: INPUT_TIME_COMPONENT_EMPTY + }); } return value; } function inputTimeDomValueAsDateGet(element) { var components = inputTimeComponentsGet(element), date = null; - if (components.hour !== INPUT_TIME_COMPONENT_EMPTY && components.minute !== INPUT_TIME_COMPONENT_EMPTY) { + if (components.hh !== INPUT_TIME_COMPONENT_EMPTY && components.ii !== INPUT_TIME_COMPONENT_EMPTY) { date = new Date(0); - date.setUTCHours(components.hour); - date.setUTCMinutes(components.minute); - if (components.second > INPUT_TIME_COMPONENT_EMPTY) { - date.setUTCSeconds(components.second); + date.setUTCHours(components.hh); + date.setUTCMinutes(components.ii); + if (components.ss > INPUT_TIME_COMPONENT_EMPTY) { + date.setUTCSeconds(components.ss); } - if (components.milisecond > INPUT_TIME_COMPONENT_EMPTY) { - date.setUTCMilliseconds(components.milisecond); + if (components.ms > INPUT_TIME_COMPONENT_EMPTY) { + date.setUTCMilliseconds(components.ms); } } return date; } function inputTimeDomValueAsDateSet(element, value) { - inputTimeComponentsSet(element, value.getUTCHours(), value.getUTCMinutes(), value.getUTCSeconds(), value.getUTCMilliseconds()); + inputTimeComponentsSet(element, { + hh: value.getUTCHours(), + ii: value.getUTCMinutes(), + ss: value.getUTCSeconds(), + ms: value.getUTCMilliseconds() + }); } function inputTimeNormalizationOnLoadFormatInputElements(element) { var components = inputTimeComponentsGet(element); - inputTimeComponentsSet(element, components.hour, components.minute, components.second, components.milisecond); + inputTimeComponentsSet(element, components); } function inputTimeNormalizationOnSubmitNormalizeInput(element) { inputDomOriginalValueSetter.call(element, inputTimeGetRfc3339(element)); } -})(window, document); \ No newline at end of file + var inputDomOriginalTypeGetter, inputDomOriginalValueGetter, inputDomOriginalValueSetter, inputDomOriginalValueAsNumberGetter, inputDomOriginalValueAsNumberSetter, inputDomOriginalStepUp, inputDomOriginalStepDown, inputDomOriginalSetSelectionRange, inputDateValueFormatter, inputDateFormatOrderGetter, inputDateFormatSeparatorGetter, inputDatetimeLocalValueFormatter, inputDatetimeLocalFormatOrderGetter, inputDatetimeLocalFormatSeparatorGetter, inputTimeValueFormatter, inputTimeFormatOrderGetter, inputTimeFormatSeparatorGetter, INPUT_ATTR_TYPE = "type", INPUT_ATTR_LANG = "lang", INPUT_TYPE_TEXT = "text", INPUT_TYPE_DATE = "date", INPUT_TYPE_DATETIME_LOCAL = "datetime-local", INPUT_TYPE_TIME = "time", INPUT_PROPERTY_VALUE = "value", INPUT_PROPERTY_VALUEASDATE = "valueAsDate", INPUT_PROPERTY_VALUEASNUMBER = "valueAsNumber", INPUT_PROPERTY_COMPONENTS = "__polyformfillInputComponents", DOMEXCEPTION_INVALID_STATE_ERR = 11, INPUT_COMPONENT_YEAR = "yy", INPUT_COMPONENT_MONTH = "mm", INPUT_COMPONENT_DAY = "dd", INPUT_DATE_YEAR_EMPTY = 0, INPUT_DATE_MONTH_EMPTY = -1, INPUT_DATE_DAY_EMPTY = 0, INPUT_DATE_YEAR_MIN = 1, INPUT_DATE_YEAR_MAX = 275760, INPUT_DATE_MONTH_MIN = 0, INPUT_DATE_MONTH_MAX = 11, INPUT_DATE_DAY_MIN = 1, INPUT_DATE_DAY_MAX = 31, rfc3999FullDateRegExp = /^([0-9]{4,})-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/, INPUT_DATE_STEP_DEFAULT = 1, INPUT_DATE_STEP_SCALE_FACTOR = 864e5, INPUT_COMPONENT_HOUR = "hh", INPUT_COMPONENT_MINUTE = "ii", INPUT_COMPONENT_SECOND = "ss", INPUT_COMPONENT_MILISECOND = "ms", INPUT_TIME_COMPONENT_EMPTY = -1, INPUT_TIME_COMPONENT_HIDDEN = -2, INPUT_TIME_COMPONENT_HOUR_MIN = 0, INPUT_TIME_COMPONENT_HOUR_MAX = 23, INPUT_TIME_COMPONENT_MINUTE_MIN = 0, INPUT_TIME_COMPONENT_MINUTE_MAX = 59, INPUT_TIME_COMPONENT_SECOND_MIN = 0, INPUT_TIME_COMPONENT_SECOND_MAX = 59, INPUT_TIME_COMPONENT_MILISECOND_MIN = 0, INPUT_TIME_COMPONENT_MILISECOND_MAX = 999, inputTimeValidTimeStringRegExp = /^(([0-1][0-9])|(2[0-3])):[0-5][0-9](:[0-5][0-9](\.[0-9]{1,3})?)?$/, INPUT_TIME_STEP_DEFAULT = 60, INPUT_TIME_STEP_SCALE_FACTOR = 1e3; + init(); +}(window, document); \ No newline at end of file diff --git a/polyformfill.min.js b/polyformfill.min.js index e0c174f..a1fd64b 100644 --- a/polyformfill.min.js +++ b/polyformfill.min.js @@ -1,2 +1,2 @@ -!function(e,t,n){"use strict";function r(){var e=t.createElement("input");"valueAsDate"in e||(a(e),i(),p())}function a(e){P(e),A(),X()}function i(){jt=s,xt=o,Nt=l,pt()}function c(e,t,n,r){var a;return e.__polyformfillInputDate={year:t,month:n,day:r},a=jt(e,t,n,r),qt.call(e,a),a}function u(e){return e.__polyformfillInputDate===n&&d(e),e.__polyformfillInputDate}function s(e,t,n,r){return t===en?t="yyyy":9999>=t&&(t=("000"+t).slice(-4)),n=n===tn?"mm":("00"+(n+1)).slice(-2),r=r===nn?"dd":("00"+r).slice(-2),t+"-"+n+"-"+r}function o(){return[Wt,Xt,Zt]}function l(){return["-"]}function f(e){var t,n;return e&&ln.test(e)&&(n=e.split("-"),n.join("")<2757600914)?(t=new Date(0),t.setUTCFullYear(n[0],n[1]-1,n[2]),t.getUTCMonth()!=n[1]-1||t.getUTCDate()!=n[2]?null:t):null}function d(e){var t,n=e.getAttribute("value");""!==n&&(t=f(n)),e.__polyformfillInputDate=t?{year:t.getUTCFullYear(),month:t.getUTCMonth(),day:t.getUTCDate()}:{year:en,month:tn,day:nn}}function h(e){var t,n=m(e);return n?(t=n.toISOString().replace("+0","").replace("+",""),t=t.substr(0,t.indexOf("T"))):t="",t}function m(e){var t=u(e),n=null;return t.year!==en&&t.month!==tn&&t.day!==nn&&(n=new Date(0),n.setUTCFullYear(t.year,t.month,t.day)),n}function p(){Ft=T,Yt=w,Bt=I}function y(e){return e.__polyformfillInputTime===n&&g(e),e.__polyformfillInputTime}function b(e,t,n,r,a){var i;return e.__polyformfillInputTime={hour:t,minute:n,second:r,milisecond:a},i=Ft(e,t,n,r,a),qt.call(e,i),i}function g(e){var t,n=e.getAttribute("value");""!==n&&(t=v(n)),e.__polyformfillInputTime=t?t:{hour:pn,minute:pn,second:yn,milisecond:yn}}function v(e){var t;return e&&En.test(e)?(t=e.split(/[:.]/),t[2]===n&&(t[2]=yn),t[3]=t[3]===n?yn:(t[3]+"000").slice(0,3),{hour:parseInt(t[0],10),minute:parseInt(t[1],10),second:parseInt(t[2],10),milisecond:parseInt(t[3],10)}):null}function k(e){var t=y(e);return t.hour>pn&&t.minute>pn?(t.second===pn&&(t.second=yn),t.milisecond===pn&&(t.milisecond=yn),T(e,t.hour,t.minute,t.second,t.milisecond)):""}function T(e,t,n,r,a){var i;return i=t===pn?"--":("00"+t).slice(-2),i+=":",i+=n===pn?"--":("00"+n).slice(-2),r!==yn&&(i+=":",i+=r===pn?"--":("00"+r).slice(-2),a!==yn&&(i+=".",i+=a===pn?"---":("000"+a).slice(-3))),i}function w(){return[fn,dn,hn,mn]}function I(){return[":","."]}function A(){e.addEventListener("keydown",E),e.addEventListener("keypress",D),e.addEventListener("focus",L,!0),e.addEventListener("focusin",L),e.addEventListener("click",L),e.addEventListener("blur",C,!0)}function E(e){if(!e.defaultPrevented&&!e.charCode&&e.target instanceof HTMLInputElement)switch(e.target.getAttribute(Pt)){case"date":tt(e.target,e);break;case"time":Tt(e.target,e)}}function D(e){if(!e.defaultPrevented&&!(e.altKey||e.ctrlKey||e.shiftKey||e.metaKey)&&e.charCode&&e.target instanceof HTMLInputElement)switch(e.target.getAttribute(Pt)){case"date":nt(e.target,e);break;case"time":wt(e.target,e)}}function L(e){if(e.target instanceof HTMLInputElement)switch(e.target.getAttribute(Pt)){case"date":rt(e.target,e);break;case"time":It(e.target,e)}}function C(e){if(e.target instanceof HTMLInputElement)switch(e.target.getAttribute(Pt)){case"date":at(e.target);break;case"time":At(e.target)}}function U(e,t,n,r){return e+=t,e>r?e=n:n>e&&(e=r),e}function M(e,t,n,r,a){return e>a?(e=parseInt(t,10),0===n&&(e-=1)):e=0===n?parseInt(""+(e+1)+t,10)-1:parseInt(""+e+t,10),e>r&&(e=r),e}function S(e,t,n){var r,a,i=0,c=n.length;for(a=0;c>a;a++)r=e.lastIndexOf(n[a],t-1)+1,r>i&&(i=r);return i}function H(e,t,n){var r,a,i=e.length,c=n.length;for(a=0;c>a;a++)r=e.indexOf(n[a],t),i>r&&-1!==r&&(i=r);return i}function O(e,t,n){var r=S(e,t,n),a=H(e,t,n);return[r,a]}function _(e,t,n){var r,a;return a=S(e,t,n),0===a?(r=a,a=H(e,t,n)):(a-=1,r=S(e,a,n)),[r,a]}function R(e,t,n){var r,a;return r=H(e,t,n),r===e.length?(a=r,r=S(e,t,n)):(r+=1,a=H(e,r,n)),[r,a]}function K(e,t,n){for(var r,a,i=0,c=n.length;t>0;){for(r=-1,a=0;c>a;a++)r=Math.max(r,e.lastIndexOf(n[a],t));t=r-1,t>-2&&i++}return i}function P(e){var t;HTMLInputElement&&Object.isExtensible(HTMLInputElement.prototype)&&(t=Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,"type"),t===n&&(t=Object.getOwnPropertyDescriptor(e,"type")),$t=t.get,t.configurable&&Object.defineProperty(HTMLInputElement.prototype,"type",{get:x}),t=Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,"value"),t.configurable&&(Object.defineProperty(HTMLInputElement.prototype,"value",{get:N,set:F}),Vt=t.get,qt=t.set),t=Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,"valueAsNumber"),(t===n||t.configurable)&&(Object.defineProperty(HTMLInputElement.prototype,"valueAsNumber",{get:Y,set:$}),t&&(zt=t.get,Gt=t.set)),Object.defineProperty(HTMLInputElement.prototype,"valueAsDate",{get:q,set:z}),Jt=HTMLInputElement.prototype.stepUp,HTMLInputElement.prototype.stepUp=G,Qt=HTMLInputElement.prototype.stepDown,HTMLInputElement.prototype.stepDown=J)}function j(e,t){return new Error(e+": "+t)}function x(){var e,t=$t.call(this);if("text"===t)switch(e=this.getAttribute(Pt)){case"date":case"time":return e;default:return t}return t}function N(){var e=this.getAttribute(Pt);switch(e){case"date":return ft(this);case"time":return St(this);default:return Vt.call(this)}}function F(e){var t=this.getAttribute(Pt);switch(t){case"date":return dt(this,e);case"time":return Ht(this,e);default:return qt.call(this)}}function Y(){var e=this.getAttribute(Pt);switch(e){case"date":case"time":return B.call(this);default:return zt?zt.call(this):0/0}}function B(){var e=q.call(this);return e?e.getTime():0/0}function $(e){var t=this.getAttribute(Pt);switch(t){case"date":case"time":V.call(this,e);break;default:qt.call(this)}}function V(e){var t=new Date(e);t&&z.call(this,t)}function q(){var e=this.getAttribute(Pt);switch(e){case"date":return ht(this);case"time":return Ot(this);default:return null}}function z(e){var t=this.getAttribute(Pt);switch(t){case"date":return mt(this,e);case"time":return _t(this,e);default:return qt.call(this,e)}}function G(e){var t=this.getAttribute(Pt);switch(e=e||1,t){case"date":return Q(this,e,Dn,Ln);case"time":return Q(this,e,Cn,Un);default:return Jt.call(this,e)}}function J(e){var t=this.getAttribute(Pt);switch(e=e||1,t){case"date":return Q(this,-e,Dn,Ln);case"time":return Q(this,-e,Cn,Un);default:return Jt.call(this,e)}}function Q(e,t,n,r){var a,i,c;if(a=W(e,n,r),null===a)throw j(DOMException.INVALID_STATE_ERR);c=e.valueAsNumber,i=a*t,c+=i,e.valueAsNumber=c}function W(e,t,n){var r;if(e.hasAttribute("step")){if(r=e.getAttribute("step"),"any"===r)return null;r=parseInt(r,10),1>r&&(r=t)}else r=t;return r*n}function X(){e.addEventListener("submit",et),e.addEventListener("load",Z)}function Z(e){var t,n=e.target.getElementsByTagName("INPUT");for(t=0;t47&&t.charCode<58){var n=e.selectionStart,r=!1,a=Vt.call(e),i=u(e),s=xt(e),o=Nt(e),l=it(a,n,s,o);switch(l){case Wt:i.year=parseInt((i.year+t.key).substr(-6),10);break;case Xt:i.month=M(i.month,t.key,cn,un,0),i.month>0&&(r=!0);break;case Zt:i.day=M(i.day,t.key,sn,on,3),i.day>3&&(r=!0);break;default:return}a=c(e,i.year,i.month,i.day);var f=O(a,n,o);r?ot(e,f[0],f[1]):e.setSelectionRange.apply(e,f)}t.preventDefault()}function rt(e,t){var n,r,a,i;r=Vt.call(e),i=Nt(e),r?a=e.selectionStart:(r=c(e,en,tn,nn),a=0),n=O(r,a,i),e.setSelectionRange.apply(e,n),t.preventDefault()}function at(e){ut(e,e.selectionStart)}function it(e,t,n,r){return n[K(e,t,r)]}function ct(e,t){var n=Vt.call(e),r=u(e),a=xt(e),i=Nt(e),s=it(n,t,a,i);switch(s){case Wt:r.year=en;break;case Xt:r.month=tn;break;case Zt:r.day=nn;break;default:return}n=c(e,r.year,r.month,r.day),e.setSelectionRange.apply(e,O(n,t,i))}function ut(e,t){var n=Vt.call(e),r=u(e),a=xt(e),i=Nt(e),s=it(n,t,a,i);switch(s){case Wt:r.year>an&&(r.year=an);break;case Xt:r.month>un&&(r.month=un);break;case Zt:r.day>on&&(r.day=on);break;default:return}c(e,r.year,r.month,r.day)}function st(e,t){var n=Vt.call(e),r=Nt(e),a=_(n,t,r);e.setSelectionRange(a[0],a[1])}function ot(e,t){var n=Vt.call(e),r=Nt(e),a=R(n,t,r);e.setSelectionRange(a[0],a[1])}function lt(e,t,n){var r=Vt.call(e),a=u(e),i=xt(e),s=Nt(e),o=it(r,t,i,s);switch(o){case Wt:a.year=U(a.year,n,rn,an);break;case Xt:a.month=U(a.month,n,cn,un);break;case Zt:a.day=U(a.day,n,sn,on);break;default:return}r=c(e,a.year,a.month,a.day),e.setSelectionRange.apply(e,O(r,t,s))}function ft(e){return h(e)}function dt(e,t){var n;return""!==t&&(n=f(t)),n?c(e,n.getUTCFullYear(),n.getUTCMonth(),n.getUTCDate()):c(e,en,tn,nn),t}function ht(e){return m(e)}function mt(e,t){c(e,t.getUTCFullYear(),t.getUTCMonth(),t.getUTCDate())}function pt(){jt=yt,xt=bt,Nt=gt}function yt(e,t,n,r){var a,i=Nt(e);t===en?t="yyyy":9999>=t&&(t=("000"+t).slice(-4)),n=n===tn?"mm":("00"+(n+1)).slice(-2),r=r===nn?"dd":("00"+r).slice(-2);var c;switch(e.hasAttribute("lang")&&(c=e.getAttribute("lang").toLowerCase()),c){case"en":case"en-us":a=n+i+r+i+t;break;case"en-gb":case"de":case"nl":a=r+i+n+i+t;break;default:a=t+i+n+i+r}return a}function bt(e){var t,n;switch(e.hasAttribute("lang")&&(t=e.getAttribute("lang").toLowerCase()),t){case"en":case"en-us":n=[Xt,Zt,Wt];break;case"en-gb":case"de":case"nl":n=[Zt,Xt,Wt];break;default:n=[Wt,Xt,Zt]}return n}function gt(e){var t,n;switch(e.hasAttribute("lang")&&(t=e.getAttribute("lang").toLowerCase()),t){case"en":case"en-us":case"en-gb":case"fr":n="/";break;case"de":n=".";break;default:n="-"}return[n]}function vt(e){var t=u(e);c(e,t.year,t.month,t.day)}function kt(e){qt.call(e,h(e))}function Tt(e,t){var n=e.selectionStart;switch(t.key){case"Backspace":case"U+0008":case"Del":Dt(e,n);break;case"Tab":case"U+0009":if(t.altKey||t.ctrlKey||t.metaKey)return;if(t.shiftKey){if(0===n)return void Lt(e,n)}else if(e.selectionEnd===Vt.call(e).length)return void Lt(e,n);t.shiftKey?Ct(e,n):Ut(e,n);break;case"Left":Ct(e,n);break;case"Up":Mt(e,n,1);break;case"Right":Ut(e,n);break;case"Down":Mt(e,n,-1);break;default:return}t.preventDefault()}function wt(e,t){if(t.charCode>47&&t.charCode<58){var n=e.selectionStart,r=!1,a=Vt.call(e),i=y(e),c=Yt(e),u=Bt(e),s=Et(a,n,c,u);switch(s){case fn:i.hour=M(i.hour,t.key,bn,gn,2),i.hour>2&&(r=!0);break;case dn:i.minute=M(i.minute,t.key,vn,kn,5),i.minute>5&&(r=!0);break;case hn:i.second=M(i.second,t.key,Tn,wn,5),i.second>5&&(r=!0);break;case mn:i.milisecond=M(i.second,t.key,In,An,99),i.milisecond>99&&(r=!0);break;default:return}a=b(e,i.hour,i.minute,i.second,i.milisecond);var o=O(a,n,u);r?Ut(e,o[0]):e.setSelectionRange.apply(e,o)}t.preventDefault()}function It(e,t){var n,r,a,i;r=Vt.call(e),i=Bt(e),r?a=e.selectionStart:(r=b(e,pn,pn,yn,yn),a=0),n=O(r,a,i),e.setSelectionRange.apply(e,n),t.preventDefault()}function At(e){Lt(e,e.selectionStart)}function Et(e,t,n,r){return n[K(e,t,r)]}function Dt(e,t){var n=Vt.call(e),r=y(e),a=Yt(e),i=Bt(e),c=Et(n,t,a,i);switch(c){case fn:r.hour=pn;break;case dn:r.minute=pn;break;case hn:r.second=pn;break;case mn:r.milisecond=pn;break;default:return}n=b(e,r.hour,r.minute,r.second,r.milisecond),e.setSelectionRange.apply(e,O(n,t,i))}function Lt(e,t){var n=Vt.call(e),r=y(e),a=Yt(e),i=Bt(e),c=Et(n,t,a,i);switch(c){case fn:r.hour>gn&&(r.hour=gn);break;case dn:r.minute>kn&&(r.minute=kn);break;case hn:r.second>wn&&(r.second=wn);break;case mn:r.milisecond>An&&(r.milisecond=An);break;default:return}b(e,r.hour,r.minute,r.second,r.milisecond)}function Ct(e,t){Lt(e,t);var n=Vt.call(e),r=Bt(e),a=_(n,t,r);e.setSelectionRange(a[0],a[1])}function Ut(e,t){Lt(e,t);var n=Vt.call(e),r=Bt(e),a=R(n,t,r);e.setSelectionRange(a[0],a[1])}function Mt(e,t,n){var r=Vt.call(e),a=y(e),i=Yt(e),c=Bt(e),u=Et(r,t,i,c);switch(u){case fn:a.hour=U(a.hour,n,bn,gn);break;case dn:a.minute=U(a.minute,n,vn,kn);break;case hn:a.second=U(a.second,n,Tn,wn);break;case mn:a.milisecond=U(a.milisecond,n,In,An);break;default:return}r=b(e,a.hour,a.minute,a.second,a.milisecond),e.setSelectionRange.apply(e,O(r,t,c))}function St(e){return k(e)}function Ht(e,t){var n;return""!==t&&(n=v(t)),n?b(e,n.hour,n.minute,n.second,n.milisecond):b(e,pn,pn,pn,pn),t}function Ot(e){var t=y(e),n=null;return t.hour!==pn&&t.minute!==pn&&(n=new Date(0),n.setUTCHours(t.hour),n.setUTCMinutes(t.minute),t.second>pn&&n.setUTCSeconds(t.second),t.milisecond>pn&&n.setUTCMilliseconds(t.milisecond)),n}function _t(e,t){b(e,t.getUTCHours(),t.getUTCMinutes(),t.getUTCSeconds(),t.getUTCMilliseconds())}function Rt(e){var t=y(e);b(e,t.hour,t.minute,t.second,t.milisecond)}function Kt(e){qt.call(e,k(e))}var Pt="type";r();var jt,xt,Nt,Ft,Yt,Bt,$t,Vt,qt,zt,Gt,Jt,Qt,Wt=1,Xt=2,Zt=4,en=0,tn=-1,nn=0,rn=1,an=275760,cn=0,un=11,sn=1,on=31,ln=/^([0-9]{4,})-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/,fn=1,dn=2,hn=4,mn=8,pn=-1,yn=-2,bn=0,gn=23,vn=0,kn=59,Tn=0,wn=59,In=0,An=999,En=/^(([0-1][0-9])|(2[0-3])):[0-5][0-9](:[0-5][0-9](\.[0-9]{1,3})?)?$/,Dn=1,Ln=864e5,Cn=60,Un=1e3}(window,document); +!function(t,e,n){"use strict";function r(){var t=e.createElement("input");jn in t||(b(t),Q(),De(),Ve())}function a(t){t("keydown",s),t("keypress",c),t("focus",i,!0),t("focusin",i),t("click",i),t("blur",u,!0)}function s(t){if(!t.defaultPrevented&&!t.charCode&&t.target instanceof HTMLInputElement)switch(t.target.getAttribute(Sn)){case En:x(t.target,t);break;case Ln:ge(t.target,t);break;case Hn:Ne(t.target,t)}}function c(t){if(!t.defaultPrevented&&!(t.altKey||t.ctrlKey||t.shiftKey||t.metaKey)&&t.charCode&&t.target instanceof HTMLInputElement)switch(t.target.getAttribute(Sn)){case En:B(t.target,t);break;case Ln:me(t.target,t);break;case Hn:Re(t.target,t)}}function i(t){if(t.target instanceof HTMLInputElement)switch(t.target.getAttribute(Sn)){case En:R(t.target,t);break;case Ln:be(t.target,t);break;case Hn:$e(t.target,t)}}function u(t){if(t.target instanceof HTMLInputElement)switch(t.target.getAttribute(Sn)){case En:$(t.target);break;case Ln:ve(t.target);break;case Hn:_e(t.target)}}function l(t,e,n,r){return t+=e,t>r?t=n:n>t&&(t=r),t}function o(t,e,n,r,a){return t>a?(t=parseInt(e,10),0===n&&(t-=1)):t=0===n?parseInt(""+(t+1)+e,10)-1:parseInt(""+t+e,10),t>r&&(t=r),t}function f(t,e,n){var r,a,s=0,c=n.length;for(a=0;c>a;a++)r=t.lastIndexOf(n[a],e-1)+1,r>s&&(s=r);return s}function h(t,e,n){var r,a,s=t.length,c=n.length;for(a=0;c>a;a++)r=t.indexOf(n[a],e),s>r&&-1!==r&&(s=r);return s}function y(t,e,n){var r=f(t,e,n),a=h(t,e,n);return[r,a]}function d(t,e,n){var r,a;return a=f(t,e,n),0===a?(r=a,a=h(t,e,n)):(a-=1,r=f(t,a,n)),[r,a]}function g(t,e,n){var r,a;return r=h(t,e,n),r===t.length?(a=r,r=f(t,e,n)):(r+=1,a=h(t,r,n)),[r,a]}function p(t,e,n){for(var r=0;e>0;)e=f(t,e,n)-1,e>0&&r++;return r}function m(t,e,n,r){return n[p(t,e,r)]}function b(e){T(e),a(t.addEventListener),j(t.addEventListener)}function v(t,e){switch(t.hasAttribute("min"),e){case Nn:return zn;case Bn:return Jn;case Rn:return Vn;case er:return ir;case nr:return lr;case rr:return fr;case ar:return yr}}function k(t,e){switch(t.hasAttribute("max"),e){case Nn:return Gn;case Bn:return Qn;case Rn:return Wn;case er:return ur;case nr:return or;case rr:return hr;case ar:return dr}}function T(t){var e,r;HTMLInputElement&&Object.isExtensible(HTMLInputElement.prototype)&&(r=HTMLInputElement.prototype,e=Object.getOwnPropertyDescriptor(r,Sn),e===n&&(e=Object.getOwnPropertyDescriptor(t,Sn)),hn=e.get,e.configurable&&Object.defineProperty(r,Sn,{get:U}),e=Object.getOwnPropertyDescriptor(r,Pn),e.configurable&&(Object.defineProperty(r,Pn,{get:w,set:D}),yn=e.get,dn=e.set),e=Object.getOwnPropertyDescriptor(r,Fn),(e===n||e.configurable)&&(Object.defineProperty(r,Fn,{get:A,set:I}),e&&(gn=e.get,pn=e.set)),Object.defineProperty(r,jn,{get:K,set:O}),mn=r.stepUp,r.stepUp=E,bn=r.stepDown,r.stepDown=L,vn=r.setSelectionRange)}function C(t,e){return new Error(t+": "+e)}function U(){var t,e=hn.call(this);if(On===e)switch(t=this.getAttribute(Sn)){case En:case Ln:case Hn:return t;default:return e}return e}function w(){switch(this.getAttribute(Sn)){case En:return se(this);case Ln:return He(this);case Hn:return sn(this);default:return yn.call(this)}}function D(t){switch(this.getAttribute(Sn)){case En:return ce(this,t);case Ln:return Pe(this,t);case Hn:return cn(this,t);default:return dn.call(this)}}function A(){switch(this.getAttribute(Sn)){case En:case Ln:case Hn:return M.call(this);default:return gn?gn.call(this):0/0}}function M(){var t=K.call(this);return t?t.getTime():0/0}function I(t){switch(this.getAttribute(Sn)){case En:case Ln:case Hn:S.call(this,t);break;default:dn.call(this)}}function S(t){var e=new Date(t);e&&O.call(this,e)}function K(){switch(this.getAttribute(Sn)){case En:return ie(this);case Ln:return je(this);case Hn:return un(this);default:return null}}function O(t){switch(this.getAttribute(Sn)){case En:return ue(this,t);case Ln:return Fe(this,t);case Hn:return ln(this,t);default:return dn.call(this,t)}}function E(t){switch(t=t||1,this.getAttribute(Sn)){case En:return H(this,t,Zn,tr);case Ln:return H(this,t,pr,mr);case Hn:return H(this,t,pr,mr);default:return mn.call(this,t)}}function L(t){switch(t=t||1,this.getAttribute(Sn)){case En:return H(this,-t,Zn,tr);case Ln:return H(this,-t,pr,mr);case Hn:return H(this,-t,pr,mr);default:return mn.call(this,t)}}function H(t,e,n,r){var a,s,c=P(t,n,r);if(null===c)throw C(xn);s=t.valueAsNumber,a=c*e,s+=a,t.valueAsNumber=s}function P(t,e,n){var r;if(t.hasAttribute("step")){if(r=t.getAttribute("step"),"any"===r)return null;r=parseInt(r,10),1>r&&(r=e)}else r=e;return r*n}function j(t){t("load",F),t("submit",Y)}function F(t){var e,n=t.target.getElementsByTagName("INPUT");for(e=0;ee.charCode&&(n=t.selectionStart,r=yn.call(t),a=V(t),s=Tn(t),c=Cn(t),i=m(r,n,s,c),u=v(t,i),l=k(t,i),f=l/10,a[i]=o(a[i],e.key,u,l,f),r=W(t,a),a[i]>f?G(t,n):vn.apply(t,y(r,n,c))),e.preventDefault()}function R(t,e){var n,r,a,s;r=yn.call(t),s=Cn(t),r?a=t.selectionStart:(r=W(t,{yy:$n,mm:_n,dd:qn}),a=0),n=y(r,a,s),vn.apply(t,n),e.preventDefault()}function $(t){q(t,t.selectionStart)}function _(t,e){var n=yn.call(t),r=V(t),a=Tn(t),s=Cn(t),c=m(n,e,a,s);switch(c){case Nn:r.yy=$n;break;case Bn:r.mm=_n;break;case Rn:r.dd=qn;break;default:return}n=W(t,r),vn.apply(t,y(n,e,s))}function q(t,e){var n=yn.call(t),r=V(t),a=Tn(t),s=Cn(t),c=m(n,e,a,s),i=k(t,c);r[c]>i&&(r[c]=i),W(t,r)}function z(t,e){var n=yn.call(t),r=Cn(t),a=d(n,e,r);vn.apply(t,a)}function G(t,e){var n=yn.call(t),r=Cn(t),a=g(n,e,r);vn.apply(t,a)}function J(t,e,n){var r=yn.call(t),a=V(t),s=Tn(t),c=Cn(t),i=m(r,e,s,c),u=v(t,i),o=k(t,i);a[i]=l(a[i],n,u,o),r=W(t,a),vn.apply(t,y(r,e,c))}function Q(){kn=X,Tn=Z,Cn=te,le()}function V(t){return t[Yn]===n&&(t[Yn]=ne(t.getAttribute(Pn))),t[Yn]}function W(t,e){var n;return t[Yn]={yy:e[Nn],mm:e[Bn],dd:e[Rn]},n=kn(t[Yn],t),dn.call(t,n),n}function X(t){var e,n,r;return t.yy===$n?e="yyyy":9999>=t.yy&&(e=("000"+t.yy).slice(-4)),n=t.mm===_n?"mm":("00"+(t.mm+1)).slice(-2),r=t.dd===qn?"dd":("00"+t.dd).slice(-2),e+"-"+n+"-"+r}function Z(){return[Nn,Bn,Rn]}function te(){return["-"]}function ee(t){var e,n;return t&&Xn.test(t)&&(n=t.split("-"),2757600914>n.join(""))?(e=new Date(0),e.setUTCFullYear(n[0],n[1]-1,n[2]),e.getUTCMonth()!=n[1]-1||e.getUTCDate()!=n[2]?null:e):null}function ne(t){var e;return""!==t&&(e=ee(t)),e?{yy:e.getUTCFullYear(),mm:e.getUTCMonth(),dd:e.getUTCDate()}:{yy:$n,mm:_n,dd:qn}}function re(t){var e,n=ae(t);return n?(e=n.toISOString().replace("+0","").replace("+",""),e=e.substr(0,e.indexOf("T"))):e="",e}function ae(t){var e=V(t),n=null;return e.yy!==$n&&e.mm!==_n&&e.dd!==qn&&(n=new Date(0),n.setUTCFullYear(e.yy,e.mm,e.dd)),n}function se(t){return re(t)}function ce(t,e){var n;return""!==e&&(n=ee(e)),n?W(t,{yy:n.getUTCFullYear(),mm:n.getUTCMonth(),dd:n.getUTCDate()}):W(t,{yy:$n,mm:_n,dd:qn}),e}function ie(t){return ae(t)}function ue(t,e){W(t,{yy:e.getUTCFullYear(),mm:e.getUTCMonth(),dd:e.getUTCDate()})}function le(){kn=oe,Tn=fe,Cn=he}function oe(t,e){var n,r,a,s,c,i=Cn(e);switch(n=t.yy===$n?"yyyy":9999>=t.yy?("000"+t.yy).slice(-4):t.yy,r=t.mm===_n?"mm":("00"+(t.mm+1)).slice(-2),a=t.dd===qn?"dd":("00"+t.dd).slice(-2),e.hasAttribute(Kn)&&(c=e.getAttribute(Kn).toLowerCase()),c){case"en":case"en-us":s=r+i+a+i+n;break;case"en-gb":case"de":case"nl":s=a+i+r+i+n;break;default:s=n+i+r+i+a}return s}function fe(t){var e,n;switch(t.hasAttribute(Kn)&&(e=t.getAttribute(Kn).toLowerCase()),e){case"en":case"en-us":n=[Bn,Rn,Nn];break;case"en-gb":case"de":case"nl":n=[Rn,Bn,Nn];break;default:n=[Nn,Bn,Rn]}return n}function he(t){var e,n;switch(t.hasAttribute(Kn)&&(e=t.getAttribute(Kn).toLowerCase()),e){case"en":case"en-us":case"en-gb":case"fr":n="/";break;case"de":n=".";break;default:n="-"}return[n]}function ye(t){var e=V(t);W(t,e)}function de(t){dn.call(t,re(t))}function ge(t,e){var n=t.selectionStart;switch(e.key){case"Backspace":case"U+0008":case"Del":ke(t,n);break;case"Tab":case"U+0009":return void pe(t,e,n);case"Left":Ce(t,n);break;case"Up":we(t,n,1);break;case"Right":Ue(t,n);break;case"Down":we(t,n,-1);break;default:return}e.preventDefault()}function pe(t,e,n){if(!(e.altKey||e.ctrlKey||e.metaKey)){if(e.shiftKey){if(0===n)return void Te(t,n)}else if(t.selectionEnd===yn.call(t).length)return void Te(t,n);e.shiftKey?Ce(t,n):Ue(t,n),e.preventDefault()}}function me(t,e){var n,r,a,s,c,i,u,l,f;47e.charCode&&(n=t.selectionStart,r=yn.call(t),a=V(t),s=Tn(t),c=Cn(t),i=m(r,n,s,c),u=v(t,i),l=k(t,i),f=l/10,a[i]=o(a[i],e.key,u,l,f),r=Me(t,a),a[i]>f?Ue(t,n):vn.apply(t,y(r,n,c))),e.preventDefault()}function be(t,e){var n,r,a,s;r=yn.call(t),s=Dn(t),r?a=t.selectionStart:(r=Me(t,{yy:$n,mm:_n,dd:qn,hh:sr,ii:sr,ss:cr,ms:cr}),a=0),n=y(r,a,s),vn.apply(t,n),e.preventDefault()}function ve(t){Te(t,t.selectionStart)}function ke(t,e){var n=yn.call(t),r=Ae(t),a=wn(t),s=Dn(t),c=m(n,e,a,s);switch(c){case Nn:r.yy=$n;break;case Bn:r.mm=_n;break;case Rn:r.dd=qn;break;case er:r.hh=sr;break;case nr:r.ii=sr;break;case rr:r.ss=sr;break;case ar:r.ms=sr;break;default:return}n=Me(t,r),vn.apply(t,y(n,e,s))}function Te(t,e){var n=yn.call(t),r=Ae(t),a=wn(t),s=Dn(t),c=m(n,e,a,s),i=k(t,c);r[c]>i&&(r[c]=i),Me(t,r)}function Ce(t,e){Te(t,e);var n=yn.call(t),r=Dn(t),a=d(n,e,r);vn.apply(t,a)}function Ue(t,e){Te(t,e);var n=yn.call(t),r=Dn(t),a=g(n,e,r);vn.apply(t,a)}function we(t,e,n){var r=yn.call(t),a=Ae(t),s=wn(t),c=Dn(t),i=m(r,e,s,c),u=v(t,i),o=k(t,i);a[i]=l(a[i],n,u,o),r=Me(t,a),vn.apply(t,y(r,e,c))}function De(){Un=Oe,wn=Ee,Dn=Le}function Ae(t){return t[Yn]===n&&(t[Yn]=Ie(t.getAttribute(Pn))),t[Yn]}function Me(t,e){var n;return t[Yn]={yy:e[Nn],mm:e[Bn],dd:e[Rn],hh:e[er],ii:e[nr],ss:e[rr],ms:e[ar]},n=Un(t[Yn],t),dn.call(t,n),n}function Ie(t){var e;return t&&(e=Se(t)),e?e:{yy:$n,mm:_n,dd:qn,hh:sr,ii:sr,ss:cr,ms:cr}}function Se(t){var e,n;return t=t.split("T"),2===t.length?(e=ee(t[0]),null===e?null:(n=tn(t[1]),null===n?null:{yy:e.getUTCFullYear(),mm:e.getUTCMonth(),dd:e.getUTCDate(),hh:n.hh,ii:n.ii,ss:n.ss,ms:n.ms})):null}function Ke(t){var e=Ae(t);return e.hh>sr&&e.ii>sr?(e.ss===sr&&(e.ss=cr),e.ms===sr&&(e.ms=cr),X(e)+"T"+nn(e)):""}function Oe(t){return X(t)+" "+nn(t)}function Ee(){return[Nn,Bn,Rn,er,nr,rr,ar]}function Le(){return["-"," ",":","."]}function He(t){return Ke(t)}function Pe(t,e){var n;return""!==e&&(n=Se(e+"")),n?Me(t,n):Me(t,{yy:$n,mm:_n,dd:qn,hh:sr,ii:sr,ss:cr,ms:cr}),e}function je(t){var e=Ae(t),n=null;return e.hh!==sr&&e.ii!==sr&&(n=ae(t),n&&(n.setUTCHours(e.hh),n.setUTCMinutes(e.ii),e.ss>sr&&n.setUTCSeconds(e.ss),e.ms>sr&&n.setUTCMilliseconds(e.ms))),n}function Fe(t,e){Me(t,{yy:e.getUTCFullYear(),mm:e.getUTCMonth(),dd:e.getUTCDate(),hh:e.getUTCHours(),ii:e.getUTCMinutes(),ss:e.getUTCSeconds(),ms:e.getUTCMilliseconds()})}function Ye(t){var e=Ae(t);Me(t,e)}function xe(t){dn.call(t,Ke(t))}function Ne(t,e){var n=t.selectionStart;switch(e.key){case"Backspace":case"U+0008":case"Del":qe(t,n);break;case"Tab":case"U+0009":return void Be(t,e,n);case"Left":Ge(t,n);break;case"Up":Qe(t,n,1);break;case"Right":Je(t,n);break;case"Down":Qe(t,n,-1);break;default:return}e.preventDefault()}function Be(t,e,n){if(!(e.altKey||e.ctrlKey||e.metaKey)){if(e.shiftKey){if(0===n)return void ze(t,n)}else if(t.selectionEnd===yn.call(t).length)return void ze(t,n);e.shiftKey?Ge(t,n):Je(t,n),e.preventDefault()}}function Re(t,e){var n,r,a,s,c,i,u,l,f;47e.charCode&&(n=t.selectionStart,r=yn.call(t),a=We(t),s=Mn(t),c=In(t),i=m(r,n,s,c),u=v(t,i),l=k(t,i),f=l/10,a[i]=o(a[i],e.key,u,l,f),r=Xe(t,a),a[i]>f?Je(t,n):vn.apply(t,y(r,n,c))),e.preventDefault()}function $e(t,e){var n,r,a;n=yn.call(t),a=In(t),n?r=t.selectionStart:(n=Xe(t,{hh:sr,ii:sr,ss:cr,ms:cr}),r=0),vn.apply(t,y(n,r,a)),e.preventDefault()}function _e(t){ze(t,t.selectionStart)}function qe(t,e){var n=yn.call(t),r=We(t),a=Mn(t),s=In(t),c=m(n,e,a,s);r[c]=sr,n=Xe(t,r),vn.apply(t,y(n,e,s))}function ze(t,e){var n=yn.call(t),r=We(t),a=Mn(t),s=In(t),c=m(n,e,a,s),i=k(t,c);r[c]>i&&(r[c]=i),Xe(t,r)}function Ge(t,e){ze(t,e);var n=yn.call(t),r=In(t);vn.apply(t,d(n,e,r))}function Je(t,e){ze(t,e);var n=yn.call(t),r=In(t);vn.apply(t,g(n,e,r))}function Qe(t,e,n){var r=yn.call(t),a=We(t),s=Mn(t),c=In(t),i=m(r,e,s,c),u=v(t,i),o=k(t,i);a[i]=l(a[i],n,u,o),r=Xe(t,a),vn.apply(t,y(r,e,c))}function Ve(){An=nn,Mn=rn,In=an}function We(t){return t[Yn]===n&&(t[Yn]=Ze(t.getAttribute(Pn))),t[Yn]}function Xe(t,e){var n;return t[Yn]={hh:e[er],ii:e[nr],ss:e[rr],ms:e[ar]},n=An(t[Yn],t),dn.call(t,n),n}function Ze(t){var e;return""!==t&&(e=tn(t)),e?e:{hh:sr,ii:sr,ss:cr,ms:cr}}function tn(t){var e;return t&&gr.test(t)?(e=t.split(/[:.]/),e[2]===n&&(e[2]=cr),e[3]=e[3]===n?cr:(e[3]+"000").slice(0,3),{hh:parseInt(e[0],10),ii:parseInt(e[1],10),ss:parseInt(e[2],10),ms:parseInt(e[3],10)}):null}function en(t){var e=We(t);return e.hh>sr&&e.ii>sr?(e.ss===sr&&(e.ss=cr),e.ms===sr&&(e.ms=cr),nn(e)):""}function nn(t){var e;return e=t.hh===sr?"--":("00"+t.hh).slice(-2),e+=":",e+=t.ii===sr?"--":("00"+t.ii).slice(-2),t.ss!==cr&&(e+=":",e+=t.ss===sr?"--":("00"+t.ss).slice(-2),t.ms!==cr&&(e+=".",e+=t.ms===sr?"---":("000"+t.ms).slice(-3))),e}function rn(){return[er,nr,rr,ar]}function an(){return[":","."]}function sn(t){return en(t)}function cn(t,e){var n;return""!==e&&(n=tn(e)),n?Xe(t,n):Xe(t,{hh:sr,ii:sr,ss:sr,ms:sr}),e}function un(t){var e=We(t),n=null;return e.hh!==sr&&e.ii!==sr&&(n=new Date(0),n.setUTCHours(e.hh),n.setUTCMinutes(e.ii),e.ss>sr&&n.setUTCSeconds(e.ss),e.ms>sr&&n.setUTCMilliseconds(e.ms)),n}function ln(t,e){Xe(t,{hh:e.getUTCHours(),ii:e.getUTCMinutes(),ss:e.getUTCSeconds(),ms:e.getUTCMilliseconds()})}function on(t){var e=We(t);Xe(t,e)}function fn(t){dn.call(t,en(t))}var hn,yn,dn,gn,pn,mn,bn,vn,kn,Tn,Cn,Un,wn,Dn,An,Mn,In,Sn="type",Kn="lang",On="text",En="date",Ln="datetime-local",Hn="time",Pn="value",jn="valueAsDate",Fn="valueAsNumber",Yn="__polyformfillInputComponents",xn=11,Nn="yy",Bn="mm",Rn="dd",$n=0,_n=-1,qn=0,zn=1,Gn=275760,Jn=0,Qn=11,Vn=1,Wn=31,Xn=/^([0-9]{4,})-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/,Zn=1,tr=864e5,er="hh",nr="ii",rr="ss",ar="ms",sr=-1,cr=-2,ir=0,ur=23,lr=0,or=59,fr=0,hr=59,yr=0,dr=999,gr=/^(([0-1][0-9])|(2[0-3])):[0-5][0-9](:[0-5][0-9](\.[0-9]{1,3})?)?$/,pr=60,mr=1e3;r()}(window,document); //# sourceMappingURL=polyformfill.min.js.map \ No newline at end of file diff --git a/polyformfill.min.js.map b/polyformfill.min.js.map index 0b07eaf..cf7c73c 100644 --- a/polyformfill.min.js.map +++ b/polyformfill.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["?"],"names":["window","document","undefined","init","testInput","createElement","initInput","initInputDate","initInputTime","initInputDom","initInputAccessibility","initInputNormalization","inputDateValueFormatter","inputDateFuzzyRfc3339ValueFormatter","inputDateFormatOrderGetter","inputDateRfc3339FormatOrder","inputDateFormatSeparatorGetter","inputDateRfc3339FormatSeparator","initInputDateLocalization","inputDateComponentsSet","input","year","month","day","formattedValue","__polyformfillInputDate","inputDomOriginalValueSetter","call","inputDateComponentsGet","inputDateInitInternalValue","INPUT_DATE_YEAR_EMPTY","slice","INPUT_DATE_MONTH_EMPTY","INPUT_DATE_DAY_EMPTY","DATECOMPONENT_YEAR","DATECOMPONENT_MONTH","DATECOMPONENT_DAY","getDateFromRfc3339FullDateString","str","date","dateComponents","rfc3999FullDateRegExp","test","split","join","Date","setUTCFullYear","getUTCMonth","getUTCDate","value","getAttribute","getUTCFullYear","inputDateGetRfc3339","inputDateGetDate","toISOString","replace","substr","indexOf","inputTimeValueFormatter","inputTimeDefaultValueFormatter","inputTimeFormatOrderGetter","inputTimeDefaultFormatOrder","inputTimeFormatSeparatorGetter","inputTimeDefaultFormatSeparator","inputTimeComponentsGet","__polyformfillInputTime","inputTimeInitInternalValue","inputTimeComponentsSet","hour","minute","second","milisecond","components","inputTimeValidTimeStringToComponents","INPUT_TIME_COMPONENT_EMPTY","INPUT_TIME_COMPONENT_HIDDEN","inputTimeValidTimeStringRegExp","parseInt","inputTimeGetRfc3339","element","formatted","INPUT_TIME_COMPONENT_HOUR","INPUT_TIME_COMPONENT_MINUTE","INPUT_TIME_COMPONENT_SECOND","INPUT_TIME_COMPONENT_MILISECOND","addEventListener","inputAccessibilityOnKeydownHandleNavigation","inputAccessibilityOnKeyPressHandleUserInput","inputAccessibilityOnFocusHandleInputSelection","inputAccessibilityOnBlurHandleInputNormalization","event","defaultPrevented","charCode","target","HTMLInputElement","INPUT_ATTR_TYPE","inputDateAccessibilityOnKeydownHandleNavigation","inputTimeAccessibilityOnKeydownHandleNavigation","altKey","ctrlKey","shiftKey","metaKey","inputDateAccessibilityOnKeyPressHandleUserInput","inputTimeAccessibilityOnKeyPressHandleUserInput","inputDateAccessibilityOnFocusHandleInputSelection","inputTimeAccessibilityOnFocusHandleInputSelection","inputDateAccessibilityOnBlurHandleInputNormalization","inputTimeAccessibilityOnBlurHandleInputNormalization","inputAccessibilityIncreaseComponent","amount","min","max","inputAccessibilityComplementComponent","addition","limit","inputAccessibilityPreviousSeparator","position","componentSeparators","i","previous","componentSeparatorsCount","length","lastIndexOf","inputAccessibilityNextSeparator","next","inputAccessibilityGetComponentRange","start","end","inputAccessibilityGetPreviousComponentRange","inputAccessibilityGetNextComponentRange","inputAccessibilityGetSelectedComponentNumber","number","Math","descriptor","Object","isExtensible","prototype","getOwnPropertyDescriptor","inputDomOriginalTypeGetter","get","configurable","defineProperty","inputDomTypeGet","inputDomValueGet","set","inputDomValueSet","inputDomOriginalValueGetter","inputDomValueAsNumberGet","inputDomValueAsNumberSet","inputDomOriginalValueAsNumberGetter","inputDomOriginalValueAsNumberSetter","inputDomValueAsDateGet","inputDomValueAsDateSet","inputDomOriginalStepUp","stepUp","inputDomStepUp","inputDomOriginalStepDown","stepDown","inputDomStepDown","inputDomException","code","message","Error","attr","type","this","inputType","inputDateDomValueGet","inputTimeDomValueGet","inputDateDomValueSet","inputTimeDomValueSet","inputDomValueAsNumberGetFromDate","NaN","getTime","inputDomValueAsNumberSetFromDate","inputDateDomValueAsDateGet","inputTimeDomValueAsDateGet","inputDateDomValueAsDateSet","inputTimeDomValueAsDateSet","n","inputDomStepUpOrDown","INPUT_DATE_STEP_DEFAULT","INPUT_DATE_STEP_SCALE_FACTOR","INPUT_TIME_STEP_DEFAULT","INPUT_TIME_STEP_SCALE_FACTOR","defaultStep","stepScaleFactor","allowedValueStep","delta","inputDomGetAllowedValueStep","DOMException","INVALID_STATE_ERR","valueAsNumber","step","hasAttribute","inputNormalizationOnSubmitNormalizeInput","inputNormalizationOnLoadFormatInputElements","elements","getElementsByTagName","inputDateNormalizationOnLoadFormatInputDateElements","inputTimeNormalizationOnLoadFormatInputElements","inputDateNormalizationOnSubmitNormalizeDateInput","inputTimeNormalizationOnSubmitNormalizeInput","selectionStart","key","inputDateClearDateComponent","inputDateAccessibilityNormalizeSelectedComponent","inputDateAccessibilitySelectPreviousDateComponent","inputDateAccessibilitySelectNextDateComponent","inputDateAccessibilityIncreaseDateComponent","preventDefault","selectNext","componentOrder","componentSeparator","selectedComponent","inputDateAccessibilityGetSelectedComponent","INPUT_DATE_MONTH_MIN","INPUT_DATE_MONTH_MAX","INPUT_DATE_DAY_MIN","INPUT_DATE_DAY_MAX","selection","setSelectionRange","apply","componentRange","INPUT_DATE_YEAR_MAX","INPUT_DATE_YEAR_MIN","inputDateLocalizationValueFormatter","inputDateLocalizationFormatOrder","inputDateLocalizationFormatSeparator","separator","lang","toLowerCase","order","inputTimeClearComponent","inputTimeAccessibilityNormalizeSelectedComponent","selectionEnd","inputTimeAccessibilitySelectPreviousComponent","inputTimeAccessibilitySelectNextComponent","inputTimeAccessibilityIncreaseComponent","inputTimeAccessibilityGetSelectedComponent","INPUT_TIME_COMPONENT_HOUR_MIN","INPUT_TIME_COMPONENT_HOUR_MAX","INPUT_TIME_COMPONENT_MINUTE_MIN","INPUT_TIME_COMPONENT_MINUTE_MAX","INPUT_TIME_COMPONENT_SECOND_MIN","INPUT_TIME_COMPONENT_SECOND_MAX","INPUT_TIME_COMPONENT_MILISECOND_MIN","INPUT_TIME_COMPONENT_MILISECOND_MAX","setUTCHours","setUTCMinutes","setUTCSeconds","setUTCMilliseconds","getUTCHours","getUTCMinutes","getUTCSeconds","getUTCMilliseconds"],"mappings":"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","file":"polyformfill.min.js","sourcesContent":[null],"sourceRoot":"/source/"} \ No newline at end of file +{"version":3,"sources":["?"],"names":["window","document","undefined","init","testInput","createElement","INPUT_PROPERTY_VALUEASDATE","initInput","initInputDate","initInputDatetimeLocal","initInputTime","initInputAccessibility","addEventListener","inputAccessibilityOnKeydownHandleNavigation","inputAccessibilityOnKeyPressHandleUserInput","inputAccessibilityOnFocusHandleInputSelection","inputAccessibilityOnBlurHandleInputNormalization","event","defaultPrevented","charCode","target","HTMLInputElement","getAttribute","INPUT_ATTR_TYPE","INPUT_TYPE_DATE","inputDateAccessibilityOnKeydownHandleNavigation","INPUT_TYPE_DATETIME_LOCAL","inputDatetimeLocalAccessibilityOnKeydownHandleNavigation","INPUT_TYPE_TIME","inputTimeAccessibilityOnKeydownHandleNavigation","altKey","ctrlKey","shiftKey","metaKey","inputDateAccessibilityOnKeyPressHandleUserInput","inputDatetimeLocalAccessibilityOnKeyPressHandleUserInput","inputTimeAccessibilityOnKeyPressHandleUserInput","inputDateAccessibilityOnFocusHandleInputSelection","inputDatetimeLocalAccessibilityOnFocusHandleInputSelection","inputTimeAccessibilityOnFocusHandleInputSelection","inputDateAccessibilityOnBlurHandleInputNormalization","inputDatetimeLocalAccessibilityOnBlurHandleInputNormalization","inputTimeAccessibilityOnBlurHandleInputNormalization","inputAccessibilityIncreaseComponent","value","amount","min","max","inputAccessibilityComplementComponent","addition","limit","parseInt","inputAccessibilityPreviousSeparator","position","componentSeparators","test","i","previous","componentSeparatorsCount","length","lastIndexOf","inputAccessibilityNextSeparator","next","indexOf","inputAccessibilityGetComponentRange","start","end","inputAccessibilityGetPreviousComponentRange","inputAccessibilityGetNextComponentRange","inputAccessibilityGetSelectedComponentNumber","number","inputAccessibilityGetSelectedComponent","selectionStart","componentOrder","componentSeparator","initInputDom","initInputNormalization","inputComponentGetMinimum","element","selectedComponent","hasAttribute","INPUT_COMPONENT_YEAR","INPUT_DATE_YEAR_MIN","INPUT_COMPONENT_MONTH","INPUT_DATE_MONTH_MIN","INPUT_COMPONENT_DAY","INPUT_DATE_DAY_MIN","INPUT_COMPONENT_HOUR","INPUT_TIME_COMPONENT_HOUR_MIN","INPUT_COMPONENT_MINUTE","INPUT_TIME_COMPONENT_MINUTE_MIN","INPUT_COMPONENT_SECOND","INPUT_TIME_COMPONENT_SECOND_MIN","INPUT_COMPONENT_MILISECOND","INPUT_TIME_COMPONENT_MILISECOND_MIN","inputComponentGetMaximum","INPUT_DATE_YEAR_MAX","INPUT_DATE_MONTH_MAX","INPUT_DATE_DAY_MAX","INPUT_TIME_COMPONENT_HOUR_MAX","INPUT_TIME_COMPONENT_MINUTE_MAX","INPUT_TIME_COMPONENT_SECOND_MAX","INPUT_TIME_COMPONENT_MILISECOND_MAX","descriptor","HTMLInputElementPrototype","Object","isExtensible","prototype","getOwnPropertyDescriptor","inputDomOriginalTypeGetter","get","configurable","defineProperty","inputDomTypeGet","INPUT_PROPERTY_VALUE","inputDomValueGet","set","inputDomValueSet","inputDomOriginalValueGetter","inputDomOriginalValueSetter","INPUT_PROPERTY_VALUEASNUMBER","inputDomValueAsNumberGet","inputDomValueAsNumberSet","inputDomOriginalValueAsNumberGetter","inputDomOriginalValueAsNumberSetter","inputDomValueAsDateGet","inputDomValueAsDateSet","inputDomOriginalStepUp","stepUp","inputDomStepUp","inputDomOriginalStepDown","stepDown","inputDomStepDown","inputDomOriginalSetSelectionRange","setSelectionRange","inputDomException","code","message","Error","attr","type","call","this","INPUT_TYPE_TEXT","inputDateDomValueGet","inputDatetimeLocalDomValueGet","inputTimeDomValueGet","inputDateDomValueSet","inputDatetimeLocalDomValueSet","inputTimeDomValueSet","inputDomValueAsNumberGetFromDate","date","getTime","inputDomValueAsNumberSetFromDate","Date","inputDateDomValueAsDateGet","inputDatetimeLocalDomValueAsDateGet","inputTimeDomValueAsDateGet","inputDateDomValueAsDateSet","inputDatetimeLocalDomValueAsDateSet","inputTimeDomValueAsDateSet","n","inputDomStepUpOrDown","INPUT_DATE_STEP_DEFAULT","INPUT_DATE_STEP_SCALE_FACTOR","INPUT_TIME_STEP_DEFAULT","INPUT_TIME_STEP_SCALE_FACTOR","defaultStep","stepScaleFactor","delta","allowedValueStep","inputDomGetAllowedValueStep","DOMEXCEPTION_INVALID_STATE_ERR","valueAsNumber","step","inputNormalizationOnLoadFormatInputElements","inputNormalizationOnSubmitNormalizeInput","elements","getElementsByTagName","inputDateNormalizationOnLoadFormatInputElements","inputDatetimeLocalNormalizationOnLoadFormatInputElements","inputTimeNormalizationOnLoadFormatInputElements","inputDateNormalizationOnSubmitNormalizeInput","inputDatetimeLocalNormalizationOnSubmitNormalizeInput","inputTimeNormalizationOnSubmitNormalizeInput","key","inputDateAccessibilityClearComponent","inputDateAccessibilityOnTabKeydownHandleNavigation","inputDateAccessibilityNormalizeSelectedComponent","inputDateAccessibilitySelectPreviousComponent","inputDateAccessibilityIncreaseComponent","inputDateAccessibilitySelectNextComponent","preventDefault","inputDateFormatSeparatorGetter","components","componentMin","componentMax","componentLimit","inputDateComponentsGet","inputDateFormatOrderGetter","inputDateComponentsSet","apply","componentRange","yy","INPUT_DATE_YEAR_EMPTY","mm","INPUT_DATE_MONTH_EMPTY","dd","INPUT_DATE_DAY_EMPTY","selection","inputDateValueFormatter","inputDateFuzzyRfc3339ValueFormatter","inputDateRfc3339FormatOrder","inputDateRfc3339FormatSeparator","initInputDateLocalization","input","INPUT_PROPERTY_COMPONENTS","inputDateComponentsFromValue","formattedValue","year","month","day","slice","getDateFromRfc3339FullDateString","str","dateComponents","rfc3999FullDateRegExp","split","join","setUTCFullYear","getUTCMonth","getUTCDate","getUTCFullYear","inputDateGetRfc3339","inputDateGetDate","toISOString","replace","substr","inputDateLocalizationValueFormatter","inputDateLocalizationFormatOrder","inputDateLocalizationFormatSeparator","lang","separator","INPUT_ATTR_LANG","toLowerCase","order","inputDatetimeLocalClearComponent","inputDatetimeLocalAccessibilityOnTabKeydownHandleNavigation","inputDatetimeLocalAccessibilitySelectPreviousComponent","inputDatetimeLocalAccessibilityIncreaseComponent","inputDatetimeLocalAccessibilitySelectNextComponent","inputDatetimeLocalAccessibilityNormalizeSelectedComponent","selectionEnd","inputDatetimeLocalComponentsSet","inputDatetimeLocalFormatSeparatorGetter","hh","INPUT_TIME_COMPONENT_EMPTY","ii","ss","INPUT_TIME_COMPONENT_HIDDEN","ms","inputDatetimeLocalComponentsGet","inputDatetimeLocalFormatOrderGetter","inputDatetimeLocalValueFormatter","inputDatetimeLocalDefaultValueFormatter","inputDatetimeLocalDefaultFormatOrder","inputDatetimeLocalDefaultFormatSeparator","inputDatetimeLocalComponentsFromValue","inputDatetimeLocalValidValueStringToComponents","time","inputTimeValidTimeStringToComponents","inputDatetimeLocalGetRfc3339","inputTimeDefaultValueFormatter","setUTCHours","setUTCMinutes","setUTCSeconds","setUTCMilliseconds","getUTCHours","getUTCMinutes","getUTCSeconds","getUTCMilliseconds","inputTimeAccessibilityClearComponent","inputTimeAccessibilityOnTabKeydownHandleNavigation","inputTimeAccessibilitySelectPreviousComponent","inputTimeAccessibilityIncreaseComponent","inputTimeAccessibilitySelectNextComponent","inputTimeAccessibilityNormalizeSelectedComponent","inputTimeComponentsGet","inputTimeFormatOrderGetter","inputTimeFormatSeparatorGetter","inputTimeComponentsSet","inputTimeValueFormatter","inputTimeDefaultFormatOrder","inputTimeDefaultFormatSeparator","inputTimeComponentsFromValue","inputTimeValidTimeStringRegExp","inputTimeGetRfc3339","formatted"],"mappings":"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","file":"polyformfill.min.js","sourcesContent":[null],"sourceRoot":"/source/"} \ No newline at end of file diff --git a/src/.jshintrc b/src/.jshintrc index d8e19eb..6816fc2 100644 --- a/src/.jshintrc +++ b/src/.jshintrc @@ -4,7 +4,9 @@ "browser": true, "node": false, - "maxstatements": 10, + "maxstatements": 15, + + "unused": false, "validthis": true, diff --git a/src/base.js b/src/base.js index 3be51ae..e245508 100644 --- a/src/base.js +++ b/src/base.js @@ -1,17 +1,17 @@ -'use strict'; +"use strict"; /** @const */ -var INPUT_ATTR_TYPE = 'type'; +var INPUT_ATTR_TYPE = "type", + INPUT_ATTR_LANG = "lang"; function init() { - var testInput = document.createElement('input'); + var testInput = document.createElement("input"); - if (!('valueAsDate' in testInput)) { + if (!(INPUT_PROPERTY_VALUEASDATE in testInput)) { initInput(testInput); initInputDate(); + initInputDatetimeLocal(); initInputTime(); } } - -init(); diff --git a/src/init.js b/src/init.js new file mode 100644 index 0000000..e41e1d7 --- /dev/null +++ b/src/init.js @@ -0,0 +1,2 @@ + +init(); diff --git a/src/input-date/accessibility.js b/src/input-date/accessibility.js index 113470f..2c8b87a 100644 --- a/src/input-date/accessibility.js +++ b/src/input-date/accessibility.js @@ -1,4 +1,4 @@ -'use strict'; +"use strict"; /** * Handles keyboard navigation for HTML input elements of type "date". @@ -13,47 +13,28 @@ function inputDateAccessibilityOnKeydownHandleNavigation(element, event) { var selectionStart = element.selectionStart; switch (event.key) { - case 'Backspace': - case 'U+0008': - case 'Del': - inputDateClearDateComponent(element, selectionStart); + case "Backspace": + case "U+0008": + case "Del": + inputDateAccessibilityClearComponent(element, selectionStart); break; - case 'Tab': - case 'U+0009': - inputDateAccessibilityNormalizeSelectedComponent(element, selectionStart); - if (event.altKey || event.ctrlKey || event.metaKey) { - return; - } - - if (event.shiftKey) { - if (inputAccessibilityGetSelectedComponentNumber(inputDomOriginalValueGetter.call(element), selectionStart, inputDateFormatSeparatorGetter(element)) !== 0) { - inputDateAccessibilitySelectPreviousDateComponent(element, selectionStart); - } - else { - return; - } - } - else if (inputAccessibilityGetSelectedComponentNumber(inputDomOriginalValueGetter.call(element), selectionStart, inputDateFormatSeparatorGetter(element)) !== 2) { - inputDateAccessibilitySelectNextDateComponent(element, selectionStart); - } - else { - return; - } - - break; - case 'Left': + case "Tab": + case "U+0009": + inputDateAccessibilityOnTabKeydownHandleNavigation(element, event, selectionStart); + return; + case "Left": inputDateAccessibilityNormalizeSelectedComponent(element, selectionStart); - inputDateAccessibilitySelectPreviousDateComponent(element, selectionStart); + inputDateAccessibilitySelectPreviousComponent(element, selectionStart); break; - case 'Up': - inputDateAccessibilityIncreaseDateComponent(element, selectionStart, 1); + case "Up": + inputDateAccessibilityIncreaseComponent(element, selectionStart, 1); break; - case 'Right': + case "Right": inputDateAccessibilityNormalizeSelectedComponent(element, selectionStart); - inputDateAccessibilitySelectNextDateComponent(element, selectionStart); + inputDateAccessibilitySelectNextComponent(element, selectionStart); break; - case 'Down': - inputDateAccessibilityIncreaseDateComponent(element, selectionStart, -1); + case "Down": + inputDateAccessibilityIncreaseComponent(element, selectionStart, -1); break; default: return; @@ -61,6 +42,29 @@ function inputDateAccessibilityOnKeydownHandleNavigation(element, event) { event.preventDefault(); } +function inputDateAccessibilityOnTabKeydownHandleNavigation(element, event, selectionStart) { + inputDateAccessibilityNormalizeSelectedComponent(element, selectionStart); + if (event.altKey || event.ctrlKey || event.metaKey) { + return; + } + + if (event.shiftKey) { + if (0 !== inputAccessibilityGetSelectedComponentNumber(inputDomOriginalValueGetter.call(element), selectionStart, inputDateFormatSeparatorGetter(element))) { + inputDateAccessibilitySelectPreviousComponent(element, selectionStart); + } + else { + return; + } + } + else if (2 !== inputAccessibilityGetSelectedComponentNumber(inputDomOriginalValueGetter.call(element), selectionStart, inputDateFormatSeparatorGetter(element))) { + inputDateAccessibilitySelectNextComponent(element, selectionStart); + } + else { + return; + } + event.preventDefault(); +} + /** * Handles user input for HTML input elements of type "date". * @@ -71,46 +75,31 @@ function inputDateAccessibilityOnKeydownHandleNavigation(element, event) { * every time an actual character is being inserted (keydown and keyup events are triggered only once). */ function inputDateAccessibilityOnKeyPressHandleUserInput(element, event) { + var selectionStart, value, components, componentOrder, componentSeparator, selectedComponent, componentMin, componentMax, componentLimit; + // Only allow numeric input. - if (event.charCode > 47 && event.charCode < 58) { - var selectionStart = element.selectionStart; - var selectNext = false; - - var value = inputDomOriginalValueGetter.call(element), - components = inputDateComponentsGet(element), - - componentOrder = inputDateFormatOrderGetter(element), - componentSeparator = inputDateFormatSeparatorGetter(element), - selectedComponent = inputDateAccessibilityGetSelectedComponent(value, selectionStart, componentOrder, componentSeparator); - - switch (selectedComponent) { - case DATECOMPONENT_YEAR: - components.year = parseInt((components.year + event.key).substr(-6), 10); - break; - case DATECOMPONENT_MONTH: - components.month = inputAccessibilityComplementComponent(components.month, event.key, INPUT_DATE_MONTH_MIN, INPUT_DATE_MONTH_MAX, 0); - if (components.month > 0) { - selectNext = true; - } - break; - case DATECOMPONENT_DAY: - components.day = inputAccessibilityComplementComponent(components.day, event.key, INPUT_DATE_DAY_MIN, INPUT_DATE_DAY_MAX, 3); - if (components.day > 3) { - selectNext = true; - } - break; - default: - return; - } + if (47 < event.charCode && 58 > event.charCode) { + selectionStart = element.selectionStart; + + value = inputDomOriginalValueGetter.call(element); + components = inputDateComponentsGet(element); + + componentOrder = inputDateFormatOrderGetter(element); + componentSeparator = inputDateFormatSeparatorGetter(element); + selectedComponent = inputAccessibilityGetSelectedComponent(value, selectionStart, componentOrder, componentSeparator); + componentMin = inputComponentGetMinimum(element, selectedComponent); + componentMax = inputComponentGetMaximum(element, selectedComponent); + componentLimit = componentMax / 10; - value = inputDateComponentsSet(element, components.year, components.month, components.day); + components[selectedComponent] = inputAccessibilityComplementComponent(components[selectedComponent], event.key, componentMin, componentMax, componentLimit); - var selection = inputAccessibilityGetComponentRange(value, selectionStart, componentSeparator); - if (selectNext) { - inputDateAccessibilitySelectNextDateComponent(element, selection[0], selection[1]); + value = inputDateComponentsSet(element, components); + + if (components[selectedComponent] > componentLimit) { + inputDateAccessibilitySelectNextComponent(element, selectionStart); } else { - element.setSelectionRange.apply(element, selection); + inputDomOriginalSetSelectionRange.apply(element, inputAccessibilityGetComponentRange(value, selectionStart, componentSeparator)); } } event.preventDefault(); @@ -123,7 +112,7 @@ function inputDateAccessibilityOnFocusHandleInputSelection(element, event) { componentSeparator = inputDateFormatSeparatorGetter(element); if (!value) { - value = inputDateComponentsSet(element, INPUT_DATE_YEAR_EMPTY, INPUT_DATE_MONTH_EMPTY, INPUT_DATE_DAY_EMPTY); + value = inputDateComponentsSet(element, {yy: INPUT_DATE_YEAR_EMPTY, mm: INPUT_DATE_MONTH_EMPTY, dd: INPUT_DATE_DAY_EMPTY}); selectionStart = 0; } else { @@ -132,7 +121,7 @@ function inputDateAccessibilityOnFocusHandleInputSelection(element, event) { componentRange = inputAccessibilityGetComponentRange(value, selectionStart, componentSeparator); - element.setSelectionRange.apply(element, componentRange); + inputDomOriginalSetSelectionRange.apply(element, componentRange); event.preventDefault(); } @@ -140,102 +129,73 @@ function inputDateAccessibilityOnBlurHandleInputNormalization(element) { inputDateAccessibilityNormalizeSelectedComponent(element, element.selectionStart); } -function inputDateAccessibilityGetSelectedComponent(value, selectionStart, componentOrder, componentSeparator) { - return componentOrder[inputAccessibilityGetSelectedComponentNumber(value, selectionStart, componentSeparator)]; -} - -function inputDateClearDateComponent(input, selectionStart) { - var value = inputDomOriginalValueGetter.call(input), - components = inputDateComponentsGet(input), - componentOrder = inputDateFormatOrderGetter(input), - componentSeparator = inputDateFormatSeparatorGetter(input), - selectedComponent = inputDateAccessibilityGetSelectedComponent(value, selectionStart, componentOrder, componentSeparator); +function inputDateAccessibilityClearComponent(element, selectionStart) { + var value = inputDomOriginalValueGetter.call(element), + components = inputDateComponentsGet(element), + componentOrder = inputDateFormatOrderGetter(element), + componentSeparator = inputDateFormatSeparatorGetter(element), + selectedComponent = inputAccessibilityGetSelectedComponent(value, selectionStart, componentOrder, componentSeparator); switch (selectedComponent) { - case DATECOMPONENT_YEAR: - components.year = INPUT_DATE_YEAR_EMPTY; + case INPUT_COMPONENT_YEAR: + components.yy = INPUT_DATE_YEAR_EMPTY; break; - case DATECOMPONENT_MONTH: - components.month = INPUT_DATE_MONTH_EMPTY; + case INPUT_COMPONENT_MONTH: + components.mm = INPUT_DATE_MONTH_EMPTY; break; - case DATECOMPONENT_DAY: - components.day = INPUT_DATE_DAY_EMPTY; + case INPUT_COMPONENT_DAY: + components.dd = INPUT_DATE_DAY_EMPTY; break; default: return; } - value = inputDateComponentsSet(input, components.year, components.month, components.day); - input.setSelectionRange.apply(input, inputAccessibilityGetComponentRange(value, selectionStart, componentSeparator)); + value = inputDateComponentsSet(element, components); + inputDomOriginalSetSelectionRange.apply(element, inputAccessibilityGetComponentRange(value, selectionStart, componentSeparator)); } -function inputDateAccessibilityNormalizeSelectedComponent(input, selectionStart) { - var value = inputDomOriginalValueGetter.call(input), - components = inputDateComponentsGet(input), - componentOrder = inputDateFormatOrderGetter(input), - componentSeparator = inputDateFormatSeparatorGetter(input), - selectedComponent = inputDateAccessibilityGetSelectedComponent(value, selectionStart, componentOrder, componentSeparator); +function inputDateAccessibilityNormalizeSelectedComponent(element, selectionStart) { + var value = inputDomOriginalValueGetter.call(element), + components = inputDateComponentsGet(element), + componentOrder = inputDateFormatOrderGetter(element), + componentSeparator = inputDateFormatSeparatorGetter(element), + selectedComponent = inputAccessibilityGetSelectedComponent(value, selectionStart, componentOrder, componentSeparator), + componentMax = inputComponentGetMaximum(element, selectedComponent); - switch (selectedComponent) { - case DATECOMPONENT_YEAR: - if (components.year > INPUT_DATE_YEAR_MAX) { - components.year = INPUT_DATE_YEAR_MAX; - } - break; - case DATECOMPONENT_MONTH: - if (components.month > INPUT_DATE_MONTH_MAX) { - components.month = INPUT_DATE_MONTH_MAX; - } - break; - case DATECOMPONENT_DAY: - if (components.day > INPUT_DATE_DAY_MAX) { - components.day = INPUT_DATE_DAY_MAX; - } - break; - default: - return; + if (components[selectedComponent] > componentMax) { + components[selectedComponent] = componentMax; } - inputDateComponentsSet(input, components.year, components.month, components.day); + inputDateComponentsSet(element, components); } -function inputDateAccessibilitySelectPreviousDateComponent(input, selectionStart) { - var value = inputDomOriginalValueGetter.call(input), - componentSeparator = inputDateFormatSeparatorGetter(input), +function inputDateAccessibilitySelectPreviousComponent(element, selectionStart) { + var value = inputDomOriginalValueGetter.call(element), + componentSeparator = inputDateFormatSeparatorGetter(element), selection = inputAccessibilityGetPreviousComponentRange(value, selectionStart, componentSeparator); - input.setSelectionRange(selection[0], selection[1]); + inputDomOriginalSetSelectionRange.apply(element, selection); } -function inputDateAccessibilitySelectNextDateComponent(input, selectionStart) { - var value = inputDomOriginalValueGetter.call(input), - componentSeparator = inputDateFormatSeparatorGetter(input), +function inputDateAccessibilitySelectNextComponent(element, selectionStart) { + var value = inputDomOriginalValueGetter.call(element), + componentSeparator = inputDateFormatSeparatorGetter(element), selection = inputAccessibilityGetNextComponentRange(value, selectionStart, componentSeparator); - input.setSelectionRange(selection[0], selection[1]); + inputDomOriginalSetSelectionRange.apply(element, selection); } -function inputDateAccessibilityIncreaseDateComponent(input, selectionStart, amount) { - var value = inputDomOriginalValueGetter.call(input), - components = inputDateComponentsGet(input), - componentOrder = inputDateFormatOrderGetter(input), - componentSeparator = inputDateFormatSeparatorGetter(input), - selectedComponent = inputDateAccessibilityGetSelectedComponent(value, selectionStart, componentOrder, componentSeparator); +function inputDateAccessibilityIncreaseComponent(element, selectionStart, amount) { + var value = inputDomOriginalValueGetter.call(element), + components = inputDateComponentsGet(element), + componentOrder = inputDateFormatOrderGetter(element), + componentSeparator = inputDateFormatSeparatorGetter(element), + selectedComponent = inputAccessibilityGetSelectedComponent(value, selectionStart, componentOrder, componentSeparator), + componentMin = inputComponentGetMinimum(element, selectedComponent), + componentMax = inputComponentGetMaximum(element, selectedComponent); - switch (selectedComponent) { - case DATECOMPONENT_YEAR: - components.year = inputAccessibilityIncreaseComponent(components.year, amount, INPUT_DATE_YEAR_MIN, INPUT_DATE_YEAR_MAX); - break; - case DATECOMPONENT_MONTH: - components.month = inputAccessibilityIncreaseComponent(components.month, amount, INPUT_DATE_MONTH_MIN, INPUT_DATE_MONTH_MAX); - break; - case DATECOMPONENT_DAY: - components.day = inputAccessibilityIncreaseComponent(components.day, amount, INPUT_DATE_DAY_MIN, INPUT_DATE_DAY_MAX); - break; - default: - return; - } + components[selectedComponent] = inputAccessibilityIncreaseComponent(components[selectedComponent], amount, componentMin, componentMax); - value = inputDateComponentsSet(input, components.year, components.month, components.day); - input.setSelectionRange.apply(input, inputAccessibilityGetComponentRange(value, selectionStart, componentSeparator)); + value = inputDateComponentsSet(element, components); + inputDomOriginalSetSelectionRange.apply(element, inputAccessibilityGetComponentRange(value, selectionStart, componentSeparator)); } diff --git a/src/input-date/base.js b/src/input-date/base.js index ae7900c..def1014 100644 --- a/src/input-date/base.js +++ b/src/input-date/base.js @@ -1,4 +1,4 @@ -'use strict'; +"use strict"; /** * @file @@ -9,9 +9,9 @@ */ /** @const */ -var DATECOMPONENT_YEAR = 1, - DATECOMPONENT_MONTH = 2, - DATECOMPONENT_DAY = 4; +var INPUT_COMPONENT_YEAR = "yy", + INPUT_COMPONENT_MONTH ="mm", + INPUT_COMPONENT_DAY = "dd"; /** @const */ var INPUT_DATE_YEAR_EMPTY = 0, @@ -32,9 +32,9 @@ var INPUT_DATE_DAY_MIN = 1, var rfc3999FullDateRegExp = /^([0-9]{4,})-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/; -var inputDateValueFormatter; -var inputDateFormatOrderGetter; -var inputDateFormatSeparatorGetter; +var inputDateValueFormatter, + inputDateFormatOrderGetter, + inputDateFormatSeparatorGetter; function initInputDate() { inputDateValueFormatter = inputDateFuzzyRfc3339ValueFormatter; @@ -44,73 +44,75 @@ function initInputDate() { initInputDateLocalization(); } -function inputDateComponentsSet(input, year, month, day) { +function inputDateComponentsGet(input) { + if (input[INPUT_PROPERTY_COMPONENTS] === undefined) { + input[INPUT_PROPERTY_COMPONENTS] = inputDateComponentsFromValue(input.getAttribute(INPUT_PROPERTY_VALUE)); + } + + return input[INPUT_PROPERTY_COMPONENTS]; +} + +function inputDateComponentsSet(element, components) { var formattedValue; - input.__polyformfillInputDate = { - year: year, - month: month, - day: day + element[INPUT_PROPERTY_COMPONENTS] = { + yy: components[INPUT_COMPONENT_YEAR], + mm: components[INPUT_COMPONENT_MONTH], + dd: components[INPUT_COMPONENT_DAY] }; - formattedValue = inputDateValueFormatter(input, year, month, day); - inputDomOriginalValueSetter.call(input, formattedValue); + formattedValue = inputDateValueFormatter(element[INPUT_PROPERTY_COMPONENTS], element); + inputDomOriginalValueSetter.call(element, formattedValue); return formattedValue; } -function inputDateComponentsGet(input) { - if (input.__polyformfillInputDate === undefined) { - inputDateInitInternalValue(input); - } - - return input.__polyformfillInputDate; -} +function inputDateFuzzyRfc3339ValueFormatter(components) { + var year, month, day; -function inputDateFuzzyRfc3339ValueFormatter(input, year, month, day) { - if (year === INPUT_DATE_YEAR_EMPTY) { - year = 'yyyy'; + if (components.yy === INPUT_DATE_YEAR_EMPTY) { + year = "yyyy"; } else { - if (year <= 9999) { - year = ('000' + year).slice(-4); + if (9999 >= components.yy) { + year = ("000" + components.yy).slice(-4); } } - if (month === INPUT_DATE_MONTH_EMPTY) { - month = 'mm'; + if (components.mm === INPUT_DATE_MONTH_EMPTY) { + month = "mm"; } else { - month = ('00' + (month + 1)).slice(-2); + month = ("00" + (components.mm + 1)).slice(-2); } - if (day === INPUT_DATE_DAY_EMPTY) { - day = 'dd'; + if (components.dd === INPUT_DATE_DAY_EMPTY) { + day = "dd"; } else { - day = ('00' + day).slice(-2); + day = ("00" + components.dd).slice(-2); } - return year + '-' + month + '-' + day; + return year + "-" + month + "-" + day; } function inputDateRfc3339FormatOrder() { return [ - DATECOMPONENT_YEAR, - DATECOMPONENT_MONTH, - DATECOMPONENT_DAY + INPUT_COMPONENT_YEAR, + INPUT_COMPONENT_MONTH, + INPUT_COMPONENT_DAY ]; } function inputDateRfc3339FormatSeparator() { - return ['-']; + return ["-"]; } function getDateFromRfc3339FullDateString(str) { var date, dateComponents; if (str && rfc3999FullDateRegExp.test(str)) { - dateComponents = str.split('-'); + dateComponents = str.split("-"); // Max possible date; http://ecma-international.org/ecma-262/5.1/#sec-15.9.1.1 - if (dateComponents.join('') < 2757600914) { + if (2757600914 > dateComponents.join("")) { date = new Date(0); date.setUTCFullYear(dateComponents[0], dateComponents[1] - 1, dateComponents[2]); // Don't accept values like february 31th. setUTCFullYear() automatically updates these values to correct dates, @@ -124,26 +126,25 @@ function getDateFromRfc3339FullDateString(str) { return null; } -function inputDateInitInternalValue(input) { - var value = input.getAttribute('value'), - date; +function inputDateComponentsFromValue(value) { + var date; - if (value !== '') { + if ("" !== value) { date = getDateFromRfc3339FullDateString(value); } if (date) { - input.__polyformfillInputDate = { - year: date.getUTCFullYear(), - month: date.getUTCMonth(), - day: date.getUTCDate() + return { + yy: date.getUTCFullYear(), + mm: date.getUTCMonth(), + dd: date.getUTCDate() }; } else { - input.__polyformfillInputDate = { - year: INPUT_DATE_YEAR_EMPTY, - month: INPUT_DATE_MONTH_EMPTY, - day: INPUT_DATE_DAY_EMPTY + return { + yy: INPUT_DATE_YEAR_EMPTY, + mm: INPUT_DATE_MONTH_EMPTY, + dd: INPUT_DATE_DAY_EMPTY }; } } @@ -155,11 +156,11 @@ function inputDateGetRfc3339(input) { value = date .toISOString() // IE prefixes years later than 9999 with "+0" and years later than 99999 with "+". - .replace('+0', '').replace('+', ''); - value = value.substr(0, value.indexOf('T')); + .replace("+0", "").replace("+", ""); + value = value.substr(0, value.indexOf("T")); } else { - value = ''; + value = ""; } return value; } @@ -167,10 +168,10 @@ function inputDateGetRfc3339(input) { function inputDateGetDate(input) { var dateComponents = inputDateComponentsGet(input), date = null; - if (dateComponents.year !== INPUT_DATE_YEAR_EMPTY && dateComponents.month !== INPUT_DATE_MONTH_EMPTY && dateComponents.day !== INPUT_DATE_DAY_EMPTY) { + if (dateComponents.yy !== INPUT_DATE_YEAR_EMPTY && dateComponents.mm !== INPUT_DATE_MONTH_EMPTY && dateComponents.dd !== INPUT_DATE_DAY_EMPTY) { date = new Date(0); // TODO setUTCFullYear automatically updates incorrect dates, e.g. february 31th to march 3rd. - date.setUTCFullYear(dateComponents.year, dateComponents.month, dateComponents.day); + date.setUTCFullYear(dateComponents.yy, dateComponents.mm, dateComponents.dd); } return date; diff --git a/src/input-date/dom.js b/src/input-date/dom.js index 65344dc..bc5ca34 100644 --- a/src/input-date/dom.js +++ b/src/input-date/dom.js @@ -1,4 +1,4 @@ -'use strict'; +"use strict"; /** @const */ @@ -14,16 +14,16 @@ function inputDateDomValueGet(element) { function inputDateDomValueSet(element, value) { var date; - if (value !== '') { + if ("" !== value) { date = getDateFromRfc3339FullDateString(value); } if (date) { - inputDateComponentsSet(element, date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()); + inputDateComponentsSet(element, {yy: date.getUTCFullYear(), mm: date.getUTCMonth(), dd: date.getUTCDate()}); } else { //console.warn("The specified value '" + value + "' does not conform to the required format, 'yyyy-MM-dd'."); - inputDateComponentsSet(element, INPUT_DATE_YEAR_EMPTY, INPUT_DATE_MONTH_EMPTY, INPUT_DATE_DAY_EMPTY); + inputDateComponentsSet(element, {yy: INPUT_DATE_YEAR_EMPTY, mm: INPUT_DATE_MONTH_EMPTY, dd: INPUT_DATE_DAY_EMPTY}); } return value; @@ -34,5 +34,5 @@ function inputDateDomValueAsDateGet(element) { } function inputDateDomValueAsDateSet(element, value) { - inputDateComponentsSet(element, value.getUTCFullYear(), value.getUTCMonth(), value.getUTCDate()); + inputDateComponentsSet(element, {yy: value.getUTCFullYear(), mm: value.getUTCMonth(), dd: value.getUTCDate()}); } diff --git a/src/input-date/localization.js b/src/input-date/localization.js index 8c5ab67..fc00916 100644 --- a/src/input-date/localization.js +++ b/src/input-date/localization.js @@ -1,4 +1,4 @@ -'use strict'; +"use strict"; /** * @@ -13,47 +13,50 @@ function initInputDateLocalization() { inputDateFormatSeparatorGetter = inputDateLocalizationFormatSeparator; } -function inputDateLocalizationValueFormatter(input, year, month, day) { - var separator = inputDateFormatSeparatorGetter(input), +function inputDateLocalizationValueFormatter(components, element) { + var year, month, day, separator = inputDateFormatSeparatorGetter(element), value; - if (year === INPUT_DATE_YEAR_EMPTY) { - year = 'yyyy'; + if (components.yy === INPUT_DATE_YEAR_EMPTY) { + year = "yyyy"; } else { - if (year <= 9999) { - year = ('000' + year).slice(-4); + if (9999 >= components.yy) { + year = ("000" + components.yy).slice(-4); + } + else { + year = components.yy; } } - if (month === INPUT_DATE_MONTH_EMPTY) { - month = 'mm'; + if (components.mm === INPUT_DATE_MONTH_EMPTY) { + month = "mm"; } else { - month = ('00' + (month + 1)).slice(-2); + month = ("00" + (components.mm + 1)).slice(-2); } - if (day === INPUT_DATE_DAY_EMPTY) { - day = 'dd'; + if (components.dd === INPUT_DATE_DAY_EMPTY) { + day = "dd"; } else { - day = ('00' + day).slice(-2); + day = ("00" + components.dd).slice(-2); } var lang; - if (input.hasAttribute('lang')) { - lang = input.getAttribute('lang').toLowerCase(); + if (element.hasAttribute(INPUT_ATTR_LANG)) { + lang = element.getAttribute(INPUT_ATTR_LANG).toLowerCase(); } switch (lang) { - case 'en': - case 'en-us': + case "en": + case "en-us": value = month + separator + day + separator + year; break; - case 'en-gb': - case 'de': - case 'nl': + case "en-gb": + case "de": + case "nl": value = day + separator + month + separator + year; break; default: @@ -67,33 +70,33 @@ function inputDateLocalizationValueFormatter(input, year, month, day) { function inputDateLocalizationFormatOrder(input) { var lang, order; - if (input.hasAttribute('lang')) { - lang = input.getAttribute('lang').toLowerCase(); + if (input.hasAttribute(INPUT_ATTR_LANG)) { + lang = input.getAttribute(INPUT_ATTR_LANG).toLowerCase(); } switch (lang) { - case 'en': - case 'en-us': + case "en": + case "en-us": order = [ - DATECOMPONENT_MONTH, - DATECOMPONENT_DAY, - DATECOMPONENT_YEAR + INPUT_COMPONENT_MONTH, + INPUT_COMPONENT_DAY, + INPUT_COMPONENT_YEAR ]; break; - case 'en-gb': - case 'de': - case 'nl': + case "en-gb": + case "de": + case "nl": order = [ - DATECOMPONENT_DAY, - DATECOMPONENT_MONTH, - DATECOMPONENT_YEAR + INPUT_COMPONENT_DAY, + INPUT_COMPONENT_MONTH, + INPUT_COMPONENT_YEAR ]; break; default: order = [ - DATECOMPONENT_YEAR, - DATECOMPONENT_MONTH, - DATECOMPONENT_DAY + INPUT_COMPONENT_YEAR, + INPUT_COMPONENT_MONTH, + INPUT_COMPONENT_DAY ]; break; } @@ -104,22 +107,22 @@ function inputDateLocalizationFormatOrder(input) { function inputDateLocalizationFormatSeparator(input) { var lang, separator; - if (input.hasAttribute('lang')) { - lang = input.getAttribute('lang').toLowerCase(); + if (input.hasAttribute(INPUT_ATTR_LANG)) { + lang = input.getAttribute(INPUT_ATTR_LANG).toLowerCase(); } switch (lang) { - case 'en': - case 'en-us': - case 'en-gb': - case 'fr': - separator = '/'; + case "en": + case "en-us": + case "en-gb": + case "fr": + separator = "/"; break; - case 'de': - separator = '.'; + case "de": + separator = "."; break; default: - separator = '-'; + separator = "-"; break; } diff --git a/src/input-date/normalization.js b/src/input-date/normalization.js index fb04558..9a58ef3 100644 --- a/src/input-date/normalization.js +++ b/src/input-date/normalization.js @@ -1,15 +1,15 @@ -'use strict'; +"use strict"; /** * @file * Provides normalization of input[type=date] elements. */ -function inputDateNormalizationOnLoadFormatInputDateElements(element) { +function inputDateNormalizationOnLoadFormatInputElements(element) { var components = inputDateComponentsGet(element); - inputDateComponentsSet(element, components.year, components.month, components.day); + inputDateComponentsSet(element, components); } -function inputDateNormalizationOnSubmitNormalizeDateInput(element) { +function inputDateNormalizationOnSubmitNormalizeInput(element) { inputDomOriginalValueSetter.call(element, inputDateGetRfc3339(element)); } diff --git a/src/input-datetime-local/accessibility.js b/src/input-datetime-local/accessibility.js new file mode 100644 index 0000000..464e885 --- /dev/null +++ b/src/input-datetime-local/accessibility.js @@ -0,0 +1,226 @@ +"use strict"; + +/** + * Handles keyboard navigation for HTML input elements of type "datetime-local". + * + * @param {HTMLInputElement} element + * A HTMLInputElement of type "datetime-local". + * @param {KeyboardEvent} event + * A KeyboardEvent of type keydown. keypress events can't be used because IE doesn't trigger keypress events for + * keys like TAB and BACKSPACE. + */ +function inputDatetimeLocalAccessibilityOnKeydownHandleNavigation(element, event) { + var selectionStart = element.selectionStart; + + switch (event.key) { + case "Backspace": + case "U+0008": + case "Del": + inputDatetimeLocalClearComponent(element, selectionStart); + break; + case "Tab": + case "U+0009": + inputDatetimeLocalAccessibilityOnTabKeydownHandleNavigation(element, event, selectionStart); + return; + case "Left": + inputDatetimeLocalAccessibilitySelectPreviousComponent(element, selectionStart); + break; + case "Up": + inputDatetimeLocalAccessibilityIncreaseComponent(element, selectionStart, 1); + break; + case "Right": + inputDatetimeLocalAccessibilitySelectNextComponent(element, selectionStart); + break; + case "Down": + inputDatetimeLocalAccessibilityIncreaseComponent(element, selectionStart, -1); + break; + default: + return; + } + event.preventDefault(); +} + +function inputDatetimeLocalAccessibilityOnTabKeydownHandleNavigation(element, event, selectionStart) { + if (event.altKey || event.ctrlKey || event.metaKey) { + return; + } + else if (event.shiftKey) { + if (0 === selectionStart) { + inputDatetimeLocalAccessibilityNormalizeSelectedComponent(element, selectionStart); + return; + } + } + else if (element.selectionEnd === inputDomOriginalValueGetter.call(element).length) { + inputDatetimeLocalAccessibilityNormalizeSelectedComponent(element, selectionStart); + return; + } + + + if (event.shiftKey) { + inputDatetimeLocalAccessibilitySelectPreviousComponent(element, selectionStart); + } + else { + inputDatetimeLocalAccessibilitySelectNextComponent(element, selectionStart); + } + event.preventDefault(); +} + +/** + * Handles user input for HTML input elements of type "datetime-local". + * + * @param {HTMLInputElement} element + * A HTMLInputElement of type "datetime-local". + * @param {KeyboardEvent} event + * A KeyboardEvent of type keypress. User input should be handled on keypress events because these are triggered + * every time an actual character is being inserted (keydown and keyup events are triggered only once). + */ +function inputDatetimeLocalAccessibilityOnKeyPressHandleUserInput(element, event) { + var selectionStart, value, components, componentOrder, componentSeparator, selectedComponent, componentMin, componentMax, componentLimit; + + // Only allow numeric input. + if (47 < event.charCode && 58 > event.charCode) { + selectionStart = element.selectionStart; + + value = inputDomOriginalValueGetter.call(element); + components = inputDateComponentsGet(element); + + componentOrder = inputDateFormatOrderGetter(element); + componentSeparator = inputDateFormatSeparatorGetter(element); + selectedComponent = inputAccessibilityGetSelectedComponent(value, selectionStart, componentOrder, componentSeparator); + componentMin = inputComponentGetMinimum(element, selectedComponent); + componentMax = inputComponentGetMaximum(element, selectedComponent); + componentLimit = componentMax / 10; + + components[selectedComponent] = inputAccessibilityComplementComponent(components[selectedComponent], event.key, componentMin, componentMax, componentLimit); + + value = inputDatetimeLocalComponentsSet(element, components); + + if (components[selectedComponent] > componentLimit) { + inputDatetimeLocalAccessibilitySelectNextComponent(element, selectionStart); + } + else { + inputDomOriginalSetSelectionRange.apply(element, inputAccessibilityGetComponentRange(value, selectionStart, componentSeparator)); + } + } + event.preventDefault(); +} + +function inputDatetimeLocalAccessibilityOnFocusHandleInputSelection(element, event) { + var componentRange, value, selectionStart, componentSeparator; + + value = inputDomOriginalValueGetter.call(element); + componentSeparator = inputDatetimeLocalFormatSeparatorGetter(element); + + if (!value) { + value = inputDatetimeLocalComponentsSet(element, { + yy: INPUT_DATE_YEAR_EMPTY, + mm: INPUT_DATE_MONTH_EMPTY, + dd: INPUT_DATE_DAY_EMPTY, + hh: INPUT_TIME_COMPONENT_EMPTY, + ii: INPUT_TIME_COMPONENT_EMPTY, + ss: INPUT_TIME_COMPONENT_HIDDEN, + ms: INPUT_TIME_COMPONENT_HIDDEN + }); + selectionStart = 0; + } + else { + selectionStart = element.selectionStart; + } + + componentRange = inputAccessibilityGetComponentRange(value, selectionStart, componentSeparator); + + inputDomOriginalSetSelectionRange.apply(element, componentRange); + event.preventDefault(); +} + +function inputDatetimeLocalAccessibilityOnBlurHandleInputNormalization(element) { + inputDatetimeLocalAccessibilityNormalizeSelectedComponent(element, element.selectionStart); +} + +function inputDatetimeLocalClearComponent(element, selectionStart) { + var value = inputDomOriginalValueGetter.call(element), + components = inputDatetimeLocalComponentsGet(element), + componentOrder = inputDatetimeLocalFormatOrderGetter(element), + componentSeparator = inputDatetimeLocalFormatSeparatorGetter(element), + selectedComponent = inputAccessibilityGetSelectedComponent(value, selectionStart, componentOrder, componentSeparator); + + switch (selectedComponent) { + case INPUT_COMPONENT_YEAR: + components.yy = INPUT_DATE_YEAR_EMPTY; + break; + case INPUT_COMPONENT_MONTH: + components.mm = INPUT_DATE_MONTH_EMPTY; + break; + case INPUT_COMPONENT_DAY: + components.dd = INPUT_DATE_DAY_EMPTY; + break; + + case INPUT_COMPONENT_HOUR: + components.hh = INPUT_TIME_COMPONENT_EMPTY; + break; + case INPUT_COMPONENT_MINUTE: + components.ii = INPUT_TIME_COMPONENT_EMPTY; + break; + case INPUT_COMPONENT_SECOND: + components.ss = INPUT_TIME_COMPONENT_EMPTY; + break; + case INPUT_COMPONENT_MILISECOND: + components.ms = INPUT_TIME_COMPONENT_EMPTY; + break; + default: + return; + } + + value = inputDatetimeLocalComponentsSet(element, components); + inputDomOriginalSetSelectionRange.apply(element, inputAccessibilityGetComponentRange(value, selectionStart, componentSeparator)); +} + +function inputDatetimeLocalAccessibilityNormalizeSelectedComponent(element, selectionStart) { + var value = inputDomOriginalValueGetter.call(element), + components = inputDatetimeLocalComponentsGet(element), + componentOrder = inputDatetimeLocalFormatOrderGetter(element), + componentSeparator = inputDatetimeLocalFormatSeparatorGetter(element), + selectedComponent = inputAccessibilityGetSelectedComponent(value, selectionStart, componentOrder, componentSeparator), + componentMax = inputComponentGetMaximum(element, selectedComponent); + + if (components[selectedComponent] > componentMax) { + components[selectedComponent] = componentMax; + } + + inputDatetimeLocalComponentsSet(element, components); +} + +function inputDatetimeLocalAccessibilitySelectPreviousComponent(element, selectionStart) { + inputDatetimeLocalAccessibilityNormalizeSelectedComponent(element, selectionStart); + + var value = inputDomOriginalValueGetter.call(element), + componentSeparator = inputDatetimeLocalFormatSeparatorGetter(element), + selection = inputAccessibilityGetPreviousComponentRange(value, selectionStart, componentSeparator); + + inputDomOriginalSetSelectionRange.apply(element, selection); +} + +function inputDatetimeLocalAccessibilitySelectNextComponent(element, selectionStart) { + inputDatetimeLocalAccessibilityNormalizeSelectedComponent(element, selectionStart); + + var value = inputDomOriginalValueGetter.call(element), + componentSeparator = inputDatetimeLocalFormatSeparatorGetter(element), + selection = inputAccessibilityGetNextComponentRange(value, selectionStart, componentSeparator); + + inputDomOriginalSetSelectionRange.apply(element, selection); +} + +function inputDatetimeLocalAccessibilityIncreaseComponent(element, selectionStart, amount) { + var value = inputDomOriginalValueGetter.call(element), + components = inputDatetimeLocalComponentsGet(element), + componentOrder = inputDatetimeLocalFormatOrderGetter(element), + componentSeparator = inputDatetimeLocalFormatSeparatorGetter(element), + selectedComponent = inputAccessibilityGetSelectedComponent(value, selectionStart, componentOrder, componentSeparator), + componentMin = inputComponentGetMinimum(element, selectedComponent), + componentMax = inputComponentGetMaximum(element, selectedComponent); + + components[selectedComponent] = inputAccessibilityIncreaseComponent(components[selectedComponent], amount, componentMin, componentMax); + + value = inputDatetimeLocalComponentsSet(element, components); + inputDomOriginalSetSelectionRange.apply(element, inputAccessibilityGetComponentRange(value, selectionStart, componentSeparator)); +} diff --git a/src/input-datetime-local/base.js b/src/input-datetime-local/base.js new file mode 100644 index 0000000..957a590 --- /dev/null +++ b/src/input-datetime-local/base.js @@ -0,0 +1,144 @@ +"use strict"; + +/** + * @file + * Initialization code for input elements of type datetime-local and code shared between the optional features (dom, accessibility, etc). + * + * @see {@link http://www.w3.org/TR/html-markup/input.datetime-local.html} + */ + +var inputDatetimeLocalValueFormatter, + inputDatetimeLocalFormatOrderGetter, + inputDatetimeLocalFormatSeparatorGetter; + +function initInputDatetimeLocal() { + inputDatetimeLocalValueFormatter = inputDatetimeLocalDefaultValueFormatter; + inputDatetimeLocalFormatOrderGetter = inputDatetimeLocalDefaultFormatOrder; + inputDatetimeLocalFormatSeparatorGetter = inputDatetimeLocalDefaultFormatSeparator; +} + +function inputDatetimeLocalComponentsGet(input) { + if (input[INPUT_PROPERTY_COMPONENTS] === undefined) { + input[INPUT_PROPERTY_COMPONENTS] = inputDatetimeLocalComponentsFromValue(input.getAttribute(INPUT_PROPERTY_VALUE)); + } + + return input[INPUT_PROPERTY_COMPONENTS]; +} + +function inputDatetimeLocalComponentsSet(element, components) { + var formattedValue; + + element[INPUT_PROPERTY_COMPONENTS] = { + yy: components[INPUT_COMPONENT_YEAR], + mm: components[INPUT_COMPONENT_MONTH], + dd: components[INPUT_COMPONENT_DAY], + + hh: components[INPUT_COMPONENT_HOUR], + ii: components[INPUT_COMPONENT_MINUTE], + ss: components[INPUT_COMPONENT_SECOND], + ms: components[INPUT_COMPONENT_MILISECOND] + }; + + formattedValue = inputDatetimeLocalValueFormatter(element[INPUT_PROPERTY_COMPONENTS], element); + inputDomOriginalValueSetter.call(element, formattedValue); + return formattedValue; +} + + +function inputDatetimeLocalComponentsFromValue(value) { + var components; + + if (value) { + components = inputDatetimeLocalValidValueStringToComponents(value); + } + + if (components) { + return components; + } + else { + return { + yy: INPUT_DATE_YEAR_EMPTY, + mm: INPUT_DATE_MONTH_EMPTY, + dd: INPUT_DATE_DAY_EMPTY, + + hh: INPUT_TIME_COMPONENT_EMPTY, + ii: INPUT_TIME_COMPONENT_EMPTY, + ss: INPUT_TIME_COMPONENT_HIDDEN, + ms: INPUT_TIME_COMPONENT_HIDDEN + }; + } +} + +/** + * + * @param str + * @returns {*} + * + * @see {@link http://www.w3.org/TR/html/infrastructure.html#floating-dates-and-times} + */ +function inputDatetimeLocalValidValueStringToComponents(str) { + var date, time; + + str = str.split("T"); + if (2 === str.length) { + date = getDateFromRfc3339FullDateString(str[0]); + if (null === date) { + return null; + } + + time = inputTimeValidTimeStringToComponents(str[1]); + if (null === time) { + return null; + } + + return { + yy: date.getUTCFullYear(), + mm: date.getUTCMonth(), + dd: date.getUTCDate(), + + hh: time.hh, + ii: time.ii, + ss: time.ss, + ms: time.ms + }; + } + return null; +} + +function inputDatetimeLocalGetRfc3339(element) { + var components = inputDatetimeLocalComponentsGet(element); + + if (components.hh > INPUT_TIME_COMPONENT_EMPTY && components.ii > INPUT_TIME_COMPONENT_EMPTY) { + if (components.ss === INPUT_TIME_COMPONENT_EMPTY) { + components.ss = INPUT_TIME_COMPONENT_HIDDEN; + } + if (components.ms === INPUT_TIME_COMPONENT_EMPTY) { + components.ms = INPUT_TIME_COMPONENT_HIDDEN; + } + return inputDateFuzzyRfc3339ValueFormatter(components) + "T" + inputTimeDefaultValueFormatter(components); + } + else { + return ""; + } +} + +function inputDatetimeLocalDefaultValueFormatter(components) { + return inputDateFuzzyRfc3339ValueFormatter(components) + " " + inputTimeDefaultValueFormatter(components); +} + + +function inputDatetimeLocalDefaultFormatOrder() { + return [ + INPUT_COMPONENT_YEAR, + INPUT_COMPONENT_MONTH, + INPUT_COMPONENT_DAY, + INPUT_COMPONENT_HOUR, + INPUT_COMPONENT_MINUTE, + INPUT_COMPONENT_SECOND, + INPUT_COMPONENT_MILISECOND + ]; +} + +function inputDatetimeLocalDefaultFormatSeparator() { + return ["-", " ", ":", "."]; +} diff --git a/src/input-datetime-local/dom.js b/src/input-datetime-local/dom.js new file mode 100644 index 0000000..d286b7e --- /dev/null +++ b/src/input-datetime-local/dom.js @@ -0,0 +1,62 @@ +"use strict"; + +function inputDatetimeLocalDomValueGet(element) { + return inputDatetimeLocalGetRfc3339(element); +} + +function inputDatetimeLocalDomValueSet(element, value) { + var components; + + if ("" !== value) { + components = inputDatetimeLocalValidValueStringToComponents(value + ""); + } + + if (components) { + inputDatetimeLocalComponentsSet(element, components); + } + else { + inputDatetimeLocalComponentsSet(element, { + yy: INPUT_DATE_YEAR_EMPTY, + mm: INPUT_DATE_MONTH_EMPTY, + dd: INPUT_DATE_DAY_EMPTY, + hh: INPUT_TIME_COMPONENT_EMPTY, + ii: INPUT_TIME_COMPONENT_EMPTY, + ss: INPUT_TIME_COMPONENT_HIDDEN, + ms: INPUT_TIME_COMPONENT_HIDDEN + }); + } + + return value; +} + +function inputDatetimeLocalDomValueAsDateGet(element) { + var components = inputDatetimeLocalComponentsGet(element), date = null; + + if (components.hh !== INPUT_TIME_COMPONENT_EMPTY && components.ii !== INPUT_TIME_COMPONENT_EMPTY) { + date = inputDateGetDate(element); + if (date) { + date.setUTCHours(components.hh); + date.setUTCMinutes(components.ii); + if (components.ss > INPUT_TIME_COMPONENT_EMPTY) { + date.setUTCSeconds(components.ss); + } + if (components.ms > INPUT_TIME_COMPONENT_EMPTY) { + date.setUTCMilliseconds(components.ms); + } + } + } + + return date; +} + +function inputDatetimeLocalDomValueAsDateSet(element, value) { + inputDatetimeLocalComponentsSet(element, { + yy: value.getUTCFullYear(), + mm: value.getUTCMonth(), + dd: value.getUTCDate(), + hh: value.getUTCHours(), + ii: value.getUTCMinutes(), + ss: value.getUTCSeconds(), + ms: value.getUTCMilliseconds() + }); +} diff --git a/src/input-datetime-local/normalization.js b/src/input-datetime-local/normalization.js new file mode 100644 index 0000000..31a459f --- /dev/null +++ b/src/input-datetime-local/normalization.js @@ -0,0 +1,15 @@ +"use strict"; + +/** + * @file + * Provides normalization of input[type=datetime-local] elements. + */ + +function inputDatetimeLocalNormalizationOnLoadFormatInputElements(element) { + var components = inputDatetimeLocalComponentsGet(element); + inputDatetimeLocalComponentsSet(element, components); +} + +function inputDatetimeLocalNormalizationOnSubmitNormalizeInput(element) { + inputDomOriginalValueSetter.call(element, inputDatetimeLocalGetRfc3339(element)); +} diff --git a/src/input-time/accessibility.js b/src/input-time/accessibility.js index cc5d11f..103f796 100644 --- a/src/input-time/accessibility.js +++ b/src/input-time/accessibility.js @@ -1,4 +1,4 @@ -'use strict'; +"use strict"; /** * Handles keyboard navigation for HTML input elements of type "time". @@ -13,46 +13,25 @@ function inputTimeAccessibilityOnKeydownHandleNavigation(element, event) { var selectionStart = element.selectionStart; switch (event.key) { - case 'Backspace': - case 'U+0008': - case 'Del': - inputTimeClearComponent(element, selectionStart); - break; - case 'Tab': - case 'U+0009': - if (event.altKey || event.ctrlKey || event.metaKey) { - return; - } - else if (event.shiftKey) { - if (selectionStart === 0) { - inputTimeAccessibilityNormalizeSelectedComponent(element, selectionStart); - return; - } - } - else if (element.selectionEnd === inputDomOriginalValueGetter.call(element).length) { - inputTimeAccessibilityNormalizeSelectedComponent(element, selectionStart); - return; - } - - - if (event.shiftKey) { - inputTimeAccessibilitySelectPreviousComponent(element, selectionStart); - } - else { - inputTimeAccessibilitySelectNextComponent(element, selectionStart); - } - - break; - case 'Left': + case "Backspace": + case "U+0008": + case "Del": + inputTimeAccessibilityClearComponent(element, selectionStart); + break; + case "Tab": + case "U+0009": + inputTimeAccessibilityOnTabKeydownHandleNavigation(element, event, selectionStart); + return; + case "Left": inputTimeAccessibilitySelectPreviousComponent(element, selectionStart); break; - case 'Up': + case "Up": inputTimeAccessibilityIncreaseComponent(element, selectionStart, 1); break; - case 'Right': + case "Right": inputTimeAccessibilitySelectNextComponent(element, selectionStart); break; - case 'Down': + case "Down": inputTimeAccessibilityIncreaseComponent(element, selectionStart, -1); break; default: @@ -61,6 +40,31 @@ function inputTimeAccessibilityOnKeydownHandleNavigation(element, event) { event.preventDefault(); } +function inputTimeAccessibilityOnTabKeydownHandleNavigation(element, event, selectionStart) { + if (event.altKey || event.ctrlKey || event.metaKey) { + return; + } + else if (event.shiftKey) { + if (0 === selectionStart) { + inputTimeAccessibilityNormalizeSelectedComponent(element, selectionStart); + return; + } + } + else if (element.selectionEnd === inputDomOriginalValueGetter.call(element).length) { + inputTimeAccessibilityNormalizeSelectedComponent(element, selectionStart); + return; + } + + + if (event.shiftKey) { + inputTimeAccessibilitySelectPreviousComponent(element, selectionStart); + } + else { + inputTimeAccessibilitySelectNextComponent(element, selectionStart); + } + event.preventDefault(); +} + /** * Handles user input for HTML input elements of type "time". * @@ -71,77 +75,56 @@ function inputTimeAccessibilityOnKeydownHandleNavigation(element, event) { * every time an actual character is being inserted (keydown and keyup events are triggered only once). */ function inputTimeAccessibilityOnKeyPressHandleUserInput(element, event) { + var selectionStart, value, components, componentOrder, componentSeparator, selectedComponent, componentMin, componentMax, componentLimit; + // Only allow numeric input. - if (event.charCode > 47 && event.charCode < 58) { - var selectionStart = element.selectionStart, - selectNext = false, - - value = inputDomOriginalValueGetter.call(element), - components = inputTimeComponentsGet(element), - - componentOrder = inputTimeFormatOrderGetter(element), - componentSeparator = inputTimeFormatSeparatorGetter(element), - selectedComponent = inputTimeAccessibilityGetSelectedComponent(value, selectionStart, componentOrder, componentSeparator); - - switch (selectedComponent) { - case INPUT_TIME_COMPONENT_HOUR: - components.hour = inputAccessibilityComplementComponent(components.hour, event.key, INPUT_TIME_COMPONENT_HOUR_MIN, INPUT_TIME_COMPONENT_HOUR_MAX, 2); - if (components.hour > 2) { - selectNext = true; - } - break; - case INPUT_TIME_COMPONENT_MINUTE: - components.minute = inputAccessibilityComplementComponent(components.minute, event.key, INPUT_TIME_COMPONENT_MINUTE_MIN, INPUT_TIME_COMPONENT_MINUTE_MAX, 5); - if (components.minute > 5) { - selectNext = true; - } - break; - case INPUT_TIME_COMPONENT_SECOND: - components.second = inputAccessibilityComplementComponent(components.second, event.key, INPUT_TIME_COMPONENT_SECOND_MIN, INPUT_TIME_COMPONENT_SECOND_MAX, 5); - if (components.second > 5) { - selectNext = true; - } - break; - case INPUT_TIME_COMPONENT_MILISECOND: - components.milisecond = inputAccessibilityComplementComponent(components.second, event.key, INPUT_TIME_COMPONENT_MILISECOND_MIN, INPUT_TIME_COMPONENT_MILISECOND_MAX, 99); - if (components.milisecond > 99) { - selectNext = true; - } - break; - default: - return; - } + if (47 < event.charCode && 58 > event.charCode) { + selectionStart = element.selectionStart; + + value = inputDomOriginalValueGetter.call(element); + components = inputTimeComponentsGet(element); - value = inputTimeComponentsSet(element, components.hour, components.minute, components.second, components.milisecond); + componentOrder = inputTimeFormatOrderGetter(element); + componentSeparator = inputTimeFormatSeparatorGetter(element); + selectedComponent = inputAccessibilityGetSelectedComponent(value, selectionStart, componentOrder, componentSeparator); + componentMin = inputComponentGetMinimum(element, selectedComponent); + componentMax = inputComponentGetMaximum(element, selectedComponent); + componentLimit = componentMax / 10; - var selection = inputAccessibilityGetComponentRange(value, selectionStart, componentSeparator); - if (selectNext) { - inputTimeAccessibilitySelectNextComponent(element, selection[0]); + components[selectedComponent] = inputAccessibilityComplementComponent(components[selectedComponent], event.key, componentMin, componentMax, componentLimit); + + value = inputTimeComponentsSet(element, components); + + if (components[selectedComponent] > componentLimit) { + inputTimeAccessibilitySelectNextComponent(element, selectionStart); } else { - element.setSelectionRange.apply(element, selection); + inputDomOriginalSetSelectionRange.apply(element, inputAccessibilityGetComponentRange(value, selectionStart, componentSeparator)); } } event.preventDefault(); } function inputTimeAccessibilityOnFocusHandleInputSelection(element, event) { - var componentRange, value, selectionStart, componentSeparator; + var value, selectionStart, componentSeparator; value = inputDomOriginalValueGetter.call(element); componentSeparator = inputTimeFormatSeparatorGetter(element); if (!value) { - value = inputTimeComponentsSet(element, INPUT_TIME_COMPONENT_EMPTY, INPUT_TIME_COMPONENT_EMPTY, INPUT_TIME_COMPONENT_HIDDEN, INPUT_TIME_COMPONENT_HIDDEN); + value = inputTimeComponentsSet(element, { + hh: INPUT_TIME_COMPONENT_EMPTY, + ii: INPUT_TIME_COMPONENT_EMPTY, + ss: INPUT_TIME_COMPONENT_HIDDEN, + ms: INPUT_TIME_COMPONENT_HIDDEN + }); selectionStart = 0; } else { selectionStart = element.selectionStart; } - componentRange = inputAccessibilityGetComponentRange(value, selectionStart, componentSeparator); - - element.setSelectionRange.apply(element, componentRange); + inputDomOriginalSetSelectionRange.apply(element, inputAccessibilityGetComponentRange(value, selectionStart, componentSeparator)); event.preventDefault(); } @@ -149,117 +132,63 @@ function inputTimeAccessibilityOnBlurHandleInputNormalization(element) { inputTimeAccessibilityNormalizeSelectedComponent(element, element.selectionStart); } -function inputTimeAccessibilityGetSelectedComponent(value, selectionStart, componentOrder, componentSeparator) { - return componentOrder[inputAccessibilityGetSelectedComponentNumber(value, selectionStart, componentSeparator)]; -} - -function inputTimeClearComponent(input, selectionStart) { - var value = inputDomOriginalValueGetter.call(input), - components = inputTimeComponentsGet(input), - componentOrder = inputTimeFormatOrderGetter(input), - componentSeparator = inputTimeFormatSeparatorGetter(input), - selectedComponent = inputTimeAccessibilityGetSelectedComponent(value, selectionStart, componentOrder, componentSeparator); +function inputTimeAccessibilityClearComponent(element, selectionStart) { + var value = inputDomOriginalValueGetter.call(element), + components = inputTimeComponentsGet(element), + componentOrder = inputTimeFormatOrderGetter(element), + componentSeparator = inputTimeFormatSeparatorGetter(element), + selectedComponent = inputAccessibilityGetSelectedComponent(value, selectionStart, componentOrder, componentSeparator); - switch (selectedComponent) { - case INPUT_TIME_COMPONENT_HOUR: - components.hour = INPUT_TIME_COMPONENT_EMPTY; - break; - case INPUT_TIME_COMPONENT_MINUTE: - components.minute = INPUT_TIME_COMPONENT_EMPTY; - break; - case INPUT_TIME_COMPONENT_SECOND: - components.second = INPUT_TIME_COMPONENT_EMPTY; - break; - case INPUT_TIME_COMPONENT_MILISECOND: - components.milisecond = INPUT_TIME_COMPONENT_EMPTY; - break; - default: - return; - } + components[selectedComponent] = INPUT_TIME_COMPONENT_EMPTY; - value = inputTimeComponentsSet(input, components.hour, components.minute, components.second, components.milisecond); - input.setSelectionRange.apply(input, inputAccessibilityGetComponentRange(value, selectionStart, componentSeparator)); + value = inputTimeComponentsSet(element, components); + inputDomOriginalSetSelectionRange.apply(element, inputAccessibilityGetComponentRange(value, selectionStart, componentSeparator)); } -function inputTimeAccessibilityNormalizeSelectedComponent(input, selectionStart) { - var value = inputDomOriginalValueGetter.call(input), - components = inputTimeComponentsGet(input), - componentOrder = inputTimeFormatOrderGetter(input), - componentSeparator = inputTimeFormatSeparatorGetter(input), - selectedComponent = inputTimeAccessibilityGetSelectedComponent(value, selectionStart, componentOrder, componentSeparator); - - switch (selectedComponent) { - case INPUT_TIME_COMPONENT_HOUR: - if (components.hour > INPUT_TIME_COMPONENT_HOUR_MAX) { - components.hour = INPUT_TIME_COMPONENT_HOUR_MAX; - } - break; - case INPUT_TIME_COMPONENT_MINUTE: - if (components.minute > INPUT_TIME_COMPONENT_MINUTE_MAX) { - components.minute = INPUT_TIME_COMPONENT_MINUTE_MAX; - } - break; - case INPUT_TIME_COMPONENT_SECOND: - if (components.second > INPUT_TIME_COMPONENT_SECOND_MAX) { - components.second = INPUT_TIME_COMPONENT_SECOND_MAX; - } - break; - case INPUT_TIME_COMPONENT_MILISECOND: - if (components.milisecond > INPUT_TIME_COMPONENT_MILISECOND_MAX) { - components.milisecond = INPUT_TIME_COMPONENT_MILISECOND_MAX; - } - break; - default: - return; +function inputTimeAccessibilityNormalizeSelectedComponent(element, selectionStart) { + var value = inputDomOriginalValueGetter.call(element), + components = inputTimeComponentsGet(element), + componentOrder = inputTimeFormatOrderGetter(element), + componentSeparator = inputTimeFormatSeparatorGetter(element), + selectedComponent = inputAccessibilityGetSelectedComponent(value, selectionStart, componentOrder, componentSeparator), + componentMax = inputComponentGetMaximum(element, selectedComponent); + + if (components[selectedComponent] > componentMax) { + components[selectedComponent] = componentMax; } - inputTimeComponentsSet(input, components.hour, components.minute, components.second, components.milisecond); + inputTimeComponentsSet(element, components); } function inputTimeAccessibilitySelectPreviousComponent(element, selectionStart) { inputTimeAccessibilityNormalizeSelectedComponent(element, selectionStart); var value = inputDomOriginalValueGetter.call(element), - componentSeparator = inputTimeFormatSeparatorGetter(element), - selection = inputAccessibilityGetPreviousComponentRange(value, selectionStart, componentSeparator); + componentSeparator = inputTimeFormatSeparatorGetter(element); - element.setSelectionRange(selection[0], selection[1]); + inputDomOriginalSetSelectionRange.apply(element, inputAccessibilityGetPreviousComponentRange(value, selectionStart, componentSeparator)); } function inputTimeAccessibilitySelectNextComponent(element, selectionStart) { inputTimeAccessibilityNormalizeSelectedComponent(element, selectionStart); var value = inputDomOriginalValueGetter.call(element), - componentSeparator = inputTimeFormatSeparatorGetter(element), - selection = inputAccessibilityGetNextComponentRange(value, selectionStart, componentSeparator); + componentSeparator = inputTimeFormatSeparatorGetter(element); - element.setSelectionRange(selection[0], selection[1]); + inputDomOriginalSetSelectionRange.apply(element, inputAccessibilityGetNextComponentRange(value, selectionStart, componentSeparator)); } -function inputTimeAccessibilityIncreaseComponent(input, selectionStart, amount) { - var value = inputDomOriginalValueGetter.call(input), - components = inputTimeComponentsGet(input), - componentOrder = inputTimeFormatOrderGetter(input), - componentSeparator = inputTimeFormatSeparatorGetter(input), - selectedComponent = inputTimeAccessibilityGetSelectedComponent(value, selectionStart, componentOrder, componentSeparator); +function inputTimeAccessibilityIncreaseComponent(element, selectionStart, amount) { + var value = inputDomOriginalValueGetter.call(element), + components = inputTimeComponentsGet(element), + componentOrder = inputTimeFormatOrderGetter(element), + componentSeparator = inputTimeFormatSeparatorGetter(element), + selectedComponent = inputAccessibilityGetSelectedComponent(value, selectionStart, componentOrder, componentSeparator), + componentMin = inputComponentGetMinimum(element, selectedComponent), + componentMax = inputComponentGetMaximum(element, selectedComponent); - switch (selectedComponent) { - case INPUT_TIME_COMPONENT_HOUR: - components.hour = inputAccessibilityIncreaseComponent(components.hour, amount, INPUT_TIME_COMPONENT_HOUR_MIN, INPUT_TIME_COMPONENT_HOUR_MAX); - break; - case INPUT_TIME_COMPONENT_MINUTE: - components.minute = inputAccessibilityIncreaseComponent(components.minute, amount, INPUT_TIME_COMPONENT_MINUTE_MIN, INPUT_TIME_COMPONENT_MINUTE_MAX); - break; - case INPUT_TIME_COMPONENT_SECOND: - components.second = inputAccessibilityIncreaseComponent(components.second, amount, INPUT_TIME_COMPONENT_SECOND_MIN, INPUT_TIME_COMPONENT_SECOND_MAX); - break; - case INPUT_TIME_COMPONENT_MILISECOND: - components.milisecond = inputAccessibilityIncreaseComponent(components.milisecond, amount, INPUT_TIME_COMPONENT_MILISECOND_MIN, INPUT_TIME_COMPONENT_MILISECOND_MAX); - break; - default: - return; - } + components[selectedComponent] = inputAccessibilityIncreaseComponent(components[selectedComponent], amount, componentMin, componentMax); - value = inputTimeComponentsSet(input, components.hour, components.minute, components.second, components.milisecond); - input.setSelectionRange.apply(input, inputAccessibilityGetComponentRange(value, selectionStart, componentSeparator)); + value = inputTimeComponentsSet(element, components); + inputDomOriginalSetSelectionRange.apply(element, inputAccessibilityGetComponentRange(value, selectionStart, componentSeparator)); } diff --git a/src/input-time/base.js b/src/input-time/base.js index 30b9b94..95c8e93 100644 --- a/src/input-time/base.js +++ b/src/input-time/base.js @@ -1,4 +1,4 @@ -'use strict'; +"use strict"; /** * @file @@ -9,10 +9,10 @@ */ /** @const */ -var INPUT_TIME_COMPONENT_HOUR = 1, - INPUT_TIME_COMPONENT_MINUTE = 2, - INPUT_TIME_COMPONENT_SECOND = 4, - INPUT_TIME_COMPONENT_MILISECOND = 8; +var INPUT_COMPONENT_HOUR = "hh", + INPUT_COMPONENT_MINUTE = "ii", + INPUT_COMPONENT_SECOND = "ss", + INPUT_COMPONENT_MILISECOND = "ms"; /** @const */ var INPUT_TIME_COMPONENT_EMPTY = -1; @@ -21,23 +21,26 @@ var INPUT_TIME_COMPONENT_EMPTY = -1; var INPUT_TIME_COMPONENT_HIDDEN = -2; /** @const */ -var INPUT_TIME_COMPONENT_HOUR_MIN = 0; -var INPUT_TIME_COMPONENT_HOUR_MAX = 23; +var INPUT_TIME_COMPONENT_HOUR_MIN = 0, + INPUT_TIME_COMPONENT_HOUR_MAX = 23; -var INPUT_TIME_COMPONENT_MINUTE_MIN = 0; -var INPUT_TIME_COMPONENT_MINUTE_MAX = 59; +/** @const */ +var INPUT_TIME_COMPONENT_MINUTE_MIN = 0, + INPUT_TIME_COMPONENT_MINUTE_MAX = 59; -var INPUT_TIME_COMPONENT_SECOND_MIN = 0; -var INPUT_TIME_COMPONENT_SECOND_MAX = 59; +/** @const */ +var INPUT_TIME_COMPONENT_SECOND_MIN = 0, + INPUT_TIME_COMPONENT_SECOND_MAX = 59; -var INPUT_TIME_COMPONENT_MILISECOND_MIN = 0; -var INPUT_TIME_COMPONENT_MILISECOND_MAX = 999; +/** @const */ +var INPUT_TIME_COMPONENT_MILISECOND_MIN = 0, + INPUT_TIME_COMPONENT_MILISECOND_MAX = 999; var inputTimeValidTimeStringRegExp = /^(([0-1][0-9])|(2[0-3])):[0-5][0-9](:[0-5][0-9](\.[0-9]{1,3})?)?$/; -var inputTimeValueFormatter; -var inputTimeFormatOrderGetter; -var inputTimeFormatSeparatorGetter; +var inputTimeValueFormatter, + inputTimeFormatOrderGetter, + inputTimeFormatSeparatorGetter; function initInputTime() { inputTimeValueFormatter = inputTimeDefaultValueFormatter; @@ -46,46 +49,45 @@ function initInputTime() { } function inputTimeComponentsGet(input) { - if (input.__polyformfillInputTime === undefined) { - inputTimeInitInternalValue(input); + if (input[INPUT_PROPERTY_COMPONENTS] === undefined) { + input[INPUT_PROPERTY_COMPONENTS] = inputTimeComponentsFromValue(input.getAttribute(INPUT_PROPERTY_VALUE)); } - return input.__polyformfillInputTime; + return input[INPUT_PROPERTY_COMPONENTS]; } -function inputTimeComponentsSet(input, hour, minute, second, milisecond) { +function inputTimeComponentsSet(element, components) { var formattedValue; - input.__polyformfillInputTime = { - hour: hour, - minute: minute, - second: second, - milisecond: milisecond + element[INPUT_PROPERTY_COMPONENTS] = { + hh: components[INPUT_COMPONENT_HOUR], + ii: components[INPUT_COMPONENT_MINUTE], + ss: components[INPUT_COMPONENT_SECOND], + ms: components[INPUT_COMPONENT_MILISECOND] }; - formattedValue = inputTimeValueFormatter(input, hour, minute, second, milisecond); - inputDomOriginalValueSetter.call(input, formattedValue); + formattedValue = inputTimeValueFormatter(element[INPUT_PROPERTY_COMPONENTS], element); + inputDomOriginalValueSetter.call(element, formattedValue); return formattedValue; } -function inputTimeInitInternalValue(input) { - var value = input.getAttribute('value'), - components; +function inputTimeComponentsFromValue(value) { + var components; - if (value !== '') { + if ("" !== value) { components = inputTimeValidTimeStringToComponents(value); } if (components) { - input.__polyformfillInputTime = components; + return components; } else { - input.__polyformfillInputTime = { - hour: INPUT_TIME_COMPONENT_EMPTY, - minute: INPUT_TIME_COMPONENT_EMPTY, - second: INPUT_TIME_COMPONENT_HIDDEN, - milisecond: INPUT_TIME_COMPONENT_HIDDEN + return { + hh: INPUT_TIME_COMPONENT_EMPTY, + ii: INPUT_TIME_COMPONENT_EMPTY, + ss: INPUT_TIME_COMPONENT_HIDDEN, + ms: INPUT_TIME_COMPONENT_HIDDEN }; } } @@ -109,14 +111,14 @@ function inputTimeValidTimeStringToComponents(str) { components[3] = INPUT_TIME_COMPONENT_HIDDEN; } else { - components[3] = (components[3] + '000').slice(0, 3); + components[3] = (components[3] + "000").slice(0, 3); } return { - hour: parseInt(components[0], 10), - minute: parseInt(components[1], 10), - second: parseInt(components[2], 10), - milisecond: parseInt(components[3], 10) + hh: parseInt(components[0], 10), + ii: parseInt(components[1], 10), + ss: parseInt(components[2], 10), + ms: parseInt(components[3], 10) }; } return null; @@ -125,54 +127,54 @@ function inputTimeValidTimeStringToComponents(str) { function inputTimeGetRfc3339(element) { var components = inputTimeComponentsGet(element); - if (components.hour > INPUT_TIME_COMPONENT_EMPTY && components.minute > INPUT_TIME_COMPONENT_EMPTY) { - if (components.second === INPUT_TIME_COMPONENT_EMPTY) { - components.second = INPUT_TIME_COMPONENT_HIDDEN + if (components.hh > INPUT_TIME_COMPONENT_EMPTY && components.ii > INPUT_TIME_COMPONENT_EMPTY) { + if (components.ss === INPUT_TIME_COMPONENT_EMPTY) { + components.ss = INPUT_TIME_COMPONENT_HIDDEN; } - if (components.milisecond === INPUT_TIME_COMPONENT_EMPTY) { - components.milisecond = INPUT_TIME_COMPONENT_HIDDEN + if (components.ms === INPUT_TIME_COMPONENT_EMPTY) { + components.ms = INPUT_TIME_COMPONENT_HIDDEN; } - return inputTimeDefaultValueFormatter(element, components.hour, components.minute, components.second, components.milisecond); + return inputTimeDefaultValueFormatter(components); } else { - return ''; + return ""; } } -function inputTimeDefaultValueFormatter(input, hour, minute, second, milisecond) { +function inputTimeDefaultValueFormatter(components) { var formatted; - if (hour === INPUT_TIME_COMPONENT_EMPTY) { - formatted = '--'; + if (components.hh === INPUT_TIME_COMPONENT_EMPTY) { + formatted = "--"; } else { - formatted = ('00' + hour).slice(-2); + formatted = ("00" + components.hh).slice(-2); } - formatted += ':'; - if (minute === INPUT_TIME_COMPONENT_EMPTY) { - formatted += '--'; + formatted += ":"; + if (components.ii === INPUT_TIME_COMPONENT_EMPTY) { + formatted += "--"; } else { - formatted += ('00' + minute).slice(-2); + formatted += ("00" + components.ii).slice(-2); } - if (second !== INPUT_TIME_COMPONENT_HIDDEN) { - formatted += ':'; - if (second === INPUT_TIME_COMPONENT_EMPTY) { - formatted += '--'; + if (components.ss !== INPUT_TIME_COMPONENT_HIDDEN) { + formatted += ":"; + if (components.ss === INPUT_TIME_COMPONENT_EMPTY) { + formatted += "--"; } else { - formatted += ('00' + second).slice(-2); + formatted += ("00" + components.ss).slice(-2); } - if (milisecond !== INPUT_TIME_COMPONENT_HIDDEN) { - formatted += '.'; - if (milisecond === INPUT_TIME_COMPONENT_EMPTY) { - formatted += '---'; + if (components.ms !== INPUT_TIME_COMPONENT_HIDDEN) { + formatted += "."; + if (components.ms === INPUT_TIME_COMPONENT_EMPTY) { + formatted += "---"; } else { - formatted += ('000' + milisecond).slice(-3); + formatted += ("000" + components.ms).slice(-3); } } } @@ -183,13 +185,13 @@ function inputTimeDefaultValueFormatter(input, hour, minute, second, milisecond) function inputTimeDefaultFormatOrder() { return [ - INPUT_TIME_COMPONENT_HOUR, - INPUT_TIME_COMPONENT_MINUTE, - INPUT_TIME_COMPONENT_SECOND, - INPUT_TIME_COMPONENT_MILISECOND + INPUT_COMPONENT_HOUR, + INPUT_COMPONENT_MINUTE, + INPUT_COMPONENT_SECOND, + INPUT_COMPONENT_MILISECOND ]; } function inputTimeDefaultFormatSeparator() { - return [':', '.']; + return [":", "."]; } diff --git a/src/input-time/dom.js b/src/input-time/dom.js index 7aba0d9..c8d59db 100644 --- a/src/input-time/dom.js +++ b/src/input-time/dom.js @@ -1,4 +1,4 @@ -'use strict'; +"use strict"; /** * @file @@ -23,15 +23,20 @@ function inputTimeDomValueGet(element) { function inputTimeDomValueSet(element, value) { var components; - if (value !== '') { + if ("" !== value) { components = inputTimeValidTimeStringToComponents(value); } if (components) { - inputTimeComponentsSet(element, components.hour, components.minute, components.second, components.milisecond); + inputTimeComponentsSet(element, components); } else { - inputTimeComponentsSet(element, INPUT_TIME_COMPONENT_EMPTY, INPUT_TIME_COMPONENT_EMPTY, INPUT_TIME_COMPONENT_EMPTY, INPUT_TIME_COMPONENT_EMPTY); + inputTimeComponentsSet(element, { + hh: INPUT_TIME_COMPONENT_EMPTY, + ii: INPUT_TIME_COMPONENT_EMPTY, + ss: INPUT_TIME_COMPONENT_EMPTY, + ms: INPUT_TIME_COMPONENT_EMPTY + }); } return value; @@ -40,15 +45,15 @@ function inputTimeDomValueSet(element, value) { function inputTimeDomValueAsDateGet(element) { var components = inputTimeComponentsGet(element), date = null; - if (components.hour !== INPUT_TIME_COMPONENT_EMPTY && components.minute !== INPUT_TIME_COMPONENT_EMPTY) { + if (components.hh !== INPUT_TIME_COMPONENT_EMPTY && components.ii !== INPUT_TIME_COMPONENT_EMPTY) { date = new Date(0); - date.setUTCHours(components.hour); - date.setUTCMinutes(components.minute); - if (components.second > INPUT_TIME_COMPONENT_EMPTY) { - date.setUTCSeconds(components.second); + date.setUTCHours(components.hh); + date.setUTCMinutes(components.ii); + if (components.ss > INPUT_TIME_COMPONENT_EMPTY) { + date.setUTCSeconds(components.ss); } - if (components.milisecond > INPUT_TIME_COMPONENT_EMPTY) { - date.setUTCMilliseconds(components.milisecond); + if (components.ms > INPUT_TIME_COMPONENT_EMPTY) { + date.setUTCMilliseconds(components.ms); } } @@ -56,5 +61,10 @@ function inputTimeDomValueAsDateGet(element) { } function inputTimeDomValueAsDateSet(element, value) { - inputTimeComponentsSet(element, value.getUTCHours(), value.getUTCMinutes(), value.getUTCSeconds(), value.getUTCMilliseconds()); + inputTimeComponentsSet(element, { + hh: value.getUTCHours(), + ii: value.getUTCMinutes(), + ss: value.getUTCSeconds(), + ms: value.getUTCMilliseconds() + }); } diff --git a/src/input-time/normalization.js b/src/input-time/normalization.js index 3ad58ef..81abcc9 100644 --- a/src/input-time/normalization.js +++ b/src/input-time/normalization.js @@ -1,4 +1,4 @@ -'use strict'; +"use strict"; /** * @file @@ -7,7 +7,7 @@ function inputTimeNormalizationOnLoadFormatInputElements(element) { var components = inputTimeComponentsGet(element); - inputTimeComponentsSet(element, components.hour, components.minute, components.second, components.milisecond); + inputTimeComponentsSet(element, components); } function inputTimeNormalizationOnSubmitNormalizeInput(element) { diff --git a/src/input/accessibility.js b/src/input/accessibility.js index 85b785b..68f5df2 100644 --- a/src/input/accessibility.js +++ b/src/input/accessibility.js @@ -1,6 +1,6 @@ -'use strict'; +"use strict"; -/* global window, HTMLInputElement */ +/* global HTMLInputElement */ /** * @file @@ -14,19 +14,24 @@ * @see {@link http://www.w3.org/TR/html/forms.html#input-impl-notes} */ -function initInputAccessibility() { +/** + * Initializes the accessibility feature of the polyfill script for HTML input elements. + * + * @param {Function} addEventListener + */ +function initInputAccessibility(addEventListener) { // Binding event handlers to the window (instead of to each input element) to closely emulate native behavior (e.g. so // that other scripts can override it). - window.addEventListener('keydown', inputAccessibilityOnKeydownHandleNavigation); - window.addEventListener('keypress', inputAccessibilityOnKeyPressHandleUserInput); + addEventListener("keydown", inputAccessibilityOnKeydownHandleNavigation); + addEventListener("keypress", inputAccessibilityOnKeyPressHandleUserInput); - window.addEventListener('focus', inputAccessibilityOnFocusHandleInputSelection, true); - window.addEventListener('focusin', inputAccessibilityOnFocusHandleInputSelection); + addEventListener("focus", inputAccessibilityOnFocusHandleInputSelection, true); + addEventListener("focusin", inputAccessibilityOnFocusHandleInputSelection); - window.addEventListener('click', inputAccessibilityOnFocusHandleInputSelection); + addEventListener("click", inputAccessibilityOnFocusHandleInputSelection); - window.addEventListener('blur', inputAccessibilityOnBlurHandleInputNormalization, true); - //window.addEventListener('focusout', inputAccessibilityOnBlurHandleInputNormalization); + addEventListener("blur", inputAccessibilityOnBlurHandleInputNormalization, true); + //addEventListener("focusout", inputAccessibilityOnBlurHandleInputNormalization); } /** @@ -38,9 +43,10 @@ function initInputAccessibility() { * A KeyboardEvent of type keydown. */ function inputAccessibilityOnKeydownHandleNavigation(event) { - if (event.defaultPrevented) { + // TODO in IE, defaultPrevented seems to be always set for Up and Down keydown events. + /*if (event.defaultPrevented) { return; - } + }*/ // Returning early if the user input is irrelevant for this event handler. if (event.charCode) { @@ -49,10 +55,13 @@ function inputAccessibilityOnKeydownHandleNavigation(event) { if (event.target instanceof HTMLInputElement) { switch (event.target.getAttribute(INPUT_ATTR_TYPE)) { - case 'date': + case INPUT_TYPE_DATE: inputDateAccessibilityOnKeydownHandleNavigation(event.target, event); break; - case 'time': + case INPUT_TYPE_DATETIME_LOCAL: + inputDatetimeLocalAccessibilityOnKeydownHandleNavigation(event.target, event); + break; + case INPUT_TYPE_TIME: inputTimeAccessibilityOnKeydownHandleNavigation(event.target, event); break; default: @@ -82,10 +91,13 @@ function inputAccessibilityOnKeyPressHandleUserInput(event) { if (event.target instanceof HTMLInputElement) { switch (event.target.getAttribute(INPUT_ATTR_TYPE)) { - case 'date': + case INPUT_TYPE_DATE: inputDateAccessibilityOnKeyPressHandleUserInput(event.target, event); break; - case 'time': + case INPUT_TYPE_DATETIME_LOCAL: + inputDatetimeLocalAccessibilityOnKeyPressHandleUserInput(event.target, event); + break; + case INPUT_TYPE_TIME: inputTimeAccessibilityOnKeyPressHandleUserInput(event.target, event); break; default: @@ -97,10 +109,13 @@ function inputAccessibilityOnKeyPressHandleUserInput(event) { function inputAccessibilityOnFocusHandleInputSelection(event) { if (event.target instanceof HTMLInputElement) { switch (event.target.getAttribute(INPUT_ATTR_TYPE)) { - case 'date': + case INPUT_TYPE_DATE: inputDateAccessibilityOnFocusHandleInputSelection(event.target, event); break; - case 'time': + case INPUT_TYPE_DATETIME_LOCAL: + inputDatetimeLocalAccessibilityOnFocusHandleInputSelection(event.target, event); + break; + case INPUT_TYPE_TIME: inputTimeAccessibilityOnFocusHandleInputSelection(event.target, event); break; default: @@ -112,10 +127,13 @@ function inputAccessibilityOnFocusHandleInputSelection(event) { function inputAccessibilityOnBlurHandleInputNormalization(event) { if (event.target instanceof HTMLInputElement) { switch (event.target.getAttribute(INPUT_ATTR_TYPE)) { - case 'date': + case INPUT_TYPE_DATE: inputDateAccessibilityOnBlurHandleInputNormalization(event.target); break; - case 'time': + case INPUT_TYPE_DATETIME_LOCAL: + inputDatetimeLocalAccessibilityOnBlurHandleInputNormalization(event.target); + break; + case INPUT_TYPE_TIME: inputTimeAccessibilityOnBlurHandleInputNormalization(event.target); break; default: @@ -139,15 +157,15 @@ function inputAccessibilityIncreaseComponent(value, amount, min, max) { function inputAccessibilityComplementComponent(value, addition, min, max, limit) { if (value > limit) { value = parseInt(addition, 10); - if (min === 0) { + if (0 === min) { value -= 1; } } - else if (min === 0) { - value = parseInt('' + (value + 1) + addition, 10) - 1; + else if (0 === min) { + value = parseInt("" + (value + 1) + addition, 10) - 1; } else { - value = parseInt('' + value + addition, 10); + value = parseInt("" + value + addition, 10); } if (value > max) { value = max; @@ -192,7 +210,7 @@ function inputAccessibilityGetPreviousComponentRange(value, position, componentS var start, end; end = inputAccessibilityPreviousSeparator(value, position, componentSeparators); - if (end === 0) { + if (0 === end) { start = end; end = inputAccessibilityNextSeparator(value, position, componentSeparators); } @@ -221,18 +239,18 @@ function inputAccessibilityGetNextComponentRange(value, position, componentSepar } function inputAccessibilityGetSelectedComponentNumber(value, position, componentSeparators) { - var number = 0, test, i, componentSeparatorsCount = componentSeparators.length; + var number = 0; - while (position > 0) { - test = -1; - for (i = 0; i < componentSeparatorsCount; i++) { - test = Math.max(test, value.lastIndexOf(componentSeparators[i], position)); - } - position = test - 1; - if (position > -2) { + while (0 < position) { + position = inputAccessibilityPreviousSeparator(value, position, componentSeparators) - 1; + if (0 < position) { number++; } } return number; } + +function inputAccessibilityGetSelectedComponent(value, selectionStart, componentOrder, componentSeparator) { + return componentOrder[inputAccessibilityGetSelectedComponentNumber(value, selectionStart, componentSeparator)]; +} diff --git a/src/input/base.js b/src/input/base.js index fdeb893..856a329 100644 --- a/src/input/base.js +++ b/src/input/base.js @@ -1,16 +1,78 @@ -'use strict'; +"use strict"; + +/** @const */ +var INPUT_TYPE_TEXT = "text", + INPUT_TYPE_DATE = "date", + INPUT_TYPE_DATETIME_LOCAL = "datetime-local", + INPUT_TYPE_TIME = "time"; + +/** @const */ +var INPUT_PROPERTY_VALUE = "value", + INPUT_PROPERTY_VALUEASDATE = "valueAsDate", + INPUT_PROPERTY_VALUEASNUMBER = "valueAsNumber"; + +/** @const */ +var INPUT_PROPERTY_COMPONENTS = "__polyformfillInputComponents"; function initInput(testInput) { // @if FEATURES.DOM initInputDom(testInput); // @endif // @if FEATURES.ACCESSIBILITY - initInputAccessibility(); + initInputAccessibility(window.addEventListener); // @endif // @if FEATURES.LOCALIZATION //initInputLocalization(); // @endif // @if FEATURES.NORMALIZATION - initInputNormalization(); + initInputNormalization(window.addEventListener); // @endif } + +function inputComponentGetMinimum(element, selectedComponent) { + if (element.hasAttribute("min")) { + + } + + switch (selectedComponent) { + case INPUT_COMPONENT_YEAR: + return INPUT_DATE_YEAR_MIN; + case INPUT_COMPONENT_MONTH: + return INPUT_DATE_MONTH_MIN; + case INPUT_COMPONENT_DAY: + return INPUT_DATE_DAY_MIN; + + case INPUT_COMPONENT_HOUR: + return INPUT_TIME_COMPONENT_HOUR_MIN; + case INPUT_COMPONENT_MINUTE: + return INPUT_TIME_COMPONENT_MINUTE_MIN; + case INPUT_COMPONENT_SECOND: + return INPUT_TIME_COMPONENT_SECOND_MIN; + case INPUT_COMPONENT_MILISECOND: + return INPUT_TIME_COMPONENT_MILISECOND_MIN; + } +} + +function inputComponentGetMaximum(element, selectedComponent) { + if (element.hasAttribute("max")) { + + } + + switch (selectedComponent) { + case INPUT_COMPONENT_YEAR: + return INPUT_DATE_YEAR_MAX; + case INPUT_COMPONENT_MONTH: + return INPUT_DATE_MONTH_MAX; + case INPUT_COMPONENT_DAY: + return INPUT_DATE_DAY_MAX; + + case INPUT_COMPONENT_HOUR: + return INPUT_TIME_COMPONENT_HOUR_MAX; + case INPUT_COMPONENT_MINUTE: + return INPUT_TIME_COMPONENT_MINUTE_MAX; + case INPUT_COMPONENT_SECOND: + return INPUT_TIME_COMPONENT_SECOND_MAX; + case INPUT_COMPONENT_MILISECOND: + return INPUT_TIME_COMPONENT_MILISECOND_MAX; + } +} diff --git a/src/input/dom.js b/src/input/dom.js index 0cd650c..afed536 100644 --- a/src/input/dom.js +++ b/src/input/dom.js @@ -1,41 +1,47 @@ -'use strict'; +"use strict"; -/* global HTMLInputElement, DOMException */ +/* global HTMLInputElement */ /** * @file * Provides implementation of HTMLInputElement DOM interface for unsupporting browsers. */ +/** @const */ +var DOMEXCEPTION_INVALID_STATE_ERR = 11; + var inputDomOriginalTypeGetter, inputDomOriginalValueGetter, inputDomOriginalValueSetter, inputDomOriginalValueAsNumberGetter, inputDomOriginalValueAsNumberSetter, inputDomOriginalStepUp, - inputDomOriginalStepDown; + inputDomOriginalStepDown, + inputDomOriginalSetSelectionRange; function initInputDom(testInput) { - var descriptor; + var descriptor, HTMLInputElementPrototype; if (HTMLInputElement && Object.isExtensible(HTMLInputElement.prototype)) { + HTMLInputElementPrototype = HTMLInputElement.prototype; + // FF and IE - descriptor = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'type'); + descriptor = Object.getOwnPropertyDescriptor(HTMLInputElementPrototype, INPUT_ATTR_TYPE); // Chrome if (descriptor === undefined) { - descriptor = Object.getOwnPropertyDescriptor(testInput, 'type'); + descriptor = Object.getOwnPropertyDescriptor(testInput, INPUT_ATTR_TYPE); } inputDomOriginalTypeGetter = descriptor.get; if (descriptor.configurable) { - Object.defineProperty(HTMLInputElement.prototype, 'type', { + Object.defineProperty(HTMLInputElementPrototype, INPUT_ATTR_TYPE, { get: inputDomTypeGet }); } - descriptor = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value'); + descriptor = Object.getOwnPropertyDescriptor(HTMLInputElementPrototype, INPUT_PROPERTY_VALUE); if (descriptor.configurable) { - Object.defineProperty(HTMLInputElement.prototype, 'value', { + Object.defineProperty(HTMLInputElementPrototype, INPUT_PROPERTY_VALUE, { get: inputDomValueGet, set: inputDomValueSet }); @@ -44,9 +50,9 @@ function initInputDom(testInput) { inputDomOriginalValueSetter = descriptor.set; } - descriptor = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'valueAsNumber'); + descriptor = Object.getOwnPropertyDescriptor(HTMLInputElementPrototype, INPUT_PROPERTY_VALUEASNUMBER); if (descriptor === undefined || descriptor.configurable) { - Object.defineProperty(HTMLInputElement.prototype, 'valueAsNumber', { + Object.defineProperty(HTMLInputElementPrototype, INPUT_PROPERTY_VALUEASNUMBER, { get: inputDomValueAsNumberGet, set: inputDomValueAsNumberSet }); @@ -57,32 +63,35 @@ function initInputDom(testInput) { } } - Object.defineProperty(HTMLInputElement.prototype, 'valueAsDate', { + Object.defineProperty(HTMLInputElementPrototype, INPUT_PROPERTY_VALUEASDATE, { get: inputDomValueAsDateGet, set: inputDomValueAsDateSet }); - inputDomOriginalStepUp = HTMLInputElement.prototype.stepUp; - HTMLInputElement.prototype.stepUp = inputDomStepUp; + inputDomOriginalStepUp = HTMLInputElementPrototype.stepUp; + HTMLInputElementPrototype.stepUp = inputDomStepUp; - inputDomOriginalStepDown = HTMLInputElement.prototype.stepDown; - HTMLInputElement.prototype.stepDown = inputDomStepDown; + inputDomOriginalStepDown = HTMLInputElementPrototype.stepDown; + HTMLInputElementPrototype.stepDown = inputDomStepDown; + + inputDomOriginalSetSelectionRange = HTMLInputElementPrototype.setSelectionRange; } } function inputDomException(code, message) { - return new Error(code + ': ' + message); + return new Error(code + ": " + message); } function inputDomTypeGet() { var attr, type = inputDomOriginalTypeGetter.call(this); - if (type === 'text') { + if (INPUT_TYPE_TEXT === type) { attr = this.getAttribute(INPUT_ATTR_TYPE); switch (attr) { - case 'date': - case 'time': + case INPUT_TYPE_DATE: + case INPUT_TYPE_DATETIME_LOCAL: + case INPUT_TYPE_TIME: return attr; default: return type; @@ -92,12 +101,12 @@ function inputDomTypeGet() { } function inputDomValueGet() { - var inputType = this.getAttribute(INPUT_ATTR_TYPE); - - switch (inputType) { - case 'date': + switch (this.getAttribute(INPUT_ATTR_TYPE)) { + case INPUT_TYPE_DATE: return inputDateDomValueGet(this); - case 'time': + case INPUT_TYPE_DATETIME_LOCAL: + return inputDatetimeLocalDomValueGet(this); + case INPUT_TYPE_TIME: return inputTimeDomValueGet(this); default: return inputDomOriginalValueGetter.call(this); @@ -105,15 +114,15 @@ function inputDomValueGet() { } function inputDomValueSet(value) { - var inputType = this.getAttribute(INPUT_ATTR_TYPE); - - switch (inputType) { - case 'date': + switch (this.getAttribute(INPUT_ATTR_TYPE)) { + case INPUT_TYPE_DATE: return inputDateDomValueSet(this, value); - case 'time': + case INPUT_TYPE_DATETIME_LOCAL: + return inputDatetimeLocalDomValueSet(this, value); + case INPUT_TYPE_TIME: return inputTimeDomValueSet(this, value); default: - return inputDomOriginalValueSetter.call(this); + return inputDomOriginalValueSetter.call(this, value); } } @@ -125,11 +134,10 @@ function inputDomValueSet(value) { * @see {@link http://www.w3.org/TR/html/forms.html#dom-input-valueasnumber} */ function inputDomValueAsNumberGet() { - var inputType = this.getAttribute(INPUT_ATTR_TYPE); - - switch (inputType) { - case 'date': - case 'time': + switch (this.getAttribute(INPUT_ATTR_TYPE)) { + case INPUT_TYPE_DATE: + case INPUT_TYPE_DATETIME_LOCAL: + case INPUT_TYPE_TIME: return inputDomValueAsNumberGetFromDate.call(this); default: if (inputDomOriginalValueAsNumberGetter) { @@ -158,11 +166,10 @@ function inputDomValueAsNumberGetFromDate() { * @see {@link http://www.w3.org/TR/html/forms.html#dom-input-valueasnumber} */ function inputDomValueAsNumberSet(value) { - var inputType = this.getAttribute(INPUT_ATTR_TYPE); - - switch (inputType) { - case 'date': - case 'time': + switch (this.getAttribute(INPUT_ATTR_TYPE)) { + case INPUT_TYPE_DATE: + case INPUT_TYPE_DATETIME_LOCAL: + case INPUT_TYPE_TIME: inputDomValueAsNumberSetFromDate.call(this, value); break; default: @@ -187,12 +194,12 @@ function inputDomValueAsNumberSetFromDate(value) { * @see {@link http://www.w3.org/TR/html/forms.html#dom-input-valueasdate} */ function inputDomValueAsDateGet() { - var inputType = this.getAttribute(INPUT_ATTR_TYPE); - - switch (inputType) { - case 'date': + switch (this.getAttribute(INPUT_ATTR_TYPE)) { + case INPUT_TYPE_DATE: return inputDateDomValueAsDateGet(this); - case 'time': + case INPUT_TYPE_DATETIME_LOCAL: + return inputDatetimeLocalDomValueAsDateGet(this); + case INPUT_TYPE_TIME: return inputTimeDomValueAsDateGet(this); default: return null; @@ -205,15 +212,15 @@ function inputDomValueAsDateGet() { * @see {@link http://www.w3.org/TR/html/forms.html#dom-input-valueasdate} */ function inputDomValueAsDateSet(value) { - var inputType = this.getAttribute(INPUT_ATTR_TYPE); - if (value instanceof Date) { } - switch (inputType) { - case 'date': + switch (this.getAttribute(INPUT_ATTR_TYPE)) { + case INPUT_TYPE_DATE: return inputDateDomValueAsDateSet(this, value); - case 'time': + case INPUT_TYPE_DATETIME_LOCAL: + return inputDatetimeLocalDomValueAsDateSet(this, value); + case INPUT_TYPE_TIME: return inputTimeDomValueAsDateSet(this, value); default: return inputDomOriginalValueSetter.call(this, value); @@ -221,14 +228,14 @@ function inputDomValueAsDateSet(value) { } function inputDomStepUp(n) { - var inputType = this.getAttribute(INPUT_ATTR_TYPE); - n = n || 1; - switch (inputType) { - case 'date': + switch (this.getAttribute(INPUT_ATTR_TYPE)) { + case INPUT_TYPE_DATE: return inputDomStepUpOrDown(this, n, INPUT_DATE_STEP_DEFAULT, INPUT_DATE_STEP_SCALE_FACTOR); - case 'time': + case INPUT_TYPE_DATETIME_LOCAL: + return inputDomStepUpOrDown(this, n, INPUT_TIME_STEP_DEFAULT, INPUT_TIME_STEP_SCALE_FACTOR); + case INPUT_TYPE_TIME: return inputDomStepUpOrDown(this, n, INPUT_TIME_STEP_DEFAULT, INPUT_TIME_STEP_SCALE_FACTOR); default: return inputDomOriginalStepUp.call(this, n); @@ -236,14 +243,14 @@ function inputDomStepUp(n) { } function inputDomStepDown(n) { - var inputType = this.getAttribute(INPUT_ATTR_TYPE); - n = n || 1; - switch (inputType) { - case 'date': + switch (this.getAttribute(INPUT_ATTR_TYPE)) { + case INPUT_TYPE_DATE: return inputDomStepUpOrDown(this, -n, INPUT_DATE_STEP_DEFAULT, INPUT_DATE_STEP_SCALE_FACTOR); - case 'time': + case INPUT_TYPE_DATETIME_LOCAL: + return inputDomStepUpOrDown(this, -n, INPUT_TIME_STEP_DEFAULT, INPUT_TIME_STEP_SCALE_FACTOR); + case INPUT_TYPE_TIME: return inputDomStepUpOrDown(this, -n, INPUT_TIME_STEP_DEFAULT, INPUT_TIME_STEP_SCALE_FACTOR); default: return inputDomOriginalStepUp.call(this, n); @@ -261,18 +268,17 @@ function inputDomStepDown(n) { * @see {@link http://www.w3.org/TR/html/forms.html#dom-input-stepup} */ function inputDomStepUpOrDown(element, n, defaultStep, stepScaleFactor) { - var allowedValueStep, delta, value; + var allowedValueStep = inputDomGetAllowedValueStep(element, defaultStep, stepScaleFactor), delta, value; - allowedValueStep = inputDomGetAllowedValueStep(element, defaultStep, stepScaleFactor); - if (allowedValueStep === null) { - throw inputDomException(DOMException.INVALID_STATE_ERR); - } + if (null === allowedValueStep) { + throw inputDomException(DOMEXCEPTION_INVALID_STATE_ERR); + } - value = element.valueAsNumber; + value = element.valueAsNumber; - delta = allowedValueStep * n; + delta = allowedValueStep * n; - value += delta; + value += delta; element.valueAsNumber = value; } @@ -289,14 +295,14 @@ function inputDomStepUpOrDown(element, n, defaultStep, stepScaleFactor) { function inputDomGetAllowedValueStep(element, defaultStep, stepScaleFactor) { var step; - if (element.hasAttribute('step')) { - step = element.getAttribute('step'); + if (element.hasAttribute("step")) { + step = element.getAttribute("step"); - if (step === 'any') { + if ("any" === step) { return null; } step = parseInt(step, 10); - if (step < 1) { + if (1 > step) { step = defaultStep; } } diff --git a/src/input/normalization.js b/src/input/normalization.js index cc4d2f8..678a81c 100644 --- a/src/input/normalization.js +++ b/src/input/normalization.js @@ -1,25 +1,39 @@ -'use strict'; +"use strict"; /** * @file * Provides normalization of input elements. */ -function initInputNormalization() { - window.addEventListener('submit', inputNormalizationOnSubmitNormalizeInput); +/** + * Initializes the normalization feature of the polyfill script for HTML input elements. + * + * @param {Function} addEventListener + */ +function initInputNormalization(addEventListener) { + addEventListener("load", inputNormalizationOnLoadFormatInputElements); - window.addEventListener('load', inputNormalizationOnLoadFormatInputElements); + addEventListener("submit", inputNormalizationOnSubmitNormalizeInput); } +/** + * Handles initial formatting of the value of HTML input elements. + * + * @param {Event} event + * An Event of type load. + */ function inputNormalizationOnLoadFormatInputElements(event) { - var elements = event.target.getElementsByTagName('INPUT'), i; + var elements = event.target.getElementsByTagName("INPUT"), i; for (i = 0; i < elements.length; i++) { switch (elements[i].getAttribute(INPUT_ATTR_TYPE)) { - case 'date': - inputDateNormalizationOnLoadFormatInputDateElements(elements[i]); + case INPUT_TYPE_DATE: + inputDateNormalizationOnLoadFormatInputElements(elements[i]); + break; + case INPUT_TYPE_DATETIME_LOCAL: + inputDatetimeLocalNormalizationOnLoadFormatInputElements(elements[i]); break; - case 'time': + case INPUT_TYPE_TIME: inputTimeNormalizationOnLoadFormatInputElements(elements[i]); break; default: @@ -28,15 +42,25 @@ function inputNormalizationOnLoadFormatInputElements(event) { } } + +/** + * Normalizes submitted value of HTML input elements. + * + * @param {Event} event + * An Event of type submit. + */ function inputNormalizationOnSubmitNormalizeInput(event) { var elements = event.target.elements, i; for (i = 0; i < elements.length; i++) { switch (elements[i].getAttribute(INPUT_ATTR_TYPE)) { - case 'date': - inputDateNormalizationOnSubmitNormalizeDateInput(elements[i]); + case INPUT_TYPE_DATE: + inputDateNormalizationOnSubmitNormalizeInput(elements[i]); + break; + case INPUT_TYPE_DATETIME_LOCAL: + inputDatetimeLocalNormalizationOnSubmitNormalizeInput(elements[i]); break; - case 'time': + case INPUT_TYPE_TIME: inputTimeNormalizationOnSubmitNormalizeInput(elements[i]); break; default: diff --git a/src/polyformfill.js.prefix b/src/polyformfill.js.prefix index 73925fa..ea03317 100644 --- a/src/polyformfill.js.prefix +++ b/src/polyformfill.js.prefix @@ -1,2 +1,2 @@ (function(window, document, undefined) { - "use strict"; + 'use strict'; diff --git a/test/helpers/keyboardevent.js b/test/helpers/keyboardevent.js index b760591..f843d09 100644 --- a/test/helpers/keyboardevent.js +++ b/test/helpers/keyboardevent.js @@ -2,16 +2,16 @@ * https://gist.github.com/termi/4654819 */ (function (window, document) { - 'use strict'; + "use strict"; var _initKeyboardEvent_type = (function (e) { try { e.initKeyboardEvent( - 'keyup', // in DOMString typeArg + "keyup", // in DOMString typeArg false, // in boolean canBubbleArg false, // in boolean cancelableArg window, // in views::AbstractView viewArg - '+', // [test]in DOMString keyIdentifierArg | webkit event.keyIdentifier | IE9 event.key + "+", // [test]in DOMString keyIdentifierArg | webkit event.keyIdentifier | IE9 event.key 3, // [test]in unsigned long keyLocationArg | webkit event.keyIdentifier | IE9 event.location true, // [test]in boolean ctrlKeyArg | webkit event.shiftKey | old webkit event.ctrlKey | IE9 event.modifiersList false, // [test]shift | alt @@ -20,7 +20,7 @@ false // altGraphKey ); - return ((e['keyIdentifier'] || e['key']) == '+' && (e['keyLocation'] || e['location']) == 3) && ( + return ("+" === (e["keyIdentifier"] || e["key"]) && 3 == (e["keyLocation"] || e["location"])) && ( e.ctrlKey ? e.altKey ? // webkit 1 @@ -35,20 +35,20 @@ ; } catch (__e__) { - _initKeyboardEvent_type = 0 + _initKeyboardEvent_type = 0; } - })(document.createEvent('KeyboardEvent')), + })(document.createEvent("KeyboardEvent")), _keyboardEvent_properties_dictionary = { - char: '', - key: '', + char: "", + key: "", location: 0, ctrlKey: false, shiftKey: false, altKey: false, metaKey: false, repeat: false, - locale: '', + locale: "", detail: 0, bubbles: false, @@ -88,86 +88,86 @@ } function crossBrowser_initKeyboardEvent(type, dict) { - var e; + var event; if (_initKeyboardEvent_type) { - e = document.createEvent('KeyboardEvent'); + event = document.createEvent("KeyboardEvent"); } else { - e = document.createEvent('Event'); + event = document.createEvent("Event"); } var localDict = getNormalizedProperties(dict); - if (!localDict['keyCode']) { - localDict['keyCode'] = _key && _key.charCodeAt(0) || 0; + if (!localDict["keyCode"]) { + localDict["keyCode"] = _key && _key.charCodeAt(0) || 0; } - if (!localDict['charCode']) { - localDict['charCode'] = _char && _char.charCodeAt(0) || 0; + if (!localDict["charCode"]) { + localDict["charCode"] = _char && _char.charCodeAt(0) || 0; } - if (!localDict['which']) { - localDict['which'] = localDict['keyCode']; + if (!localDict["which"]) { + localDict["which"] = localDict["keyCode"]; } - var _ctrlKey = localDict['ctrlKey'], - _shiftKey = localDict['shiftKey'], - _altKey = localDict['altKey'], - _metaKey = localDict['metaKey'], - _altGraphKey = localDict['altGraphKey'], - - _modifiersListArg = _initKeyboardEvent_type > 3 ? ( - (_ctrlKey ? 'Control' : '') - + (_shiftKey ? ' Shift' : '') - + (_altKey ? ' Alt' : '') - + (_metaKey ? ' Meta' : '') - + (_altGraphKey ? ' AltGraph' : '') + var _ctrlKey = localDict["ctrlKey"], + _shiftKey = localDict["shiftKey"], + _altKey = localDict["altKey"], + _metaKey = localDict["metaKey"], + _altGraphKey = localDict["altGraphKey"], + + _modifiersListArg = 3 < _initKeyboardEvent_type ? ( + (_ctrlKey ? "Control" : "") + + (_shiftKey ? " Shift" : "") + + (_altKey ? " Alt" : "") + + (_metaKey ? " Meta" : "") + + (_altGraphKey ? " AltGraph" : "") ).trim() : null, - _key = localDict['key'] + '', - _char = localDict['char'] + '', - _location = localDict['location'], - _keyCode = localDict['keyCode'], - _charCode = localDict['charCode'], + _key = localDict["key"] + "", + _char = localDict["char"] + "", + _location = localDict["location"], + _keyCode = localDict["keyCode"], + _charCode = localDict["charCode"], - _bubbles = localDict['bubbles'], - _cancelable = localDict['cancelable'], + _bubbles = localDict["bubbles"], + _cancelable = localDict["cancelable"], - _repeat = localDict['repeat'], - _locale = localDict['locale'], + _repeat = localDict["repeat"], + _locale = localDict["locale"], _view = window; - if ('initKeyEvent' in e) {//FF + if ("initKeyEvent" in event) {//FF //https://developer.mozilla.org/en/DOM/event.initKeyEvent - e.initKeyEvent(type, _bubbles, _cancelable, _view, _ctrlKey, _altKey, _shiftKey, _metaKey, _keyCode, _charCode); + event.initKeyEvent(type, _bubbles, _cancelable, _view, _ctrlKey, _altKey, _shiftKey, _metaKey, _keyCode, _charCode); } - else if (_initKeyboardEvent_type && 'initKeyboardEvent' in e) {//https://developer.mozilla.org/en/DOM/KeyboardEvent#initKeyboardEvent() - if (_initKeyboardEvent_type == 1) { // webkit + else if (_initKeyboardEvent_type && "initKeyboardEvent" in event) {//https://developer.mozilla.org/en/DOM/KeyboardEvent#initKeyboardEvent() + if (1 === _initKeyboardEvent_type) { // webkit //http://stackoverflow.com/a/8490774/1437207 //https://bugs.webkit.org/show_bug.cgi?id=13368 - e.initKeyboardEvent(type, _bubbles, _cancelable, _view, _key, _location, _ctrlKey, _shiftKey, _altKey, _metaKey, _altGraphKey); + event.initKeyboardEvent(type, _bubbles, _cancelable, _view, _key, _location, _ctrlKey, _shiftKey, _altKey, _metaKey, _altGraphKey); } - else if (_initKeyboardEvent_type == 2) { // old webkit + else if (2 === _initKeyboardEvent_type) { // old webkit //http://code.google.com/p/chromium/issues/detail?id=52408 - e.initKeyboardEvent(type, _bubbles, _cancelable, _view, _ctrlKey, _altKey, _shiftKey, _metaKey, _keyCode, _charCode); + event.initKeyboardEvent(type, _bubbles, _cancelable, _view, _ctrlKey, _altKey, _shiftKey, _metaKey, _keyCode, _charCode); } - else if (_initKeyboardEvent_type == 3) { // webkit - e.initKeyboardEvent(type, _bubbles, _cancelable, _view, _key, _location, _ctrlKey, _altKey, _shiftKey, _metaKey, _altGraphKey); + else if (3 === _initKeyboardEvent_type) { // webkit + event.initKeyboardEvent(type, _bubbles, _cancelable, _view, _key, _location, _ctrlKey, _altKey, _shiftKey, _metaKey, _altGraphKey); } - else if (_initKeyboardEvent_type == 4) { // IE9 + else if (4 === _initKeyboardEvent_type) { // IE9 //http://msdn.microsoft.com/en-us/library/ie/ff975297(v=vs.85).aspx - e.initKeyboardEvent(type, _bubbles, _cancelable, _view, _key, _location, _modifiersListArg, _repeat, _locale); + event.initKeyboardEvent(type, _bubbles, _cancelable, _view, _key, _location, _modifiersListArg, _repeat, _locale); } else { // FireFox|w3c //http://www.w3.org/TR/DOM-Level-3-Events/#events-KeyboardEvent-initKeyboardEvent //https://developer.mozilla.org/en/DOM/KeyboardEvent#initKeyboardEvent() - e.initKeyboardEvent(type, _bubbles, _cancelable, _view, _char, _key, _location, _modifiersListArg, _repeat, _locale); + event.initKeyboardEvent(type, _bubbles, _cancelable, _view, _char, _key, _location, _modifiersListArg, _repeat, _locale); } } else { - e.initEvent(type, _bubbles, _cancelable) + event.initEvent(type, _bubbles, _cancelable); } - normalizeEventProperties(e, localDict); + normalizeEventProperties(event, localDict); - return e; + return event; } //export diff --git a/test/input-date/accessiblity.spec.js b/test/input-date/accessiblity.spec.js index 74eb320..08d7c0f 100644 --- a/test/input-date/accessiblity.spec.js +++ b/test/input-date/accessiblity.spec.js @@ -1,8 +1,8 @@ -'use strict'; +"use strict"; /* global afterEach, beforeEach, describe, expect, it */ -describe('An accessible input[type=date] element', function () { +describe("An accessible input[type=date] element", function () { var originalTimeout; beforeEach(function() { originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL; @@ -12,34 +12,34 @@ describe('An accessible input[type=date] element', function () { jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout; }); - describe('can be navigated using the arrow keys', function () { + describe("can be navigated using the arrow keys", function () { var w; - it('test 1', function(done) { + it("test 1", function(done) { window.hello = function() { - var input = w.document.createElement('input'); - input.setAttribute('type', 'date'); - input.setAttribute('value', '1970-01-01'); + var input = w.document.createElement("input"); + input.setAttribute("type", "date"); + input.setAttribute("value", "1970-01-01"); w.document.body.appendChild(input); input.focus(); - input.dispatchEvent(w.crossBrowser_initKeyboardEvent('keydown', {'key': 'Right', 'bubbles': true})); - input.dispatchEvent(w.crossBrowser_initKeyboardEvent('keydown', {'key': 'Up', 'bubbles': true})); + input.dispatchEvent(w.crossBrowser_initKeyboardEvent("keydown", {"key": "Right", "bubbles": true})); + input.dispatchEvent(w.crossBrowser_initKeyboardEvent("keydown", {"key": "Up", "bubbles": true})); - expect(input.value).toBe('1970-02-01'); + expect(input.value).toBe("1970-02-01"); - input.dispatchEvent(w.crossBrowser_initKeyboardEvent('keydown', {'key': 'Right', 'bubbles': true})); - input.dispatchEvent(w.crossBrowser_initKeyboardEvent('keydown', {'key': 'Left', 'bubbles': true})); - input.dispatchEvent(w.crossBrowser_initKeyboardEvent('keydown', {'key': 'Up', 'bubbles': true})); + input.dispatchEvent(w.crossBrowser_initKeyboardEvent("keydown", {"key": "Right", "bubbles": true})); + input.dispatchEvent(w.crossBrowser_initKeyboardEvent("keydown", {"key": "Left", "bubbles": true})); + input.dispatchEvent(w.crossBrowser_initKeyboardEvent("keydown", {"key": "Up", "bubbles": true})); - expect(input.value).toBe('1970-03-01'); + expect(input.value).toBe("1970-03-01"); - input.dispatchEvent(w.crossBrowser_initKeyboardEvent('keydown', {'key': 'Down', 'bubbles': true})); + input.dispatchEvent(w.crossBrowser_initKeyboardEvent("keydown", {"key": "Down", "bubbles": true})); - expect(input.value).toBe('1970-02-01'); + expect(input.value).toBe("1970-02-01"); setTimeout(function() { w.close(); @@ -47,27 +47,27 @@ describe('An accessible input[type=date] element', function () { }, 100); }; - w = window.open('base/test/popup.html', 'test'); + w = window.open("base/test/popup.html", "test"); }); - it('test 2', function(done) { + it("test 2", function(done) { window.hello = function(){ - var input = w.document.createElement('input'); - input.setAttribute('type', 'date'); - input.setAttribute('value', '1970-01-01'); + var input = w.document.createElement("input"); + input.setAttribute("type", "date"); + input.setAttribute("value", "1970-01-01"); w.document.body.appendChild(input); input.focus(); - input.dispatchEvent(w.crossBrowser_initKeyboardEvent('keydown', {'key': 'Right', 'bubbles': true})); - input.dispatchEvent(w.crossBrowser_initKeyboardEvent('keydown', {'key': 'Right', 'bubbles': true})); - input.dispatchEvent(w.crossBrowser_initKeyboardEvent('keydown', {'key': 'Left', 'bubbles': true})); - input.dispatchEvent(w.crossBrowser_initKeyboardEvent('keydown', {'key': 'Up', 'bubbles': true})); - input.dispatchEvent(w.crossBrowser_initKeyboardEvent('keydown', {'key': 'Up', 'bubbles': true})); + input.dispatchEvent(w.crossBrowser_initKeyboardEvent("keydown", {"key": "Right", "bubbles": true})); + input.dispatchEvent(w.crossBrowser_initKeyboardEvent("keydown", {"key": "Right", "bubbles": true})); + input.dispatchEvent(w.crossBrowser_initKeyboardEvent("keydown", {"key": "Left", "bubbles": true})); + input.dispatchEvent(w.crossBrowser_initKeyboardEvent("keydown", {"key": "Up", "bubbles": true})); + input.dispatchEvent(w.crossBrowser_initKeyboardEvent("keydown", {"key": "Up", "bubbles": true})); - expect(input.value).toBe('1970-03-01'); + expect(input.value).toBe("1970-03-01"); setTimeout(function() { w.close(); @@ -75,34 +75,34 @@ describe('An accessible input[type=date] element', function () { }, 100); }; - w = window.open('base/test/popup.html', 'test'); + w = window.open("base/test/popup.html", "test"); }); }); - describe('can be navigated using Tab and Shift+Tab keydown', function () { + describe("can be navigated using Tab and Shift+Tab keydown", function () { var w; - it('test 1', function (done) { + it("test 1", function (done) { window.hello = function () { - var inputBefore = w.document.createElement('input'); - inputBefore.setAttribute('type', 'text'); + var inputBefore = w.document.createElement("input"); + inputBefore.setAttribute("type", "text"); - var input = w.document.createElement('input'); - input.setAttribute('type', 'date'); - input.setAttribute('value', '1007-06-15'); + var input = w.document.createElement("input"); + input.setAttribute("type", "date"); + input.setAttribute("value", "1007-06-15"); w.document.body.appendChild(inputBefore); w.document.body.appendChild(input); inputBefore.focus(); - inputBefore.dispatchEvent(w.crossBrowser_initKeyboardEvent('keydown', {'key': 'U+0009', 'bubbles': true})); - input.dispatchEvent(w.crossBrowser_initKeyboardEvent('keydown', {'key': 'U+0009', 'bubbles': true})); - input.dispatchEvent(w.crossBrowser_initKeyboardEvent('keydown', {'key': 'Up', 'bubbles': true})); + inputBefore.dispatchEvent(w.crossBrowser_initKeyboardEvent("keydown", {"key": "U+0009", "bubbles": true})); + input.dispatchEvent(w.crossBrowser_initKeyboardEvent("keydown", {"key": "U+0009", "bubbles": true})); + input.dispatchEvent(w.crossBrowser_initKeyboardEvent("keydown", {"key": "Up", "bubbles": true})); - expect(input.value).toBe('1007-07-15'); + expect(input.value).toBe("1007-07-15"); setTimeout(function () { w.close(); @@ -110,41 +110,41 @@ describe('An accessible input[type=date] element', function () { }, 100); }; - w = window.open('base/test/popup.html', 'test'); + w = window.open("base/test/popup.html", "test"); }); }); - describe('allows its date components to be cleared on Backspace or Del keydown', function () { + describe("allows its date components to be cleared on Backspace or Del keydown", function () { var w; - it('test 1', function (done) { + it("test 1", function (done) { window.hello = function () { - var input = w.document.createElement('input'); - input.setAttribute('type', 'date'); - input.setAttribute('value', '1007-06-15'); + var input = w.document.createElement("input"); + input.setAttribute("type", "date"); + input.setAttribute("value", "1007-06-15"); w.document.body.appendChild(input); input.focus(); - input.dispatchEvent(w.crossBrowser_initKeyboardEvent('keydown', {'key': 'Right', 'bubbles': true})); - input.dispatchEvent(w.crossBrowser_initKeyboardEvent('keydown', {'key': 'U+0008', 'bubbles': true})); + input.dispatchEvent(w.crossBrowser_initKeyboardEvent("keydown", {"key": "Right", "bubbles": true})); + input.dispatchEvent(w.crossBrowser_initKeyboardEvent("keydown", {"key": "U+0008", "bubbles": true})); - expect(input.value).toBe(''); + expect(input.value).toBe(""); - input.dispatchEvent(w.crossBrowser_initKeyboardEvent('keydown', {'key': 'Up', 'bubbles': true})); + input.dispatchEvent(w.crossBrowser_initKeyboardEvent("keydown", {"key": "Up", "bubbles": true})); - expect(input.value).toBe('1007-01-15'); + expect(input.value).toBe("1007-01-15"); - input.dispatchEvent(w.crossBrowser_initKeyboardEvent('keydown', {'key': 'Right', 'bubbles': true})); - input.dispatchEvent(w.crossBrowser_initKeyboardEvent('keydown', {'key': 'U+0008', 'bubbles': true})); + input.dispatchEvent(w.crossBrowser_initKeyboardEvent("keydown", {"key": "Right", "bubbles": true})); + input.dispatchEvent(w.crossBrowser_initKeyboardEvent("keydown", {"key": "U+0008", "bubbles": true})); - expect(input.value).toBe(''); + expect(input.value).toBe(""); - input.dispatchEvent(w.crossBrowser_initKeyboardEvent('keydown', {'key': 'Up', 'bubbles': true})); + input.dispatchEvent(w.crossBrowser_initKeyboardEvent("keydown", {"key": "Up", "bubbles": true})); - expect(input.value).toBe('1007-01-01'); + expect(input.value).toBe("1007-01-01"); setTimeout(function () { w.close(); @@ -152,7 +152,7 @@ describe('An accessible input[type=date] element', function () { }, 100); }; - w = window.open('base/test/popup.html', 'test'); + w = window.open("base/test/popup.html", "test"); }); }); diff --git a/test/input-date/dom.spec.js b/test/input-date/dom.spec.js index a0c2d19..b923267 100644 --- a/test/input-date/dom.spec.js +++ b/test/input-date/dom.spec.js @@ -1,207 +1,207 @@ -'use strict'; +"use strict"; /* global describe, expect, it */ -describe('The DOM interface of input[type=date] elements', function () { +describe("The DOM interface of input[type=date] elements", function () { - describe('has a type property, which', function () { + describe("has a type property, which", function () { - it('should return "date" for input elements with type=date', function () { + it("should return 'date' for input elements with type=date", function () { var input; - input = document.createElement('input'); - input.setAttribute('type', 'date'); + input = document.createElement("input"); + input.setAttribute("type", "date"); - expect(input.type).toBe('date'); + expect(input.type).toBe("date"); }); }); - describe('has a value property, which', function () { + describe("has a value property, which", function () { - it('should accept an empty string to clear the value', function () { - var input, initialValue = '1970-01-01'; + it("should accept an empty string to clear the value", function () { + var input, initialValue = "1970-01-01"; - input = document.createElement('input'); - input.setAttribute('type', 'date'); - input.setAttribute('value', initialValue); + input = document.createElement("input"); + input.setAttribute("type", "date"); + input.setAttribute("value", initialValue); expect(input.value).toBe(initialValue); - input.value = ''; - expect(input.value).toBe(''); + input.value = ""; + expect(input.value).toBe(""); }); - it('should return a valid full-date as defined in RFC 3339', function () { + it("should return a valid full-date as defined in RFC 3339", function () { var input; - input = document.createElement('input'); - input.setAttribute('type', 'date'); + input = document.createElement("input"); + input.setAttribute("type", "date"); - input.value = '1970-01-01'; - expect(input.value).toBe('1970-01-01'); + input.value = "1970-01-01"; + expect(input.value).toBe("1970-01-01"); - input.value = '0001-01-01'; - expect(input.value).toBe('0001-01-01'); + input.value = "0001-01-01"; + expect(input.value).toBe("0001-01-01"); - input.value = '0101-01-01'; - expect(input.value).toBe('0101-01-01'); + input.value = "0101-01-01"; + expect(input.value).toBe("0101-01-01"); - input.value = '12345-01-01'; - expect(input.value).toBe('12345-01-01'); + input.value = "12345-01-01"; + expect(input.value).toBe("12345-01-01"); - input.value = '123456-01-01'; - expect(input.value).toBe('123456-01-01'); + input.value = "123456-01-01"; + expect(input.value).toBe("123456-01-01"); // Max date. - input.value = '275760-09-13'; - expect(input.value).toBe('275760-09-13'); + input.value = "275760-09-13"; + expect(input.value).toBe("275760-09-13"); - input.value = ''; - expect(input.value).toBe(''); + input.value = ""; + expect(input.value).toBe(""); }); - it('should not accept assignments with an invalid date', function () { + it("should not accept assignments with an invalid date", function () { var input; - input = document.createElement('input'); - input.setAttribute('type', 'date'); + input = document.createElement("input"); + input.setAttribute("type", "date"); - input.value = '1 January 1970'; - expect(input.value).toBe(''); + input.value = "1 January 1970"; + expect(input.value).toBe(""); input.value = 0; - expect(input.value).toBe(''); + expect(input.value).toBe(""); - input.value = '1'; - expect(input.value).toBe(''); + input.value = "1"; + expect(input.value).toBe(""); - input.value = '01-01-01'; - expect(input.value).toBe(''); + input.value = "01-01-01"; + expect(input.value).toBe(""); - input.value = '101-01-01'; - expect(input.value).toBe(''); + input.value = "101-01-01"; + expect(input.value).toBe(""); - input.value = '275760-09-14'; - expect(input.value).toBe(''); + input.value = "275760-09-14"; + expect(input.value).toBe(""); - input.value = '1970-02-31'; - expect(input.value).toBe(''); + input.value = "1970-02-31"; + expect(input.value).toBe(""); }); }); - describe('has a valueAsDate property, which', function () { + describe("has a valueAsDate property, which", function () { - it('should return a Date object for input elements with a valid value', function () { + it("should return a Date object for input elements with a valid value", function () { var input; - input = document.createElement('input'); - input.setAttribute('type', 'date'); + input = document.createElement("input"); + input.setAttribute("type", "date"); - input.value = '1970-01-01'; + input.value = "1970-01-01"; expect(input.valueAsDate instanceof Date).toBeTruthy(); }); - it('should return null for input elements with an invalid value', function () { + it("should return null for input elements with an invalid value", function () { var input; - input = document.createElement('input'); - input.setAttribute('type', 'date'); + input = document.createElement("input"); + input.setAttribute("type", "date"); - input.value = '1970-02-31'; + input.value = "1970-02-31"; expect(input.valueAsDate).toBe(null); }); }); - describe('has a valueAsNumber property, which', function () { + describe("has a valueAsNumber property, which", function () { - it('should return an integer for input elements with a valid value', function () { + it("should return an integer for input elements with a valid value", function () { var input; - input = document.createElement('input'); - input.setAttribute('type', 'date'); + input = document.createElement("input"); + input.setAttribute("type", "date"); - input.setAttribute('value', '1970-01-01'); + input.setAttribute("value", "1970-01-01"); expect(input.valueAsNumber).toBe(0); - input.value = '1970-01-01'; + input.value = "1970-01-01"; expect(input.valueAsNumber).toBe(0); - input.value = '0001-01-01'; + input.value = "0001-01-01"; expect(input.valueAsNumber).toBe(-62135596800000); // Max date. - input.value = '275760-09-13'; + input.value = "275760-09-13"; expect(input.valueAsNumber).toBe(8640000000000000); }); - it('should return NaN for input elements with an invalid value', function () { + it("should return NaN for input elements with an invalid value", function () { var input; - input = document.createElement('input'); - input.setAttribute('type', 'date'); + input = document.createElement("input"); + input.setAttribute("type", "date"); - input.value = '1 January 1970'; + input.value = "1 January 1970"; expect(input.valueAsNumber).toBeNaN(); input.value = 0; expect(input.valueAsNumber).toBeNaN(); - input.value = '1'; + input.value = "1"; expect(input.valueAsNumber).toBeNaN(); - input.value = '01-01-01'; + input.value = "01-01-01"; expect(input.valueAsNumber).toBeNaN(); - input.value = '101-01-01'; + input.value = "101-01-01"; expect(input.valueAsNumber).toBeNaN(); - input.value = '275760-09-14'; + input.value = "275760-09-14"; expect(input.valueAsNumber).toBeNaN(); }); }); - describe('has a stepUp() method, which', function () { + describe("has a stepUp() method, which", function () { - it('for elements without step, min and max attributes should increase the value by one day', function () { + it("for elements without step, min and max attributes should increase the value by one day", function () { var input; - input = document.createElement('input'); - input.setAttribute('type', 'date'); - input.setAttribute('value', '1970-01-01'); + input = document.createElement("input"); + input.setAttribute("type", "date"); + input.setAttribute("value", "1970-01-01"); input.stepUp(); - expect(input.value).toBe('1970-01-02'); + expect(input.value).toBe("1970-01-02"); input.stepUp(8); - expect(input.value).toBe('1970-01-10'); + expect(input.value).toBe("1970-01-10"); input.stepUp(22); - expect(input.value).toBe('1970-02-01'); + expect(input.value).toBe("1970-02-01"); }); }); - describe('has a stepDown() method, which', function () { + describe("has a stepDown() method, which", function () { - it('for elements without step, min and max attributes should decrease the value by one day', function () { + it("for elements without step, min and max attributes should decrease the value by one day", function () { var input; - input = document.createElement('input'); - input.setAttribute('type', 'date'); - input.setAttribute('value', '1970-01-10'); + input = document.createElement("input"); + input.setAttribute("type", "date"); + input.setAttribute("value", "1970-01-10"); input.stepDown(); - expect(input.value).toBe('1970-01-09'); + expect(input.value).toBe("1970-01-09"); input.stepDown(8); - expect(input.value).toBe('1970-01-01'); + expect(input.value).toBe("1970-01-01"); input.stepDown(20); - expect(input.value).toBe('1969-12-12'); + expect(input.value).toBe("1969-12-12"); }); }); diff --git a/test/input-date/localization.spec.js b/test/input-date/localization.spec.js index 3019b3f..8aec6aa 100644 --- a/test/input-date/localization.spec.js +++ b/test/input-date/localization.spec.js @@ -1,7 +1,7 @@ -'use strict'; +"use strict"; /* global describe, expect, it */ -describe('A localizable input[type=date] element', function () { +describe("A localizable input[type=date] element", function () { }); diff --git a/test/input-datetime-local/dom.spec.js b/test/input-datetime-local/dom.spec.js new file mode 100644 index 0000000..2b0593e --- /dev/null +++ b/test/input-datetime-local/dom.spec.js @@ -0,0 +1,219 @@ +"use strict"; + +/* global describe, expect, it */ + +describe("The DOM interface of input[type=datetime-local] elements", function () { + + describe("has a type property, which", function () { + + it("should return 'datetime-local' for input elements with type=datetime-local", function () { + var input; + + input = document.createElement("input"); + input.setAttribute("type", "datetime-local"); + + expect(input.type).toBe("datetime-local"); + }); + + }); + + describe("has a value property, which", function () { + + it("should accept an empty string to clear the value", function () { + var input, initialValue = "1010-10-10T10:10:10.101"; + + input = document.createElement("input"); + input.setAttribute("type", "datetime-local"); + input.setAttribute("value", initialValue); + + expect(input.value).toBe(initialValue); + + input.value = ""; + expect(input.value).toBe(""); + }); + + it("should accept assignments with a valid partial time as defined in RFC 3339", function () { + var input; + + input = document.createElement("input"); + input.setAttribute("type", "datetime-local"); + + input.value = "1970-01-01T00:00:00.001"; + expect(input.value).toBe("1970-01-01T00:00:00.001"); + + input.value = "1970-01-01T01:00:00.001"; + expect(input.value).toBe("1970-01-01T01:00:00.001"); + + input.value = "1970-01-01T12:12:12.120"; + expect(input.value).toBe("1970-01-01T12:12:12.120"); + + // Can"t test 10:10:10.1 easily, since chrome will return the same value if set through .value, but padded with + // zeros when set through user input. This polyfill always returns with padding of zeros. + input.value = "1970-01-01T10:10:10.100"; + expect(input.value).toBe("1970-01-01T10:10:10.100"); + + input.value = "1970-01-01T12:12:12"; + expect(input.value).toBe("1970-01-01T12:12:12"); + + input.value = "1970-01-01T23:12:12"; + expect(input.value).toBe("1970-01-01T23:12:12"); + + //input.value = "1970-01-01T23:59:59.1001"; + //expect(input.value).toBe("1970-01-01T23:59:59.100"); + + }); + + it("should not accept assignments with an invalid time", function () { + var input; + + input = document.createElement("input"); + input.setAttribute("type", "datetime-local"); + + input.value = "not a datetime-local string"; + expect(input.value).toBe(""); + + input.value = 0; + expect(input.value).toBe(""); + + input.value = "1"; + expect(input.value).toBe(""); + + input.value = "1:1"; + expect(input.value).toBe(""); + + input.value = "1:01"; + expect(input.value).toBe(""); + + input.value = "24:01"; + expect(input.value).toBe(""); + + input.value = "23:60"; + expect(input.value).toBe(""); + + input.value = "23:59:60"; + expect(input.value).toBe(""); + }); + + }); + + /* TODO chrome doesn't seem to support valueAsDate for datetime-local input elements!? + describe("has a valueAsDate property, which", function () { + + it("should return a Date object for input elements with a valid value", function () { + var input; + + input = document.createElement("input"); + input.setAttribute("type", "datetime-local"); + + input.value = "1971-01-01T01:01:01.01"; + expect(input.valueAsDate instanceof Date).toBeTruthy(); + }); + + it("should return null for input elements with an invalid value", function () { + var input; + + input = document.createElement("input"); + input.setAttribute("type", "datetime-local"); + + input.value = "1970-01-01T24:01:01.01"; + expect(input.valueAsDate).toBe(null); + }); + + });*/ + + describe("has a valueAsNumber property, which", function () { + + it("should return an integer for input elements with a valid value", function () { + var input; + + input = document.createElement("input"); + input.setAttribute("type", "datetime-local"); + + input.setAttribute("value", "1970-01-01T00:00"); + expect(input.valueAsNumber).toBe(0); + + input.value = "1970-01-01T01:01"; + expect(input.valueAsNumber).toBe(3660000); + + input.value = "1970-01-01T03:25:45.678"; + expect(input.valueAsNumber).toBe(12345678); + + input.value = "1970-01-01T23:59:59.999"; + expect(input.valueAsNumber).toBe(86399999); + }); + + it("should return NaN for input elements with an invalid value", function () { + var input; + + input = document.createElement("input"); + input.setAttribute("type", "datetime-local"); + + input.value = "not a datetime-local string"; + expect(input.valueAsNumber).toBeNaN(); + + input.value = 0; + expect(input.valueAsNumber).toBeNaN(); + + input.value = "1970-01-01T1"; + expect(input.valueAsNumber).toBeNaN(); + + input.value = "1970-01-01T1:1"; + expect(input.valueAsNumber).toBeNaN(); + + input.value = "1970-01-01T1:01"; + expect(input.valueAsNumber).toBeNaN(); + + input.value = "1970-01-01T24:01"; + expect(input.valueAsNumber).toBeNaN(); + + input.value = "1970-01-01T23:60"; + expect(input.valueAsNumber).toBeNaN(); + + input.value = "1970-01-01T23:59:60"; + expect(input.valueAsNumber).toBeNaN(); + }); + }); + + describe("has a stepUp() method, which", function () { + + it("for elements without step, min and max attributes should increase the value by minutes", function () { + var input; + + input = document.createElement("input"); + input.setAttribute("type", "datetime-local"); + input.setAttribute("value", "1970-01-01T00:00:00.001"); + + input.stepUp(); + expect(input.value).toBe("1970-01-01T00:01:00.001"); + + input.stepUp(8); + expect(input.value).toBe("1970-01-01T00:09:00.001"); + + input.stepUp(51); + expect(input.value).toBe("1970-01-01T01:00:00.001"); + }); + + }); + + describe("has a stepDown() method, which", function () { + + it("for elements without step, min and max attributes should decrease the value by minutes", function () { + var input; + + input = document.createElement("input"); + input.setAttribute("type", "datetime-local"); + input.setAttribute("value", "1970-01-01T01:00:00.001"); + + input.stepDown(); + expect(input.value).toBe("1970-01-01T00:59:00.001"); + + input.stepDown(8); + expect(input.value).toBe("1970-01-01T00:51:00.001"); + + input.stepDown(51); + expect(input.value).toBe("1970-01-01T00:00:00.001"); + }); + + }); + +}); diff --git a/test/input-time/dom.spec.js b/test/input-time/dom.spec.js index b7884d7..8fa912f 100644 --- a/test/input-time/dom.spec.js +++ b/test/input-time/dom.spec.js @@ -1,216 +1,216 @@ -'use strict'; +"use strict"; /* global describe, expect, it */ -describe('The DOM interface of input[type=time] elements', function () { +describe("The DOM interface of input[type=time] elements", function () { - describe('has a type property, which', function () { + describe("has a type property, which", function () { - it('should return "time" for input elements with type=time', function () { + it("should return 'time' for input elements with type=time", function () { var input; - input = document.createElement('input'); - input.setAttribute('type', 'time'); + input = document.createElement("input"); + input.setAttribute("type", "time"); - expect(input.type).toBe('time'); + expect(input.type).toBe("time"); }); }); - describe('has a value property, which', function () { + describe("has a value property, which", function () { - it('should accept an empty string to clear the value', function () { - var input, initialValue = '12:34:56.789'; + it("should accept an empty string to clear the value", function () { + var input, initialValue = "12:34:56.789"; - input = document.createElement('input'); - input.setAttribute('type', 'time'); - input.setAttribute('value', initialValue); + input = document.createElement("input"); + input.setAttribute("type", "time"); + input.setAttribute("value", initialValue); expect(input.value).toBe(initialValue); - input.value = ''; - expect(input.value).toBe(''); + input.value = ""; + expect(input.value).toBe(""); }); - it('should accept assignments with a valid partial time as defined in RFC 3339', function () { + it("should accept assignments with a valid partial time as defined in RFC 3339", function () { var input; - input = document.createElement('input'); - input.setAttribute('type', 'time'); + input = document.createElement("input"); + input.setAttribute("type", "time"); - input.value = '00:00:00.001'; - expect(input.value).toBe('00:00:00.001'); + input.value = "00:00:00.001"; + expect(input.value).toBe("00:00:00.001"); - input.value = '01:00:00.001'; - expect(input.value).toBe('01:00:00.001'); + input.value = "01:00:00.001"; + expect(input.value).toBe("01:00:00.001"); - input.value = '12:12:12.120'; - expect(input.value).toBe('12:12:12.120'); + input.value = "12:12:12.120"; + expect(input.value).toBe("12:12:12.120"); - // Can't test 10:10:10.1 easily, since chrome will return the same value if set through .value, but padded with + // Can"t test 10:10:10.1 easily, since chrome will return the same value if set through .value, but padded with // zeros when set through user input. This polyfill always returns with padding of zeros. - input.value = '10:10:10.100'; - expect(input.value).toBe('10:10:10.100'); + input.value = "10:10:10.100"; + expect(input.value).toBe("10:10:10.100"); - input.value = '12:12:12'; - expect(input.value).toBe('12:12:12'); + input.value = "12:12:12"; + expect(input.value).toBe("12:12:12"); - input.value = '23:12:12'; - expect(input.value).toBe('23:12:12'); + input.value = "23:12:12"; + expect(input.value).toBe("23:12:12"); - //input.value = '23:59:59.1001'; - //expect(input.value).toBe('23:59:59.100'); + //input.value = "23:59:59.1001"; + //expect(input.value).toBe("23:59:59.100"); }); - it('should not accept assignments with an invalid time', function () { + it("should not accept assignments with an invalid time", function () { var input; - input = document.createElement('input'); - input.setAttribute('type', 'time'); + input = document.createElement("input"); + input.setAttribute("type", "time"); - input.value = 'not a time string'; - expect(input.value).toBe(''); + input.value = "not a time string"; + expect(input.value).toBe(""); input.value = 0; - expect(input.value).toBe(''); + expect(input.value).toBe(""); - input.value = '1'; - expect(input.value).toBe(''); + input.value = "1"; + expect(input.value).toBe(""); - input.value = '1:1'; - expect(input.value).toBe(''); + input.value = "1:1"; + expect(input.value).toBe(""); - input.value = '1:01'; - expect(input.value).toBe(''); + input.value = "1:01"; + expect(input.value).toBe(""); - input.value = '24:01'; - expect(input.value).toBe(''); + input.value = "24:01"; + expect(input.value).toBe(""); - input.value = '23:60'; - expect(input.value).toBe(''); + input.value = "23:60"; + expect(input.value).toBe(""); - input.value = '23:59:60'; - expect(input.value).toBe(''); + input.value = "23:59:60"; + expect(input.value).toBe(""); }); }); - describe('has a valueAsDate property, which', function () { + describe("has a valueAsDate property, which", function () { - it('should return a Date object for input elements with a valid value', function () { + it("should return a Date object for input elements with a valid value", function () { var input; - input = document.createElement('input'); - input.setAttribute('type', 'time'); + input = document.createElement("input"); + input.setAttribute("type", "time"); - input.value = '01:01:01.01'; + input.value = "01:01:01.01"; expect(input.valueAsDate instanceof Date).toBeTruthy(); }); - it('should return null for input elements with an invalid value', function () { + it("should return null for input elements with an invalid value", function () { var input; - input = document.createElement('input'); - input.setAttribute('type', 'time'); + input = document.createElement("input"); + input.setAttribute("type", "time"); - input.value = '24:01:01.01'; + input.value = "24:01:01.01"; expect(input.valueAsDate).toBe(null); }); }); - describe('has a valueAsNumber property, which', function () { + describe("has a valueAsNumber property, which", function () { - it('should return an integer for input elements with a valid value', function () { + it("should return an integer for input elements with a valid value", function () { var input; - input = document.createElement('input'); - input.setAttribute('type', 'time'); + input = document.createElement("input"); + input.setAttribute("type", "time"); - input.setAttribute('value', '00:00'); + input.setAttribute("value", "00:00"); expect(input.valueAsNumber).toBe(0); - input.value = '01:01'; + input.value = "01:01"; expect(input.valueAsNumber).toBe(3660000); - input.value = '03:25:45.678'; + input.value = "03:25:45.678"; expect(input.valueAsNumber).toBe(12345678); - input.value = '23:59:59.999'; + input.value = "23:59:59.999"; expect(input.valueAsNumber).toBe(86399999); }); - it('should return NaN for input elements with an invalid value', function () { + it("should return NaN for input elements with an invalid value", function () { var input; - input = document.createElement('input'); - input.setAttribute('type', 'time'); + input = document.createElement("input"); + input.setAttribute("type", "time"); - input.value = 'not a time string'; + input.value = "not a time string"; expect(input.valueAsNumber).toBeNaN(); input.value = 0; expect(input.valueAsNumber).toBeNaN(); - input.value = '1'; + input.value = "1"; expect(input.valueAsNumber).toBeNaN(); - input.value = '1:1'; + input.value = "1:1"; expect(input.valueAsNumber).toBeNaN(); - input.value = '1:01'; + input.value = "1:01"; expect(input.valueAsNumber).toBeNaN(); - input.value = '24:01'; + input.value = "24:01"; expect(input.valueAsNumber).toBeNaN(); - input.value = '23:60'; + input.value = "23:60"; expect(input.valueAsNumber).toBeNaN(); - input.value = '23:59:60'; + input.value = "23:59:60"; expect(input.valueAsNumber).toBeNaN(); }); }); - describe('has a stepUp() method, which', function () { + describe("has a stepUp() method, which", function () { - it('for elements without step, min and max attributes should increase the value by minutes', function () { + it("for elements without step, min and max attributes should increase the value by minutes", function () { var input; - input = document.createElement('input'); - input.setAttribute('type', 'time'); - input.setAttribute('value', '00:00:00.001'); + input = document.createElement("input"); + input.setAttribute("type", "time"); + input.setAttribute("value", "00:00:00.001"); input.stepUp(); - expect(input.value).toBe('00:01:00.001'); + expect(input.value).toBe("00:01:00.001"); input.stepUp(8); - expect(input.value).toBe('00:09:00.001'); + expect(input.value).toBe("00:09:00.001"); input.stepUp(51); - expect(input.value).toBe('01:00:00.001'); + expect(input.value).toBe("01:00:00.001"); }); }); - describe('has a stepDown() method, which', function () { + describe("has a stepDown() method, which", function () { - it('for elements without step, min and max attributes should decrease the value by minutes', function () { + it("for elements without step, min and max attributes should decrease the value by minutes", function () { var input; - input = document.createElement('input'); - input.setAttribute('type', 'time'); - input.setAttribute('value', '01:00:00.001'); + input = document.createElement("input"); + input.setAttribute("type", "time"); + input.setAttribute("value", "01:00:00.001"); input.stepDown(); - expect(input.value).toBe('00:59:00.001'); + expect(input.value).toBe("00:59:00.001"); input.stepDown(8); - expect(input.value).toBe('00:51:00.001'); + expect(input.value).toBe("00:51:00.001"); input.stepDown(51); - expect(input.value).toBe('00:00:00.001'); + expect(input.value).toBe("00:00:00.001"); }); }); diff --git a/test/input/dom.spec.js b/test/input/dom.spec.js index 04822bc..3c2f298 100644 --- a/test/input/dom.spec.js +++ b/test/input/dom.spec.js @@ -1,73 +1,73 @@ -'use strict'; +"use strict"; /* global describe, expect, it */ -describe('The DOM interface of input elements', function () { +describe("The DOM interface of input elements", function () { - describe('has a type property, which', function () { + describe("has a type property, which", function () { - it('should return the type of the input', function () { + it("should return the type of the input", function () { var input; - input = document.createElement('input'); + input = document.createElement("input"); - expect(input.type).toBe('text'); + expect(input.type).toBe("text"); - input.setAttribute('type', 'text'); + input.setAttribute("type", "text"); - expect(input.type).toBe('text'); + expect(input.type).toBe("text"); - input.setAttribute('type', 'checkbox'); + input.setAttribute("type", "checkbox"); - expect(input.type).toBe('checkbox'); + expect(input.type).toBe("checkbox"); }); - it('should return "date" for input elements with type=date', function () { + it("should return 'date' for input elements with type=date", function () { var input; - input = document.createElement('input'); - input.setAttribute('type', 'date'); + input = document.createElement("input"); + input.setAttribute("type", "date"); - expect(input.type).toBe('date'); + expect(input.type).toBe("date"); }); - it('should return "time" for input elements with type=time', function () { + it("should return 'time' for input elements with type=time", function () { var input; - input = document.createElement('input'); - input.setAttribute('type', 'time'); + input = document.createElement("input"); + input.setAttribute("type", "time"); - expect(input.type).toBe('time'); + expect(input.type).toBe("time"); }); - it('should return "text" if the type is unknown', function () { + it("should return 'text' if the type is unknown", function () { var input; - input = document.createElement('input'); - input.setAttribute('type', 'fake-type'); + input = document.createElement("input"); + input.setAttribute("type", "fake-type"); - expect(input.type).toBe('text'); + expect(input.type).toBe("text"); }); }); - describe('has a valueAsDate property, which', function () { + describe("has a valueAsDate property, which", function () { - it('should return null for input elements not of type date or time', function () { + it("should return null for input elements not of type date or time", function () { var input; - input = document.createElement('input'); + input = document.createElement("input"); expect(input.valueAsDate).toBe(null); }); }); - describe('has a valueAsNumber property, which', function () { + describe("has a valueAsNumber property, which", function () { - it('should return NaN for input elements not of type date or time', function () { + it("should return NaN for input elements not of type date or time", function () { var input; - input = document.createElement('input'); + input = document.createElement("input"); expect(input.valueAsNumber).toBeNaN(); }); diff --git a/test/popup.html b/test/popup.html index 5781552..a5d2d3a 100644 --- a/test/popup.html +++ b/test/popup.html @@ -5,20 +5,25 @@ Test for datetime polyfill + + + + + + + + - - - - +