Skip to content

Commit

Permalink
feat: add from-event element modifier`
Browse files Browse the repository at this point in the history
  • Loading branch information
alexlafroscia committed Feb 13, 2019
1 parent 9ca7df4 commit c3fa885
Show file tree
Hide file tree
Showing 5 changed files with 266 additions and 0 deletions.
71 changes: 71 additions & 0 deletions addon/modifiers/from-event.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import Ember from "ember";
import { fromEvent } from "rxjs";

export default Ember._setModifierManager(
() => ({
createModifier() {
return {
subscription: undefined,
element: undefined
};
},

_setupSubscription(state, eventName, operatorOrObserver, maybeObserver) {
const { element } = state;
let operator, observer;

if (operatorOrObserver && maybeObserver) {
operator = operatorOrObserver;
observer = maybeObserver;
} else if (operatorOrObserver && !maybeObserver) {
observer = operatorOrObserver;
}

let observable = fromEvent(element, eventName);

if (operator) {
observable = observable.pipe(operator);
}

state.subscription = observable.subscribe(observer);
},

installModifier(
state,
element,
{
positional: [eventName, operatorOrObserver, maybeObserver]
}
) {
state.element = element;

this._setupSubscription(
state,
eventName,
operatorOrObserver,
maybeObserver
);
},

updateModifier(
state,
{
positional: [eventName, operatorOrSubscribe, maybeObserver]
}
) {
state.subscription.unsubscribe();

this._setupSubscription(
state,
eventName,
operatorOrSubscribe,
maybeObserver
);
},

destroyModifier({ subscription }) {
subscription.unsubscribe();
}
}),
class FromEventModifier {}
);
1 change: 1 addition & 0 deletions app/modifiers/from-event.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from "ember-rx/modifiers/from-event";
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
"ember-export-application-global": "^2.0.0",
"ember-load-initializers": "^1.1.0",
"ember-maybe-import-regenerator": "^0.1.6",
"ember-modifier-manager-polyfill": "^1.0.2",
"ember-qunit": "^3.4.1",
"ember-resolver": "^5.0.1",
"ember-source": "~3.7.0",
Expand Down
134 changes: 134 additions & 0 deletions tests/integration/modifiers/from-event-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import { module, test } from "qunit";
import { setupRenderingTest } from "ember-qunit";
import { setupScheduler } from "ember-rx/test-support";
import { render, click } from "@ember/test-helpers";
import { Subject } from "rxjs";
import { filter, scan } from "rxjs/operators";
import hbs from "htmlbars-inline-precompile";
import td from "testdouble";

module("Integration | Modifier | from-event", function(hooks) {
setupRenderingTest(hooks);
setupScheduler(hooks);

test("it can subscribe to events", async function(assert) {
this.observer = td.function();

await render(hbs`
<button {{from-event 'click' this.observer}}>
My Button
</button>
`);

await click("button");

assert.verify(
this.observer(td.matchers.isA(MouseEvent)),
"The observer was called with the event"
);
});

test("it can pipe the observable through an operator", async function(assert) {
this.operator = filter((_event, index) => index % 2 === 0);
this.observer = td.function();

await render(hbs`
<button {{from-event 'click' this.operator this.observer}}>
My Button
</button>
`);

await click("button");
await click("button");

assert.verify(
this.observer(td.matchers.isA(MouseEvent)),
{ times: 1 },
"The observer was called one time"
);
});

test("it handles the arguments changing", async function(assert) {
const originalObserver = td.function("original observer");
const newObserver = td.function("new observer");

this.observer = originalObserver;

await render(hbs`
<button {{from-event 'click' this.observer}}>
My Button
</button>
`);

this.set("observer", newObserver);

await click("button");

assert.verify(
originalObserver(td.matchers.isA(MouseEvent)),
{ times: 0 },
"The original observer is never called"
);

assert.verify(
newObserver(td.matchers.isA(MouseEvent)),
{ times: 1 },
"The new observer is called"
);
});

test("it can receive a `Subject` to surface the observable", async function(assert) {
this.subject = new Subject();
const observer = td.function("Original observer");

this.subject.subscribe(observer);

await render(hbs`
<button {{from-event 'click' this.subject}}>
My Button
</button>
`);

await click("button");

assert.verify(
observer(td.matchers.isA(MouseEvent)),
"The observer is called through the Subject"
);
});

module("cookbook", function() {
test("adding to a list with each click", async function(assert) {
this.subject = new Subject();
this.accumulate = scan((acc, event) => [...acc, event], []);

await render(hbs`
<button {{from-event 'click' this.accumulate this.subject}}>
My Button
</button>
<ul>
{{#each (subscribe this.subject) as |item index|}}
<li data-test-index={{index}}>{{index}}</li>
{{/each}}
</ul>
`);

assert
.dom("[data-test-index]")
.exists({ count: 0 }, "Renders no elements");

await click("button");

assert
.dom("[data-test-index]")
.exists({ count: 1 }, "Renders one element");

await click("button");

assert
.dom("[data-test-index]")
.exists({ count: 2 }, "Renders two elements");
});
});
});
59 changes: 59 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2412,6 +2412,23 @@ broccoli-babel-transpiler@^7.1.2:
rsvp "^4.8.3"
workerpool "^2.3.1"

broccoli-babel-transpiler@^7.1.2:
version "7.1.2"
resolved "https://registry.yarnpkg.com/broccoli-babel-transpiler/-/broccoli-babel-transpiler-7.1.2.tgz#fb5d6f8b9a805627ac3f2914ac9d86e82ca2413b"
integrity sha512-rljx86xgZJ2BjWt+xCSVfvyt3ONpCdMMXzMpeeVpAGdBHj3bqQICdPHZDAbzn1vKY/LIPsJZftvdxql1jiLGzw==
dependencies:
"@babel/core" "^7.0.0"
"@babel/polyfill" "^7.0.0"
broccoli-funnel "^2.0.1"
broccoli-merge-trees "^3.0.0"
broccoli-persistent-filter "^1.4.3"
clone "^2.1.2"
hash-for-dep "^1.2.3"
heimdalljs-logger "^0.1.9"
json-stable-stringify "^1.0.1"
rsvp "^4.8.3"
workerpool "^2.3.1"

broccoli-bridge@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/broccoli-bridge/-/broccoli-bridge-1.0.0.tgz#6223fd64b62062c31333539f0f3c42d0acd92fb1"
Expand Down Expand Up @@ -4752,6 +4769,30 @@ ember-cli-babel@^7.4.2:
ensure-posix-path "^1.0.2"
semver "^5.5.0"

ember-cli-babel@^7.4.2:
version "7.4.2"
resolved "https://registry.yarnpkg.com/ember-cli-babel/-/ember-cli-babel-7.4.2.tgz#9d7daa165b509e41f6dc3bb443ae32072f766aa2"
integrity sha512-5PJOkQ3B3Cvef2nQVPuZSPA6ckwiED3qF4cqzu7jcKhZ0Fy2TwPqABVbiPBJ46NujAsMZrjverVRST74Q25GqQ==
dependencies:
"@babel/core" "^7.0.0"
"@babel/plugin-transform-modules-amd" "^7.0.0"
"@babel/plugin-transform-runtime" "^7.2.0"
"@babel/polyfill" "^7.0.0"
"@babel/preset-env" "^7.0.0"
"@babel/runtime" "^7.2.0"
amd-name-resolver "^1.2.1"
babel-plugin-debug-macros "^0.2.0-beta.6"
babel-plugin-ember-modules-api-polyfill "^2.6.0"
babel-plugin-module-resolver "^3.1.1"
broccoli-babel-transpiler "^7.1.2"
broccoli-debug "^0.6.4"
broccoli-funnel "^2.0.1"
broccoli-source "^1.1.0"
clone "^2.1.2"
ember-cli-version-checker "^2.1.2"
ensure-posix-path "^1.0.2"
semver "^5.5.0"

ember-cli-broccoli-sane-watcher@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/ember-cli-broccoli-sane-watcher/-/ember-cli-broccoli-sane-watcher-3.0.0.tgz#dc1812c047e1ceec4413d3c41b51a9ffc61b4cfe"
Expand Down Expand Up @@ -5177,6 +5218,15 @@ ember-compatibility-helpers@^1.1.1, ember-compatibility-helpers@^1.1.2:
ember-cli-version-checker "^2.1.1"
semver "^5.4.1"

ember-compatibility-helpers@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/ember-compatibility-helpers/-/ember-compatibility-helpers-1.2.0.tgz#feee16c5e9ef1b1f1e53903b241740ad4b01097e"
integrity sha512-pUW4MzJdcaQtwGsErYmitFRs0rlCYBAnunVzlFFUBr4xhjlCjgHJo0b53gFnhTgenNM3d3/NqLarzRhDTjXRTg==
dependencies:
babel-plugin-debug-macros "^0.2.0"
ember-cli-version-checker "^2.1.1"
semver "^5.4.1"

ember-component-css@^0.6.7:
version "0.6.7"
resolved "https://registry.yarnpkg.com/ember-component-css/-/ember-component-css-0.6.7.tgz#dbc6debe5c04a2c0fe8a5edc64303c7324b33945"
Expand Down Expand Up @@ -5374,6 +5424,15 @@ [email protected]:
ember-ignore-children-helper "^1.0.0"
ember-wormhole "^0.5.1"

ember-modifier-manager-polyfill@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/ember-modifier-manager-polyfill/-/ember-modifier-manager-polyfill-1.0.2.tgz#c0b2da9816aad56fb1398023185c249cf76fe4bc"
integrity sha512-zu0gcSbQ7aOAtGFPQbMPQ1XKU2/NUBN6+Px65L9r4HxEzKXNUd76o1HE5p4QhLS1V6rNCD7UNmsi5r57ar0Rag==
dependencies:
ember-cli-babel "^7.4.2"
ember-cli-version-checker "^2.1.2"
ember-compatibility-helpers "^1.2.0"

ember-qunit@^3.4.1:
version "3.5.3"
resolved "https://registry.yarnpkg.com/ember-qunit/-/ember-qunit-3.5.3.tgz#bfd0bff8298c78c77e870cca43fe0826e78a0d09"
Expand Down

0 comments on commit c3fa885

Please sign in to comment.