diff --git a/addon-test-support/-private/get-element-with-assert.js b/addon-test-support/-private/get-element-with-assert.js deleted file mode 100644 index 33f7cdd..0000000 --- a/addon-test-support/-private/get-element-with-assert.js +++ /dev/null @@ -1,16 +0,0 @@ -import getElement from './get-element'; - -/* - @method getElementWithAssert - @param {String|HTMLElement} selectorOrElement - @param {HTMLElement} contextEl to query within, query from its contained DOM - @return {Error|HTMLElement} element if found, or raises an error - @private -*/ -export default function getElementWithAssert(selectorOrElement, contextEl) { - let el = getElement(selectorOrElement, contextEl); - if (el) { - return el; - } - throw new Error(`Element ${selectorOrElement} not found.`); -} diff --git a/addon-test-support/-private/get-element-with-assert.ts b/addon-test-support/-private/get-element-with-assert.ts new file mode 100644 index 0000000..4854ee4 --- /dev/null +++ b/addon-test-support/-private/get-element-with-assert.ts @@ -0,0 +1,10 @@ +import getElement from './get-element'; +import { ElementOrSelector } from './types'; + +export default function getElementWithAssert(selectorOrElement: ElementOrSelector, contextEl: ElementOrSelector) : HTMLElement { + let el = getElement(selectorOrElement, contextEl); + if (el) { + return el; + } + throw new Error(`Element ${selectorOrElement} not found.`); +} diff --git a/addon-test-support/-private/get-element.js b/addon-test-support/-private/get-element.ts similarity index 55% rename from addon-test-support/-private/get-element.js rename to addon-test-support/-private/get-element.ts index 24b9247..eb2d756 100644 --- a/addon-test-support/-private/get-element.js +++ b/addon-test-support/-private/get-element.ts @@ -1,13 +1,7 @@ import settings from '../settings'; +import { ElementOrSelector } from './types'; -/* - @method getElement - @param {String|HTMLElement} selectorOrElement - @param {HTMLElement} contextEl to query within, query from its contained DOM - @return HTMLElement - @private -*/ -export default function getElement(selectorOrElement, contextEl) { +export default function getElement(selectorOrElement: ElementOrSelector, contextEl: ElementOrSelector) : HTMLElement { if (selectorOrElement instanceof HTMLElement) { return selectorOrElement; } @@ -17,5 +11,5 @@ export default function getElement(selectorOrElement, contextEl) { } else { result = document.querySelector(`${settings.rootElement} ${selectorOrElement}`); } - return result; + return result as HTMLElement; } diff --git a/addon-test-support/-private/is-focusable.js b/addon-test-support/-private/is-focusable.js deleted file mode 100644 index bfd22f9..0000000 --- a/addon-test-support/-private/is-focusable.js +++ /dev/null @@ -1,10 +0,0 @@ -export default function isFocusable(el) { - let focusableTags = ['INPUT', 'BUTTON', 'LINK', 'SELECT', 'A', 'TEXTAREA']; - let { tagName, type } = el; - - if (type === 'hidden') { - return false; - } - - return focusableTags.indexOf(tagName) > -1 || el.contentEditable; -} diff --git a/addon-test-support/-private/is-focusable.ts b/addon-test-support/-private/is-focusable.ts new file mode 100644 index 0000000..a144806 --- /dev/null +++ b/addon-test-support/-private/is-focusable.ts @@ -0,0 +1,15 @@ +const focusableTypes = [ + HTMLInputElement, + HTMLButtonElement, + HTMLLinkElement, + HTMLSelectElement, + HTMLAnchorElement, + HTMLTextAreaElement +]; +export default function isFocusable(el: HTMLElement) : boolean { + if (el instanceof HTMLInputElement && el.type === 'hidden') { + return false; + } + + return focusableTypes.some((type) => el instanceof type) || el.contentEditable === 'true'; +} diff --git a/addon-test-support/-private/types.ts b/addon-test-support/-private/types.ts new file mode 100644 index 0000000..5550df4 --- /dev/null +++ b/addon-test-support/-private/types.ts @@ -0,0 +1,6 @@ +export type ElementOrSelector = string | HTMLElement; +export interface EventOptions { + bubbles?: boolean, + cancelable?: boolean, + [propName: string]: any; +}; diff --git a/addon-test-support/find.js b/addon-test-support/find.ts similarity index 59% rename from addon-test-support/find.js rename to addon-test-support/find.ts index efaa00d..2b36968 100644 --- a/addon-test-support/find.js +++ b/addon-test-support/find.ts @@ -1,5 +1,5 @@ import getElement from './-private/get-element'; - +import { ElementOrSelector } from './-private/types'; /* The find test helper uses `querySelector` to search inside the test DOM (based on app configuration for the rootElement). @@ -8,11 +8,8 @@ import getElement from './-private/get-element'; DOM context to search within. @method find - @param {String} CSS selector to find one or more elements in the test DOM - @param {HTMLElement} contextEl to query within, query from its contained DOM - @return {null|HTMLElement} null or an element @public */ -export function find(selector, contextEl) { +export function find(selector: ElementOrSelector, contextEl: ElementOrSelector) : ElementOrSelector { return getElement(selector, contextEl); } diff --git a/addon-test-support/fire-event.js b/addon-test-support/fire-event.ts similarity index 71% rename from addon-test-support/fire-event.js rename to addon-test-support/fire-event.ts index da5c28b..849370b 100644 --- a/addon-test-support/fire-event.js +++ b/addon-test-support/fire-event.ts @@ -1,23 +1,16 @@ import Ember from 'ember'; +import { EventOptions } from './-private/types'; const { merge } = Ember; -const DEFAULT_EVENT_OPTIONS = { bubbles: true, cancelable: true }; +const DEFAULT_EVENT_OPTIONS: EventOptions = { bubbles: true, cancelable: true }; const KEYBOARD_EVENT_TYPES = ['keydown', 'keypress', 'keyup']; const MOUSE_EVENT_TYPES = ['click', 'mousedown', 'mouseup', 'dblclick', 'mouseenter', 'mouseleave', 'mousemove', 'mouseout', 'mouseover']; -/* - @method fireEvent - @param {HTMLElement} element - @param {String} type - @param {Object} (optional) options - @return {Event} The dispatched event - @private -*/ -export function fireEvent(element, type, options = {}) { +export function fireEvent(element: HTMLElement, type: string, options: EventOptions = {}): Event { if (!element) { return; } - let event; + let event: Event; if (KEYBOARD_EVENT_TYPES.indexOf(type) > -1) { event = buildKeyboardEvent(type, options); } else if (MOUSE_EVENT_TYPES.indexOf(type) > -1) { @@ -38,41 +31,19 @@ export function fireEvent(element, type, options = {}) { return event; } -/* - @method buildBasicEvent - @param {String} type - @param {Object} (optional) options - @return {Event} - @private -*/ -function buildBasicEvent(type, options = {}) { +function buildBasicEvent(type: string, { bubbles = true, cancelable = true, ...otherOptions }: EventOptions = {}): Event { let event = document.createEvent('Events'); - let bubbles = options.bubbles !== undefined ? options.bubbles : true; - let cancelable = options.cancelable !== undefined ? options.cancelable : true; - - delete options.bubbles; - delete options.cancelable; - - // bubbles and cancelable are readonly, so they can be - // set when initializing event + // bubbles and cancelable are readonly, so they can be set when initializing event event.initEvent(type, bubbles, cancelable); - merge(event, options); + merge(event, otherOptions); return event; } -/* - @method buildMouseEvent - @param {String} type - @param {Object} (optional) options - @return {Event} - @private -*/ -function buildMouseEvent(type, options = {}) { - let event; +function buildMouseEvent(type: string, options: EventOptions = {}): Event { try { - event = document.createEvent('MouseEvents'); - let eventOpts = merge(merge({}, DEFAULT_EVENT_OPTIONS), options); + let event = document.createEvent('MouseEvents'); + let eventOpts: EventOptions = merge(merge({}, DEFAULT_EVENT_OPTIONS), options); event.initMouseEvent( type, eventOpts.bubbles, @@ -89,10 +60,10 @@ function buildMouseEvent(type, options = {}) { eventOpts.metaKey, eventOpts.button, eventOpts.relatedTarget); - } catch (e) { - event = buildBasicEvent(type, options); + return event; + } catch(e) { + return buildBasicEvent(type, options); } - return event; } /* @@ -102,7 +73,7 @@ function buildMouseEvent(type, options = {}) { @return {Event} @private */ -function buildKeyboardEvent(type, options = {}) { +function buildKeyboardEvent(type: string, options: EventOptions = {}): KeyboardEvent { let eventOpts = merge(merge({}, DEFAULT_EVENT_OPTIONS), options); let event, eventMethodName; diff --git a/addon-test-support/settings.js b/addon-test-support/settings.ts similarity index 94% rename from addon-test-support/settings.js rename to addon-test-support/settings.ts index 7ba9004..b0baf4d 100644 --- a/addon-test-support/settings.js +++ b/addon-test-support/settings.ts @@ -4,6 +4,7 @@ @class TestSupportSettings */ class TestSupportSettings { + private _rootElement: string; constructor(init = { rootElement: '#ember-testing' }) { this._rootElement = init.rootElement; diff --git a/app/config/environment.d.ts b/app/config/environment.d.ts new file mode 100644 index 0000000..999045b --- /dev/null +++ b/app/config/environment.d.ts @@ -0,0 +1,15 @@ +export default config; + +/** + * Type declarations for + * import config from './config/environment' + * + * For now these need to be managed by the developer + * since different ember addons can materialize new entries. + */ +declare namespace config { + export var environment: any; + export var modulePrefix: string; + export var podModulePrefix: string; + export var locationType: string; +} diff --git a/package.json b/package.json index 62f5348..8274cf7 100644 --- a/package.json +++ b/package.json @@ -26,9 +26,12 @@ }, "dependencies": { "broccoli-funnel": "^1.1.0", - "ember-cli-babel": "^6.1.0" + "ember-cli-typescript": "^0.4.0", + "ember-cli-babel": "^6.1.0", + "typescript": "^2.1" }, "devDependencies": { + "@types/ember": "^2.7.34", "broccoli-asset-rev": "^2.4.5", "ember-cli": "~2.13.1", "ember-cli-dependency-checker": "^1.3.0", diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..d0ff592 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "target": "ES6", + "allowJs": true, + "moduleResolution": "node", + "noEmitOnError": false, + "noEmit": true, + "baseUrl": ".", + "paths": { + "ember-native-dom-helpers/tests/*": ["tests/*"], + "ember-native-dom-helpers/*": ["app/*"] + } + }, + "include": [ + "app/**/*", + "tests/**/*" + ] +} diff --git a/yarn.lock b/yarn.lock index 80892c8..eae18db 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12,6 +12,21 @@ dependencies: "@glimmer/di" "^0.2.0" +"@types/ember@^2.7.34": + version "2.7.39" + resolved "https://registry.yarnpkg.com/@types/ember/-/ember-2.7.39.tgz#6d6716d5b85d25f227ce73012fb4deda485ca9b2" + dependencies: + "@types/handlebars" "*" + "@types/jquery" "*" + +"@types/handlebars@*": + version "4.0.32" + resolved "https://registry.yarnpkg.com/@types/handlebars/-/handlebars-4.0.32.tgz#637e8d945a9354aab47df7125005490fe9f8e592" + +"@types/jquery@*": + version "2.0.42" + resolved "https://registry.yarnpkg.com/@types/jquery/-/jquery-2.0.42.tgz#57cdb1a0f610ddad488adf620e40f8d07ff3ecdf" + abbrev@1: version "1.1.0" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.0.tgz#d0554c2256636e2f56e7c2e5ad183f859428d81f" @@ -1199,7 +1214,7 @@ broccoli-lint-eslint@^3.1.0: json-stable-stringify "^1.0.1" md5-hex "^2.0.0" -broccoli-merge-trees@^1.0.0, broccoli-merge-trees@^1.1.0, broccoli-merge-trees@^1.1.1: +broccoli-merge-trees@^1.0.0, broccoli-merge-trees@^1.1.0, broccoli-merge-trees@^1.1.1, broccoli-merge-trees@^1.1.4: version "1.2.4" resolved "https://registry.yarnpkg.com/broccoli-merge-trees/-/broccoli-merge-trees-1.2.4.tgz#a001519bb5067f06589d91afa2942445a2d0fdb5" dependencies: @@ -1282,7 +1297,7 @@ broccoli-sri-hash@^2.1.0: sri-toolbox "^0.2.0" symlink-or-copy "^1.0.1" -broccoli-stew@^1.2.0, broccoli-stew@^1.3.3: +broccoli-stew@^1.2.0, broccoli-stew@^1.3.3, broccoli-stew@^1.4.0: version "1.4.2" resolved "https://registry.yarnpkg.com/broccoli-stew/-/broccoli-stew-1.4.2.tgz#9ec4062fd7162c6026561a2fbf64558363aff8d6" dependencies: @@ -1316,6 +1331,21 @@ broccoli-templater@^1.0.0: broccoli-stew "^1.2.0" lodash.template "^3.3.2" +broccoli-typescript-compiler@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/broccoli-typescript-compiler/-/broccoli-typescript-compiler-1.0.1.tgz#648055f23f4257a1ec434a455c77f5e43bd28d2f" + dependencies: + broccoli-funnel "^1.0.6" + broccoli-merge-trees "^1.1.4" + broccoli-plugin "^1.2.1" + findup "^0.1.5" + fs-tree-diff "^0.5.2" + get-caller-file "^1.0.1" + heimdalljs "^0.3.0-alpha3" + json-stable-stringify "^1.0.1" + md5-hex "^1.3.0" + walk-sync "^0.3.1" + broccoli-uglify-sourcemap@^1.0.0: version "1.5.2" resolved "https://registry.yarnpkg.com/broccoli-uglify-sourcemap/-/broccoli-uglify-sourcemap-1.5.2.tgz#04f84ab0db539031fa868ccfa563c9932d50cedb" @@ -1584,6 +1614,10 @@ colors@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" +colors@~0.6.0-1: + version "0.6.2" + resolved "https://registry.yarnpkg.com/colors/-/colors-0.6.2.tgz#2423fe6678ac0c5dae8852e5d0e5be08c997abcc" + columnify@~1.5.4: version "1.5.4" resolved "https://registry.yarnpkg.com/columnify/-/columnify-1.5.4.tgz#4737ddf1c7b69a8a7c340570782e947eec8e78bb" @@ -1609,6 +1643,10 @@ commander@2.9.0, commander@^2.5.0, commander@^2.6.0, commander@^2.9.0: dependencies: graceful-readlink ">= 1.0.0" +commander@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.1.0.tgz#d121bbae860d9992a3d517ba96f56588e47c6781" + commoner@~0.10.3: version "0.10.8" resolved "https://registry.yarnpkg.com/commoner/-/commoner-0.10.8.tgz#34fc3672cd24393e8bb47e70caa0293811f4f2c5" @@ -1961,21 +1999,7 @@ ember-cli-babel@^5.1.5, ember-cli-babel@^5.1.7: ember-cli-version-checker "^1.0.2" resolve "^1.1.2" -ember-cli-babel@^6.0.0-beta.4, ember-cli-babel@^6.0.0-beta.7: - version "6.0.0-beta.9" - resolved "https://registry.yarnpkg.com/ember-cli-babel/-/ember-cli-babel-6.0.0-beta.9.tgz#b597d52f12d4429cd5716b55f749ebf6144b7b16" - dependencies: - amd-name-resolver "0.0.6" - babel-plugin-transform-es2015-modules-amd "^6.24.0" - babel-polyfill "^6.16.0" - babel-preset-env "^1.2.0" - broccoli-babel-transpiler "^6.0.0" - broccoli-funnel "^1.0.0" - broccoli-source "^1.1.0" - clone "^2.0.0" - ember-cli-version-checker "^1.2.0" - -ember-cli-babel@^6.1.0: +ember-cli-babel@^6.0.0-beta.4, ember-cli-babel@^6.0.0-beta.7, ember-cli-babel@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/ember-cli-babel/-/ember-cli-babel-6.1.0.tgz#d9c83a7d0c67cc8a3ccb9bd082971c3593e54fad" dependencies: @@ -2191,6 +2215,19 @@ ember-cli-test-loader@^2.0.0: dependencies: ember-cli-babel "^6.0.0-beta.7" +ember-cli-typescript@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/ember-cli-typescript/-/ember-cli-typescript-0.4.0.tgz#9fe1ecee835ede60d5977e2801a0a964f1837e2f" + dependencies: + broccoli-funnel "^1.0.6" + broccoli-merge-trees "^1.1.4" + broccoli-plugin "^1.2.1" + broccoli-source "^1.1.0" + broccoli-stew "^1.4.0" + broccoli-typescript-compiler "^1.0.1" + debug "^2.2.0" + ember-cli-babel "^5.1.7" + ember-cli-uglify@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/ember-cli-uglify/-/ember-cli-uglify-1.2.0.tgz#3208c32b54bc2783056e8bb0d5cfe9bbaf17ffb2" @@ -2871,6 +2908,13 @@ findup-sync@^0.4.2, findup-sync@^0.4.3: micromatch "^2.3.7" resolve-dir "^0.1.0" +findup@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/findup/-/findup-0.1.5.tgz#8ad929a3393bac627957a7e5de4623b06b0e2ceb" + dependencies: + colors "~0.6.0-1" + commander "~2.1.0" + fireworm@^0.7.0: version "0.7.1" resolved "https://registry.yarnpkg.com/fireworm/-/fireworm-0.7.1.tgz#ccf20f7941f108883fcddb99383dbe6e1861c758" @@ -3074,7 +3118,7 @@ generate-object-property@^1.1.0: dependencies: is-property "^1.0.0" -get-caller-file@^1.0.0: +get-caller-file@^1.0.0, get-caller-file@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" @@ -3306,6 +3350,12 @@ heimdalljs@^0.2.0, heimdalljs@^0.2.1, heimdalljs@^0.2.3: dependencies: rsvp "~3.2.1" +heimdalljs@^0.3.0-alpha3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/heimdalljs/-/heimdalljs-0.3.3.tgz#e92d2c6f77fd46d5bf50b610d28ad31755054d0b" + dependencies: + rsvp "~3.2.1" + hoek@2.x.x: version "2.16.3" resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" @@ -4230,7 +4280,7 @@ matcher-collection@^1.0.0, matcher-collection@^1.0.1: dependencies: minimatch "^3.0.2" -md5-hex@^1.0.2: +md5-hex@^1.0.2, md5-hex@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/md5-hex/-/md5-hex-1.3.0.tgz#d2c4afe983c4370662179b8cad145219135046c4" dependencies: @@ -5067,7 +5117,7 @@ read@1, read@~1.0.1, read@~1.0.7: dependencies: mute-stream "~0.0.4" -"readable-stream@1 || 2", readable-stream@^2.0.2, readable-stream@~2.0.5: +"readable-stream@1 || 2", readable-stream@^2, "readable-stream@^2.0.0 || ^1.1.13", readable-stream@^2.0.2, readable-stream@~2.0.5: version "2.0.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e" dependencies: @@ -5078,7 +5128,7 @@ read@1, read@~1.0.1, read@~1.0.7: string_decoder "~0.10.x" util-deprecate "~1.0.1" -readable-stream@^2, "readable-stream@^2.0.0 || ^1.1.13", readable-stream@^2.1.4, readable-stream@^2.2.2: +readable-stream@^2.1.4, readable-stream@^2.2.2: version "2.2.9" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.9.tgz#cf78ec6f4a6d1eb43d26488cac97f042e74b7fc8" dependencies: @@ -5519,13 +5569,13 @@ signal-exit@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" -silent-error@^1.0.0, silent-error@^1.0.1: +silent-error@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/silent-error/-/silent-error-1.0.1.tgz#71b7d503d1c6f94882b51b56be879b113cb4822c" dependencies: debug "^2.2.0" -silent-error@^1.1.0: +silent-error@^1.0.1, silent-error@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/silent-error/-/silent-error-1.1.0.tgz#2209706f1c850a9f1d10d0d840918b46f26e1bc9" dependencies: @@ -6003,6 +6053,10 @@ typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" +typescript@^2.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.3.2.tgz#f0f045e196f69a72f06b25fd3bd39d01c3ce9984" + uc.micro@^1.0.0, uc.micro@^1.0.1, uc.micro@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.3.tgz#7ed50d5e0f9a9fb0a573379259f2a77458d50192"