-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #11278 from mixonic/helpers
Implement Ember.Helper: RFC#53.
- Loading branch information
Showing
39 changed files
with
728 additions
and
194 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import Object from "ember-runtime/system/object"; | ||
|
||
// Ember.Helper.extend({ compute(params, hash) {} }); | ||
var Helper = Object.extend({ | ||
isHelper: true, | ||
recompute() { | ||
this._stream.notify(); | ||
} | ||
}); | ||
|
||
Helper.reopenClass({ | ||
isHelperFactory: true | ||
}); | ||
|
||
// Ember.Helper.helper(function(params, hash) {}); | ||
export function helper(helperFn) { | ||
return { | ||
isHelperInstance: true, | ||
compute: helperFn | ||
}; | ||
} | ||
|
||
export default Helper; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,17 @@ | ||
import { findHelper } from "ember-htmlbars/system/lookup-helper"; | ||
import { validateLazyHelperName } from "ember-htmlbars/system/lookup-helper"; | ||
|
||
export default function hasHelperHook(env, scope, helperName) { | ||
return !!findHelper(helperName, scope.self, env); | ||
if (env.helpers[helperName]) { | ||
return true; | ||
} | ||
|
||
var container = env.container; | ||
if (validateLazyHelperName(helperName, container, env.hooks.keywords)) { | ||
var containerName = 'helper:' + helperName; | ||
if (container._registry.has(containerName)) { | ||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,43 +1,24 @@ | ||
import Ember from 'ember-metal/core'; // Ember.assert | ||
import getValue from "ember-htmlbars/hooks/get-value"; | ||
import { buildHelperStream } from "ember-htmlbars/system/invoke-helper"; | ||
|
||
export default function invokeHelper(morph, env, scope, visitor, params, hash, helper, templates, context) { | ||
|
||
|
||
export default function invokeHelper(morph, env, scope, visitor, _params, _hash, helper, templates, context) { | ||
var params, hash; | ||
|
||
if (typeof helper === 'function') { | ||
params = getArrayValues(_params); | ||
hash = getHashValues(_hash); | ||
return { value: helper.call(context, params, hash, templates) }; | ||
} else if (helper.isLegacyViewHelper) { | ||
if (helper.isLegacyViewHelper) { | ||
Ember.assert("You can only pass attributes (such as name=value) not bare " + | ||
"values to a helper for a View found in '" + helper.viewClass + "'", _params.length === 0); | ||
"values to a helper for a View found in '" + helper.viewClass + "'", params.length === 0); | ||
|
||
env.hooks.keyword('view', morph, env, scope, [helper.viewClass], _hash, templates.template.raw, null, visitor); | ||
env.hooks.keyword('view', morph, env, scope, [helper.viewClass], hash, templates.template.raw, null, visitor); | ||
// Opts into a special mode for view helpers | ||
return { handled: true }; | ||
} else if (helper && helper.helperFunction) { | ||
var helperFunc = helper.helperFunction; | ||
return { value: helperFunc.call({}, _params, _hash, templates, env, scope) }; | ||
} | ||
} | ||
|
||
// We don't want to leak mutable cells into helpers, which | ||
// are pure functions that can only work with values. | ||
function getArrayValues(params) { | ||
let out = []; | ||
for (let i=0, l=params.length; i<l; i++) { | ||
out.push(getValue(params[i])); | ||
} | ||
|
||
return out; | ||
} | ||
var helperStream = buildHelperStream(helper, params, hash, templates, env, scope, context); | ||
|
||
function getHashValues(hash) { | ||
let out = {}; | ||
for (let prop in hash) { | ||
out[prop] = getValue(hash[prop]); | ||
// Ember.Helper helpers are pure values, thus linkable | ||
if (helperStream.linkable) { | ||
return { link: true, value: helperStream }; | ||
} | ||
|
||
return out; | ||
// Legacy helpers are not linkable, they must run every rerender | ||
return { value: helperStream.value() }; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import Stream from "ember-metal/streams/stream"; | ||
import create from "ember-metal/platform/create"; | ||
import merge from "ember-metal/merge"; | ||
import { | ||
getArrayValues, | ||
getHashValues | ||
} from "ember-htmlbars/streams/utils"; | ||
|
||
export default function BuiltInHelperStream(helper, params, hash, templates, env, scope, context, label) { | ||
this.init(label); | ||
this.helper = helper; | ||
this.params = params; | ||
this.templates = templates; | ||
this.env = env; | ||
this.scope = scope; | ||
this.hash = hash; | ||
this.context = context; | ||
} | ||
|
||
BuiltInHelperStream.prototype = create(Stream.prototype); | ||
|
||
merge(BuiltInHelperStream.prototype, { | ||
compute() { | ||
// Using call and undefined is probably not needed, these are only internal | ||
return this.helper.call(this.context, getArrayValues(this.params), getHashValues(this.hash), this.templates, this.env, this.scope); | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import Stream from "ember-metal/streams/stream"; | ||
import create from "ember-metal/platform/create"; | ||
import merge from "ember-metal/merge"; | ||
|
||
export default function CompatHelperStream(helper, params, hash, templates, env, scope, label) { | ||
this.init(label); | ||
this.helper = helper.helperFunction; | ||
this.params = params; | ||
this.templates = templates; | ||
this.env = env; | ||
this.scope = scope; | ||
this.hash = hash; | ||
} | ||
|
||
CompatHelperStream.prototype = create(Stream.prototype); | ||
|
||
merge(CompatHelperStream.prototype, { | ||
compute() { | ||
// Using call and undefined is probably not needed, these are only internal | ||
return this.helper.call(undefined, this.params, this.hash, this.templates, this.env, this.scope); | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import Stream from "ember-metal/streams/stream"; | ||
import create from "ember-metal/platform/create"; | ||
import merge from "ember-metal/merge"; | ||
import { | ||
getArrayValues, | ||
getHashValues | ||
} from "ember-htmlbars/streams/utils"; | ||
|
||
export default function HelperFactoryStream(helperFactory, params, hash, label) { | ||
this.init(label); | ||
this.helperFactory = helperFactory; | ||
this.params = params; | ||
this.hash = hash; | ||
this.linkable = true; | ||
this.helper = null; | ||
} | ||
|
||
HelperFactoryStream.prototype = create(Stream.prototype); | ||
|
||
merge(HelperFactoryStream.prototype, { | ||
compute() { | ||
if (!this.helper) { | ||
this.helper = this.helperFactory.create({ _stream: this }); | ||
} | ||
return this.helper.compute(getArrayValues(this.params), getHashValues(this.hash)); | ||
}, | ||
deactivate() { | ||
this.super$deactivate(); | ||
if (this.helper) { | ||
this.helper.destroy(); | ||
this.helper = null; | ||
} | ||
}, | ||
super$deactivate: HelperFactoryStream.prototype.deactivate | ||
}); |
Oops, something went wrong.