-
-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add elementReady.subscribe()
#24
Conversation
*/ | ||
stop(): void; | ||
}; | ||
|
||
type StoppablePromise<T> = Promise<T> & { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps, but the description doesn't match.
type StoppablePromise<T> = Promise<T> & Stoppable;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually wanted to do so, but I didn't want to change the doc comments.
@bfred-it Hey! I've made a small change and I guess this PR is ready to be merged. |
index.js
Outdated
if (checkFrame) { | ||
const allElements = target.querySelectorAll(selector); | ||
|
||
for (let i = 0; i < allElements.length; ++i) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use a for-of
loop.
index.js
Outdated
@@ -54,4 +54,52 @@ const elementReady = (selector, { | |||
return Object.assign(promise, {stop}); | |||
}; | |||
|
|||
elementReady.subscribe = (selector, cb, { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't use abbreviations. cb
=> callback
.
readme.md
Outdated
|
||
Same as `elementReady` options. | ||
|
||
#### elementReady.subscribe()#stop() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
?
test.js
Outdated
@@ -187,3 +187,56 @@ test('ensure different promises are returned on second call with the same select | |||
document.querySelector('.unicorn').remove(); | |||
t.is(prependElement(), await elementReady('.unicorn')); | |||
}); | |||
|
|||
test('subscribe: check if elements are detected', async t => { | |||
const e = () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't use one character variable names.
### elementReady.subscribe(selector, cb, options?) | ||
|
||
Detect elements as they are added to the DOM. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Include some use-cases for this method.
index.d.ts
Outdated
/** | ||
Called on each new element that matches the selector in the DOM. | ||
*/ | ||
type SubscribeCallback<T> = (el: T) => any; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This type is incorrect. According to the JS code, the return value is not used.
type SubscribeCallback<T> = (el: T) => any; | |
type SubscribeCallback<T> = (element: T) => any; |
index.d.ts
Outdated
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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@param cb Callback that is called for each new element. | |
@param cb - Callback that is called for each new element. |
index.d.ts
Outdated
/** | ||
Stop checking for new elements. | ||
|
||
Calling it multiple times does nothing. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incorrect indentation.
index.js
Outdated
stopOnDomReady = true, | ||
timeout = Infinity | ||
} = {}) => { | ||
const seen = new WeakSet(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const seen = new WeakSet(); | |
const seenElements = new WeakSet(); |
The implementation looks good, but I think you need to put more effort into the docs and TS definition. |
elementReady.subscribe()
@sindresorhus Sorry for all of this style-guide related issues, I wasn't quite familiar with your coding guide-lines, anyway I've addressed all of your comments. Also, I made a change to |
|
ping @bfred-it |
There are still some unresolved PR comments and some space indentation that needs to be converted to tab indentation. |
index.test-d.ts
Outdated
@@ -12,4 +12,17 @@ expectType<elementReady.StoppablePromise<Element | undefined>>(promise); | |||
expectType<elementReady.StoppablePromise<HTMLDivElement | undefined>>(elementReady('div')); | |||
expectType<elementReady.StoppablePromise<SVGElement | undefined>>(elementReady('text')); | |||
|
|||
|
|||
const {stop} = elementReady.subscribe('.unicorn', e => null); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
index.test-d.ts
Outdated
|
||
elementReady.subscribe('.unicorn', e => expectType<Element>(e)); | ||
elementReady.subscribe('div', e => expectType<HTMLDivElement>(e)); | ||
elementReady.subscribe('text', e => expectType<SVGElement>(e)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And these callbacks should not be inline arrow functions. They don't return anything so it's clearer with normal arrow functions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be clear, Sindre means this by "normal arrow functions":
elementReady.subscribe('text', e => {
expectType<SVGElement>(e);
});
@qti3e Ping back :) |
@sindresorhus I've been busy working on something, sorry I forgot about this pr since it's been a long time. |
selector: string, | ||
callback: elementReady.SubscribeCallback<ElementName>, | ||
options?: elementReady.Options | ||
): Stoppable; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use tab-indentation.
expectType<SVGElement>(element) | ||
}); | ||
|
||
expectType<() => any>(stop); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not correct. It returns void
.
continue; | ||
} | ||
|
||
callback(element); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you pass undefined
instead of null
(which querySelectorAll
returns). To be consistent with our other usage of undefined
.
/** | ||
Called on each new element that matches the selector in the DOM. | ||
*/ | ||
type SubscribeCallback<T> = (element: T) => void; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The element is not guaranteed to exist so should be optional.
@@ -185,3 +185,56 @@ test('ensure different promises are returned on second call with the same select | |||
document.querySelector('.unicorn').remove(); | |||
t.is(prependElement(), await elementReady('.unicorn')); | |||
}); | |||
|
|||
test('subscribe: check if elements are detected', async t => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There needs to be tests for the timeout
and stopOnDomReady
options with subscribe
too.
const seenElements = new WeakSet(); | ||
|
||
let rafId; | ||
let checkFrame = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should should have a should
, is
, or has
prefix. Not clear to me which one fits the best.
@qti3e Bump :) |
Closing for lack of activity. |
This approach uses a
WeakMap
to store already seen elements (to prevent memory leak) in order to detect new elements, also because checking all the elements to find out new ones might be a bit heavy we do this in half of therequestAnimationFrame
s, feedback is welcome.Fixes #22
IssueHunt Summary
Referenced issues
This pull request has been submitted to:
IssueHunt has been backed by the following sponsors. Become a sponsor