Added mutation queues
This commit is contained in:
parent
44803adc2d
commit
4a76c12803
@ -2,17 +2,26 @@ import { Application } from "./Application"
|
|||||||
import { Diff } from "./Diff"
|
import { Diff } from "./Diff"
|
||||||
import { displayLocalDate } from "./DateView"
|
import { displayLocalDate } from "./DateView"
|
||||||
import { findAll, delay } from "./Utils"
|
import { findAll, delay } from "./Utils"
|
||||||
|
import { MutationQueue } from "./MutationQueue"
|
||||||
import * as actions from "./Actions"
|
import * as actions from "./Actions"
|
||||||
|
|
||||||
export class AnimeNotifier {
|
export class AnimeNotifier {
|
||||||
app: Application
|
app: Application
|
||||||
visibilityObserver: IntersectionObserver
|
|
||||||
user: HTMLElement
|
user: HTMLElement
|
||||||
|
visibilityObserver: IntersectionObserver
|
||||||
|
|
||||||
|
imageFound: MutationQueue
|
||||||
|
imageNotFound: MutationQueue
|
||||||
|
unmount: MutationQueue
|
||||||
|
|
||||||
constructor(app: Application) {
|
constructor(app: Application) {
|
||||||
this.app = app
|
this.app = app
|
||||||
this.user = null
|
this.user = null
|
||||||
|
|
||||||
|
this.imageFound = new MutationQueue(elem => elem.classList.add("image-found"))
|
||||||
|
this.imageNotFound = new MutationQueue(elem => elem.classList.add("image-not-found"))
|
||||||
|
this.unmount = new MutationQueue(elem => elem.classList.remove("mounted"))
|
||||||
|
|
||||||
if("IntersectionObserver" in window) {
|
if("IntersectionObserver" in window) {
|
||||||
// Enable lazy load
|
// Enable lazy load
|
||||||
this.visibilityObserver = new IntersectionObserver(
|
this.visibilityObserver = new IntersectionObserver(
|
||||||
@ -185,15 +194,15 @@ export class AnimeNotifier {
|
|||||||
img.src = img.dataset.src
|
img.src = img.dataset.src
|
||||||
|
|
||||||
if(img.naturalWidth === 0) {
|
if(img.naturalWidth === 0) {
|
||||||
img.onload = function() {
|
img.onload = () => {
|
||||||
this.classList.add("image-found")
|
this.imageFound.queue(img)
|
||||||
}
|
}
|
||||||
|
|
||||||
img.onerror = function() {
|
img.onerror = () => {
|
||||||
this.classList.add("image-not-found")
|
this.imageNotFound.queue(img)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
img.classList.add("image-found")
|
this.imageFound.queue(img)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,7 +219,7 @@ export class AnimeNotifier {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
element.classList.remove("mounted")
|
this.unmount.queue(element)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,18 @@
|
|||||||
export class Diff {
|
export class Diff {
|
||||||
|
// Reuse container for diffs to avoid memory allocation
|
||||||
|
static container: HTMLElement
|
||||||
|
|
||||||
|
// innerHTML will diff the element with the given HTML string and apply DOM mutations.
|
||||||
|
static innerHTML(aRoot: HTMLElement, html: string) {
|
||||||
|
if(!Diff.container) {
|
||||||
|
Diff.container = document.createElement("main")
|
||||||
|
}
|
||||||
|
|
||||||
|
Diff.container.innerHTML = html
|
||||||
|
Diff.childNodes(aRoot, Diff.container)
|
||||||
|
}
|
||||||
|
|
||||||
|
// childNodes diffs the child nodes of 2 given elements and applies DOM mutations.
|
||||||
static childNodes(aRoot: Node, bRoot: Node) {
|
static childNodes(aRoot: Node, bRoot: Node) {
|
||||||
let aChild = [...aRoot.childNodes]
|
let aChild = [...aRoot.childNodes]
|
||||||
let bChild = [...bRoot.childNodes]
|
let bChild = [...bRoot.childNodes]
|
||||||
@ -33,6 +47,7 @@ export class Diff {
|
|||||||
let elemA = a as HTMLElement
|
let elemA = a as HTMLElement
|
||||||
let elemB = b as HTMLElement
|
let elemB = b as HTMLElement
|
||||||
|
|
||||||
|
// Skip iframes
|
||||||
if(elemA.tagName === "IFRAME") {
|
if(elemA.tagName === "IFRAME") {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -75,11 +90,4 @@ export class Diff {
|
|||||||
Diff.childNodes(a, b)
|
Diff.childNodes(a, b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static innerHTML(aRoot: HTMLElement, html: string) {
|
|
||||||
let bRoot = document.createElement("main")
|
|
||||||
bRoot.innerHTML = html
|
|
||||||
|
|
||||||
Diff.childNodes(aRoot, bRoot)
|
|
||||||
}
|
|
||||||
}
|
}
|
29
scripts/MutationQueue.ts
Normal file
29
scripts/MutationQueue.ts
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
export class MutationQueue {
|
||||||
|
elements: Array<HTMLElement>
|
||||||
|
mutation: (elem: HTMLElement) => void
|
||||||
|
|
||||||
|
constructor(mutation: (elem: HTMLElement) => void) {
|
||||||
|
this.mutation = mutation
|
||||||
|
this.elements = []
|
||||||
|
}
|
||||||
|
|
||||||
|
queue(elem: HTMLElement) {
|
||||||
|
this.elements.push(elem)
|
||||||
|
|
||||||
|
if(this.elements.length === 1) {
|
||||||
|
window.requestAnimationFrame(() => this.mutateAll())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutateAll() {
|
||||||
|
for(let i = 0; i < this.elements.length; i++) {
|
||||||
|
this.mutation(this.elements[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
this.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
clear() {
|
||||||
|
this.elements.length = 0
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user