Merge branch 'master' into eslint

pull/2958/head
Rich Harris 6 years ago committed by GitHub
commit fa1ee4be9c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -89,7 +89,7 @@ function attribute_matches(node: Node, name: string, expected_value: string, ope
function class_matches(node, name: string) { function class_matches(node, name: string) {
return node.classes.some((class_directive) => { return node.classes.some((class_directive) => {
return class_directive.name === name; return new RegExp(`\\b${name}\\b`).test(class_directive.name);
}); });
} }

@ -10,7 +10,7 @@ type Unsubscriber = () => void;
type Updater<T> = (value: T) => T; type Updater<T> = (value: T) => T;
/** Cleanup logic callback. */ /** Cleanup logic callback. */
type Invalidater<T> = (value?: T) => void; type Invalidator<T> = (value?: T) => void;
/** Start and stop notification callbacks. */ /** Start and stop notification callbacks. */
type StartStopNotifier<T> = (set: Subscriber<T>) => Unsubscriber | void; type StartStopNotifier<T> = (set: Subscriber<T>) => Unsubscriber | void;
@ -22,7 +22,7 @@ export interface Readable<T> {
* @param run subscription callback * @param run subscription callback
* @param invalidate cleanup callback * @param invalidate cleanup callback
*/ */
subscribe(run: Subscriber<T>, invalidate?: Invalidater<T>): Unsubscriber; subscribe(run: Subscriber<T>, invalidate?: Invalidator<T>): Unsubscriber;
} }
/** Writable interface for both updating and subscribing. */ /** Writable interface for both updating and subscribing. */
@ -41,7 +41,7 @@ export interface Writable<T> extends Readable<T> {
} }
/** Pair of subscriber and invalidator. */ /** Pair of subscriber and invalidator. */
type SubscribeInvalidateTuple<T> = [Subscriber<T>, Invalidater<T>]; type SubscribeInvalidateTuple<T> = [Subscriber<T>, Invalidator<T>];
/** /**
* Create a `Writable` store that allows both updating and reading by subscription. * Create a `Writable` store that allows both updating and reading by subscription.
@ -67,7 +67,7 @@ export function writable<T>(value: T, start: StartStopNotifier<T> = noop): Writa
set(fn(value)); set(fn(value));
} }
function subscribe(run: Subscriber<T>, invalidate: Invalidater<T> = noop): Unsubscriber { function subscribe(run: Subscriber<T>, invalidate: Invalidator<T> = noop): Unsubscriber {
const subscriber: SubscribeInvalidateTuple<T> = [run, invalidate]; const subscriber: SubscribeInvalidateTuple<T> = [run, invalidate];
subscribers.push(subscriber); subscribers.push(subscriber);
if (subscribers.length === 1) { if (subscribers.length === 1) {
@ -127,7 +127,9 @@ export function derived<T, S extends Stores>(
const auto = fn.length < 2; const auto = fn.length < 2;
return readable(initial_value, (set) => { const invalidators: Array<Invalidator<T>> = [];
const store = readable(initial_value, (set) => {
let inited = false; let inited = false;
const values: StoresValues<S> = [] as StoresValues<S>; const values: StoresValues<S> = [] as StoresValues<S>;
@ -156,6 +158,7 @@ export function derived<T, S extends Stores>(
} }
}, },
() => { () => {
run_all(invalidators);
pending |= (1 << i); pending |= (1 << i);
}), }),
); );
@ -168,6 +171,22 @@ export function derived<T, S extends Stores>(
cleanup(); cleanup();
}; };
}); });
return {
subscribe(run: Subscriber<T>, invalidate: Invalidator<T> = noop): Unsubscriber {
invalidators.push(invalidate);
const unsubscribe = store.subscribe(run, invalidate);
return () => {
const index = invalidators.indexOf(invalidate);
if (index !== -1) {
invalidators.splice(index, 1);
}
unsubscribe();
};
}
}
} }
/** /**

@ -0,0 +1 @@
<div class="svelte-xyz foo:bar">Hello world</div>

@ -0,0 +1,11 @@
<script>
const enabled = true;
</script>
<div class:foo:bar={enabled}>Hello world</div>
<style>
.foo\:bar {
color: red;
}
</style>

@ -189,6 +189,34 @@ describe('store', () => {
unsubscribe(); unsubscribe();
}); });
it('prevents diamond dependency problem', () => {
const count = writable(0);
const values = [];
const a = derived(count, $count => {
return 'a' + $count;
});
const b = derived(count, $count => {
return 'b' + $count;
});
const combined = derived([a, b], ([a, b]) => {
return a + b;
});
const unsubscribe = combined.subscribe(v => {
values.push(v);
});
assert.deepEqual(values, ['a0b0']);
count.set(1);
assert.deepEqual(values, ['a0b0', 'a1b1']);
unsubscribe();
});
it('is updated with safe_not_equal logic', () => { it('is updated with safe_not_equal logic', () => {
const arr = [0]; const arr = [0];

Loading…
Cancel
Save