mirror of
https://github.com/vale981/tridactyl
synced 2025-03-10 04:36:39 -04:00
164 lines
3.7 KiB
TypeScript
164 lines
3.7 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',
|
||
|
)
|
||
|
}
|