Skip to content

Commit 50ea627

Browse files
committed
ha
1 parent 8c951ef commit 50ea627

File tree

1 file changed

+0
-311
lines changed

1 file changed

+0
-311
lines changed

packages/@ember/object/index.ts

Lines changed: 0 additions & 311 deletions
Original file line numberDiff line numberDiff line change
@@ -1,311 +0,0 @@
1-
import { assert } from '@ember/debug';
2-
import { ENV } from '@ember/-internals/environment';
3-
import type { ElementDescriptor, ExtendedMethodDecorator } from '@ember/-internals/metal';
4-
import {
5-
isElementDescriptor,
6-
expandProperties,
7-
setClassicDecorator,
8-
} from '@ember/-internals/metal';
9-
import { getFactoryFor } from '@ember/-internals/container';
10-
import { setObservers } from '@ember/-internals/utils';
11-
import type { AnyFn } from '@ember/-internals/utility-types';
12-
import CoreObject from '@ember/object/core';
13-
import Observable from '@ember/object/observable';
14-
15-
export {
16-
notifyPropertyChange,
17-
defineProperty,
18-
get,
19-
set,
20-
getProperties,
21-
setProperties,
22-
computed,
23-
trySet,
24-
} from '@ember/-internals/metal';
25-
26-
/**
27-
@module @ember/object
28-
*/
29-
30-
/**
31-
`EmberObject` is the main base class for all Ember objects. It is a subclass
32-
of `CoreObject` with the `Observable` mixin applied. For details,
33-
see the documentation for each of these.
34-
35-
@class EmberObject
36-
@extends CoreObject
37-
@uses Observable
38-
@public
39-
*/
40-
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
41-
interface EmberObject extends Observable {}
42-
class EmberObject extends CoreObject.extend(Observable) {
43-
get _debugContainerKey() {
44-
let factory = getFactoryFor(this);
45-
return factory !== undefined && factory.fullName;
46-
}
47-
}
48-
49-
export default EmberObject;
50-
51-
/**
52-
Decorator that turns the target function into an Action which can be accessed
53-
directly by reference.
54-
55-
```js
56-
import Component from '@ember/component';
57-
import { tracked } from '@glimmer/tracking';
58-
import { action } from '@ember/object';
59-
60-
export default class Tooltip extends Component {
61-
@tracked isShowing = false;
62-
63-
@action
64-
toggleShowing() {
65-
this.isShowing = !this.isShowing;
66-
}
67-
}
68-
```
69-
```hbs
70-
<!-- template.hbs -->
71-
<button {{on "click" this.toggleShowing}}>Show tooltip</button>
72-
73-
{{#if isShowing}}
74-
<div class="tooltip">
75-
I'm a tooltip!
76-
</div>
77-
{{/if}}
78-
```
79-
80-
It also binds the function directly to the instance, so it can be used in any
81-
context and will correctly refer to the class it came from:
82-
83-
```js
84-
import Component from '@ember/component';
85-
import { tracked } from '@glimmer/tracking';
86-
import { action } from '@ember/object';
87-
88-
export default class Tooltip extends Component {
89-
constructor() {
90-
super(...arguments);
91-
92-
// this.toggleShowing is still bound correctly when added to
93-
// the event listener
94-
document.addEventListener('click', this.toggleShowing);
95-
}
96-
97-
@tracked isShowing = false;
98-
99-
@action
100-
toggleShowing() {
101-
this.isShowing = !this.isShowing;
102-
}
103-
}
104-
```
105-
106-
@public
107-
@method action
108-
@for @ember/object
109-
@static
110-
@param {Function|undefined} callback The function to turn into an action,
111-
when used in classic classes
112-
@return {PropertyDecorator} property decorator instance
113-
*/
114-
115-
const BINDINGS_MAP = new WeakMap();
116-
117-
interface HasProto {
118-
constructor: {
119-
proto(): void;
120-
};
121-
}
122-
123-
function hasProto(obj: unknown): obj is HasProto {
124-
return (
125-
obj != null &&
126-
(obj as any).constructor !== undefined &&
127-
typeof ((obj as any).constructor as any).proto === 'function'
128-
);
129-
}
130-
131-
interface HasActions {
132-
actions: Record<string | symbol, unknown>;
133-
}
134-
135-
function setupAction(
136-
target: Partial<HasActions>,
137-
key: string | symbol,
138-
actionFn: Function
139-
): TypedPropertyDescriptor<unknown> {
140-
if (hasProto(target)) {
141-
target.constructor.proto();
142-
}
143-
144-
if (!Object.prototype.hasOwnProperty.call(target, 'actions')) {
145-
let parentActions = target.actions;
146-
// we need to assign because of the way mixins copy actions down when inheriting
147-
target.actions = parentActions ? Object.assign({}, parentActions) : {};
148-
}
149-
150-
assert("[BUG] Somehow the target doesn't have actions!", target.actions != null);
151-
152-
target.actions[key] = actionFn;
153-
154-
return {
155-
get() {
156-
let bindings = BINDINGS_MAP.get(this);
157-
158-
if (bindings === undefined) {
159-
bindings = new Map();
160-
BINDINGS_MAP.set(this, bindings);
161-
}
162-
163-
let fn = bindings.get(actionFn);
164-
165-
if (fn === undefined) {
166-
fn = actionFn.bind(this);
167-
bindings.set(actionFn, fn);
168-
}
169-
170-
return fn;
171-
},
172-
};
173-
}
174-
175-
export function action(
176-
target: ElementDescriptor[0],
177-
key: ElementDescriptor[1],
178-
desc: ElementDescriptor[2]
179-
): PropertyDescriptor;
180-
export function action(desc: PropertyDescriptor): ExtendedMethodDecorator;
181-
export function action(
182-
...args: ElementDescriptor | [PropertyDescriptor]
183-
): PropertyDescriptor | ExtendedMethodDecorator {
184-
let actionFn: object | Function;
185-
186-
if (!isElementDescriptor(args)) {
187-
actionFn = args[0];
188-
189-
let decorator: ExtendedMethodDecorator = function (
190-
target,
191-
key,
192-
_desc,
193-
_meta,
194-
isClassicDecorator
195-
) {
196-
assert(
197-
'The @action decorator may only be passed a method when used in classic classes. You should decorate methods directly in native classes',
198-
isClassicDecorator
199-
);
200-
201-
assert(
202-
'The action() decorator must be passed a method when used in classic classes',
203-
typeof actionFn === 'function'
204-
);
205-
206-
return setupAction(target, key, actionFn);
207-
};
208-
209-
setClassicDecorator(decorator);
210-
211-
return decorator;
212-
}
213-
214-
let [target, key, desc] = args;
215-
216-
actionFn = desc?.value;
217-
218-
assert(
219-
'The @action decorator must be applied to methods when used in native classes',
220-
typeof actionFn === 'function'
221-
);
222-
223-
// SAFETY: TS types are weird with decorators. This should work.
224-
return setupAction(target, key, actionFn);
225-
}
226-
227-
// SAFETY: TS types are weird with decorators. This should work.
228-
setClassicDecorator(action as ExtendedMethodDecorator);
229-
230-
// ..........................................................
231-
// OBSERVER HELPER
232-
//
233-
234-
type ObserverDefinition<T extends AnyFn> = {
235-
dependentKeys: string[];
236-
fn: T;
237-
sync: boolean;
238-
};
239-
240-
/**
241-
Specify a method that observes property changes.
242-
243-
```javascript
244-
import EmberObject from '@ember/object';
245-
import { observer } from '@ember/object';
246-
247-
export default EmberObject.extend({
248-
valueObserver: observer('value', function() {
249-
// Executes whenever the "value" property changes
250-
})
251-
});
252-
```
253-
254-
Also available as `Function.prototype.observes` if prototype extensions are
255-
enabled.
256-
257-
@method observer
258-
@for @ember/object
259-
@param {String} propertyNames*
260-
@param {Function} func
261-
@return func
262-
@public
263-
@static
264-
*/
265-
export function observer<T extends AnyFn>(
266-
...args:
267-
| [propertyName: string, ...additionalPropertyNames: string[], func: T]
268-
| [ObserverDefinition<T>]
269-
): T {
270-
let funcOrDef = args.pop();
271-
272-
assert(
273-
'observer must be provided a function or an observer definition',
274-
typeof funcOrDef === 'function' || (typeof funcOrDef === 'object' && funcOrDef !== null)
275-
);
276-
277-
let func: T;
278-
let dependentKeys: string[];
279-
let sync: boolean;
280-
281-
if (typeof funcOrDef === 'function') {
282-
func = funcOrDef;
283-
dependentKeys = args as string[];
284-
sync = !ENV._DEFAULT_ASYNC_OBSERVERS;
285-
} else {
286-
func = funcOrDef.fn;
287-
dependentKeys = funcOrDef.dependentKeys;
288-
sync = funcOrDef.sync;
289-
}
290-
291-
assert('observer called without a function', typeof func === 'function');
292-
assert(
293-
'observer called without valid path',
294-
Array.isArray(dependentKeys) &&
295-
dependentKeys.length > 0 &&
296-
dependentKeys.every((p) => typeof p === 'string' && Boolean(p.length))
297-
);
298-
assert('observer called without sync', typeof sync === 'boolean');
299-
300-
let paths: string[] = [];
301-
302-
for (let dependentKey of dependentKeys) {
303-
expandProperties(dependentKey, (path: string) => paths.push(path));
304-
}
305-
306-
setObservers(func as Function, {
307-
paths,
308-
sync,
309-
});
310-
return func;
311-
}

0 commit comments

Comments
 (0)