Skip to content

Commit

Permalink
Reviews - Update SubscribeOptions.stopOnDomReady's default to false
Browse files Browse the repository at this point in the history
  • Loading branch information
qti3e committed Jul 8, 2019
1 parent 6efea53 commit a6f2f88
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 40 deletions.
48 changes: 36 additions & 12 deletions index.d.ts
Expand Up @@ -24,12 +24,36 @@ declare namespace elementReady {
readonly stopOnDomReady?: boolean;
}

interface SubscribeOptions {
/**
The element that's expected to contain a match.
@default document
*/
readonly target?: Element | Document;

/**
Milliseconds to wait before stopping the search.
@default Infinity
*/
readonly timeout?: number

/**
Automatically stop searching for new elements after the DOM ready event.
If this is true, and `subscribe` function is being called after the DOM ready event, it just detects the elements that are currently in the DOM and then stops searching for new elements immediately.
@default false
*/
readonly stopOnDomReady?: boolean;
}

type Stoppable = {
/**
Stop checking for new elements.
Stop checking for new elements.
Calling it multiple times does nothing.
*/
Calling it multiple times does nothing.
*/
stop(): void;
};

Expand All @@ -45,14 +69,14 @@ declare namespace elementReady {
/**
Called on each new element that matches the selector in the DOM.
*/
type SubscribeCallback<T> = (el: T) => any;
type SubscribeCallback<T> = (element: T) => void;

/**
Detect elements as they are added to the DOM.
@param selector - [CSS selector.](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_Started/Selectors)
@param cb Callback that is called for each new element.
@returns The unsubscribe function.
@param callback - Callback to be called for each new element.
@returns A stoppable that can be used to unsubscribe to this event.
@example
```
Expand All @@ -64,20 +88,20 @@ declare namespace elementReady {
*/
function subscribe<ElementName extends keyof HTMLElementTagNameMap>(
selector: ElementName,
cb: elementReady.SubscribeCallback<HTMLElementTagNameMap[ElementName]>,
options?: elementReady.Options
callback: elementReady.SubscribeCallback<HTMLElementTagNameMap[ElementName]>,
options?: elementReady.SubscribeOptions
): Stoppable;

function subscribe<ElementName extends keyof SVGElementTagNameMap>(
selector: ElementName,
cb: elementReady.SubscribeCallback<SVGElementTagNameMap[ElementName]>,
options?: elementReady.Options
callback: elementReady.SubscribeCallback<SVGElementTagNameMap[ElementName]>,
options?: elementReady.SubscribeOptions
): Stoppable;

function subscribe<ElementName extends Element = Element>(
selector: string,
cb: elementReady.SubscribeCallback<ElementName>,
options?: elementReady.Options
callback: elementReady.SubscribeCallback<ElementName>,
options?: elementReady.SubscribeOptions
): Stoppable;
}

