Skip to content

Commit

Permalink
feat(signals): port from vCurrent
Browse files Browse the repository at this point in the history
  • Loading branch information
EisenbergEffect committed Apr 24, 2018
1 parent 4b39aae commit 49ea175
Show file tree
Hide file tree
Showing 6 changed files with 200 additions and 3 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ An experimental re-working of Aurelia, oriented around compile-time reflection a
* [x] `debounce`
* [x] `throttle`
* [x] `updateTrigger`
* [x] `signal`
* [x] `self`
* Template Controllers
* [x] `if`
Expand Down
94 changes: 92 additions & 2 deletions scripts/app-bundle.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion scripts/app-bundle.js.map

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions src/debug/reporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,5 +93,13 @@ const codeLookup: Record<string, IMessageInfo> = {
10: {
type: MessageType.error,
message: 'The updateTrigger binding behavior can only be applied to two-way/ from-view bindings on input/select elements.'
},
11: {
type: MessageType.error,
message: 'Only property bindings and string interpolation bindings can be signaled. Trigger, delegate and call bindings cannot be signaled.'
},
12: {
type: MessageType.error,
message: 'Signal name is required.'
}
};
3 changes: 3 additions & 0 deletions src/runtime/configuration/standard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { SelfBindingBehavior } from "../resources/self-binding-behavior";
import { ThrottleBindingBehavior } from "../resources/throttle-binding-behavior";
import { UpdateTriggerBindingBehavior } from "../resources/update-trigger-binding-behavior";
import { With } from "../resources/with";
import { ISignaler, Signaler, SignalBindingBehavior } from "../resources/signals";

export const StandardConfiguration = {
register(container: IContainer) {
Expand All @@ -32,6 +33,7 @@ export const StandardConfiguration = {
DebounceBindingBehavior,
ThrottleBindingBehavior,
UpdateTriggerBindingBehavior,
SignalBindingBehavior,
SelfBindingBehavior,

// Template Controllers
Expand All @@ -51,5 +53,6 @@ export const StandardConfiguration = {
container.register(Registration.instance(IObserverLocator, ObserverLocator));
container.register(Registration.instance(IAnimator, Animator));
container.register(Registration.instance(ISanitizer, Sanitizer));
container.register(Registration.instance(ISignaler, Signaler));
}
};
95 changes: 95 additions & 0 deletions src/runtime/resources/signals.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { sourceContext, IScope } from '../binding/binding-context';
import { DI } from '../di';
import { IBinding, Binding } from '../binding/binding';
import { ICallable } from '../interfaces';
import { bindingBehavior } from '../decorators';
import { Reporter } from '../reporter';

type Signal = string;

export const ISignaler = DI.createInterface('ISignaler');

export interface ISignaler {
dispatchSignal(name: Signal): void;
addSignalListener(name: Signal, listener: ICallable): void;
removeSignalListener(name: Signal, listener: ICallable): void;
}

const signals: Record<Signal, ICallable[]> = {};

export const Signaler: ISignaler = {
dispatchSignal(name: Signal): void {
let bindings = signals[name];

if (!bindings) {
return;
}

let i = bindings.length;

while (i--) {
bindings[i].call(sourceContext);
}
},

addSignalListener(name: Signal, listener: ICallable) {
(signals[name] || (signals[name] = [])).push(listener);
},

removeSignalListener(name: Signal, listener: ICallable) {
let listeners = signals[name];

if (listeners) {
listeners.splice(listeners.indexOf(listener), 1);
}
}
}

type SignalableBinding = Binding & {
signal: string | string[];
};

@bindingBehavior('signal')
export class SignalBindingBehavior {
signals;

bind(binding: SignalableBinding, scope: IScope) {
if (!binding.updateTarget) {
throw Reporter.error(11);
}

if (arguments.length === 3) {
let name = arguments[2];
Signaler.addSignalListener(name, binding);
binding.signal = name;
} else if (arguments.length > 3) {
let names = Array.prototype.slice.call(arguments, 2);
let i = names.length;

while (i--) {
let name = names[i];
Signaler.addSignalListener(name, binding);
}

binding.signal = names;
} else {
throw Reporter.error(12);
}
}

unbind(binding: SignalableBinding, scope: IScope) {
let name = binding.signal;
binding.signal = null;

if (Array.isArray(name)) {
let names = name;
let i = names.length;

while (i--) {
Signaler.removeSignalListener(names[i], binding);
}
} else {
Signaler.removeSignalListener(name, binding);
}
}
}

0 comments on commit 49ea175

Please sign in to comment.