Chromium 中前端HTMLDialogElement <Dialog> c++代码实现

一、HTMLDialogElement: open property

Baseline Widely available

The open property of the HTMLDialogElement interface is a boolean value reflecting the open HTML attribute, indicating whether the <dialog> is available for interaction.

Value

A boolean value representing the state of the open HTML attribute. true means it is set, and therefore the dialog is shown. false means it not set, and therefore the dialog is not shown.

The property is not read only --- it is possible to set the value to programmatically show or hide the dialog.

HTMLDialogElement: open property - Web APIs | MDN (mozilla.org)

html例子:

html 复制代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>pop-up dialog box</title>
</head>
<body>
  <!-- pop-up dialog box, containing a form -->
<dialog id="favDialog">
  <form method="dialog">
    <p>
      <label for="favAnimal">Favorite animal:</label>
      <select id="favAnimal" name="favAnimal">
        <option></option>
        <option>Brine shrimp</option>
        <option>Red panda</option>
        <option>Spider monkey</option>
      </select>
    </p>
    <div>
      <button id="cancel" type="reset">Cancel</button>
      <button type="submit">Confirm</button>
    </div>
  </form>
</dialog>

<div>
  <button id="Dialog Test">Dialog Test</button>
</div>

<script>const updateButton = document.getElementById("Dialog Test");
const cancelButton = document.getElementById("cancel");
const dialog = document.getElementById("favDialog");
dialog.returnValue = "favAnimal";

function openCheck(dialog) {
  if (dialog.open) {
    console.log("Dialog open");
  } else {
    console.log("Dialog closed");
    console.log(dialog.returnValue);
  }
}

// Update button opens a modal dialog
updateButton.addEventListener("click", () => {
  dialog.showModal();
  openCheck(dialog);
});

// Form cancel button closes the dialog box
cancelButton.addEventListener("click", () => {
  dialog.close("animalNotChosen");
  openCheck(dialog);
});
</script>

</body>
</html>

二、HTMLDialogElement 接口blink接口定义:

前端 show();showModal()等方法都在此接口中。

third_party\blink\renderer\core\html\html_dialog_element.idl

cpp 复制代码
// https://html.spec.whatwg.org/C/#the-dialog-element
[
    Exposed=Window,
    HTMLConstructor
] interface HTMLDialogElement : HTMLElement {
    [CEReactions, Reflect] attribute boolean open;
    attribute DOMString returnValue;
    [CEReactions, Measure, RaisesException] void show();
    [CEReactions, Measure, RaisesException] void showModal();
    [CEReactions] void close(optional DOMString returnValue);
};

third_party\blink\renderer\core\html\html_dialog_element.h

third_party\blink\renderer\core\html\html_dialog_element.cc

cpp 复制代码
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_HTML_DIALOG_ELEMENT_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_HTML_DIALOG_ELEMENT_H_

#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/html/closewatcher/close_watcher.h"
#include "third_party/blink/renderer/core/html/html_element.h"
#include "third_party/blink/renderer/platform/geometry/layout_unit.h"

namespace blink {

class Document;
class ExceptionState;

class CORE_EXPORT HTMLDialogElement final : public HTMLElement {
  DEFINE_WRAPPERTYPEINFO();

 public:
  explicit HTMLDialogElement(Document&);

  void Trace(Visitor*) const override;

  void close(const String& return_value = String());
  void show(ExceptionState&);
  void showModal(ExceptionState&);
  void RemovedFrom(ContainerNode&) override;

  bool IsModal() const { return is_modal_; }

  String returnValue() const { return return_value_; }
  void setReturnValue(const String& return_value) {
    return_value_ = return_value;
  }

  void CloseWatcherFiredCancel(Event*);
  void CloseWatcherFiredClose();

  // Dialogs support focus, since the dialog focus algorithm
  // https://html.spec.whatwg.org/multipage/interactive-elements.html#dialog-focusing-steps
  // can decide to focus the dialog itself if the dialog does not have a focus
  // delegate.
  bool SupportsFocus(UpdateBehavior) const override { return true; }
  bool IsKeyboardFocusable(UpdateBehavior update_behavior =
                               UpdateBehavior::kStyleAndLayout) const override;

  // https://html.spec.whatwg.org/C/#the-dialog-element
  // Chooses the focused element when show() or showModal() is invoked.
  void SetFocusForDialog();

  // This is the old dialog initial focus behavior which is currently being
  // replaced by SetFocusForDialog.
  // TODO(http://crbug.com/383230): Remove this when DialogNewFocusBehavior gets
  // to stable with no issues.
  static void SetFocusForDialogLegacy(HTMLDialogElement* dialog);

 private:
  void SetIsModal(bool is_modal);
  void ScheduleCloseEvent();

  bool is_modal_;
  String return_value_;
  WeakMember<Element> previously_focused_element_;

  Member<CloseWatcher> close_watcher_;
};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_HTML_DIALOG_ELEMENT_H_

三、HTMLDialogElement v8接口定义

out\Debug\gen\third_party\blink\renderer\bindings\core\v8\v8_html_dialog_element.cc

out\Debug\gen\third_party\blink\renderer\bindings\core\v8\v8_html_dialog_element.h

截取部分:

cpp 复制代码
void ShowModalOperationCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
  RUNTIME_CALL_TIMER_SCOPE_DISABLED_BY_DEFAULT(info.GetIsolate(), "Blink_HTMLDialogElement_showModal");
BLINK_BINDINGS_TRACE_EVENT("HTMLDialogElement.showModal");


v8::Isolate* isolate = info.GetIsolate();
v8::Local<v8::Context> current_context = isolate->GetCurrentContext();
ExecutionContext* current_execution_context = ExecutionContext::From(current_context);
// [Measure], [MeasureAs]
UseCounter::Count(current_execution_context, WebFeature::kV8HTMLDialogElement_ShowModal_Method);




const ExceptionContextType exception_context_type = ExceptionContextType::kOperationInvoke;
const char* const class_like_name = "HTMLDialogElement";
const char* const property_name = "showModal";
ExceptionState exception_state(isolate, exception_context_type, class_like_name, property_name);

// [CEReactions]
CEReactionsScope ce_reactions_scope;


v8::Local<v8::Object> v8_receiver = info.This();
HTMLDialogElement* blink_receiver = V8HTMLDialogElement::ToWrappableUnsafe(isolate, v8_receiver);
blink_receiver->showModal(exception_state);
if (UNLIKELY(exception_state.HadException())) {
  return;
}

}

四、打开测试用例test04.html看下堆栈:

要附加新打开的测试页test04.html进程ID=21488

相关推荐
子兮曰5 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰5 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
倒头就睡的小比特5 天前
算法竞赛C++常用的STL
c++·算法
weilx12345 天前
C++笔记-文件IO-<fcntl.h>
c++
小羊没烦恼!5 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
前端小万5 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝5 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋5 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
伞伞悦读5 天前
【第38期】Python 模块与包详解:import、from、模块搜索路径、包结构和 __init__
开发语言·python
卡布鲁5 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js