Skip to content

Commit

Permalink
Merge pull request #620 from adopted-ember-addons/ember-modifier-v4-c…
Browse files Browse the repository at this point in the history
…ompat

Fix ember-modifier v3.2 compatibility
  • Loading branch information
lukemelia authored Apr 10, 2022
2 parents c965275 + 66acbb7 commit a7a4eee
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 76 deletions.
144 changes: 72 additions & 72 deletions addon/src/modifiers/on-key.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,54 +11,86 @@ const ONLY_WHEN_FOCUSED_TAG_NAMES = ['input', 'select', 'textarea'];
let modifier;

if (macroCondition(dependencySatisfies('ember-modifier', '>=3.2.0 || 4.x'))) {
/**
* This is an element modifier to trigger some behavior when
* specified key combo is pressed. When used with a form element
* (input, textarea, or select), the action fires only when element
* has focus. When used with another element type, it will trigger the
* passed action, OR if no action is passed, it will trigger a `click`
* on the element. This allows for easy declaration of keyboard shortcuts
* for anything clickable: In the following example, we trigger a
* click on the button when the B key is pressed:
*
* <button
* type="button"
* {{on-key 'b'}}>
* Click me, or press "B"
* </button>
*/
modifier = class OnKeyModifier extends Modifier {
@service keyboard;

element;
keyboardPriority = 0;
activatedParamValue = true;
eventName = 'keydown';
onlyWhenFocused = true;
listenerName;

didReceiveArguments() {
let [keyCombo, callback] = this.args.positional;
let { activated, event, priority } = this.args.named;
constructor(owner, args) {
super(owner, args);
this.keyboard.register(this);

registerDestructor(this, () => {
this.removeEventListeners();
this.keyboard.unregister(this);
});
}

modify(element, positional, named) {
this.element = element;

this.removeEventListeners();

this.setupProperties(positional, named);

if (this.onlyWhenFocused) {
this.addEventListeners();
}
}

setupProperties(positional, named) {
let [keyCombo, callback] = positional;
let { activated, event, priority, onlyWhenFocused } = named;

this.keyCombo = keyCombo;
this.callback = callback;
this.eventName = event || 'keydown';
this.activatedParamValue = Object.keys(this.args.named).includes(
'activated'
)
? !!activated
: undefined;
this.activatedParamValue = 'activated' in named ? !!activated : undefined;
this.keyboardPriority = priority ? parseInt(priority, 10) : 0;
this.listenerName = listenerName(this.eventName, this.keyCombo);
if (this.args.named.onlyWhenFocused !== undefined) {
this.onlyWhenFocused = this.args.named.onlyWhenFocused;
if (onlyWhenFocused !== undefined) {
this.onlyWhenFocused = onlyWhenFocused;
} else {
this.onlyWhenFocused = ONLY_WHEN_FOCUSED_TAG_NAMES.includes(
this.element.tagName.toLowerCase()
);
}
}

didInstall() {
this.keyboard.register(this);
if (this.onlyWhenFocused) {
this.element.addEventListener('click', this.onFocus, true);
this.element.addEventListener('focus', this.onFocus, true);
this.element.addEventListener('focusout', this.onFocusOut, true);
}
addEventListeners() {
this.element.addEventListener('click', this.onFocus, true);
this.element.addEventListener('focus', this.onFocus, true);
this.element.addEventListener('focusout', this.onFocusOut, true);
}

willRemove() {
removeEventListeners = () => {
if (this.onlyWhenFocused) {
this.element.removeEventListener('click', this.onFocus, true);
this.element.removeEventListener('focus', this.onFocus, true);
this.element.removeEventListener('focusout', this.onFocusOut, true);
}
this.keyboard.unregister(this);
}
};

@action onFocus() {
this.isFocused = true;
Expand Down Expand Up @@ -100,86 +132,54 @@ if (macroCondition(dependencySatisfies('ember-modifier', '>=3.2.0 || 4.x'))) {
}
};
} else {
/**
* This is an element modifier to trigger some behavior when
* specified key combo is pressed. When used with a form element
* (input, textarea, or select), the action fires only when element
* has focus. When used with another element type, it will trigger the
* passed action, OR if no action is passed, it will trigger a `click`
* on the element. This allows for easy declaration of keyboard shortcuts
* for anything clickable: In the following example, we trigger a
* click on the button when the B key is pressed:
*
* <button
* type="button"
* {{on-key 'b'}}>
* Click me, or press "B"
* </button>
*/
modifier = class OnKeyModifier extends Modifier {
@service keyboard;

element;
keyboardPriority = 0;
activatedParamValue = true;
eventName = 'keydown';
onlyWhenFocused = true;
listenerName;

constructor(owner, args) {
super(owner, args);
this.keyboard.register(this);

registerDestructor(this, () => {
this.removeEventListeners();
this.keyboard.unregister(this);
});
}

modify(element, positional, named) {
this.element = element;

this.removeEventListeners();

this.setupProperties(positional, named);

if (this.onlyWhenFocused) {
this.addEventListeners();
}
}

setupProperties(positional, named) {
let [keyCombo, callback] = positional;
let { activated, event, priority, onlyWhenFocused } = named;

didReceiveArguments() {
let [keyCombo, callback] = this.args.positional;
let { activated, event, priority } = this.args.named;
this.keyCombo = keyCombo;
this.callback = callback;
this.eventName = event || 'keydown';
this.activatedParamValue = 'activated' in named ? !!activated : undefined;
this.activatedParamValue = Object.keys(this.args.named).includes(
'activated'
)
? !!activated
: undefined;
this.keyboardPriority = priority ? parseInt(priority, 10) : 0;
this.listenerName = listenerName(this.eventName, this.keyCombo);
if (onlyWhenFocused !== undefined) {
this.onlyWhenFocused = onlyWhenFocused;
if (this.args.named.onlyWhenFocused !== undefined) {
this.onlyWhenFocused = this.args.named.onlyWhenFocused;
} else {
this.onlyWhenFocused = ONLY_WHEN_FOCUSED_TAG_NAMES.includes(
this.element.tagName.toLowerCase()
);
}
}

addEventListeners() {
this.element.addEventListener('click', this.onFocus, true);
this.element.addEventListener('focus', this.onFocus, true);
this.element.addEventListener('focusout', this.onFocusOut, true);
didInstall() {
this.keyboard.register(this);
if (this.onlyWhenFocused) {
this.element.addEventListener('click', this.onFocus, true);
this.element.addEventListener('focus', this.onFocus, true);
this.element.addEventListener('focusout', this.onFocusOut, true);
}
}

removeEventListeners = () => {
willRemove() {
if (this.onlyWhenFocused) {
this.element.removeEventListener('click', this.onFocus, true);
this.element.removeEventListener('focus', this.onFocus, true);
this.element.removeEventListener('focusout', this.onFocusOut, true);
}
};
this.keyboard.unregister(this);
}

@action onFocus() {
this.isFocused = true;
Expand Down
6 changes: 6 additions & 0 deletions test-app/config/ember-try.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ const { embroiderSafe, embroiderOptimized } = require('@embroider/test-setup');

module.exports = async function () {
return {
/**
* `ember-classic` scenario should not use `useWorkspaces`
* as only test-app need to get classic flags.
* Otherwise, this scenario would fail.
*/
useWorkspaces: process.argv.every((a) => !a.includes('ember-classic')),
useYarn: true,
scenarios: [
{
Expand Down
7 changes: 6 additions & 1 deletion test-app/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"name": "test-app",
"version": "8.1.0",
"private": true,
"description": "Test app for ember-keyboard addon",
"keywords": [],
"repository": {
Expand Down Expand Up @@ -86,5 +87,9 @@
},
"volta": {
"extends": "../package.json"
}
},
"workspaces": [
"../addon",
"../docs"
]
}
6 changes: 3 additions & 3 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5370,9 +5370,9 @@ ember-modifier-manager-polyfill@^1.2.0:
ember-compatibility-helpers "^1.2.0"

"ember-modifier@^2.1.2 || ^3.1.0":
version "3.2.5"
resolved "https://registry.yarnpkg.com/ember-modifier/-/ember-modifier-3.2.5.tgz#b82052afe941f3b27c0840019992d59466dfbd77"
integrity sha512-66YA4pQijoDIAfoI0pYAhjYWu/VrTaD3BfxpA311hLIoBlaI2QQY/LR+32aah1EvKY/yInnCJA5wcl7C+f3mkg==
version "3.2.7"
resolved "https://registry.yarnpkg.com/ember-modifier/-/ember-modifier-3.2.7.tgz#f2d35b7c867cbfc549e1acd8d8903c5ecd02ea4b"
integrity sha512-ezcPQhH8jUfcJQbbHji4/ZG/h0yyj1jRDknfYue/ypQS8fM8LrGcCMo0rjDZLzL1Vd11InjNs3BD7BdxFlzGoA==
dependencies:
ember-cli-babel "^7.26.6"
ember-cli-normalize-entity-name "^1.0.0"
Expand Down

0 comments on commit a7a4eee

Please sign in to comment.