Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
"git-repo-info": "^1.1.4",
"git-repo-version": "^0.3.1",
"github": "^0.2.3",
"glimmer-engine": "0.13.0",
"glimmer-engine": "0.13.1",
"glob": "^5.0.13",
"html-differ": "^1.3.4",
"mocha": "^2.4.5",
Expand Down
30 changes: 18 additions & 12 deletions packages/ember-glimmer/lib/environment.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import { wrapComponentClassAttribute } from './utils/bindings';
import { default as action } from './helpers/action';
import { default as componentHelper } from './helpers/component';
import { default as concat } from './helpers/concat';
import { default as debuggerHelper } from './helpers/debugger';
import { default as get } from './helpers/get';
import { default as hash } from './helpers/hash';
import { default as loc } from './helpers/loc';
Expand Down Expand Up @@ -107,6 +108,7 @@ export default class Environment extends GlimmerEnvironment {
action,
component: componentHelper,
concat,
debugger: debuggerHelper,
get,
hash,
loc,
Expand All @@ -121,7 +123,7 @@ export default class Environment extends GlimmerEnvironment {
'-input-type': inputTypeHelper,
'-normalize-class': normalizeClassHelper,
'-html-safe': htmlSafeHelper,
'-get-dynamic-var': { glimmerNativeHelper: getDynamicVar }
'-get-dynamic-var': getDynamicVar
};
}

Expand Down Expand Up @@ -202,7 +204,7 @@ export default class Environment extends GlimmerEnvironment {
assert(`A helper named "${key}" could not be found`, !isBlock || this.hasHelper(path, symbolTable));
}

if ((!isSimple && appendType === 'unknown') || appendType === 'self-get') {
if (!isSimple && appendType === 'unknown') {
return statement.original.deopt();
}

Expand Down Expand Up @@ -275,36 +277,40 @@ export default class Environment extends GlimmerEnvironment {
}

let name = nameParts[0];

if (this.builtInHelpers[name]) {
return true;
}

let blockMeta = symbolTable.getMeta();
let owner = blockMeta.owner;
let options = { source: `template:${blockMeta.moduleName}` };

return !!this.builtInHelpers[name] ||
owner.hasRegistration(`helper:${name}`, options) ||
return owner.hasRegistration(`helper:${name}`, options) ||
owner.hasRegistration(`helper:${name}`);
}

lookupHelper(nameParts, symbolTable) {
assert('The first argument passed into `lookupHelper` should be an array', Array.isArray(nameParts));

let name = nameParts[0];
let helper = this.builtInHelpers[name];

if (helper) {
return helper;
}

let blockMeta = symbolTable.getMeta();
let owner = blockMeta.owner;
let options = blockMeta.moduleName && { source: `template:${blockMeta.moduleName}` } || {};

let helper = this.builtInHelpers[name] ||
owner.lookup(`helper:${name}`, options) ||
owner.lookup(`helper:${name}`);
helper = owner.lookup(`helper:${name}`, options) || owner.lookup(`helper:${name}`);

// TODO: try to unify this into a consistent protocol to avoid wasteful closure allocations
if (helper.isInternalHelper) {
return (vm, args) => helper.toReference(args, this, symbolTable);
} else if (helper.isHelperInstance) {
if (helper.isHelperInstance) {
return (vm, args) => SimpleHelperReference.create(helper.compute, args);
} else if (helper.isHelperFactory) {
return (vm, args) => ClassBasedHelperReference.create(helper, vm, args);
} else if (helper.glimmerNativeHelper) {
return helper.glimmerNativeHelper;
} else {
throw new Error(`${nameParts} is not a helper`);
}
Expand Down
9 changes: 3 additions & 6 deletions packages/ember-glimmer/lib/helpers/-class.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@ function classHelper({ positional }) {
return value;
}

export default {
isInternalHelper: true,
toReference(args) {
return new InternalHelperReference(classHelper, args);
}
};
export default function(vm, args) {
return new InternalHelperReference(classHelper, args);
}
9 changes: 3 additions & 6 deletions packages/ember-glimmer/lib/helpers/-html-safe.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ function htmlSafe({ positional }) {
return new SafeString(path.value());
}

export default {
isInternalHelper: true,
toReference(args) {
return new InternalHelperReference(htmlSafe, args);
}
};
export default function(vm, args) {
return new InternalHelperReference(htmlSafe, args);
}
9 changes: 3 additions & 6 deletions packages/ember-glimmer/lib/helpers/-input-type.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@ function inputTypeHelper({ positional, named }) {
return '-text-field';
}

export default {
isInternalHelper: true,
toReference(args) {
return new InternalHelperReference(inputTypeHelper, args);
}
};
export default function(vm, args) {
return new InternalHelperReference(inputTypeHelper, args);
}
9 changes: 3 additions & 6 deletions packages/ember-glimmer/lib/helpers/-normalize-class.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@ function normalizeClass({ positional, named }) {
}
}

export default {
isInternalHelper: true,
toReference(args) {
return new InternalHelperReference(normalizeClass, args);
}
};
export default function(vm, args) {
return new InternalHelperReference(normalizeClass, args);
}
10 changes: 3 additions & 7 deletions packages/ember-glimmer/lib/helpers/action.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,9 @@ export class ClosureActionReference extends CachedReference {
}
}

