import{assert}from"./assert.js";import{helper}from"./helper.js";import{createJSHandle,JSHandle}from"./JSHandle.js";export const EVALUATION_SCRIPT_URL="__puppeteer_evaluation_script__";const SOURCE_URL_REGEX=/^[\040\t]*\/\/[@#] sourceURL=\s*(\S*?)\s*$/m;export class ExecutionContext{constructor(e,t,n){this._client=e,this._world=n,this._contextId=t.id,this._contextName=t.name}frame(){return this._world?this._world.frame():null}async evaluate(e,...t){return await this._evaluateInternal(!0,e,...t)}async evaluateHandle(e,...t){return this._evaluateInternal(!1,e,...t)}async _evaluateInternal(e,t,...n){const r=`//# sourceURL=${EVALUATION_SCRIPT_URL}`;if(helper.isString(t)){const n=this._contextId,a=t,i=SOURCE_URL_REGEX.test(a)?a:a+"\n"+r,{exceptionDetails:s,result:o}=await this._client.send("Runtime.evaluate",{expression:i,contextId:n,returnByValue:e,awaitPromise:!0,userGesture:!0}).catch(c);if(s)throw new Error("Evaluation failed: "+helper.getExceptionMessage(s));return e?helper.valueFromRemoteObject(o):createJSHandle(this,o)}if("function"!==typeof t)throw new Error(`Expected to get |string| or |function| as the first argument, but got "${t}" instead.`);let a,i=t.toString();try{new Function("("+i+")")}catch(l){i=i.startsWith("async ")?"async function "+i.substring("async ".length):"function "+i;try{new Function("("+i+")")}catch(l){throw new Error("Passed function is not well-serializable!")}}try{a=this._client.send("Runtime.callFunctionOn",{functionDeclaration:i+"\n"+r+"\n",executionContextId:this._contextId,arguments:n.map(function(e){if("bigint"===typeof e)return{unserializableValue:`${e.toString()}n`};if(Object.is(e,-0))return{unserializableValue:"-0"};if(Object.is(e,1/0))return{unserializableValue:"Infinity"};if(Object.is(e,-1/0))return{unserializableValue:"-Infinity"};if(Object.is(e,NaN))return{unserializableValue:"NaN"};const t=e&&e instanceof JSHandle?e:null;if(t){if(t._context!==this)throw new Error("JSHandles can be evaluated only in the context they were created!");if(t._disposed)throw new Error("JSHandle is disposed!");return t._remoteObject.unserializableValue?{unserializableValue:t._remoteObject.unserializableValue}:t._remoteObject.objectId?{objectId:t._remoteObject.objectId}:{value:t._remoteObject.value}}return{value:e}}.bind(this)),returnByValue:e,awaitPromise:!0,userGesture:!0})}catch(l){throw l instanceof TypeError&&l.message.startsWith("Converting circular structure to JSON")&&(l.message+=" Are you passing a nested JSHandle?"),l}const{exceptionDetails:s,result:o}=await a.catch(c);if(s)throw new Error("Evaluation failed: "+helper.getExceptionMessage(s));return e?helper.valueFromRemoteObject(o):createJSHandle(this,o);function c(e){if(e.message.includes("Object reference chain is too long"))return{result:{type:"undefined"}};if(e.message.includes("Object couldn't be returned by value"))return{result:{type:"undefined"}};if(e.message.endsWith("Cannot find context with specified id")||e.message.endsWith("Inspected target navigated or closed"))throw new Error("Execution context was destroyed, most likely because of a navigation.");throw e}}async queryObjects(e){assert(!e._disposed,"Prototype JSHandle is disposed!"),assert(e._remoteObject.objectId,"Prototype JSHandle must not be referencing primitive value");const t=await this._client.send("Runtime.queryObjects",{prototypeObjectId:e._remoteObject.objectId});return createJSHandle(this,t.objects)}async _adoptBackendNodeId(e){const{object:t}=await this._client.send("DOM.resolveNode",{backendNodeId:e,executionContextId:this._contextId});return createJSHandle(this,t)}async _adoptElementHandle(e){assert(e.executionContext()!==this,"Cannot adopt handle that already belongs to this execution context"),assert(this._world,"Cannot adopt handle without DOMWorld");const t=await this._client.send("DOM.describeNode",{objectId:e._remoteObject.objectId});return this._adoptBackendNodeId(t.node.backendNodeId)}}