@blackglory/observe 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -2
- package/src/index.ts +4 -0
- package/src/observe-addtion-of-descendant-nodes.ts +18 -0
- package/src/observe-removal-of-descendant-nodes.ts +18 -0
- package/src/observe-state-changes.ts +55 -0
- package/src/observe-url-changes.ts +11 -0
- package/src/utils/from-mutation-observer.ts +13 -0
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blackglory/observe",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "A module for observing things happening.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"DOM"
|
|
7
7
|
],
|
|
8
8
|
"files": [
|
|
9
|
-
"lib"
|
|
9
|
+
"lib",
|
|
10
|
+
"src"
|
|
10
11
|
],
|
|
11
12
|
"type": "module",
|
|
12
13
|
"main": "lib/index.js",
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { fromMutationObserver } from '@utils/from-mutation-observer.js'
|
|
2
|
+
import { filter, map } from 'rxjs/operators'
|
|
3
|
+
import { Observable } from 'rxjs'
|
|
4
|
+
import * as Iter from 'iterable-operator'
|
|
5
|
+
|
|
6
|
+
export function observeAdditionOfDescendantNodes(node: Node): Observable<Node[]> {
|
|
7
|
+
return fromMutationObserver(
|
|
8
|
+
node
|
|
9
|
+
, { childList: true, subtree: true }
|
|
10
|
+
).pipe(
|
|
11
|
+
map(records => Iter.toArray(
|
|
12
|
+
Iter.flatten<Node>(
|
|
13
|
+
Iter.map(records, x => x.addedNodes)
|
|
14
|
+
)
|
|
15
|
+
))
|
|
16
|
+
, filter(addedNodes => addedNodes.length > 0)
|
|
17
|
+
)
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { fromMutationObserver } from '@utils/from-mutation-observer.js'
|
|
2
|
+
import { filter, map } from 'rxjs/operators'
|
|
3
|
+
import { Observable } from 'rxjs'
|
|
4
|
+
import * as Iter from 'iterable-operator'
|
|
5
|
+
|
|
6
|
+
export function observeRemovalOfDescendantNodes(node: Node): Observable<Node[]> {
|
|
7
|
+
return fromMutationObserver(
|
|
8
|
+
node
|
|
9
|
+
, { childList: true, subtree: true }
|
|
10
|
+
).pipe(
|
|
11
|
+
map(records => Iter.toArray(
|
|
12
|
+
Iter.flatten<Node>(
|
|
13
|
+
Iter.map(records, x => x.removedNodes)
|
|
14
|
+
)
|
|
15
|
+
))
|
|
16
|
+
, filter(removedNodes => removedNodes.length > 0)
|
|
17
|
+
)
|
|
18
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Observable, Subscriber, fromEvent, merge } from 'rxjs'
|
|
2
|
+
import { map } from 'rxjs/operators'
|
|
3
|
+
|
|
4
|
+
const pushStateHooks = new Set<Subscriber<void>>()
|
|
5
|
+
const replaceStateHooks = new Set<Subscriber<void>>()
|
|
6
|
+
let pushStateHookRegistered = false
|
|
7
|
+
let replaceStateHookRegistered = false
|
|
8
|
+
|
|
9
|
+
export function observeStateChanges(): Observable<void> {
|
|
10
|
+
return merge(
|
|
11
|
+
observePushState()
|
|
12
|
+
, observeReplaceState()
|
|
13
|
+
, fromEvent(window, 'popstate')
|
|
14
|
+
).pipe(
|
|
15
|
+
map(_ => undefined)
|
|
16
|
+
)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function observePushState(): Observable<void> {
|
|
20
|
+
return new Observable(observer => {
|
|
21
|
+
if (!pushStateHookRegistered) {
|
|
22
|
+
registerPushStateHook()
|
|
23
|
+
}
|
|
24
|
+
pushStateHooks.add(observer)
|
|
25
|
+
return () => pushStateHooks.delete(observer)
|
|
26
|
+
})
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function observeReplaceState(): Observable<void> {
|
|
30
|
+
return new Observable(observer => {
|
|
31
|
+
if (!replaceStateHookRegistered) {
|
|
32
|
+
registerReplaceStateHook()
|
|
33
|
+
}
|
|
34
|
+
replaceStateHooks.add(observer)
|
|
35
|
+
return () => replaceStateHooks.delete(observer)
|
|
36
|
+
})
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function registerPushStateHook() {
|
|
40
|
+
const pushState = history.pushState
|
|
41
|
+
history.pushState = function (...args) {
|
|
42
|
+
Reflect.apply(pushState, this, args)
|
|
43
|
+
pushStateHooks.forEach(observer => observer.next())
|
|
44
|
+
}
|
|
45
|
+
pushStateHookRegistered = true
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function registerReplaceStateHook() {
|
|
49
|
+
const replaceState = history.replaceState
|
|
50
|
+
history.replaceState = function (...args) {
|
|
51
|
+
Reflect.apply(replaceState, this, args)
|
|
52
|
+
replaceStateHooks.forEach(observer => observer.next())
|
|
53
|
+
}
|
|
54
|
+
replaceStateHookRegistered = true
|
|
55
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Observable, animationFrames } from 'rxjs'
|
|
2
|
+
import { filter, tap, map } from 'rxjs/operators'
|
|
3
|
+
|
|
4
|
+
export function observeURLChanges(): Observable<void> {
|
|
5
|
+
let url = document.URL
|
|
6
|
+
return animationFrames().pipe(
|
|
7
|
+
filter(() => url !== document.URL)
|
|
8
|
+
, tap(() => url = document.URL)
|
|
9
|
+
, map(() => undefined)
|
|
10
|
+
)
|
|
11
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Observable } from 'rxjs'
|
|
2
|
+
|
|
3
|
+
export function fromMutationObserver(
|
|
4
|
+
...args: Parameters<MutationObserver['observe']>
|
|
5
|
+
): Observable<MutationRecord[]> {
|
|
6
|
+
return new Observable(subscriber => {
|
|
7
|
+
const observer = new MutationObserver(
|
|
8
|
+
mutationList => subscriber.next(mutationList)
|
|
9
|
+
)
|
|
10
|
+
observer.observe(...args)
|
|
11
|
+
return () => observer.disconnect()
|
|
12
|
+
})
|
|
13
|
+
}
|