Skip to content
Open
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
6 changes: 0 additions & 6 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,11 @@ const shim = addonV1Shim(path.join(__dirname, '..'), {
'./dist/dev/packages/@ember/-internals/routing/index.js',
'./dist/dev/packages/@ember/-internals/runtime/index.js',
'./dist/dev/packages/@ember/-internals/runtime/lib/ext/rsvp.js',
'./dist/dev/packages/@ember/-internals/runtime/lib/mixins/-proxy.js',
'./dist/dev/packages/@ember/-internals/runtime/lib/mixins/comparable.js',
'./dist/dev/packages/@ember/-internals/string/index.js',
'./dist/dev/packages/@ember/-internals/utility-types/index.js',
'./dist/dev/packages/@ember/-internals/utils/index.js',
'./dist/dev/packages/@ember/-internals/views/index.js',
'./dist/dev/packages/@ember/-internals/views/lib/compat/attrs.js',
'./dist/dev/packages/@ember/-internals/views/lib/mixins/action_support.js',
'./dist/dev/packages/@ember/-internals/views/lib/system/utils.js',
'./dist/dev/packages/@ember/-internals/views/lib/views/core_view.js',
'./dist/dev/packages/@ember/-internals/views/lib/views/states.js',
Expand Down Expand Up @@ -78,8 +75,6 @@ const shim = addonV1Shim(path.join(__dirname, '..'), {
'./dist/dev/packages/@ember/engine/index.js',
'./dist/dev/packages/@ember/engine/instance.js',
'./dist/dev/packages/@ember/engine/lib/engine-parent.js',
'./dist/dev/packages/@ember/enumerable/index.js',
'./dist/dev/packages/@ember/enumerable/mutable.js',
'./dist/dev/packages/@ember/helper/index.js',
'./dist/dev/packages/@ember/instrumentation/index.js',
'./dist/dev/packages/@ember/modifier/index.js',
Expand All @@ -96,7 +91,6 @@ const shim = addonV1Shim(path.join(__dirname, '..'), {
'./dist/dev/packages/@ember/object/mixin.js',
'./dist/dev/packages/@ember/object/observable.js',
'./dist/dev/packages/@ember/object/observers.js',
'./dist/dev/packages/@ember/object/promise-proxy-mixin.js',
'./dist/dev/packages/@ember/object/proxy.js',
'./dist/dev/packages/@ember/owner/index.js',
'./dist/dev/packages/@ember/renderer/index.js',
Expand Down
9 changes: 0 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -187,19 +187,13 @@
"@ember/-internals/routing/index.js": "ember-source/@ember/-internals/routing/index.js",
"@ember/-internals/runtime/index.js": "ember-source/@ember/-internals/runtime/index.js",
"@ember/-internals/runtime/lib/ext/rsvp.js": "ember-source/@ember/-internals/runtime/lib/ext/rsvp.js",
"@ember/-internals/runtime/lib/mixins/-proxy.js": "ember-source/@ember/-internals/runtime/lib/mixins/-proxy.js",
"@ember/-internals/runtime/lib/mixins/action_handler.js": "ember-source/@ember/-internals/runtime/lib/mixins/action_handler.js",
"@ember/-internals/runtime/lib/mixins/comparable.js": "ember-source/@ember/-internals/runtime/lib/mixins/comparable.js",
"@ember/-internals/runtime/lib/mixins/container_proxy.js": "ember-source/@ember/-internals/runtime/lib/mixins/container_proxy.js",
"@ember/-internals/runtime/lib/mixins/registry_proxy.js": "ember-source/@ember/-internals/runtime/lib/mixins/registry_proxy.js",
"@ember/-internals/runtime/lib/mixins/target_action_support.js": "ember-source/@ember/-internals/runtime/lib/mixins/target_action_support.js",
"@ember/-internals/string/index.js": "ember-source/@ember/-internals/string/index.js",
"@ember/-internals/utility-types/index.js": "ember-source/@ember/-internals/utility-types/index.js",
"@ember/-internals/utils/index.js": "ember-source/@ember/-internals/utils/index.js",
"@ember/-internals/views/index.js": "ember-source/@ember/-internals/views/index.js",
"@ember/-internals/views/lib/compat/attrs.js": "ember-source/@ember/-internals/views/lib/compat/attrs.js",
"@ember/-internals/views/lib/compat/fallback-view-registry.js": "ember-source/@ember/-internals/views/lib/compat/fallback-view-registry.js",
"@ember/-internals/views/lib/mixins/action_support.js": "ember-source/@ember/-internals/views/lib/mixins/action_support.js",
"@ember/-internals/views/lib/system/event_dispatcher.js": "ember-source/@ember/-internals/views/lib/system/event_dispatcher.js",
"@ember/-internals/views/lib/system/utils.js": "ember-source/@ember/-internals/views/lib/system/utils.js",
"@ember/-internals/views/lib/views/core_view.js": "ember-source/@ember/-internals/views/lib/views/core_view.js",
Expand Down Expand Up @@ -234,8 +228,6 @@
"@ember/engine/instance.js": "ember-source/@ember/engine/instance.js",
"@ember/engine/lib/engine-parent.js": "ember-source/@ember/engine/lib/engine-parent.js",
"@ember/engine/parent.js": "ember-source/@ember/engine/parent.js",
"@ember/enumerable/index.js": "ember-source/@ember/enumerable/index.js",
"@ember/enumerable/mutable.js": "ember-source/@ember/enumerable/mutable.js",
"@ember/helper/index.js": "ember-source/@ember/helper/index.js",
"@ember/instrumentation/index.js": "ember-source/@ember/instrumentation/index.js",
"@ember/modifier/index.js": "ember-source/@ember/modifier/index.js",
Expand All @@ -253,7 +245,6 @@
"@ember/object/mixin.js": "ember-source/@ember/object/mixin.js",
"@ember/object/observable.js": "ember-source/@ember/object/observable.js",
"@ember/object/observers.js": "ember-source/@ember/object/observers.js",
"@ember/object/promise-proxy-mixin.js": "ember-source/@ember/object/promise-proxy-mixin.js",
"@ember/object/proxy.js": "ember-source/@ember/object/proxy.js",
"@ember/owner/index.js": "ember-source/@ember/owner/index.js",
"@ember/reactive/collections.js": "ember-source/@ember/reactive/collections.js",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -252,8 +252,7 @@ export default class CurlyComponentManager
/*
* This hook is responsible for actually instantiating the component instance.
* It also is where we perform additional bookkeeping to support legacy
* features like exposed by view mixins like ChildViewSupport, ActionSupport,
* etc.
* features like exposed by view mixins, etc.
*/
create(
owner: Owner,
Expand Down
144 changes: 137 additions & 7 deletions packages/@ember/-internals/glimmer/lib/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import { get } from '@ember/-internals/metal/lib/property_get';
import { PROPERTY_DID_CHANGE } from '@ember/-internals/metal/lib/property_events';
import type { PropertyDidChange } from '@ember/-internals/metal/lib/property_events';
import { getOwner } from '@ember/-internals/owner';
import TargetActionSupport from '@ember/-internals/runtime/lib/mixins/target_action_support';
import type ViewStates from '@ember/-internals/views/lib/views/states';
import ActionSupport from '@ember/-internals/views/lib/mixins/action_support';
import inspect from '@ember/debug/lib/inspect';
import { context } from '@ember/-internals/environment/lib/context';
import computed from '@ember/-internals/metal/lib/computed';
import {
addChildView,
getChildViews,
Expand Down Expand Up @@ -54,6 +55,42 @@ function matches(el: Element, selector: string): boolean {
return elMatches.call(el, selector);
}

interface Sendable {
send(action: string, ...context: unknown[]): unknown;
}

type TriggerActionOptions = {
action?: string;
target?: unknown;
actionContext?: unknown;
};

function isSendable(obj: unknown): obj is Sendable {
return obj != null && typeof obj === 'object' && typeof (obj as Sendable).send === 'function';
}

function getTarget(instance: { target: unknown; _target?: unknown }) {
let target = get(instance, 'target');
if (target) {
if (typeof target === 'string') {
let value = get(instance, target);
if (value === undefined) {
value = get(context.lookup, target);
}

return value;
} else {
return target;
}
}

if (instance._target) {
return instance._target;
}

return null;
}

/**
@module @ember/component
*/
Expand Down Expand Up @@ -786,19 +823,15 @@ declare const SIGNATURE: unique symbol;

@class Component
@extends Ember.CoreView
@uses Ember.TargetActionSupport
@uses Ember.ActionSupport
@public
*/
// This type param is used in the class, so must appear here.
// eslint-disable-next-line @typescript-eslint/no-unused-vars
interface Component<S = unknown>
extends CoreView, TargetActionSupport, ActionSupport, ComponentMethods {}
extends CoreView, ComponentMethods {}

class Component<S = unknown>
extends CoreView.extend(
TargetActionSupport,
ActionSupport,
{
// These need to be overridable via extend/create but should still
// have a default. Defining them here is the best way to achieve that.
Expand All @@ -808,6 +841,96 @@ class Component<S = unknown>
didUpdateAttrs() {},
willRender() {},
willUpdate() {},

// triggerAction support
target: null,
action: null,
actionContext: null,

actionContextObject: computed('actionContext', function () {
let actionContext = get(this, 'actionContext');
if (typeof actionContext === 'string') {
let value = get(this, actionContext);
if (value === undefined) {
value = get(context.lookup, actionContext);
}
return value;
} else {
return actionContext;
}
}),

/**
Send an `action` with an `actionContext` to a `target`.

The `action`, `target`, and `actionContext` are read from the component instance
unless they are provided in the optional `opts` argument. If `actionContext` is
omitted, the component instance is used as the default context.

@method triggerAction
@param opts {Object} (optional, with the optional keys action, target and/or actionContext)
@return {Boolean} true if the action was sent successfully and did not return false
@private
*/
triggerAction(opts: TriggerActionOptions = {}) {
let { action, target, actionContext } = opts;
action = action || get(this, 'action');
target = target || getTarget(this);

if (actionContext === undefined) {
actionContext = get(this, 'actionContextObject') || this;
}

let context = Array.isArray(actionContext) ? actionContext : [actionContext];

if (target && action) {
let ret;

if (isSendable(target)) {
ret = target.send(action, ...context);
} else {
assert(
`The action '${action}' did not exist on ${target}`,
typeof (target as any)[action] === 'function'
);
ret = (target as any)[action](...context);
}

if (ret !== false) {
return true;
}
}

return false;
},

// action sending support
send(actionName: string, ...args: unknown[]) {
assert(
`Attempted to call .send() with the action '${actionName}' on the destroyed object '${this}'.`,
!this.isDestroying && !this.isDestroyed
);

let action = this.actions && this.actions[actionName];

if (action) {
let shouldBubble = action.apply(this, args) === true;
if (!shouldBubble) {
return;
}
}

let target = get(this, 'target');
if (target) {
assert(
`The \`target\` for ${this} (${target}) does not have a \`send\` method`,
typeof target.send === 'function'
);
target.send(...arguments);
} else {
assert(`${inspect(this)} had no action handler for: ${actionName}`, action);
}
},
} as ComponentMethods,
{
concatenatedProperties: ['attributeBindings', 'classNames', 'classNameBindings'],
Expand Down Expand Up @@ -841,6 +964,13 @@ class Component<S = unknown>
*/
declare classNames: string[];

declare target: unknown;
declare action: string | null;
declare actionContext: unknown;
declare actionContextObject: unknown;
declare triggerAction: (opts?: TriggerActionOptions) => boolean;
declare send: (actionName: string, ...args: unknown[]) => void;

/**
A list of properties of the view to apply as class names. If the property
is a string value, the value of that string will be applied as a class
Expand Down
2 changes: 1 addition & 1 deletion packages/@ember/-internals/glimmer/lib/helpers/each-in.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
@module ember
*/
import { tagForObject } from '@ember/-internals/metal/lib/tags';
import { contentFor as _contentFor } from '@ember/-internals/runtime/lib/mixins/-proxy';
import { contentFor as _contentFor } from '@ember/-internals/runtime/lib/proxy-utils';
import { isProxy } from '@ember/-internals/utils/lib/is_proxy';
import { assert } from '@ember/debug';
import type { CapturedArguments } from '@glimmer/interfaces';
Expand Down
Loading