From a88545812e08ca617dd3f33174c91b824e0481f1 Mon Sep 17 00:00:00 2001 From: Keith Cirkel Date: Tue, 22 Nov 2022 17:45:12 +0000 Subject: [PATCH 1/4] move customElements define calls to index.js and refactor This moves the `customeElements.define` calls from each respective element and into the index.js file. This is useful for if we wish to load the components classes without defining the custom element. In addition, this changes the pattern of how we register the custom elements, to allow for HMR, as we did in https://github.com/github/catalyst/pull/197. --- src/index.ts | 44 ++++++++++++++++++++++++++++++++++++ src/local-time-element.ts | 19 ---------------- src/relative-time-element.ts | 19 ---------------- src/time-ago-element.ts | 14 ------------ src/time-until-element.ts | 14 ------------ test/constructor.js | 3 +-- test/local-time.js | 2 +- test/relative-time.js | 2 +- test/time-ago.js | 2 +- test/time-until.js | 2 +- test/title-format.js | 2 +- 11 files changed, 50 insertions(+), 73 deletions(-) diff --git a/src/index.ts b/src/index.ts index f57f30f..b1de0f7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,4 +3,48 @@ import RelativeTimeElement from './relative-time-element.js' import TimeAgoElement from './time-ago-element.js' import TimeUntilElement from './time-until-element.js' +const root = (typeof globalThis !== 'undefined' ? globalThis : window) as typeof window +try { + customElements.define('relative-time', RelativeTimeElement) + root.RelativeTimeElement = RelativeTimeElement +} catch (e: unknown) { + if (!(e instanceof DOMException && e.name === 'NotSupportedError') && !(e instanceof ReferenceError)) throw e +} + +try { + customElements.define('local-time', LocalTimeElement) + root.LocalTimeElement = LocalTimeElement +} catch (e: unknown) { + if (!(e instanceof DOMException && e.name === 'NotSupportedError') && !(e instanceof ReferenceError)) throw e +} + +try { + customElements.define('time-ago', TimeAgoElement) + root.TimeAgoElement = TimeAgoElement +} catch (e: unknown) { + if (!(e instanceof DOMException && e.name === 'NotSupportedError') && !(e instanceof ReferenceError)) throw e +} + +try { + customElements.define('time-until', TimeUntilElement) + root.TimeUntilElement = TimeUntilElement +} catch (e: unknown) { + if (!(e instanceof DOMException && e.name === 'NotSupportedError') && !(e instanceof ReferenceError)) throw e +} + +declare global { + interface Window { + RelativeTimeElement: typeof RelativeTimeElement + LocalTimeElement: typeof LocalTimeElement + TimeAgoElement: typeof TimeAgoElement + TimeUntilElement: typeof TimeUntilElement + } + interface HTMLElementTagNameMap { + 'relative-time': RelativeTimeElement + 'local-time': LocalTimeElement + 'time-ago': TimeAgoElement + 'time-until': TimeUntilElement + } +} + export {LocalTimeElement, RelativeTimeElement, TimeAgoElement, TimeUntilElement} diff --git a/src/local-time-element.ts b/src/local-time-element.ts index 956897c..3055c6d 100644 --- a/src/local-time-element.ts +++ b/src/local-time-element.ts @@ -28,22 +28,3 @@ export default class LocalTimeElement extends RelativeTimeElement { if (year === 'numeric' || year === '2-digit') return year } } - -// Public: LocalTimeElement constructor. -// -// var time = new LocalTimeElement() -// # => -// -if (!window.customElements.get('local-time')) { - window.LocalTimeElement = LocalTimeElement - window.customElements.define('local-time', LocalTimeElement) -} - -declare global { - interface Window { - LocalTimeElement: typeof LocalTimeElement - } - interface HTMLElementTagNameMap { - 'local-time': LocalTimeElement - } -} diff --git a/src/relative-time-element.ts b/src/relative-time-element.ts index 3c48216..7d91bd2 100644 --- a/src/relative-time-element.ts +++ b/src/relative-time-element.ts @@ -374,22 +374,3 @@ export default class RelativeTimeElement extends HTMLElement implements Intl.Dat } } } - -// Public: RelativeTimeElement constructor. -// -// var time = new RelativeTimeElement() -// # => -// -if (!window.customElements.get('relative-time')) { - window.RelativeTimeElement = RelativeTimeElement - window.customElements.define('relative-time', RelativeTimeElement) -} - -declare global { - interface Window { - RelativeTimeElement: typeof RelativeTimeElement - } - interface HTMLElementTagNameMap { - 'relative-time': RelativeTimeElement - } -} diff --git a/src/time-ago-element.ts b/src/time-ago-element.ts index c670b41..c022204 100644 --- a/src/time-ago-element.ts +++ b/src/time-ago-element.ts @@ -6,17 +6,3 @@ export default class TimeAgoElement extends RelativeTimeElement { return 'past' } } - -if (!window.customElements.get('time-ago')) { - window.TimeAgoElement = TimeAgoElement - window.customElements.define('time-ago', TimeAgoElement) -} - -declare global { - interface Window { - TimeAgoElement: typeof TimeAgoElement - } - interface HTMLElementTagNameMap { - 'time-ago': TimeAgoElement - } -} diff --git a/src/time-until-element.ts b/src/time-until-element.ts index 6ee58f2..be08fb7 100644 --- a/src/time-until-element.ts +++ b/src/time-until-element.ts @@ -6,17 +6,3 @@ export default class TimeUntilElement extends RelativeTimeElement { return 'future' } } - -if (!window.customElements.get('time-until')) { - window.TimeUntilElement = TimeUntilElement - window.customElements.define('time-until', TimeUntilElement) -} - -declare global { - interface Window { - TimeUntilElement: typeof TimeUntilElement - } - interface HTMLElementTagNameMap { - 'time-until': TimeUntilElement - } -} diff --git a/test/constructor.js b/test/constructor.js index 7750379..e80fd71 100644 --- a/test/constructor.js +++ b/test/constructor.js @@ -1,6 +1,5 @@ import {assert} from '@open-wc/testing' -import '../src/local-time-element.ts' -import '../src/relative-time-element.ts' +import '../src/index.ts' suite('constructor', function () { test('create local-time from document.createElement', function () { diff --git a/test/local-time.js b/test/local-time.js index a70934d..10079cd 100644 --- a/test/local-time.js +++ b/test/local-time.js @@ -1,5 +1,5 @@ import {assert} from '@open-wc/testing' -import '../src/local-time-element.ts' +import '../src/index.ts' suite('local-time', function () { let fixture diff --git a/test/relative-time.js b/test/relative-time.js index 0851329..2c42e50 100644 --- a/test/relative-time.js +++ b/test/relative-time.js @@ -1,5 +1,5 @@ import {assert} from '@open-wc/testing' -import RelativeTimeElement from '../src/relative-time-element.ts' +import {RelativeTimeElement} from '../src/index.ts' suite('relative-time', function () { let dateNow diff --git a/test/time-ago.js b/test/time-ago.js index 01ef85c..1abb9c6 100644 --- a/test/time-ago.js +++ b/test/time-ago.js @@ -1,5 +1,5 @@ import {assert} from '@open-wc/testing' -import '../src/time-ago-element.ts' +import '../src/index.ts' suite('time-ago', function () { let dateNow diff --git a/test/time-until.js b/test/time-until.js index 83b940d..ef9181f 100644 --- a/test/time-until.js +++ b/test/time-until.js @@ -1,5 +1,5 @@ import {assert} from '@open-wc/testing' -import '../src/time-until-element.ts' +import '../src/index.ts' suite('time-until', function () { test('always uses relative dates', function () { diff --git a/test/title-format.js b/test/title-format.js index db3d8e7..0f39c15 100644 --- a/test/title-format.js +++ b/test/title-format.js @@ -1,5 +1,5 @@ import {assert} from '@open-wc/testing' -import '../src/local-time-element.ts' +import '../src/index.ts' suite('title-format', function () { test('null getFormattedTitle if datetime is missing', function () { From 344cef3d66c76d17403ea3200777b85005216cf6 Mon Sep 17 00:00:00 2001 From: Keith Cirkel Date: Wed, 23 Nov 2022 15:13:05 +0000 Subject: [PATCH 2/4] add `define` export for custom element registration --- package.json | 12 +++++++ src/index.ts | 52 +++-------------------------- src/local-time-element-define.ts | 26 +++++++++++++++ src/relative-time-element-define.ts | 26 +++++++++++++++ src/time-ago-element-define.ts | 26 +++++++++++++++ src/time-until-element-define.ts | 26 +++++++++++++++ 6 files changed, 120 insertions(+), 48 deletions(-) create mode 100644 src/local-time-element-define.ts create mode 100644 src/relative-time-element-define.ts create mode 100644 src/time-ago-element-define.ts create mode 100644 src/time-until-element-define.ts diff --git a/package.json b/package.json index aac8833..03dddf2 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,18 @@ "dist", "custom-elements.json" ], + "exports": { + ".": "./dist/index.js", + "./define": "./dist/index.js", + "./relative-time": "./dist/relative-time-element.js", + "./relative-time/define": "./dist/relative-time-element-define.js", + "./local-time": "./dist/local-time-element.js", + "./local-time/define": "./dist/local-time-element-define.js", + "./time-ago": "./dist/time-ago-element.js", + "./time-ago/define": "./dist/time-ago-element-define.js", + "./time-until": "./dist/time-until-element.js", + "./time-until/define": "./dist/time-until-element-define.js" + }, "scripts": { "clean": "rm -rf dist", "lint": "eslint . --ext .js,.ts && tsc --noEmit", diff --git a/src/index.ts b/src/index.ts index b1de0f7..d43c2c6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,50 +1,6 @@ -import LocalTimeElement from './local-time-element.js' -import RelativeTimeElement from './relative-time-element.js' -import TimeAgoElement from './time-ago-element.js' -import TimeUntilElement from './time-until-element.js' - -const root = (typeof globalThis !== 'undefined' ? globalThis : window) as typeof window -try { - customElements.define('relative-time', RelativeTimeElement) - root.RelativeTimeElement = RelativeTimeElement -} catch (e: unknown) { - if (!(e instanceof DOMException && e.name === 'NotSupportedError') && !(e instanceof ReferenceError)) throw e -} - -try { - customElements.define('local-time', LocalTimeElement) - root.LocalTimeElement = LocalTimeElement -} catch (e: unknown) { - if (!(e instanceof DOMException && e.name === 'NotSupportedError') && !(e instanceof ReferenceError)) throw e -} - -try { - customElements.define('time-ago', TimeAgoElement) - root.TimeAgoElement = TimeAgoElement -} catch (e: unknown) { - if (!(e instanceof DOMException && e.name === 'NotSupportedError') && !(e instanceof ReferenceError)) throw e -} - -try { - customElements.define('time-until', TimeUntilElement) - root.TimeUntilElement = TimeUntilElement -} catch (e: unknown) { - if (!(e instanceof DOMException && e.name === 'NotSupportedError') && !(e instanceof ReferenceError)) throw e -} - -declare global { - interface Window { - RelativeTimeElement: typeof RelativeTimeElement - LocalTimeElement: typeof LocalTimeElement - TimeAgoElement: typeof TimeAgoElement - TimeUntilElement: typeof TimeUntilElement - } - interface HTMLElementTagNameMap { - 'relative-time': RelativeTimeElement - 'local-time': LocalTimeElement - 'time-ago': TimeAgoElement - 'time-until': TimeUntilElement - } -} +import LocalTimeElement from './local-time-element-define.js' +import RelativeTimeElement from './relative-time-element-define.js' +import TimeAgoElement from './time-ago-element-define.js' +import TimeUntilElement from './time-until-element-define.js' export {LocalTimeElement, RelativeTimeElement, TimeAgoElement, TimeUntilElement} diff --git a/src/local-time-element-define.ts b/src/local-time-element-define.ts new file mode 100644 index 0000000..0ad5aaa --- /dev/null +++ b/src/local-time-element-define.ts @@ -0,0 +1,26 @@ +import LocalTimeElement from './local-time-element.js' + +const root = (typeof globalThis !== 'undefined' ? globalThis : window) as typeof window +try { + customElements.define('local-time', LocalTimeElement) + root.LocalTimeElement = LocalTimeElement +} catch (e: unknown) { + if ( + !(root.DOMException && e instanceof DOMException && e.name === 'NotSupportedError') && + !(e instanceof ReferenceError) + ) { + throw e + } +} + +declare global { + interface Window { + LocalTimeElement: typeof LocalTimeElement + } + interface HTMLElementTagNameMap { + 'local-time': LocalTimeElement + } +} + +export default LocalTimeElement +export * from './local-time-element.js' diff --git a/src/relative-time-element-define.ts b/src/relative-time-element-define.ts new file mode 100644 index 0000000..33137da --- /dev/null +++ b/src/relative-time-element-define.ts @@ -0,0 +1,26 @@ +import RelativeTimeElement from './relative-time-element.js' + +const root = (typeof globalThis !== 'undefined' ? globalThis : window) as typeof window +try { + customElements.define('relative-time', RelativeTimeElement) + root.RelativeTimeElement = RelativeTimeElement +} catch (e: unknown) { + if ( + !(root.DOMException && e instanceof DOMException && e.name === 'NotSupportedError') && + !(e instanceof ReferenceError) + ) { + throw e + } +} + +declare global { + interface Window { + RelativeTimeElement: typeof RelativeTimeElement + } + interface HTMLElementTagNameMap { + 'relative-time': RelativeTimeElement + } +} + +export default RelativeTimeElement +export * from './relative-time-element.js' diff --git a/src/time-ago-element-define.ts b/src/time-ago-element-define.ts new file mode 100644 index 0000000..b6993bc --- /dev/null +++ b/src/time-ago-element-define.ts @@ -0,0 +1,26 @@ +import TimeAgoElement from './time-ago-element.js' + +const root = (typeof globalThis !== 'undefined' ? globalThis : window) as typeof window +try { + customElements.define('time-ago', TimeAgoElement) + root.TimeAgoElement = TimeAgoElement +} catch (e: unknown) { + if ( + !(root.DOMException && e instanceof DOMException && e.name === 'NotSupportedError') && + !(e instanceof ReferenceError) + ) { + throw e + } +} + +declare global { + interface Window { + TimeAgoElement: typeof TimeAgoElement + } + interface HTMLElementTagNameMap { + 'time-ago': TimeAgoElement + } +} + +export default TimeAgoElement +export * from './time-ago-element.js' diff --git a/src/time-until-element-define.ts b/src/time-until-element-define.ts new file mode 100644 index 0000000..8222c17 --- /dev/null +++ b/src/time-until-element-define.ts @@ -0,0 +1,26 @@ +import TimeUntilElement from './time-until-element.js' + +const root = (typeof globalThis !== 'undefined' ? globalThis : window) as typeof window +try { + customElements.define('time-until', TimeUntilElement) + root.TimeUntilElement = TimeUntilElement +} catch (e: unknown) { + if ( + !(root.DOMException && e instanceof DOMException && e.name === 'NotSupportedError') && + !(e instanceof ReferenceError) + ) { + throw e + } +} + +declare global { + interface Window { + TimeUntilElement: typeof TimeUntilElement + } + interface HTMLElementTagNameMap { + 'time-until': TimeUntilElement + } +} + +export default TimeUntilElement +export * from './time-until-element.js' From c8cd45fcd66d6174d59572c84e4c3d57edfa0ce1 Mon Sep 17 00:00:00 2001 From: Keith Cirkel Date: Wed, 23 Nov 2022 15:23:54 +0000 Subject: [PATCH 3/4] remove old maintaining.md --- MAINTAINING.md | 24 ------------------------ 1 file changed, 24 deletions(-) delete mode 100644 MAINTAINING.md diff --git a/MAINTAINING.md b/MAINTAINING.md deleted file mode 100644 index 490aca7..0000000 --- a/MAINTAINING.md +++ /dev/null @@ -1,24 +0,0 @@ -# Maintaining - -## Releasing a new version - -This project follows [semver](http://semver.org/). So if you are making a bug -fix, only increment the patch level "1.0.x". If any new files are added, a -minor version "1.x.x" bump is in order. - -### Make a release commit - -To prepare the release commit, edit the -[package.json](https://github.com/github/time-elements/blob/master/package.json) -`version` value. Then make a single commit with the description as -"Time Elements 1.x.x". Finally, tag the commit with `v1.x.x`. - -``` -$ git pull -$ vim package.json -$ git add package.json -$ git ci -m "Time Elements 1.x.x" -$ git tag v1.x.x -$ git push -$ git push --tags -``` From b604b5c27ac97d895032a30f43248163603ebacc Mon Sep 17 00:00:00 2001 From: Keith Cirkel Date: Wed, 23 Nov 2022 15:25:20 +0000 Subject: [PATCH 4/4] Ensure HTMLElement exists in all contexts When requiring this module in NodeJS, it will error as `HTMLElement` does not exist. Creating a variable defaulting to `null` allows the class to be created in the server without causing errors. This is useful for introspecting the class within NodeJS. --- src/relative-time-element.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/relative-time-element.ts b/src/relative-time-element.ts index 7d91bd2..0543181 100644 --- a/src/relative-time-element.ts +++ b/src/relative-time-element.ts @@ -3,6 +3,8 @@ import {DateTimeFormat as DateTimeFormatPonyFill} from './datetimeformat-ponyfil import {RelativeTimeFormat as RelativeTimeFormatPonyfill} from './relative-time-ponyfill.js' import {isDuration, withinDuration} from './duration.js' import {strftime} from './strftime.js' +const root = (typeof globalThis !== 'undefined' ? globalThis : window) as typeof window +const HTMLElement = root.HTMLElement || (null as unknown as typeof window['HTMLElement']) const supportsIntlDatetime = typeof Intl !== 'undefined' && 'DateTimeFormat' in Intl const DateTimeFormat = supportsIntlDatetime ? Intl.DateTimeFormat : DateTimeFormatPonyFill