void InspectorAnimationAgent::resolveAnimation( ErrorString* errorString, const String& animationId, std::unique_ptr<v8_inspector::protocol::Runtime::API::RemoteObject>* result) { blink::Animation* animation = assertAnimation(errorString, animationId); if (!animation) return; if (m_idToAnimationClone.get(animationId)) animation = m_idToAnimationClone.get(animationId); const Element* element = toKeyframeEffect(animation->effect())->target(); Document* document = element->ownerDocument(); LocalFrame* frame = document ? document->frame() : nullptr; ScriptState* scriptState = frame ? ScriptState::forMainWorld(frame) : nullptr; if (!scriptState) { *errorString = "Element not associated with a document."; return; } ScriptState::Scope scope(scriptState); static const char kAnimationObjectGroup[] = "animation"; m_v8Session->releaseObjectGroup( toV8InspectorStringView(kAnimationObjectGroup)); *result = m_v8Session->wrapObject( scriptState->context(), toV8(animation, scriptState->context()->Global(), scriptState->isolate()), toV8InspectorStringView(kAnimationObjectGroup)); if (!*result) *errorString = "Element not associated with a document."; }
void V8InjectedScriptHost::inspectCallback(const v8::FunctionCallbackInfo<v8::Value>& info) { if (info.Length() < 2) return; InjectedScriptHost* host = V8InjectedScriptHost::unwrap(info.GetIsolate()->GetCurrentContext(), info.Holder()); ScriptState* scriptState = ScriptState::current(info.GetIsolate()); ScriptState::Scope scope(scriptState); host->inspectImpl(toJSONValue(scriptState->context(), info[0]), toJSONValue(scriptState->context(), info[1])); }
void injectInternalsObject(v8::Local<v8::Context> context) { ScriptState* scriptState = ScriptState::from(context); ScriptState::Scope scope(scriptState); v8::Local<v8::Object> global = scriptState->context()->Global(); ExecutionContext* executionContext = scriptState->executionContext(); if (executionContext->isDocument()) { v8::Local<v8::Value> internals = toV8(Internals::create(toDocument(executionContext)), global, scriptState->isolate()); ASSERT(!internals.IsEmpty()); v8CallOrCrash(global->Set(scriptState->context(), v8AtomicString(scriptState->isolate(), Internals::internalsId), internals)); } }
// Create a V8 object with an interceptor of NPObjectPropertyGetter. bool ScriptController::bindToWindowObject(LocalFrame* frame, const String& key, NPObject* object) { ScriptState* scriptState = ScriptState::forMainWorld(frame); if (!scriptState->contextIsValid()) return false; ScriptState::Scope scope(scriptState); v8::Local<v8::Object> value = createV8ObjectForNPObject(isolate(), object, 0); // Attach to the global object. return v8CallBoolean(scriptState->context()->Global()->Set(scriptState->context(), v8String(isolate(), key), value)); }
static void promiseRejectHandler(v8::PromiseRejectMessage data, RejectedPromises& rejectedPromises, const String& fallbackResourceName) { if (data.GetEvent() == v8::kPromiseHandlerAddedAfterReject) { rejectedPromises.handlerAdded(data); return; } ASSERT(data.GetEvent() == v8::kPromiseRejectWithNoHandler); v8::Local<v8::Promise> promise = data.GetPromise(); v8::Isolate* isolate = promise->GetIsolate(); ScriptState* scriptState = ScriptState::current(isolate); v8::Local<v8::Value> exception = data.GetValue(); if (V8DOMWrapper::isWrapper(isolate, exception)) { // Try to get the stack & location from a wrapped exception object (e.g. DOMException). ASSERT(exception->IsObject()); v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast(exception); v8::Local<v8::Value> error = V8HiddenValue::getHiddenValue(scriptState, obj, V8HiddenValue::error(isolate)); if (!error.IsEmpty()) exception = error; } int scriptId = 0; int lineNumber = 0; int columnNumber = 0; String resourceName = fallbackResourceName; String errorMessage; AccessControlStatus corsStatus = NotSharableCrossOrigin; RefPtrWillBeRawPtr<ScriptCallStack> callStack = nullptr; v8::Local<v8::Message> message = v8::Exception::CreateMessage(isolate, exception); if (!message.IsEmpty()) { V8StringResource<> v8ResourceName(message->GetScriptOrigin().ResourceName()); if (v8ResourceName.prepare()) resourceName = v8ResourceName; scriptId = message->GetScriptOrigin().ScriptID()->Value(); if (v8Call(message->GetLineNumber(scriptState->context()), lineNumber) && v8Call(message->GetStartColumn(scriptState->context()), columnNumber)) ++columnNumber; // message->Get() can be empty here. https://crbug.com/450330 errorMessage = toCoreStringWithNullCheck(message->Get()); callStack = extractCallStack(isolate, message, &scriptId); if (message->IsSharedCrossOrigin()) corsStatus = SharableCrossOrigin; } String messageForConsole = extractMessageForConsole(isolate, data.GetValue()); if (!messageForConsole.isEmpty()) errorMessage = "Uncaught " + messageForConsole; rejectedPromises.rejectedWithNoHandler(scriptState, data, errorMessage, resourceName, scriptId, lineNumber, columnNumber, callStack, corsStatus); }
static void messageHandlerInMainThread(v8::Local<v8::Message> message, v8::Local<v8::Value> data) { ASSERT(isMainThread()); v8::Isolate* isolate = v8::Isolate::GetCurrent(); // If called during context initialization, there will be no entered window. LocalDOMWindow* enteredWindow = enteredDOMWindow(isolate); if (!enteredWindow || !enteredWindow->isCurrentlyDisplayedInFrame()) return; int scriptId = 0; RefPtrWillBeRawPtr<ScriptCallStack> callStack = extractCallStack(isolate, message, &scriptId); String resourceName = extractResourceName(message, enteredWindow->document()); AccessControlStatus accessControlStatus = NotSharableCrossOrigin; if (message->IsOpaque()) accessControlStatus = OpaqueResource; else if (message->IsSharedCrossOrigin()) accessControlStatus = SharableCrossOrigin; ScriptState* scriptState = ScriptState::current(isolate); String errorMessage = toCoreStringWithNullCheck(message->Get()); int lineNumber = 0; int columnNumber = 0; if (v8Call(message->GetLineNumber(scriptState->context()), lineNumber) && v8Call(message->GetStartColumn(scriptState->context()), columnNumber)) ++columnNumber; RefPtrWillBeRawPtr<ErrorEvent> event = ErrorEvent::create(errorMessage, resourceName, lineNumber, columnNumber, &scriptState->world()); String messageForConsole = extractMessageForConsole(isolate, data); if (!messageForConsole.isEmpty()) event->setUnsanitizedMessage("Uncaught " + messageForConsole); // This method might be called while we're creating a new context. In this case, we // avoid storing the exception object, as we can't create a wrapper during context creation. // FIXME: Can we even get here during initialization now that we bail out when GetEntered returns an empty handle? LocalFrame* frame = enteredWindow->document()->frame(); if (frame && frame->script().existingWindowProxy(scriptState->world())) { V8ErrorHandler::storeExceptionOnErrorEventWrapper(isolate, event.get(), data, scriptState->context()->Global()); } if (scriptState->world().isPrivateScriptIsolatedWorld()) { // We allow a private script to dispatch error events even in a EventDispatchForbiddenScope scope. // Without having this ability, it's hard to debug the private script because syntax errors // in the private script are not reported to console (the private script just crashes silently). // Allowing error events in private scripts is safe because error events don't propagate to // other isolated worlds (which means that the error events won't fire any event listeners // in user's scripts). EventDispatchForbiddenScope::AllowUserAgentEvents allowUserAgentEvents; enteredWindow->document()->reportException(event.release(), scriptId, callStack, accessControlStatus); } else { enteredWindow->document()->reportException(event.release(), scriptId, callStack, accessControlStatus); } }
void V8MessageEvent::dataAttributeGetterCustom( const v8::FunctionCallbackInfo<v8::Value>& info) { ScriptState* scriptState = ScriptState::current(info.GetIsolate()); auto privateCachedData = V8PrivateProperty::getMessageEventCachedData(info.GetIsolate()); v8::Local<v8::Value> cachedData = privateCachedData.get(scriptState->context(), info.Holder()); if (!cachedData.IsEmpty()) { v8SetReturnValue(info, cachedData); return; } MessageEvent* event = V8MessageEvent::toImpl(info.Holder()); v8::Local<v8::Value> result; switch (event->getDataType()) { case MessageEvent::DataTypeScriptValue: result = event->dataAsScriptValue().v8ValueFor(scriptState); if (result.IsEmpty()) result = v8::Null(info.GetIsolate()); break; case MessageEvent::DataTypeSerializedScriptValue: if (SerializedScriptValue* serializedValue = event->dataAsSerializedScriptValue()) { MessagePortArray ports = event->ports(); result = serializedValue->deserialize(info.GetIsolate(), &ports); } else { result = v8::Null(info.GetIsolate()); } break; case MessageEvent::DataTypeString: result = v8String(info.GetIsolate(), event->dataAsString()); break; case MessageEvent::DataTypeBlob: result = toV8(event->dataAsBlob(), info.Holder(), info.GetIsolate()); break; case MessageEvent::DataTypeArrayBuffer: result = toV8(event->dataAsArrayBuffer(), info.Holder(), info.GetIsolate()); break; } // Store the result as a private value so this callback returns the cached // result in future invocations. privateCachedData.set(scriptState->context(), info.Holder(), result); v8SetReturnValue(info, result); }
void InspectorAnimationAgent::resolveAnimation(ErrorString* errorString, const String& animationId, RefPtr<TypeBuilder::Runtime::RemoteObject>& result) { Animation* animation = assertAnimation(errorString, animationId); if (!animation) return; if (m_idToAnimationClone.get(animationId)) animation = m_idToAnimationClone.get(animationId); const Element* element = toKeyframeEffect(animation->effect())->target(); Document* document = element->ownerDocument(); LocalFrame* frame = document ? document->frame() : nullptr; if (!frame) { *errorString = "Element not associated with a document."; return; } ScriptState* scriptState = ScriptState::forMainWorld(frame); InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(scriptState); if (injectedScript.isEmpty()) return; ScriptState::Scope scope(scriptState); v8::Isolate* isolate = scriptState->isolate(); ScriptValue scriptValue = ScriptValue(scriptState, toV8(animation, scriptState->context()->Global(), isolate)); injectedScript.releaseObjectGroup("animation"); result = injectedScript.wrapObject(scriptValue, "animation"); }
static void messageHandlerInWorker(v8::Local<v8::Message> message, v8::Local<v8::Value> data) { v8::Isolate* isolate = v8::Isolate::GetCurrent(); V8PerIsolateData* perIsolateData = V8PerIsolateData::from(isolate); // During the frame teardown, there may not be a valid context. ScriptState* scriptState = ScriptState::current(isolate); if (!scriptState->contextIsValid()) return; // Exceptions that occur in error handler should be ignored since in that case // WorkerGlobalScope::reportException will send the exception to the worker object. if (perIsolateData->isReportingException()) return; perIsolateData->setReportingException(true); ExecutionContext* context = scriptState->getExecutionContext(); std::unique_ptr<SourceLocation> location = SourceLocation::fromMessage(isolate, message, context); ErrorEvent* event = ErrorEvent::create(toCoreStringWithNullCheck(message->Get()), std::move(location), &scriptState->world()); AccessControlStatus corsStatus = message->IsSharedCrossOrigin() ? SharableCrossOrigin : NotSharableCrossOrigin; // If execution termination has been triggered as part of constructing // the error event from the v8::Message, quietly leave. if (!isolate->IsExecutionTerminating()) { V8ErrorHandler::storeExceptionOnErrorEventWrapper(scriptState, event, data, scriptState->context()->Global()); scriptState->getExecutionContext()->reportException(event, corsStatus); } perIsolateData->setReportingException(false); }
void WebDevToolsFrontendImpl::didClearWindowObject(WebLocalFrameImpl* frame) { if (m_webFrame == frame) { v8::Isolate* isolate = v8::Isolate::GetCurrent(); ScriptState* scriptState = ScriptState::forMainWorld(m_webFrame->frame()); ScriptState::Scope scope(scriptState); if (m_devtoolsHost) m_devtoolsHost->disconnectClient(); m_devtoolsHost = DevToolsHost::create(this, m_webFrame->frame()); v8::Local<v8::Object> global = scriptState->context()->Global(); v8::Local<v8::Value> devtoolsHostObj = toV8(m_devtoolsHost.get(), global, scriptState->isolate()); ASSERT(!devtoolsHostObj.IsEmpty()); global->Set(v8AtomicString(isolate, "DevToolsHost"), devtoolsHostObj); } if (m_injectedScriptForOrigin.isEmpty()) return; String origin = frame->securityOrigin().toString(); String script = m_injectedScriptForOrigin.get(origin); if (script.isEmpty()) return; static int s_lastScriptId = 0; StringBuilder scriptWithId; scriptWithId.append(script); scriptWithId.append('('); scriptWithId.appendNumber(++s_lastScriptId); scriptWithId.append(')'); frame->frame()->script().executeScriptInMainWorld(scriptWithId.toString()); }
static void messageHandlerInMainThread(v8::Local<v8::Message> message, v8::Local<v8::Value> data) { ASSERT(isMainThread()); v8::Isolate* isolate = v8::Isolate::GetCurrent(); if (isolate->GetEnteredContext().IsEmpty()) return; // If called during context initialization, there will be no entered context. ScriptState* scriptState = ScriptState::current(isolate); if (!scriptState->contextIsValid()) return; ExecutionContext* context = scriptState->getExecutionContext(); std::unique_ptr<SourceLocation> location = SourceLocation::fromMessage(isolate, message, context); AccessControlStatus accessControlStatus = NotSharableCrossOrigin; if (message->IsOpaque()) accessControlStatus = OpaqueResource; else if (message->IsSharedCrossOrigin()) accessControlStatus = SharableCrossOrigin; ErrorEvent* event = ErrorEvent::create(toCoreStringWithNullCheck(message->Get()), std::move(location), &scriptState->world()); String messageForConsole = extractMessageForConsole(isolate, data); if (!messageForConsole.isEmpty()) event->setUnsanitizedMessage("Uncaught " + messageForConsole); // This method might be called while we're creating a new context. In this // case, we avoid storing the exception object, as we can't create a wrapper // during context creation. // FIXME: Can we even get here during initialization now that we bail out when // GetEntered returns an empty handle? if (context->isDocument()) { LocalFrame* frame = toDocument(context)->frame(); if (frame && frame->script().existingWindowProxy(scriptState->world())) { V8ErrorHandler::storeExceptionOnErrorEventWrapper( scriptState, event, data, scriptState->context()->Global()); } } if (scriptState->world().isPrivateScriptIsolatedWorld()) { // We allow a private script to dispatch error events even in a // EventDispatchForbiddenScope scope. Without having this ability, it's // hard to debug the private script because syntax errors in the private // script are not reported to console (the private script just crashes // silently). Allowing error events in private scripts is safe because // error events don't propagate to other isolated worlds (which means that // the error events won't fire any event listeners in user's scripts). EventDispatchForbiddenScope::AllowUserAgentEvents allowUserAgentEvents; context->dispatchErrorEvent(event, accessControlStatus); } else { context->dispatchErrorEvent(event, accessControlStatus); } }
static void messageHandlerInMainThread(v8::Handle<v8::Message> message, v8::Handle<v8::Value> data) { ASSERT(isMainThread()); // It's possible that messageHandlerInMainThread() is invoked while we're initializing a window. // In that half-baked situation, we don't have a valid context nor a valid world, // so just return immediately. if (DOMWrapperWorld::windowIsBeingInitialized()) return; v8::Isolate* isolate = v8::Isolate::GetCurrent(); // If called during context initialization, there will be no entered window. LocalDOMWindow* enteredWindow = enteredDOMWindow(isolate); if (!enteredWindow) return; String errorMessage = toCoreString(message->Get()); v8::Handle<v8::StackTrace> stackTrace = message->GetStackTrace(); RefPtr<ScriptCallStack> callStack = nullptr; int scriptId = message->GetScriptOrigin().ScriptID()->Value(); // Currently stack trace is only collected when inspector is open. if (!stackTrace.IsEmpty() && stackTrace->GetFrameCount() > 0) { callStack = createScriptCallStack(stackTrace, ScriptCallStack::maxCallStackSizeToCapture, isolate); bool success = false; int topScriptId = callStack->at(0).scriptId().toInt(&success); if (success && topScriptId == scriptId) scriptId = 0; } else { Vector<ScriptCallFrame> callFrames; callStack = ScriptCallStack::create(callFrames); } v8::Handle<v8::Value> resourceName = message->GetScriptOrigin().ResourceName(); bool shouldUseDocumentURL = resourceName.IsEmpty() || !resourceName->IsString(); String resource = shouldUseDocumentURL ? enteredWindow->document()->url() : toCoreString(resourceName.As<v8::String>()); ScriptState* scriptState = ScriptState::current(isolate); RefPtr<ErrorEvent> event = ErrorEvent::create(errorMessage, resource, message->GetLineNumber(), message->GetStartColumn() + 1, &scriptState->world()); if (V8DOMWrapper::isDOMWrapper(data)) { v8::Handle<v8::Object> obj = v8::Handle<v8::Object>::Cast(data); const WrapperTypeInfo* type = toWrapperTypeInfo(obj); if (V8DOMException::wrapperTypeInfo.isSubclass(type)) { DOMException* exception = V8DOMException::toNative(obj); if (exception && !exception->messageForConsole().isEmpty()) event->setUnsanitizedMessage("Uncaught " + exception->toStringForConsole()); } } // This method might be called while we're creating a new context. In this case, we // avoid storing the exception object, as we can't create a wrapper during context creation. // FIXME: Can we even get here during initialization now that we bail out when GetEntered returns an empty handle? LocalFrame* frame = enteredWindow->document()->frame(); if (frame && frame->script().existingWindowProxy(scriptState->world())) { V8ErrorHandler::storeExceptionOnErrorEventWrapper(event.get(), data, scriptState->context()->Global(), isolate); } enteredWindow->document()->reportException(event.release(), scriptId, callStack); }
void injectInternalsObject(v8::Local<v8::Context> context) { ScriptState* scriptState = ScriptState::from(context); ScriptState::Scope scope(scriptState); v8::Handle<v8::Object> global = scriptState->context()->Global(); ExecutionContext* executionContext = scriptState->executionContext(); if (executionContext->isDocument()) global->Set(v8::String::NewFromUtf8(scriptState->isolate(), Internals::internalsId), toV8(Internals::create(toDocument(executionContext)), global, scriptState->isolate())); }
static void promiseRejectHandlerInWorker(v8::PromiseRejectMessage data) { v8::Local<v8::Promise> promise = data.GetPromise(); // Bail out if called during context initialization. v8::Isolate* isolate = promise->GetIsolate(); ScriptState* scriptState = ScriptState::current(isolate); if (!scriptState->contextIsValid()) return; ExecutionContext* executionContext = scriptState->executionContext(); if (!executionContext) return; ASSERT(executionContext->isWorkerGlobalScope()); WorkerScriptController* scriptController = toWorkerGlobalScope(executionContext)->script(); ASSERT(scriptController); if (data.GetEvent() == v8::kPromiseHandlerAddedAfterReject) { scriptController->rejectedPromises()->handlerAdded(data); return; } ASSERT(data.GetEvent() == v8::kPromiseRejectWithNoHandler); int scriptId = 0; int lineNumber = 0; int columnNumber = 0; String resourceName; String errorMessage; v8::Local<v8::Message> message = v8::Exception::CreateMessage(data.GetValue()); if (!message.IsEmpty()) { TOSTRING_VOID(V8StringResource<>, resourceName, message->GetScriptOrigin().ResourceName()); scriptId = message->GetScriptOrigin().ScriptID()->Value(); if (v8Call(message->GetLineNumber(scriptState->context()), lineNumber) && v8Call(message->GetStartColumn(scriptState->context()), columnNumber)) ++columnNumber; // message->Get() can be empty here. https://crbug.com/450330 errorMessage = toCoreStringWithNullCheck(message->Get()); } scriptController->rejectedPromises()->rejectedWithNoHandler(scriptState, data, errorMessage, resourceName, scriptId, lineNumber, columnNumber, nullptr); }
void MainThreadDebugger::exceptionThrown(ExecutionContext* context, ErrorEvent* event) { LocalFrame* frame = nullptr; ScriptState* scriptState = nullptr; if (context->isDocument()) { frame = toDocument(context)->frame(); if (!frame) return; scriptState = event->world() ? ScriptState::forWorld(frame, *event->world()) : nullptr; } else if (context->isMainThreadWorkletGlobalScope()) { frame = toMainThreadWorkletGlobalScope(context)->frame(); if (!frame) return; scriptState = toMainThreadWorkletGlobalScope(context) ->scriptController() ->getScriptState(); } else { NOTREACHED(); } frame->console().reportMessageToClient(JSMessageSource, ErrorMessageLevel, event->messageForConsole(), event->location()); const String defaultMessage = "Uncaught"; if (scriptState && scriptState->contextIsValid()) { ScriptState::Scope scope(scriptState); v8::Local<v8::Value> exception = V8ErrorHandler::loadExceptionFromErrorEventWrapper( scriptState, event, scriptState->context()->Global()); SourceLocation* location = event->location(); String message = event->messageForConsole(); String url = location->url(); v8Inspector()->exceptionThrown( scriptState->context(), toV8InspectorStringView(defaultMessage), exception, toV8InspectorStringView(message), toV8InspectorStringView(url), location->lineNumber(), location->columnNumber(), location->takeStackTrace(), location->scriptId()); } }
void V8HTMLElement::HTMLConstructor( const v8::FunctionCallbackInfo<v8::Value>& info) { DCHECK(info.IsConstructCall()); v8::Isolate* isolate = info.GetIsolate(); ScriptState* scriptState = ScriptState::current(isolate); if (!RuntimeEnabledFeatures::customElementsV1Enabled() || !scriptState->world().isMainWorld()) { V8ThrowException::throwTypeError(info.GetIsolate(), "Illegal constructor"); return; } LocalDOMWindow* window = scriptState->domWindow(); ScriptCustomElementDefinition* definition = ScriptCustomElementDefinition::forConstructor( scriptState, window->customElements(), info.NewTarget()); if (!definition) { V8ThrowException::throwTypeError(isolate, "Illegal constructor"); return; } ExceptionState exceptionState(ExceptionState::ConstructionContext, "HTMLElement", info.Holder(), isolate); Element* element; if (definition->constructionStack().isEmpty()) { // This is an element being created with 'new' from script element = definition->createElementForConstructor(*window->document()); } else { element = definition->constructionStack().last(); if (element) { // This is an element being upgraded that has called super definition->constructionStack().last().clear(); } else { // During upgrade an element has invoked the same constructor // before calling 'super' and that invocation has poached the // element. exceptionState.throwDOMException(InvalidStateError, "this instance is already constructed"); return; } } const WrapperTypeInfo* wrapperType = element->wrapperTypeInfo(); v8::Local<v8::Object> wrapper = V8DOMWrapper::associateObjectWithWrapper( isolate, element, wrapperType, info.Holder()); // If the element had a wrapper, we now update and return that // instead. v8SetReturnValue(info, wrapper); wrapper->SetPrototype(scriptState->context(), definition->prototype()) .ToChecked(); }
// Create a V8 object with an interceptor of NPObjectPropertyGetter. void ScriptController::bindToWindowObject(LocalFrame* frame, const String& key, NPObject* object) { ScriptState* scriptState = ScriptState::forMainWorld(frame); if (!scriptState->contextIsValid()) return; ScriptState::Scope scope(scriptState); v8::Handle<v8::Object> value = createV8ObjectForNPObject(m_isolate, object, 0); // Attach to the global object. scriptState->context()->Global()->Set(v8String(m_isolate, key), value); }
static void messageHandlerInWorker(v8::Local<v8::Message> message, v8::Local<v8::Value> data) { v8::Isolate* isolate = v8::Isolate::GetCurrent(); V8PerIsolateData* perIsolateData = V8PerIsolateData::from(isolate); // Exceptions that occur in error handler should be ignored since in that case // WorkerGlobalScope::reportException will send the exception to the worker object. if (perIsolateData->isReportingException()) return; perIsolateData->setReportingException(true); ScriptState* scriptState = ScriptState::current(isolate); // During the frame teardown, there may not be a valid context. if (ExecutionContext* context = scriptState->executionContext()) { String errorMessage = toCoreStringWithNullCheck(message->Get()); TOSTRING_VOID(V8StringResource<>, sourceURL, message->GetScriptOrigin().ResourceName()); int scriptId = 0; RefPtrWillBeRawPtr<ScriptCallStack> callStack = extractCallStack(isolate, message, &scriptId); int lineNumber = 0; int columnNumber = 0; if (v8Call(message->GetLineNumber(scriptState->context()), lineNumber) && v8Call(message->GetStartColumn(scriptState->context()), columnNumber)) ++columnNumber; RefPtrWillBeRawPtr<ErrorEvent> event = ErrorEvent::create(errorMessage, sourceURL, lineNumber, columnNumber, &DOMWrapperWorld::current(isolate)); AccessControlStatus corsStatus = message->IsSharedCrossOrigin() ? SharableCrossOrigin : NotSharableCrossOrigin; // If execution termination has been triggered as part of constructing // the error event from the v8::Message, quietly leave. if (!v8::V8::IsExecutionTerminating(isolate)) { V8ErrorHandler::storeExceptionOnErrorEventWrapper(isolate, event.get(), data, scriptState->context()->Global()); context->reportException(event.release(), scriptId, callStack, corsStatus); } } perIsolateData->setReportingException(false); }
void AcceptConnectionObserver::responseWasResolved(const ScriptValue& value) { ASSERT(executionContext()); if (!m_resolver) { // TODO(mek): Get rid of this block when observer is only used for // service port connect events. if (!value.v8Value()->IsTrue()) { responseWasRejected(); return; } ServiceWorkerGlobalScopeClient::from(executionContext())->didHandleCrossOriginConnectEvent(m_eventID, true); m_state = Done; return; } ScriptState* scriptState = m_resolver->scriptState(); ExceptionState exceptionState(ExceptionState::UnknownContext, nullptr, nullptr, scriptState->context()->Global(), scriptState->isolate()); ServicePortConnectResponse response = ScriptValue::to<ServicePortConnectResponse>(scriptState->isolate(), value, exceptionState); if (exceptionState.hadException()) { exceptionState.reject(m_resolver.get()); m_resolver = nullptr; responseWasRejected(); return; } if (!response.hasAccept() || !response.accept()) { responseWasRejected(); return; } WebServicePort webPort; webPort.targetUrl = m_targetURL; if (response.hasName()) webPort.name = response.name(); if (response.hasData()) { webPort.data = SerializedScriptValueFactory::instance().create(scriptState->isolate(), response.data(), nullptr, exceptionState)->toWireString(); if (exceptionState.hadException()) { exceptionState.reject(m_resolver.get()); m_resolver = nullptr; responseWasRejected(); return; } } webPort.id = m_portID; ServicePort* port = ServicePort::create(m_collection, webPort); m_collection->addPort(port); m_resolver->resolve(port); m_callbacks->onSuccess(&webPort); m_state = Done; }
WebDevToolsFrontendImpl::~WebDevToolsFrontendImpl() { if (m_devtoolsHost) m_devtoolsHost->disconnectClient(); if (!m_devtoolsHost || !m_webFrame) return; v8::Isolate* isolate = v8::Isolate::GetCurrent(); ScriptState* scriptState = ScriptState::forMainWorld(m_webFrame->frame()); ScriptState::Scope scope(scriptState); v8::Local<v8::Object> global = scriptState->context()->Global(); global->Delete(v8AtomicString(isolate, "DevToolsHost")); m_devtoolsHost = nullptr; }
bool _NPN_EvaluateHelper(NPP npp, bool popupsAllowed, NPObject* npObject, NPString* npScript, NPVariant* result) { ScriptForbiddenScope::AllowSuperUnsafeScript thisShouldBeRemoved; VOID_TO_NPVARIANT(*result); if (!npObject) return false; V8NPObject* v8NpObject = npObjectToV8NPObject(npObject); if (!v8NpObject) return false; v8::Isolate* isolate = v8::Isolate::GetCurrent(); ScriptState* scriptState = mainWorldScriptState(isolate, npp, npObject); if (!scriptState) return false; ScriptState::Scope scope(scriptState); ExceptionCatcher exceptionCatcher; // FIXME: Is this branch still needed after switching to using UserGestureIndicator? String filename; if (!popupsAllowed) filename = "npscript"; LocalFrame* frame = v8NpObject->rootObject->frame(); ASSERT(frame); String script = String::fromUTF8(npScript->UTF8Characters, npScript->UTF8Length); UserGestureIndicator gestureIndicator(popupsAllowed ? DefinitelyProcessingNewUserGesture : PossiblyProcessingUserGesture); v8::Local<v8::Value> v8result = frame->script().executeScriptAndReturnValue(scriptState->context(), ScriptSourceCode(script, KURL(ParsedURLString, filename))); if (v8result.IsEmpty()) return false; if (_NPN_IsAlive(npObject)) convertV8ObjectToNPVariant(v8result, npObject, result, isolate); return true; }
ScriptObject InjectedScriptManager::injectWebGLScript(const String& scriptSource, const ScriptObject& glContext) { v8::HandleScope scope; ScriptState* inspectedScriptState = glContext.scriptState(); v8::Local<v8::Context> inspectedContext = inspectedScriptState->context(); v8::Context::Scope contextScope(inspectedContext); v8::Local<v8::Object> windowGlobal = inspectedContext->Global(); v8::Local<v8::Script> script = v8::Script::Compile(v8String(scriptSource)); V8RecursionScope::MicrotaskSuppression recursionScope; v8::Local<v8::Value> v = script->Run(); ASSERT(!v.IsEmpty()); ASSERT(v->IsFunction()); v8::Handle<v8::Value> args[] = { glContext.v8Value(), }; v8::Local<v8::Value> injectedScriptValue = v8::Function::Cast(*v)->Call(windowGlobal, 1, args); return ScriptObject(inspectedScriptState, v8::Handle<v8::Object>::Cast(injectedScriptValue)); }
void V8LazyEventListener::prepareListenerObject(ExecutionContext* executionContext) { if (!executionContext) return; // A ScriptState used by the event listener needs to be calculated based on // the ExecutionContext that fired the the event listener and the world // that installed the event listener. v8::HandleScope handleScope(toIsolate(executionContext)); v8::Local<v8::Context> v8Context = toV8Context(executionContext, world()); if (v8Context.IsEmpty()) return; ScriptState* scriptState = ScriptState::from(v8Context); if (!scriptState->contextIsValid()) return; if (!executionContext->isDocument()) return; if (!toDocument(executionContext)->allowInlineEventHandlers(m_node, this, m_sourceURL, m_position.m_line)) { clearListenerObject(); return; } if (hasExistingListenerObject()) return; ScriptState::Scope scope(scriptState); // FIXME: Remove the following 'with' hack. // // Nodes other than the document object, when executing inline event // handlers push document, form owner, and the target node on the scope chain. // We do this by using 'with' statement. // See chrome/fast/forms/form-action.html // chrome/fast/forms/selected-index-value.html // base/fast/overflow/onscroll-layer-self-destruct.html // // Don't use new lines so that lines in the modified handler // have the same numbers as in the original code. // FIXME: V8 does not allow us to programmatically create object environments so // we have to do this hack! What if m_code escapes to run arbitrary script? // // Call with 4 arguments instead of 3, pass additional null as the last parameter. // By calling the function with 4 arguments, we create a setter on arguments object // which would shadow property "3" on the prototype. String code = "(function() {" "with (this[2]) {" "with (this[1]) {" "with (this[0]) {" "return function(" + m_eventParameterName + ") {" + m_code + "\n" // Insert '\n' otherwise //-style comments could break the handler. "};" "}}}})"; v8::Local<v8::String> codeExternalString = v8String(isolate(), code); v8::Local<v8::Value> result; if (!V8ScriptRunner::compileAndRunInternalScript(codeExternalString, isolate(), m_sourceURL, m_position).ToLocal(&result)) return; // Call the outer function to get the inner function. if (!result->IsFunction()) return; v8::Local<v8::Function> intermediateFunction = result.As<v8::Function>(); HTMLFormElement* formElement = 0; if (m_node && m_node->isHTMLElement()) formElement = toHTMLElement(m_node)->formOwner(); v8::Local<v8::Object> nodeWrapper = toObjectWrapper<Node>(m_node, scriptState); v8::Local<v8::Object> formWrapper = toObjectWrapper<HTMLFormElement>(formElement, scriptState); v8::Local<v8::Object> documentWrapper = toObjectWrapper<Document>(m_node ? m_node->ownerDocument() : 0, scriptState); v8::Local<v8::Object> thisObject = v8::Object::New(isolate()); if (thisObject.IsEmpty()) return; if (!v8CallBoolean(thisObject->ForceSet(scriptState->context(), v8::Integer::New(isolate(), 0), nodeWrapper))) return; if (!v8CallBoolean(thisObject->ForceSet(scriptState->context(), v8::Integer::New(isolate(), 1), formWrapper))) return; if (!v8CallBoolean(thisObject->ForceSet(scriptState->context(), v8::Integer::New(isolate(), 2), documentWrapper))) return; // FIXME: Remove this code when we stop doing the 'with' hack above. v8::Local<v8::Value> innerValue; if (!V8ScriptRunner::callInternalFunction(intermediateFunction, thisObject, 0, 0, isolate()).ToLocal(&innerValue) || !innerValue->IsFunction()) return; v8::Local<v8::Function> wrappedFunction = innerValue.As<v8::Function>(); // Change the toString function on the wrapper function to avoid it // returning the source for the actual wrapper function. Instead it // returns source for a clean wrapper function with the event // argument wrapping the event source code. The reason for this is // that some web sites use toString on event functions and eval the // source returned (sometimes a RegExp is applied as well) for some // other use. That fails miserably if the actual wrapper source is // returned. v8::Local<v8::Function> toStringFunction = v8::Function::New(isolate(), V8LazyEventListenerToString); if (toStringFunction.IsEmpty()) return; String toStringString = "function " + m_functionName + "(" + m_eventParameterName + ") {\n " + m_code + "\n}"; V8HiddenValue::setHiddenValue(isolate(), wrappedFunction, V8HiddenValue::toStringString(isolate()), v8String(isolate(), toStringString)); if (!v8CallBoolean(wrappedFunction->Set(scriptState->context(), v8AtomicString(isolate(), "toString"), toStringFunction))) return; wrappedFunction->SetName(v8String(isolate(), m_functionName)); // FIXME: Remove the following comment-outs. // See https://bugs.webkit.org/show_bug.cgi?id=85152 for more details. // // For the time being, we comment out the following code since the // second parsing can happen. // // Since we only parse once, there's no need to keep data used for parsing around anymore. // m_functionName = String(); // m_code = String(); // m_eventParameterName = String(); // m_sourceURL = String(); setListenerObject(wrappedFunction); }
// https://html.spec.whatwg.org/multipage/dom.html#html-element-constructors void V8HTMLConstructor::htmlConstructor( const v8::FunctionCallbackInfo<v8::Value>& info, const WrapperTypeInfo& wrapperTypeInfo, const HTMLElementType elementInterfaceName) { TRACE_EVENT0("blink", "HTMLConstructor"); DCHECK(info.IsConstructCall()); v8::Isolate* isolate = info.GetIsolate(); ScriptState* scriptState = ScriptState::current(isolate); v8::Local<v8::Value> newTarget = info.NewTarget(); if (!scriptState->contextIsValid()) { V8ThrowException::throwError(isolate, "The context has been destroyed"); return; } if (!RuntimeEnabledFeatures::customElementsV1Enabled() || !scriptState->world().isMainWorld()) { V8ThrowException::throwTypeError(isolate, "Illegal constructor"); return; } // 2. If NewTarget is equal to the active function object, then // throw a TypeError and abort these steps. v8::Local<v8::Function> activeFunctionObject = scriptState->perContextData()->constructorForType( &V8HTMLElement::wrapperTypeInfo); if (newTarget == activeFunctionObject) { V8ThrowException::throwTypeError(isolate, "Illegal constructor"); return; } LocalDOMWindow* window = scriptState->domWindow(); CustomElementRegistry* registry = window->customElements(); // 3. Let definition be the entry in registry with constructor equal to // NewTarget. // If there is no such definition, then throw a TypeError and abort these // steps. ScriptCustomElementDefinition* definition = ScriptCustomElementDefinition::forConstructor(scriptState, registry, newTarget); if (!definition) { V8ThrowException::throwTypeError(isolate, "Illegal constructor"); return; } const AtomicString& localName = definition->descriptor().localName(); const AtomicString& name = definition->descriptor().name(); if (localName == name) { // Autonomous custom element // 4.1. If the active function object is not HTMLElement, then throw a // TypeError if (!V8HTMLElement::wrapperTypeInfo.equals(&wrapperTypeInfo)) { V8ThrowException::throwTypeError(isolate, "Illegal constructor: autonomous custom " "elements must extend HTMLElement"); return; } } else { // Customized built-in element // 5. If local name is not valid for interface, throw TypeError if (htmlElementTypeForTag(localName) != elementInterfaceName) { V8ThrowException::throwTypeError(isolate, "Illegal constructor: localName does " "not match the HTML element interface"); return; } } ExceptionState exceptionState(isolate, ExceptionState::ConstructionContext, "HTMLElement"); v8::TryCatch tryCatch(isolate); // 6. Let prototype be Get(NewTarget, "prototype"). Rethrow any exceptions. v8::Local<v8::Value> prototype; v8::Local<v8::String> prototypeString = v8AtomicString(isolate, "prototype"); if (!v8Call(newTarget.As<v8::Object>()->Get(scriptState->context(), prototypeString), prototype)) { return; } // 7. If Type(prototype) is not Object, then: ... if (!prototype->IsObject()) { if (V8PerContextData* perContextData = V8PerContextData::from( newTarget.As<v8::Object>()->CreationContext())) { prototype = perContextData->prototypeForType(&V8HTMLElement::wrapperTypeInfo); } else { V8ThrowException::throwError(isolate, "The context has been destroyed"); return; } } // 8. If definition's construction stack is empty... Element* element; if (definition->constructionStack().isEmpty()) { // This is an element being created with 'new' from script element = definition->createElementForConstructor(*window->document()); } else { element = definition->constructionStack().last(); if (element) { // This is an element being upgraded that has called super definition->constructionStack().last().clear(); } else { // During upgrade an element has invoked the same constructor // before calling 'super' and that invocation has poached the // element. exceptionState.throwDOMException(InvalidStateError, "this instance is already constructed"); return; } } const WrapperTypeInfo* wrapperType = element->wrapperTypeInfo(); v8::Local<v8::Object> wrapper = V8DOMWrapper::associateObjectWithWrapper( isolate, element, wrapperType, info.Holder()); // If the element had a wrapper, we now update and return that // instead. v8SetReturnValue(info, wrapper); // 11. Perform element.[[SetPrototypeOf]](prototype). Rethrow any exceptions. // Note: I don't think this prototype set *can* throw exceptions. wrapper->SetPrototype(scriptState->context(), prototype.As<v8::Object>()) .ToChecked(); }
v8::Local<v8::Context> MainThreadDebugger::ensureDefaultContextInGroup( int contextGroupId) { LocalFrame* frame = WeakIdentifierMap<LocalFrame>::lookup(contextGroupId); ScriptState* scriptState = frame ? ScriptState::forMainWorld(frame) : nullptr; return scriptState ? scriptState->context() : v8::Local<v8::Context>(); }
Page* InspectorOverlay::overlayPage() { if (m_overlayPage) return m_overlayPage.get(); ScriptForbiddenScope::AllowUserAgentScript allowScript; DEFINE_STATIC_LOCAL(FrameLoaderClient, dummyFrameLoaderClient, (EmptyFrameLoaderClient::create())); Page::PageClients pageClients; fillWithEmptyClients(pageClients); DCHECK(!m_overlayChromeClient); m_overlayChromeClient = InspectorOverlayChromeClient::create( m_frameImpl->frame()->host()->chromeClient(), *this); pageClients.chromeClient = m_overlayChromeClient.get(); m_overlayPage = Page::create(pageClients); Settings& settings = m_frameImpl->frame()->host()->settings(); Settings& overlaySettings = m_overlayPage->settings(); overlaySettings.genericFontFamilySettings().updateStandard( settings.genericFontFamilySettings().standard()); overlaySettings.genericFontFamilySettings().updateSerif( settings.genericFontFamilySettings().serif()); overlaySettings.genericFontFamilySettings().updateSansSerif( settings.genericFontFamilySettings().sansSerif()); overlaySettings.genericFontFamilySettings().updateCursive( settings.genericFontFamilySettings().cursive()); overlaySettings.genericFontFamilySettings().updateFantasy( settings.genericFontFamilySettings().fantasy()); overlaySettings.genericFontFamilySettings().updatePictograph( settings.genericFontFamilySettings().pictograph()); overlaySettings.setMinimumFontSize(settings.minimumFontSize()); overlaySettings.setMinimumLogicalFontSize(settings.minimumLogicalFontSize()); overlaySettings.setScriptEnabled(true); overlaySettings.setPluginsEnabled(false); overlaySettings.setLoadsImagesAutomatically(true); // FIXME: http://crbug.com/363843. Inspector should probably create its // own graphics layers and attach them to the tree rather than going // through some non-composited paint function. overlaySettings.setAcceleratedCompositingEnabled(false); LocalFrame* frame = LocalFrame::create(&dummyFrameLoaderClient, &m_overlayPage->frameHost(), 0); frame->setView(FrameView::create(*frame)); frame->init(); FrameLoader& loader = frame->loader(); frame->view()->setCanHaveScrollbars(false); frame->view()->setTransparent(true); const WebData& overlayPageHTMLResource = Platform::current()->loadResource("InspectorOverlayPage.html"); RefPtr<SharedBuffer> data = SharedBuffer::create( overlayPageHTMLResource.data(), overlayPageHTMLResource.size()); loader.load(FrameLoadRequest( 0, blankURL(), SubstituteData(data, "text/html", "UTF-8", KURL(), ForceSynchronousLoad))); v8::Isolate* isolate = toIsolate(frame); ScriptState* scriptState = ScriptState::forMainWorld(frame); DCHECK(scriptState); ScriptState::Scope scope(scriptState); v8::Local<v8::Object> global = scriptState->context()->Global(); v8::Local<v8::Value> overlayHostObj = toV8(m_overlayHost.get(), global, isolate); DCHECK(!overlayHostObj.IsEmpty()); global ->Set(scriptState->context(), v8AtomicString(isolate, "InspectorOverlayHost"), overlayHostObj) .ToChecked(); #if OS(WIN) evaluateInOverlay("setPlatform", "windows"); #elif OS(MACOSX) evaluateInOverlay("setPlatform", "mac"); #elif OS(POSIX) evaluateInOverlay("setPlatform", "linux"); #endif return m_overlayPage.get(); }
void V8LazyEventListener::prepareListenerObject(ExecutionContext* executionContext) { if (!executionContext) return; // A ScriptState used by the event listener needs to be calculated based on // the ExecutionContext that fired the the event listener and the world // that installed the event listener. v8::HandleScope handleScope(toIsolate(executionContext)); v8::Local<v8::Context> v8Context = toV8Context(executionContext, world()); if (v8Context.IsEmpty()) return; ScriptState* scriptState = ScriptState::from(v8Context); if (!scriptState->contextIsValid()) return; if (!executionContext->isDocument()) return; if (!toDocument(executionContext)->allowInlineEventHandlers(m_node, this, m_sourceURL, m_position.m_line)) { clearListenerObject(); return; } if (hasExistingListenerObject()) return; ScriptState::Scope scope(scriptState); // Nodes other than the document object, when executing inline event // handlers push document, form owner, and the target node on the scope chain. // We do this by using 'with' statement. // See fast/forms/form-action.html // fast/forms/selected-index-value.html // fast/overflow/onscroll-layer-self-destruct.html HTMLFormElement* formElement = 0; if (m_node && m_node->isHTMLElement()) formElement = toHTMLElement(m_node)->formOwner(); v8::Local<v8::Object> scopes[3]; scopes[2] = toObjectWrapper<Node>(m_node, scriptState); scopes[1] = toObjectWrapper<HTMLFormElement>(formElement, scriptState); scopes[0] = toObjectWrapper<Document>(m_node ? m_node->ownerDocument() : 0, scriptState); v8::Local<v8::String> parameterName = v8String(isolate(), m_eventParameterName); v8::ScriptOrigin origin( v8String(isolate(), m_sourceURL), v8::Integer::New(isolate(), m_position.m_line.zeroBasedInt()), v8::Integer::New(isolate(), m_position.m_column.zeroBasedInt()), v8::True(isolate()), v8::Local<v8::Integer>(), v8::True(isolate())); v8::ScriptCompiler::Source source(v8String(isolate(), m_code), origin); v8::Local<v8::Function> wrappedFunction; { // JavaScript compilation error shouldn't be reported as a runtime // exception because we're not running any program code. Instead, // it should be reported as an ErrorEvent. v8::TryCatch block(isolate()); wrappedFunction = v8::ScriptCompiler::CompileFunctionInContext(isolate(), &source, v8Context, 1, ¶meterName, 3, scopes); if (block.HasCaught()) { fireErrorEvent(v8Context, executionContext, block.Message()); return; } } // Change the toString function on the wrapper function to avoid it // returning the source for the actual wrapper function. Instead it // returns source for a clean wrapper function with the event // argument wrapping the event source code. The reason for this is // that some web sites use toString on event functions and eval the // source returned (sometimes a RegExp is applied as well) for some // other use. That fails miserably if the actual wrapper source is // returned. v8::Local<v8::Function> toStringFunction = v8::Function::New(isolate(), V8LazyEventListenerToString); if (toStringFunction.IsEmpty()) return; String toStringString = "function " + m_functionName + "(" + m_eventParameterName + ") {\n " + m_code + "\n}"; V8HiddenValue::setHiddenValue(scriptState, wrappedFunction, V8HiddenValue::toStringString(isolate()), v8String(isolate(), toStringString)); if (!v8CallBoolean(wrappedFunction->Set(scriptState->context(), v8AtomicString(isolate(), "toString"), toStringFunction))) return; wrappedFunction->SetName(v8String(isolate(), m_functionName)); // FIXME: Remove the following comment-outs. // See https://bugs.webkit.org/show_bug.cgi?id=85152 for more details. // // For the time being, we comment out the following code since the // second parsing can happen. // // Since we only parse once, there's no need to keep data used for parsing around anymore. // m_functionName = String(); // m_code = String(); // m_eventParameterName = String(); // m_sourceURL = String(); setListenerObject(wrappedFunction, scriptState); }
void WebDevToolsFrontendImpl::windowObjectCleared() { v8::Isolate* isolate = v8::Isolate::GetCurrent(); Page* page = m_webViewImpl->page(); ASSERT(page->mainFrame()); ScriptState* scriptState = ScriptState::forMainWorld(page->deprecatedLocalMainFrame()); ScriptState::Scope scope(scriptState); if (m_frontendHost) m_frontendHost->disconnectClient(); m_frontendHost = InspectorFrontendHost::create(this, page); v8::Handle<v8::Object> global = scriptState->context()->Global(); v8::Handle<v8::Value> frontendHostObj = toV8(m_frontendHost.get(), global, scriptState->isolate()); global->Set(v8::String::NewFromUtf8(isolate, "InspectorFrontendHost"), frontendHostObj); ScriptController* scriptController = page->mainFrame() ? &page->deprecatedLocalMainFrame()->script() : 0; if (scriptController) { String installAdditionalAPI = "" // Wrap messages that go to embedder. "(function(host, methodEntries) {" " host._lastCallId = 0;" " host._callbacks = [];" " host.embedderMessageAck = function(id, error)" " {" " var callback = host._callbacks[id];" " delete host._callbacks[id];" " if (callback)" " callback(error);" " };" " function dispatch(methodName, argumentCount)" " {" " var callId = ++host._lastCallId;" " var argsArray = Array.prototype.slice.call(arguments, 2);" " var callback = argsArray[argsArray.length - 1];" " if (typeof callback === \"function\") {" " argsArray.pop();" " host._callbacks[callId] = callback;" " }" " var message = { \"id\": callId, \"method\": methodName };" " argsArray = argsArray.slice(0, argumentCount);" " if (argsArray.length)" " message.params = argsArray;" " host.sendMessageToEmbedder(JSON.stringify(message));" " };" " methodEntries.forEach(function(methodEntry) { host[methodEntry[0]] = dispatch.bind(null, methodEntry[0], methodEntry[1]); });" "})(InspectorFrontendHost," " [['addFileSystem', 0]," " ['append', 2]," " ['bringToFront', 0]," " ['closeWindow', 0]," " ['indexPath', 2]," " ['inspectElementCompleted', 0]," " ['inspectedURLChanged', 1]," " ['moveWindowBy', 2]," " ['openInNewTab', 1]," " ['openUrlOnRemoteDeviceAndInspect', 2]," " ['removeFileSystem', 1]," " ['requestFileSystems', 0]," " ['resetZoom', 0]," " ['save', 3]," " ['searchInPath', 3]," " ['setDeviceCountUpdatesEnabled', 1]," " ['setDevicesUpdatesEnabled', 1]," " ['setWhitelistedShortcuts', 1]," " ['setContentsResizingStrategy', 2]," " ['setInspectedPageBounds', 1]," " ['setIsDocked', 1]," " ['stopIndexing', 1]," " ['zoomIn', 0]," " ['zoomOut', 0]]);" "" "" // Support for legacy front-ends (<M34). Do not add items here. "InspectorFrontendHost.requestSetDockSide = function(dockSide)" "{" " InspectorFrontendHost.setIsDocked(dockSide !== \"undocked\");" "};" "InspectorFrontendHost.supportsFileSystems = function() { return true; };" "" "" // Support for legacy front-ends (<M28). Do not add items here. "InspectorFrontendHost.canInspectWorkers = function() { return true; };" "InspectorFrontendHost.canSaveAs = function() { return true; };" "InspectorFrontendHost.canSave = function() { return true; };" "InspectorFrontendHost.loaded = function() {};" "InspectorFrontendHost.hiddenPanels = function() { return ""; };" "InspectorFrontendHost.localizedStringsURL = function() { return ""; };" "InspectorFrontendHost.close = function(url) { };"; scriptController->executeScriptInMainWorld(installAdditionalAPI, ScriptController::ExecuteScriptWhenScriptsDisabled); } }