UNPKG

@pluginarch/create-parch

Version:

this is way to create a ui project

158 lines (146 loc) 4.93 kB
class iframeSandBox { constructor(opts) { debugger this.microWindow = opts.microWindow this.code = opts.code this.active = opts.active // 限制属性内容 this.scopeProperties = [] // 排除属性内容 this.escapeProperties = [] this.start() this.iframe = document.createElement('iframe'); this.iframe.sandbox = 'allow-forms allow-popups allow-scripts allow-same-origin'; // 允许在iframe中执行脚本 this.iframe.style.display = 'none' document.body.appendChild(this.iframe); this.contentWindow = this.iframe.contentWindow; //this.startProxy() } start() { this.proxyWindow = new Proxy(this.microWindow,{ get:(target,key)=>{ if (key === 'top' || key === 'parent') { if (rawWindow === rawWindow.parent) { // not in iframe return this.proxyWindow } return Reflect.get(rawWindow, key) // iframe } if (key === 'hasOwnProperty') return hasOwnProperty if (key === 'document' || key === 'eval') { switch (key) { case 'document': return rawDocument case 'eval': return eval } } if (this.scopeProperties.includes(key)) { return Reflect.get(target, key) } if (Reflect.has(target, key)) { return Reflect.get(target, key) } const rawValue = Reflect.get(rawWindow, key) return this.bindFunction(rawWindow, rawValue) }, set: (target, key, value) => { if (this.active) { if (escapeSetterKeyList.includes(key)) { Reflect.set(rawWindow, key, value) } else if ( !target.hasOwnProperty(key) && rawWindow.hasOwnProperty(key) && !this.scopeProperties.includes(key) ) { const descriptor = Object.getOwnPropertyDescriptor(rawWindow, key) const { writable, configurable, enumerable } = descriptor if (writable) { Object.defineProperty(target, key, { configurable, enumerable, writable, value, }) this.injectedKeys.add(key) } } else { Reflect.set(target, key, value) this.injectedKeys.add(key) } if ( ( this.escapeProperties.includes(key) || (staticEscapeProperties.includes(key) && !Reflect.has(rawWindow, key)) ) && !this.scopeProperties.includes(key) ) { Reflect.set(rawWindow, key, value) this.escapeKeys.add(key) } } return true }, has: (target, key) => { if (this.scopeProperties.includes(key)) return key in target return key in unscopables || key in target || key in rawWindow }, getOwnPropertyDescriptor: (target, key) => { if (target.hasOwnProperty(key)) { descriptorTargetMap.set(key, 'target') return Object.getOwnPropertyDescriptor(target, key) } if (rawWindow.hasOwnProperty(key)) { descriptorTargetMap.set(key, 'rawWindow') const descriptor = Object.getOwnPropertyDescriptor(rawWindow, key) if (descriptor && !descriptor.configurable) { descriptor.configurable = true } return descriptor } return undefined }, defineProperty: (target, key, value) => { const from = descriptorTargetMap.get(key) if (from === 'rawWindow') { return Reflect.defineProperty(rawWindow, key, value) } return Reflect.defineProperty(target, key, value) }, ownKeys: (target)=> { return unique(Reflect.ownKeys(rawWindow).concat(Reflect.ownKeys(target))) }, deleteProperty: (target, key) => { if (target.hasOwnProperty(key)) { if (this.escapeKeys.has(key)) { Reflect.deleteProperty(rawWindow, key) } return Reflect.deleteProperty(target, key) } return true } }) } run(code) { debugger const script = document.createElement('script'); script.textContent = code; this.contentWindow.document.body.appendChild(script); } bindFunction (rawWindow, value) { if (rawWindowMethodMap.has(value)) { return rawWindowMethodMap.get(value) } if (isFunction(value) && !isConstructor(value)) { const bindRawWindowValue = value.bind(rawWindow) for (const key in value) { bindRawWindowValue[key] = value[key] } if (value.hasOwnProperty('prototype') && !bindRawWindowValue.hasOwnProperty('prototype')) { bindRawWindowValue.prototype = value.prototype } rawWindowMethodMap.set(value, bindRawWindowValue) return bindRawWindowValue } return value } }