Skip to content
This repository has been archived by the owner on Oct 12, 2020. It is now read-only.

Commit

Permalink
Merge pull request #195 from lifeart/cb-based-api
Browse files Browse the repository at this point in the history
cb-based api
  • Loading branch information
lifeart authored Jan 30, 2020
2 parents 29add8e + ba536d7 commit 920ca37
Show file tree
Hide file tree
Showing 13 changed files with 459 additions and 409 deletions.
18 changes: 12 additions & 6 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
module.exports = {
root: true,
parser: 'babel-eslint',
parserOptions: {
ecmaVersion: 2017,
sourceType: 'module'
ecmaVersion: 2018,
sourceType: 'module',
ecmaFeatures: {
legacyDecorators: true
}
},
plugins: ['prettier', 'ember'],
extends: [
Expand All @@ -13,7 +17,9 @@ module.exports = {
env: {
browser: true
},
rules: {},
rules: {
'ember/no-jquery': 'error'
},
overrides: [
// node files
{
Expand All @@ -25,7 +31,8 @@ module.exports = {
'testem.js',
'blueprints/*/index.js',
'config/**/*.js',
'tests/dummy/config/**/*.js'
'tests/dummy/config/**/*.js',
'server/**/*.js'
],
excludedFiles: [
'addon/**',
Expand All @@ -34,8 +41,7 @@ module.exports = {
'tests/dummy/app/**'
],
parserOptions: {
sourceType: 'script',
ecmaVersion: 2015
sourceType: 'script'
},
env: {
browser: false,
Expand Down
2 changes: 1 addition & 1 deletion .template-lintrc.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
'use strict';

module.exports = {
extends: 'recommended'
extends: 'octane'
};
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,33 @@ ember install ember-ref-modifier
{{this.button.dataset.name}} >> "foo"
```

--------------------------

```hbs
<button {{ref this.callback}} data-name="foo">
Click me baby, one more time!
</button>
```

```js
class Component {
@action callback(node) {
this.node = node;
}
}

```

------------------------

```hbs
<div {{ref this "divContainer" }}></div>
{{#-in-element this.divContainer}}
Hello!
{{/-in-element}}
```
------------------------


```hbs
// hash helper must return an EmberObject! The default hash helper returns a pojo.
Expand All @@ -42,6 +63,7 @@ ember install ember-ref-modifier
```


------------------------

------

Expand Down
51 changes: 42 additions & 9 deletions addon/modifiers/ref.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { set, get } from '@ember/object';
import { deprecate } from '@ember/application/deprecations';
import { setModifierManager, capabilities } from '@ember/modifier';

import { next } from '@ember/runloop';
function hasValidTarget(target) {
return (
typeof target === 'object' && target !== null && !Array.isArray(target)
Expand All @@ -11,6 +11,11 @@ function hasValidProperty(prop) {
return typeof prop === 'string';
}
function getParams([maybeTarget, maybePropName]) {
if (typeof maybeTarget === 'function') {
return {
cb: maybeTarget
};
}
const isPropNameString = typeof maybePropName === 'string';
if (!isPropNameString) {
deprecate(
Expand All @@ -35,37 +40,65 @@ export default setModifierManager(
return {
element: undefined,
propName: undefined,
cb: undefined,
target: undefined
};
},

installModifier(state, element, { positional }) {
const { propName, target } = getParams(positional);
const { propName, target, cb } = getParams(positional);
if (cb) {
state.cb = cb;
this._runInContext(cb, element);
return;
}
if (hasValidProperty(propName) && hasValidTarget(target)) {
set(target, propName, element);
this._setInContext(target, propName, element);
state.propName = propName;
state.target = target;
}
state.element = element;
},

updateModifier(state, { positional }) {
const { propName, target } = getParams(positional);
const { propName, target, cb } = getParams(positional);
if (cb) {
state.cb = cb;
this._runInContext(cb, state.element);
return;
}
if (hasValidProperty(propName) && hasValidTarget(target)) {
if (hasValidProperty(state.propName) && hasValidTarget(state.target)) {
if (get(target, propName) !== get(state.target, state.propName)) {
set(state.target, state.propName, null);
this._setInContext(state.target, state.propName, null);
}
}
set(target, propName, state.element);
this._setInContext(target, propName, state.element);
state.propName = propName;
state.target = target;
}
},

destroyModifier({ target, propName }) {
_setInContext(target, propName, value) {
next(this, '_setValues', target, propName, value);
},
_runInContext(cb, value) {
next(this, '_runCb', cb, value);
},
_runCb(cb, value) {
cb(value);
},
_setValues(target, propName, value) {
if (target.isDestroyed || target.isDestroying) {
return;
}
set(target, propName, value);
},
destroyModifier({ target, propName, cb }) {
if (cb) {
return;
}
if (hasValidProperty(propName) && hasValidTarget(target)) {
set(target, propName, null);
this._setInContext(target, propName, null);
}
}
}),
Expand Down
7 changes: 7 additions & 0 deletions config/optional-features.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"application-template-wrapper": false,
"default-async-observers": true,
"jquery-integration": true
"jquery-integration": false,
"template-only-glimmer-components": true
}
1 change: 1 addition & 0 deletions jsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"compilerOptions":{"target":"es6","experimentalDecorators":true},"exclude":["node_modules","bower_components","tmp","vendor",".git","dist"]}
14 changes: 9 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ember-ref-modifier",
"version": "0.1.3",
"version": "0.2.3",
"description": "{{ref propName context}} element modifier",
"keywords": [
"ember-addon",
Expand Down Expand Up @@ -28,12 +28,13 @@
"ember-modifier-manager-polyfill": "^1.0.1"
},
"devDependencies": {
"@ember/optional-features": "^1.0.0",
"broccoli-asset-rev": "^3.0.0",
"@ember/optional-features": "^1.3.0",
"broccoli-asset-rev": "^3.0.0",
"@glimmer/component": "^1.0.0",
"babel-eslint": "^10.0.3",
"ember-cli": "~3.15.0",
"ember-cli-dependency-checker": "^3.0.0",
"ember-cli-htmlbars": "^4.0.8",
"ember-cli-htmlbars-inline-precompile": "^3.0.0",
"ember-cli-inject-live-reload": "^2.0.1",
"ember-cli-sri": "^2.1.1",
"ember-cli-uglify": "^2.1.0",
Expand All @@ -49,13 +50,16 @@
"ember-try": "^1.0.0",
"eslint": "^6.2.1",
"eslint-config-prettier": "^6.1.0",
"eslint-plugin-ember": "^7.0.0",
"eslint-plugin-ember": "^7.7.1",
"eslint-plugin-node": "^11.0.0",
"eslint-plugin-prettier": "^3.0.1",
"loader.js": "^4.7.0",
"prettier": "^1.16.1",
"qunit-dom": "^0.9.0"
},
"ember": {
"edition": "octane"
},
"engines": {
"node": "6.* || 8.* || >= 10.*"
},
Expand Down
3 changes: 3 additions & 0 deletions tests/dummy/app/components/glimmer-ref.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<div {{ref this 'node'}}>
Hello, {{this.size}}
</div>
10 changes: 10 additions & 0 deletions tests/dummy/app/components/glimmer-ref.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';

export default class GlimmerRefComponent extends Component {
@tracked
node = null;
get size() {
return this.node && this.node.clientWidth;
}
}
3 changes: 2 additions & 1 deletion tests/dummy/app/templates/application.hbs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<h2 id="title">Welcome to Ember</h2>

{{outlet}}
{{ref-sample}}
<RefSample />
<GlimmerRef />
4 changes: 3 additions & 1 deletion tests/dummy/config/optional-features.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
{
"jquery-integration": false
"application-template-wrapper": false,
"jquery-integration": false,
"template-only-glimmer-components": true
}
44 changes: 27 additions & 17 deletions tests/integration/modifiers/ref-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ module('Integration | Modifier | ref', function(hooks) {
assert.expect(1);

await render(
hbs`<button data-foo="some-thing" {{ref 'btn' this}}></button>`
hbs`<button data-foo="some-thing" {{ref "btn" this}}></button>`
);
assert.equal(this.btn.dataset.foo, 'some-thing');
});
Expand All @@ -19,7 +19,7 @@ module('Integration | Modifier | ref', function(hooks) {
assert.expect(1);

await render(
hbs`<button data-foo="some-thing" {{ref this 'btn'}}></button>`
hbs`<button data-foo="some-thing" {{ref this "btn"}}></button>`
);
assert.equal(this.btn.dataset.foo, 'some-thing');
});
Expand All @@ -28,13 +28,13 @@ module('Integration | Modifier | ref', function(hooks) {
assert.expect(3);

await render(
hbs`<button data-foo="some-thing" {{ref 'btn' this}}></button>`
hbs`<button data-foo="some-thing" {{ref "btn" this}}></button>`
);

assert.equal(this.btn.dataset.foo, 'some-thing');

await render(
hbs`<button data-foo="some-thing" {{ref 'btns' this}}></button>`
hbs`<button data-foo="some-thing" {{ref "btns" this}}></button>`
);

assert.equal(this.btn, null);
Expand All @@ -45,13 +45,13 @@ module('Integration | Modifier | ref', function(hooks) {
assert.expect(3);

await render(
hbs`<button data-foo="some-thing" {{ref this 'btn'}}></button>`
hbs`<button data-foo="some-thing" {{ref this "btn"}}></button>`
);

assert.equal(this.btn.dataset.foo, 'some-thing');

await render(
hbs`<button data-foo="some-thing" {{ref this 'btns'}}></button>`
hbs`<button data-foo="some-thing" {{ref this "btns"}}></button>`
);

assert.equal(this.btn, null);
Expand All @@ -61,9 +61,9 @@ module('Integration | Modifier | ref', function(hooks) {
test('it does nothing if ref key or target `null` or `undefined`: legacy', async function(assert) {
assert.expect(0);
await render(hbs`
<button data-foo="some-thing" {{ref 'click' null}}></button>
<button data-foo="some-thing" {{ref 'click' undefined}}></button>
<button data-foo="some-thing" {{ref null 'click'}}></button>
<button data-foo="some-thing" {{ref "click" null}}></button>
<button data-foo="some-thing" {{ref "click" undefined}}></button>
<button data-foo="some-thing" {{ref null "click"}}></button>
<button data-foo="some-thing" {{ref undefined click}}></button>
<button data-foo="some-thing" {{ref null null}}></button>
<button data-foo="some-thing" {{ref undefined undefined}}></button>
Expand All @@ -73,9 +73,9 @@ module('Integration | Modifier | ref', function(hooks) {
test('it does nothing if ref key or target `null` or `undefined`', async function(assert) {
assert.expect(0);
await render(hbs`
<button data-foo="some-thing" {{ref null 'click'}}></button>
<button data-foo="some-thing" {{ref undefined 'click'}}></button>
<button data-foo="some-thing" {{ref 'click' null}}></button>
<button data-foo="some-thing" {{ref null "click"}}></button>
<button data-foo="some-thing" {{ref undefined "click"}}></button>
<button data-foo="some-thing" {{ref "click" null}}></button>
<button data-foo="some-thing" {{ref click undefined}}></button>
<button data-foo="some-thing" {{ref null null}}></button>
<button data-foo="some-thing" {{ref undefined undefined}}></button>
Expand All @@ -86,23 +86,33 @@ module('Integration | Modifier | ref', function(hooks) {
assert.expect(2);

this.set('ctx', null);
await render(hbs`<button {{ref 'btn' this.ctx}}></button>`);
await render(hbs`<button {{ref "btn" this.ctx}}></button>`);

assert.equal(this.btn, undefined);
this.set('ctx', this);

await new Promise(resolve => setTimeout(resolve));
assert.equal(this.btn.tagName, 'BUTTON');
});

test('it does not crash when updating to or from `null` / `undefined`', async function(assert) {
assert.expect(2);

this.set('ctx', null);
await render(hbs`<button {{ref this.ctx 'btn'}}></button>`);

await render(hbs`<button {{ref this.ctx "btn"}}></button>`);
assert.equal(this.btn, undefined);
this.set('ctx', this);

await new Promise(resolve => setTimeout(resolve));
assert.equal(this.btn.tagName, 'BUTTON');
});

test('it support callbacks', async function(assert) {
assert.expect(1);

let node = null;
this.set('ctx', function(value) {
node = value;
});
await render(hbs`<button {{ref this.ctx}}></button>`);
assert.equal(node.tagName, 'BUTTON');
});
});
Loading

0 comments on commit 920ca37

Please sign in to comment.