@pluginarch/create-parch
Version:
this is way to create a ui project
158 lines (146 loc) • 4.93 kB
JavaScript
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
}
}