Skip to content

Commit

Permalink
better handling of iframes, relates to #126
Browse files Browse the repository at this point in the history
  • Loading branch information
johanneswilm committed Nov 14, 2023
1 parent 8f3444f commit 4e3453c
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 34 deletions.
2 changes: 1 addition & 1 deletion browser/diffDOM.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion browser/diffDOM.js.map

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions src/TraceLogger.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import {checkElementType} from "./diffDOM/helpers"

/**
* Use TraceLogger to figure out function calls inside
* JS objects by wrapping an object with a TraceLogger
Expand Down Expand Up @@ -113,8 +115,8 @@ export class TraceLogger {
if (typeof v === "string") {
return v
}
if (v instanceof HTMLElement) {
return v.outerHTML || "<empty>"
if (checkElementType(v, "HTMLElement")) {
return (v as HTMLElement).outerHTML || "<empty>"
}
if (v instanceof Array) {
return `[${v.map(stringCollapse).join(",")}]`
Expand Down
26 changes: 26 additions & 0 deletions src/diffDOM/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,29 @@ export class Diff {
return this
}
}

export const checkElementType = (element, elementTypeName) => {
if (typeof element === 'undefined' || element === null) {
return false
}


if (typeof window !== 'undefined') {
// For browser environment
if (typeof window[elementTypeName] === 'function') {
if(element instanceof (window[elementTypeName] as any) || (
element.ownerDocument?.defaultView &&
element instanceof element.ownerDocument.defaultView[elementTypeName]
)) {
return true
} else {
return false
}
} else {
return false
}
} else {
// For node.js
return typeof global !== 'undefined' && element instanceof global[elementTypeName]
}
}
18 changes: 9 additions & 9 deletions src/diffDOM/virtual/diff.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
removeDone,
roughlyEqual,
} from "./helpers"
import { Diff } from "../helpers"
import { Diff, checkElementType, } from "../helpers"
import { applyVirtual } from "./apply"
import { nodeToObj } from "./fromDOM"
import { stringToObj } from "./fromString"
Expand All @@ -39,15 +39,15 @@ export class DiffFinder {
) {
this.options = options
this.t1 = (
typeof Element !== "undefined" && t1Node instanceof Element
? nodeToObj(t1Node, this.options)
typeof Element !== "undefined" && checkElementType(t1Node, "Element")
? nodeToObj((t1Node as Element), this.options)
: typeof t1Node === "string"
? stringToObj(t1Node, this.options)
: JSON.parse(JSON.stringify(t1Node))
) as elementDiffNodeType
this.t2 = (
typeof Element !== "undefined" && t2Node instanceof Element
? nodeToObj(t2Node, this.options)
typeof Element !== "undefined" && checkElementType(t2Node, "Element")
? nodeToObj((t2Node as Element), this.options)
: typeof t2Node === "string"
? stringToObj(t2Node, this.options)
: JSON.parse(JSON.stringify(t2Node))
Expand All @@ -56,14 +56,14 @@ export class DiffFinder {
this.foundAll = false
if (this.debug) {
this.t1Orig =
typeof Element !== "undefined" && t1Node instanceof Element
? nodeToObj(t1Node, this.options)
typeof Element !== "undefined" && checkElementType(t1Node, "Element")
? nodeToObj((t1Node as Element), this.options)
: typeof t1Node === "string"
? stringToObj(t1Node, this.options)
: JSON.parse(JSON.stringify(t1Node))
this.t2Orig =
typeof Element !== "undefined" && t2Node instanceof Element
? nodeToObj(t2Node, this.options)
typeof Element !== "undefined" && checkElementType(t2Node, "Element")
? nodeToObj((t2Node as Element), this.options)
: typeof t2Node === "string"
? stringToObj(t2Node, this.options)
: JSON.parse(JSON.stringify(t2Node))
Expand Down
39 changes: 20 additions & 19 deletions src/diffDOM/virtual/fromDOM.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { DiffDOMOptionsPartial, elementNodeType, textNodeType } from "../types"
import {checkElementType} from "../helpers"

export function nodeToObj(
aNode: Element,
Expand All @@ -7,8 +8,8 @@ export function nodeToObj(
const objNode: elementNodeType | textNodeType = {
nodeName: aNode.nodeName,
}
if (aNode instanceof Text || aNode instanceof Comment) {
;(objNode as unknown as textNodeType).data = aNode.data
if (checkElementType(aNode, "Text") || checkElementType(aNode, "Comment")) {
;(objNode as unknown as textNodeType).data = (aNode as unknown as Text | Comment).data
} else {
if (aNode.attributes && aNode.attributes.length > 0) {
objNode.attributes = {}
Expand All @@ -26,29 +27,29 @@ export function nodeToObj(
)
}
if (options.valueDiffing) {
if (aNode instanceof HTMLTextAreaElement) {
objNode.value = aNode.value
if (checkElementType(aNode, "HTMLTextAreaElement")) {
objNode.value = (aNode as HTMLTextAreaElement).value
}
if (
aNode instanceof HTMLInputElement &&
["radio", "checkbox"].includes(aNode.type.toLowerCase()) &&
aNode.checked !== undefined
checkElementType(aNode, "HTMLInputElement") &&
["radio", "checkbox"].includes((aNode as HTMLInputElement).type.toLowerCase()) &&
(aNode as HTMLInputElement).checked !== undefined
) {
objNode.checked = aNode.checked
objNode.checked = (aNode as HTMLInputElement).checked
} else if (
aNode instanceof HTMLButtonElement ||
aNode instanceof HTMLDataElement ||
aNode instanceof HTMLInputElement ||
aNode instanceof HTMLLIElement ||
aNode instanceof HTMLMeterElement ||
aNode instanceof HTMLOptionElement ||
aNode instanceof HTMLProgressElement ||
aNode instanceof HTMLParamElement
checkElementType(aNode, "HTMLButtonElement") ||
checkElementType(aNode, "HTMLDataElement") ||
checkElementType(aNode, "HTMLInputElement") ||
checkElementType(aNode, "HTMLLIElement") ||
checkElementType(aNode, "HTMLMeterElement") ||
checkElementType(aNode, "HTMLOptionElement") ||
checkElementType(aNode, "HTMLProgressElement") ||
checkElementType(aNode, "HTMLParamElement")
) {
objNode.value = aNode.value
objNode.value = (aNode as HTMLButtonElement | HTMLDataElement | HTMLInputElement | HTMLLIElement | HTMLMeterElement | HTMLOptionElement | HTMLProgressElement | HTMLParamElement).value
}
if (aNode instanceof HTMLOptionElement) {
objNode.selected = aNode.selected
if (checkElementType(aNode, "HTMLOptionElement")) {
objNode.selected = (aNode as HTMLOptionElement).selected
}
}
}
Expand Down
2 changes: 0 additions & 2 deletions src/diffDOM/virtual/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -461,5 +461,3 @@ export class DiffTracker {
this.list.forEach((li: Diff) => fn(li))
}
}

//export const elementHasValue = (element: Element) : boolean => element instanceof HTMLButtonElement || element instanceof HTMLDataElement || element instanceof HTMLInputElement || element instanceof HTMLLIElement || element instanceof HTMLMeterElement || element instanceof HTMLOptionElement || element instanceof HTMLProgressElement || element instanceof HTMLParamElement

0 comments on commit 4e3453c

Please sign in to comment.