Expand Down
16 changes: 7 additions & 9 deletions index.js
Expand Up @@ -54,12 +54,12 @@ const elementReady = (selector, {
return Object.assign(promise, {stop});
};

elementReady.subscribe = (selector, cb, {
elementReady.subscribe = (selector, callback, {
target = document,
stopOnDomReady = true,
stopOnDomReady = false,
timeout = Infinity
} = {}) => {
const seen = new WeakSet();
const seenElements = new WeakSet();

let rafId;
let checkFrame = true;
Expand All @@ -83,15 +83,13 @@ elementReady.subscribe = (selector, cb, {
if (checkFrame) {
const allElements = target.querySelectorAll(selector);

for (let i = 0; i < allElements.length; ++i) {
const element = allElements[i];

if (seen.has(element)) {
for (const element of allElements) {
if (seenElements.has(element)) {
continue;
}

cb(element);
seen.add(element);
callback(element);
seenElements.add(element);
}
}

Expand Down
16 changes: 8 additions & 8 deletions index.test-d.ts
Expand Up @@ -13,14 +13,14 @@ expectType<elementReady.StoppablePromise<HTMLDivElement | undefined>>(elementRea
expectType<elementReady.StoppablePromise<SVGElement | undefined>>(elementReady('text'));


const {stop} = elementReady.subscribe(".unicorn", e => null);
elementReady.subscribe(".unicorn", e => null, {target: document});
elementReady.subscribe(".unicorn", e => null, {target: document.documentElement});
elementReady.subscribe(".unicorn", e => null, {stopOnDomReady: false});

elementReady.subscribe(".unicorn", e => expectType<Element>(e));
elementReady.subscribe("div", e => expectType<HTMLDivElement>(e));
elementReady.subscribe("text", e => expectType<SVGElement>(e));
const {stop} = elementReady.subscribe('.unicorn', e => null);
elementReady.subscribe('.unicorn', e => null, {target: document});
elementReady.subscribe('.unicorn', e => null, {target: document.documentElement});
elementReady.subscribe('.unicorn', e => null, {stopOnDomReady: false});

elementReady.subscribe('.unicorn', e => expectType<Element>(e));
elementReady.subscribe('div', e => expectType<HTMLDivElement>(e));
elementReady.subscribe('text', e => expectType<SVGElement>(e));

expectType<() => any>(stop);

Expand Down
40 changes: 34 additions & 6 deletions readme.md
Expand Up @@ -20,6 +20,11 @@ const elementReady = require('element-ready');

console.log(element.id);
//=> 'unicorn'

elementReady('.rainbow', element => {
console.log(element.classList);
//=> ['rainbow',...]
});
})();
```

Expand Down Expand Up @@ -69,7 +74,9 @@ Stop checking for the element to be ready. The stop is synchronous and the origi

Calling it after the promise has settled or multiple times does nothing.

### elementReady.subscribe(selector, cb, options?)
<hr>

### elementReady.subscribe(selector, callback, options?)

Detect elements as they are added to the DOM.

Expand All @@ -81,18 +88,39 @@ Type: `string`

[CSS selector.](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_Started/Selectors)

#### cb
#### callback

Type: `Function`<br>
Signature: `(element: Element) => any`
Signature: `(element: Element) => void`

Callback function to be called on each of the discovered elements.
Callback function to be called on each one of the discovered elements.

#### options

Same as `elementReady` options.
##### target

Type: `Element | document`<br>
Default: `document`

The element that's expected to contain a match.

##### stopOnDomReady

Type: `boolean`<br>
Default: `false`

Automatically stop searching for new elements after the [DOM ready event](https://developer.mozilla.org/en-US/docs/Web/API/Window/DOMContentLoaded_event).

If this is true, and `subscribe` function is being called after the DOM ready event, it just detects the elements that are currently in the DOM and then stops searching for new elements immediately.

##### timeout

Type: `number`<br>
Default: `Infinity`

Milliseconds to wait before stopping the search.

#### elementReady.subscribe()#stop()
#### stoppable#stop()

Type: `Function`

Expand Down
10 changes: 5 additions & 5 deletions test.js
Expand Up @@ -189,13 +189,13 @@ test('ensure different promises are returned on second call with the same select
});

test('subscribe: check if elements are detected', async t => {
const e = () => {
const createElement = () => {
const element = document.createElement('p');
element.className = 'rainbow';
return element;
};

const elements = [e(), e(), e()];
const elements = [createElement(), createElement(), createElement()];
const seen = [];

(async () => {
Expand All @@ -215,13 +215,13 @@ test('subscribe: check if elements are detected', async t => {
});

test('subscribe: stop should work', async t => {
const e = () => {
const createElement = () => {
const element = document.createElement('p');
element.className = 'happy-unicorn';
return element;
};

const elements = [e(), e(), e()];
const elements = [createElement(), createElement(), createElement()];
const seen = [];

(async () => {
Expand All @@ -232,7 +232,7 @@ test('subscribe: stop should work', async t => {
document.body.append(elements[2]);
})();

const {stop} = elementReady.subscribe('.happy-unicorn', el => seen.push(el), {stopOnDomReady: false});
const {stop} = elementReady.subscribe('.happy-unicorn', el => seen.push(el));
await delay(100);
stop();
await delay(300);
Expand Down

0 comments on commit a6f2f88

Please sign in to comment.