export default {
isInternalHelper: true,

toReference(args) {
return ClosureActionReference.create(args);
}
};
export default function(vm, args) {
return ClosureActionReference.create(args);
}

export function createClosureAction(target, action, valuePath, actionArgs) {
let closureAction;
Expand Down
10 changes: 3 additions & 7 deletions packages/ember-glimmer/lib/helpers/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,6 @@ function curryArgs(definition, newArgs) {
return mergedArgs;
}

export default {
isInternalHelper: true,

toReference(args, env, symbolTable) {
return ClosureComponentReference.create(args, symbolTable, env);
}
};
export default function(vm, args, symbolTable) {
return ClosureComponentReference.create(args, symbolTable, vm.env);
}
10 changes: 6 additions & 4 deletions packages/ember-glimmer/lib/helpers/concat.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { helper } from '../helper';
import { InternalHelperReference } from '../utils/references';
import { normalizeTextValue } from 'glimmer-runtime';

/**
Expand All @@ -22,8 +22,10 @@ import { normalizeTextValue } from 'glimmer-runtime';
@for Ember.Templates.helpers
@since 1.13.0
*/
function concat(args) {
return args.map(normalizeTextValue).join('');
function concat({ positional }) {
return positional.value().map(normalizeTextValue).join('');
}

export default helper(concat);
export default function(vm, args) {
return new InternalHelperReference(concat, args);
}
92 changes: 92 additions & 0 deletions packages/ember-glimmer/lib/helpers/debugger.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*jshint debug:true*/

/**
@module ember
@submodule ember-htmlbars
*/

import { info } from 'ember-metal/debug';
import { UNDEFINED_REFERENCE, GetSyntax, CompileIntoList } from 'glimmer-runtime';

/**
Execute the `debugger` statement in the current template's context.

```handlebars
{{debugger}}
```

When using the debugger helper you will have access to a `get` function. This
function retrieves values available in the context of the template.
For example, if you're wondering why a value `{{foo}}` isn't rendering as
expected within a template, you could place a `{{debugger}}` statement and,
when the `debugger;` breakpoint is hit, you can attempt to retrieve this value:

```
> get('foo')
```

`get` is also aware of block variables. So in this situation

```handlebars
{{#each items as |item|}}
{{debugger}}
{{/each}}
```

You'll be able to get values from the current item:

```
> get('item.name')
```

You can also access the context of the view to make sure it is the object that
you expect:

```
> context
```

@method debugger
@for Ember.Templates.helpers
@public
*/
function defaultCallback(context, get) {
/* jshint debug: true */

info('Use `context`, and `get(<path>)` to debug this template.');

debugger;
}

let callback = defaultCallback;

export default function debuggerHelper(vm, args, symbolTable) {
let context = vm.getSelf().value();

// Note: this is totally an overkill since we are only compiling
// expressions, but this is the only kind of SymbolLookup we can
// construct. The symbol table itself should really be sufficient
// here – we should refactor the Glimmer code to make that possible.
let symbolLookup = new CompileIntoList(vm.env, symbolTable);

function get(path) {
// Problem: technically, we are getting a `PublicVM` here, but to
// evaluate an expression it requires the full VM. We happen to know
// that they are the same thing, so this would work for now. However
// this might break in the future.
return GetSyntax.build(path).compile(symbolLookup).evaluate(vm).value();
}

callback(context, get);

return UNDEFINED_REFERENCE;
}

// These are exported for testing
export function setDebuggerCallback(newCallback) {
callback = newCallback;
}

export function resetDebuggerCallback() {
callback = defaultCallback;
}
13 changes: 5 additions & 8 deletions packages/ember-glimmer/lib/helpers/each-in.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,8 @@ export function isEachIn(ref) {
return ref && ref[EACH_IN_REFERENCE];
}

export default {
isInternalHelper: true,
toReference(args) {
let ref = Object.create(args.positional.at(0));
ref[EACH_IN_REFERENCE] = true;
return ref;
}
};
export default function(vm, args) {
let ref = Object.create(args.positional.at(0));
ref[EACH_IN_REFERENCE] = true;
return ref;
}
10 changes: 3 additions & 7 deletions packages/ember-glimmer/lib/helpers/get.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,9 @@ import { CONSTANT_TAG, UpdatableTag, combine, isConst, referenceFromParts } from
@since 2.1.0
*/

export default {
isInternalHelper: true,

toReference(args) {
return GetHelperReference.create(args.positional.at(0), args.positional.at(1));
}
};
export default function(vm, args) {
return GetHelperReference.create(args.positional.at(0), args.positional.at(1));
}

class GetHelperReference extends CachedReference {
static create(sourceReference, pathReference) {
Expand Down
9 changes: 3 additions & 6 deletions packages/ember-glimmer/lib/helpers/hash.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,6 @@
@public
*/

export default {
isInternalHelper: true,
toReference(args) {
return args.named;
}
};
export default function(vm, args) {
return args.named;
}
46 changes: 20 additions & 26 deletions packages/ember-glimmer/lib/helpers/if-unless.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,20 +58,17 @@ class ConditionalHelperReference extends CachedReference {
@for Ember.Templates.helpers
@public
*/
export const inlineIf = {
isInternalHelper: true,
toReference({ positional: pargs }) {
switch (pargs.length) {
case 2: return ConditionalHelperReference.create(pargs.at(0), pargs.at(1), null);
case 3: return ConditionalHelperReference.create(pargs.at(0), pargs.at(1), pargs.at(2));
default:
assert(
'The inline form of the `if` helper expects two or three arguments, e.g. ' +
'`{{if trialExpired "Expired" expiryDate}}`.'
);
}
export function inlineIf(vm, { positional }) {
switch (positional.length) {
case 2: return ConditionalHelperReference.create(positional.at(0), positional.at(1), null);
case 3: return ConditionalHelperReference.create(positional.at(0), positional.at(1), positional.at(2));
default:
assert(
'The inline form of the `if` helper expects two or three arguments, e.g. ' +
'`{{if trialExpired "Expired" expiryDate}}`.'
);
}
};
}

/**
The inline `unless` helper conditionally renders a single property or string.
Expand All @@ -89,17 +86,14 @@ export const inlineIf = {
@for Ember.Templates.helpers
@public
*/
export const inlineUnless = {
isInternalHelper: true,
toReference({ positional: pargs }) {
switch (pargs.length) {
case 2: return ConditionalHelperReference.create(pargs.at(0), null, pargs.at(1));
case 3: return ConditionalHelperReference.create(pargs.at(0), pargs.at(2), pargs.at(1));
default:
assert(
'The inline form of the `unless` helper expects two or three arguments, e.g. ' +
'`{{unless isFirstLogin "Welcome back!"}}`.'
);
}
export function inlineUnless(vm, { positional }) {
switch (positional.length) {
case 2: return ConditionalHelperReference.create(positional.at(0), null, positional.at(1));
case 3: return ConditionalHelperReference.create(positional.at(0), positional.at(2), positional.at(1));
default:
assert(
'The inline form of the `unless` helper expects two or three arguments, e.g. ' +
'`{{unless isFirstLogin "Welcome back!"}}`.'
);
}
};
}
Loading