mirror of
https://github.com/vale981/tridactyl
synced 2025-03-09 20:26:40 -04:00
173 lines
3.8 KiB
TypeScript
173 lines
3.8 KiB
TypeScript
/** Messaging-safe copies of objects. Drops non-primitive properties.
|
|
*
|
|
* Objects to be passed by messaging API must only comprise of the following,
|
|
* otherwise they're silently dropped. The silent drop is probably a bug. If
|
|
* you include a Symbol() you get a DataCloneError.
|
|
*
|
|
* - string
|
|
* - number
|
|
* - boolean
|
|
* - null
|
|
* - undefined
|
|
* - objects containing attributes only of the above types
|
|
*
|
|
* Could just copy all primitive attributes, but then we don't get the
|
|
* interface... If we have to do this again, consider generating automatically
|
|
* from typescript/lib/lib.dom.d.ts
|
|
*
|
|
* */
|
|
|
|
const messageSafeTypes = new Set([
|
|
"string",
|
|
"number",
|
|
"boolean",
|
|
"null",
|
|
"undefined",
|
|
])
|
|
|
|
function pick(o, ...props) {
|
|
return Object.assign({}, ...props.map(prop => ({ [prop]: o[prop] })))
|
|
}
|
|
|
|
/** Messaging-safe, one level copy of obj
|
|
*
|
|
* Doesn't work for special objects like Events: Object.keys() is too
|
|
* parsimonious.
|
|
*
|
|
*/
|
|
export function generic(obj): any {
|
|
let ret = {}
|
|
for (let key of Object.keys(obj)) {
|
|
if (messageSafeTypes.has(typeof obj[key])) {
|
|
ret[key] = obj[key]
|
|
}
|
|
}
|
|
return ret
|
|
}
|
|
|
|
/** Messaging-safe, one level copy of obj
|
|
*
|
|
* Also looks at prototype properties. Works for e.g. Event.
|
|
*
|
|
*/
|
|
export function generic_all_props(obj): any {
|
|
let ret = {}
|
|
for (let key in obj) {
|
|
if (messageSafeTypes.has(typeof obj[key])) {
|
|
ret[key] = obj[key]
|
|
}
|
|
}
|
|
return ret
|
|
}
|
|
|
|
export interface MsgSafeKeyboardEvent {
|
|
// KeyboardEvent
|
|
readonly altKey: boolean
|
|
readonly shiftKey: boolean
|
|
readonly metaKey: boolean
|
|
readonly ctrlKey: boolean
|
|
readonly repeat: boolean
|
|
readonly isComposing: boolean
|
|
|
|
readonly key: string
|
|
readonly code: string
|
|
readonly location: number
|
|
readonly locale: string
|
|
|
|
// Event
|
|
readonly bubbles: boolean
|
|
readonly cancelable: boolean
|
|
readonly composed: boolean
|
|
readonly defaultPrevented: boolean
|
|
readonly eventPhase: number
|
|
|
|
readonly timeStamp: string
|
|
readonly type: string
|
|
readonly isTrusted: boolean
|
|
|
|
readonly target: MsgSafeNode
|
|
}
|
|
|
|
/** MsgSafe copy of keyevent. */
|
|
export function KeyboardEvent(ke): MsgSafeKeyboardEvent {
|
|
let copy = pick(
|
|
ke,
|
|
"shiftKey",
|
|
"metaKey",
|
|
"altKey",
|
|
"ctrlKey",
|
|
"repeat",
|
|
"key",
|
|
"bubbles",
|
|
"composed",
|
|
"defaultPrevented",
|
|
"eventPhase",
|
|
"timeStamp",
|
|
"type",
|
|
"isTrusted",
|
|
)
|
|
copy.target = Node(ke.target)
|
|
|
|
// Works but adds > 200 properties.
|
|
// let copy = generic_all_props(ke)
|
|
// copy.target = generic_all_props(ke.target)
|
|
|
|
return copy
|
|
}
|
|
|
|
export interface MsgSafeNode {
|
|
// w3 Node interface
|
|
readonly nodeName: string
|
|
readonly nodeValue: string
|
|
readonly nodeType: number
|
|
readonly namespaceURI: string
|
|
readonly prefix?: string
|
|
readonly localName: string
|
|
readonly baseURI: string
|
|
readonly textContent: string
|
|
|
|
// w3 Element interface
|
|
readonly tagName?: string
|
|
|
|
// InputElement
|
|
readonly type?: string
|
|
|
|
// WAI-ARIA
|
|
readonly role?: string
|
|
|
|
// unknown spec
|
|
readonly contentEditable?: string
|
|
readonly isContentEditable?: boolean
|
|
readonly disabled?: boolean
|
|
readonly readonly?: boolean
|
|
}
|
|
|
|
export function Node(node: HTMLElement): MsgSafeNode {
|
|
return pick(
|
|
node,
|
|
// w3 Node interface
|
|
"nodeName",
|
|
"nodeValue",
|
|
"nodeType",
|
|
"namespaceURI",
|
|
"prefix",
|
|
"localName",
|
|
"baseURI",
|
|
"textContent",
|
|
|
|
// w3 Element interface
|
|
"tagName",
|
|
|
|
// InputElement
|
|
"type",
|
|
|
|
// WAI-ARIA
|
|
"role",
|
|
|
|
// unknown spec
|
|
"contentEditable",
|
|
"isContentEditable",
|
|
"disabled",
|
|
"readonly",
|
|
)
|
|
}
|