dom相關:
https://w3c.github.io/uievents/
https://dom.spec.whatwg.org/
工作原理:
https://www.html5rocks.com/en/tutorials/internals/howbrowserswork/
自己添加更多dom函數用js而不是通過c++:https://www.chromium.org/blink/blink-in-js
void Document::SetShowBeforeUnloadDialog(bool show_dialog) {
if (!mime_handler_view_before_unload_event_listener_) {
if (!show_dialog)
return;
mime_handler_view_before_unload_event_listener_ =
MakeGarbageCollected<BeforeUnloadEventListener>(this);
domWindow()->addEventListener(
event_type_names::kBeforeunload,
mime_handler_view_before_unload_event_listener_, false);
}
TEST_F(WebViewTest, SubframeBeforeUnloadUseCounter) {
RegisterMockedHttpURLLoad("visible_iframe.html");
RegisterMockedHttpURLLoad("single_iframe.html");
WebViewImpl* web_view =
web_view_helper_.InitializeAndLoad(base_url_ + "single_iframe.html");
WebLocalFrame* frame = web_view_helper_.LocalMainFrame();
Document* document =
To<LocalFrame>(web_view_helper_.GetWebView()->GetPage()->MainFrame())
->GetDocument();
// Add a beforeunload handler in the main frame. Make sure firing
// beforeunload doesn't increment the subframe use counter.
{
frame->ExecuteScript(
WebScriptSource("addEventListener('beforeunload', function() {});"));
web_view->MainFrameImpl()->DispatchBeforeUnloadEvent(false);
EXPECT_FALSE(
document->IsUseCounted(WebFeature::kSubFrameBeforeUnloadFired));
}
// Add a beforeunload handler in the iframe and dispatch. Make sure we do
// increment the use counter for subframe beforeunloads.
{
frame->ExecuteScript(WebScriptSource(
"document.getElementsByTagName('iframe')[0].contentWindow."
"addEventListener('beforeunload', function() {});"));
To<WebLocalFrameImpl>(
web_view->MainFrame()->FirstChild()->ToWebLocalFrame())
->DispatchBeforeUnloadEvent(false);
Document* child_document = To<LocalFrame>(web_view_helper_.GetWebView()
->GetPage()
->MainFrame()
->Tree()
.FirstChild())
->GetDocument();
EXPECT_TRUE(
child_document->IsUseCounted(WebFeature::kSubFrameBeforeUnloadFired));
}
}
third_party/blink/renderer/bindings/templates/
// This file has been auto-generated from the Jinja2 template
// third_party/blink/renderer/bindings/templates/interface.cc.tmpl
// by the script code_generator_v8.py.
// third_party/blink/renderer/bindings/templates/interface.h.tmpl
js AddEventListenerMethodCallback的方法實作在
\src\out\Testing\gen\third_party\blink\renderer\bindings\modules\v8\v8_context_snapshot_external_references.cc
reinterpret_cast<intptr_t>(V8Window::AlertMethodCallback),
D:\dev\electron7\src\out\Testing\gen\third_party\blink\renderer\bindings\core\v8\v8_window.cc
static constexpr V8DOMConfiguration::MethodConfiguration kV8WindowMethods[] = {
{"stop", V8Window::StopMethodCallback, 0, v8::None, V8DOMConfiguration::kOnInstance, V8DOMConfiguration::kCheckHolder, V8DOMConfiguration::kCheckAccess, V8DOMConfiguration::kHasSideEffect, V8DOMConfiguration::kAllWorlds},
{"open", V8Window::OpenMethodCallback, 0, v8::None, V8DOMConfiguration::kOnInstance, V8DOMConfiguration::kCheckHolder, V8DOMConfiguration::kCheckAccess, V8DOMConfiguration::kHasSideEffect, V8DOMConfiguration::kAllWorlds},
{"alert", V8Window::AlertMethodCallback, 0, v8::None, V8DOMConfiguration::kOnInstance, V8DOMConfiguration::kCheckHolder, V8DOMConfiguration::kCheckAccess, V8DOMConfiguration::kHasSideEffect, V8DOMConfiguration::kAllWorlds},
{"confirm", V8Window::ConfirmMethodCallback, 0, v8::None, V8DOMConfiguration::kOnInstance, V8DOMConfiguration::kCheckHolder, V8DOMConfiguration::kCheckAccess, V8DOMConfiguration::kHasSideEffect, V8DOMConfiguration::kAllWorlds},
{"prompt", V8Window::PromptMethodCallback, 0, v8::None, V8DOMConfiguration::kOnInstance, V8DOMConfiguration::kCheckHolder, V8DOMConfiguration::kCheckAccess, V8DOMConfiguration::kHasSideEffect, V8DOMConfiguration::kAllWorlds},
JS調用到alert的堆棧:
blink_core.dll!blink::LocalDOMWindow::alert(blink::ScriptState * script_state, const WTF::String & message) 行 664 C++
blink_core.dll!blink::dom_window_v8_internal::Alert2Method(const v8::FunctionCallbackInfo<v8::Value> & info) 行 5382 C++
blink_core.dll!blink::dom_window_v8_internal::AlertMethod(const v8::FunctionCallbackInfo<v8::Value> & info) 行 5404 C++
blink_core.dll!blink::V8Window::AlertMethodCallback(const v8::FunctionCallbackInfo<v8::Value> & info) 行 12441 C++
v8.dll!v8::internal::FunctionCallbackArguments::Call(v8::internal::CallHandlerInfo handler) 行 159 C++
v8.dll!v8::internal::`anonymous namespace'::HandleApiCallHelper<0>(v8::internal::Isolate * isolate, v8::internal::Handle<v8::internal::HeapObject> function, v8::internal::Handle<v8::internal::HeapObject> new_target, v8::internal::Handle<v8::internal::FunctionTemplateInfo> fun_data, v8::internal::Handle<v8::internal::Object> receiver, v8::internal::BuiltinArguments args) 行 113 C++
v8.dll!v8::internal::Builtin_Impl_HandleApiCall(v8::internal::BuiltinArguments args, v8::internal::Isolate * isolate) 行 141 C++
v8.dll!v8::internal::Builtin_HandleApiCall(int args_length, unsigned __int64 * args_object, v8::internal::Isolate * isolate) 行 129 C++
[外部代碼]
[内聯架構] v8.dll!v8::internal::GeneratedCode<unsigned long long,unsigned long long,unsigned long long,unsigned long long,unsigned long long,long long,unsigned long long **>::Call(unsigned __int64 args, unsigned __int64 args, unsigned __int64 args, unsigned __int64 args, __int64 args, unsigned __int64 * * args) 行 138 C++
v8.dll!v8::internal::`anonymous namespace'::Invoke(v8::internal::Isolate * isolate, const v8::internal::`anonymous namespace'::InvokeParams & params) 行 266 C++
v8.dll!v8::internal::Execution::Call(v8::internal::Isolate * isolate, v8::internal::Handle<v8::internal::Object> callable, v8::internal::Handle<v8::internal::Object> receiver, int argc, v8::internal::Handle<v8::internal::Object> * argv) 行 358 C++
v8.dll!v8::Script::Run(v8::Local<v8::Context> context) 行 2159 C++
blink_core.dll!blink::V8ScriptRunner::RunCompiledScript(v8::Isolate * isolate, v8::Local<v8::Script> script, blink::ExecutionContext * context) 行 340 C++
blink_core.dll!blink::ScriptController::ExecuteScriptAndReturnValue(v8::Local<v8::Context> context, const blink::ScriptSourceCode & source, const blink::KURL & base_url, blink::SanitizeScriptErrors sanitize_script_errors, const blink::ScriptFetchOptions & fetch_options) 行 133 C++
blink_core.dll!blink::ScriptController::EvaluateScriptInMainWorld(const blink::ScriptSourceCode & source_code, const blink::KURL & base_url, blink::SanitizeScriptErrors sanitize_script_errors, const blink::ScriptFetchOptions & fetch_options, blink::ScriptController::ExecuteScriptPolicy policy) 行 353 C++
> blink_core.dll!blink::ScriptController::ExecuteScriptInMainWorld(const blink::ScriptSourceCode & source_code, const blink::KURL & base_url, blink::SanitizeScriptErrors sanitize_script_errors, const blink::ScriptFetchOptions & fetch_options) 行 321 C++
blink_core.dll!blink::ClassicScript::RunScript(blink::LocalFrame * frame, const blink::SecurityOrigin * security_origin) 行 26 C++
blink_core.dll!blink::PendingScript::ExecuteScriptBlockInternal(blink::Script * script, blink::ScriptElementBase * element, bool was_canceled, bool is_external, bool created_during_document_write, base::TimeTicks parser_blocking_load_start_time, bool is_controlled_by_script_runner) 行 265 C++
blink_core.dll!blink::PendingScript::ExecuteScriptBlock(const blink::KURL & document_url) 行 171 C++
blink_core.dll!blink::ScriptLoader::PrepareScript(const WTF::TextPosition & script_start_position, blink::ScriptLoader::LegacyTypeSupport support_legacy_types) 行 890 C++
blink_core.dll!blink::HTMLParserScriptRunner::ProcessScriptElementInternal(blink::Element * script, const WTF::TextPosition & script_start_position) 行 599 C++
blink_core.dll!blink::HTMLParserScriptRunner::ProcessScriptElement(blink::Element * script_element, const WTF::TextPosition & script_start_position) 行 333 C++
blink_core.dll!blink::HTMLDocumentParser::RunScriptsForPausedTreeBuilder() 行 299 C++
blink_core.dll!blink::HTMLDocumentParser::ProcessTokenizedChunkFromBackgroundParser(std::unique_ptr<blink::HTMLDocumentParser::TokenizedChunk,std::default_delete<blink::HTMLDocumentParser::TokenizedChunk>> pop_chunk) 行 539 C++
blink_core.dll!blink::HTMLDocumentParser::PumpPendingSpeculations() 行 595 C++
blink_core.dll!blink::HTMLDocumentParser::ResumeParsingAfterYield() 行 288 C++
blink_core.dll!blink::HTMLParserScheduler::ContinueParsing() 行 141 C++
void V8Window::AlertMethodCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
RUNTIME_CALL_TIMER_SCOPE_DISABLED_BY_DEFAULT(info.GetIsolate(), "Blink_DOMWindow_alert");
dom_window_v8_internal::AlertMethod(info);
}
void V8Window::ConfirmMethodCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
RUNTIME_CALL_TIMER_SCOPE_DISABLED_BY_DEFAULT(info.GetIsolate(), "Blink_DOMWindow_confirm");
ExecutionContext* execution_context_for_measurement = CurrentExecutionContext(info.GetIsolate());
UseCounter::Count(execution_context_for_measurement, WebFeature::kV8Window_Confirm_Method);
dom_window_v8_internal::ConfirmMethod(info);
void V8Window::PromptMethodCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
RUNTIME_CALL_TIMER_SCOPE_DISABLED_BY_DEFAULT(info.GetIsolate(), "Blink_DOMWindow_prompt");
UseCounter::Count(execution_context_for_measurement, WebFeature::kV8Window_Prompt_Method);
dom_window_v8_internal::PromptMethod(info);
javascript的window::setInterval的内部實作
調用序列圖如下:
javascript的setInterval
-->jsDOMWindowPrototypeFunctionSetInterval
-->JSDOMWindow::setInterval
-->DOMWindow::setInterval
-->DOMTimer::install(context, action, timeout, false);
#########################################################################################
附
WebCore的timer實作
最基本有幾個類,
--TimerBase
--ThreadTimers
包含TimerBase的heap堆和SharedTimer的指針
--SharedTimer
--TimerBase有一些子類,如-->SuspendableTimer-->DOMTimer, Timer等
setNextFireTime() timer開始的時候,都要調用這個函數,這裡把具體的timer更新或者插入到ThreadTimers的堆中
fired() 純虛函數
--ThreadTimers
updateSharedTimer() start timer
sharedTimerFired() fired函數,設定為内部的SharedTimer的callback函數
--SharedTimer
實作依賴具體的平台,如mac, gtk, qt等
有兩個具體的實作MainThreadSharedTimer和WorkerSharedTimer