Chromium 前端form表单提交过程分析c++

打印 上一主题 下一主题

主题 843|帖子 843|积分 2529

一、本文以一个简单的 HTML 表单,包罗两个文本输入框和一个提交按钮:

  1. <form action="demo_form.php">
  2.   First name: <input type="text" name="fname"><br>
  3.   Last name: <input type="text" name="lname"><br>
  4.   <input type="submit" value="提交">
  5. </form>
复制代码
测试时候可以打开菜鸟教程在线编辑器 (runoob.com)运行以上代码
二、看下c++form表单接口定义:

2.1)、form接口定义文件:

third_party\blink\renderer\core\html\forms\html_form_element.idl
method="get|post|dialog"
  1. // https://html.spec.whatwg.org/C/#the-form-element
  2. [
  3.     Exposed=Window,
  4.     HTMLConstructor,
  5.     LegacyOverrideBuiltIns
  6. ] interface HTMLFormElement : HTMLElement {
  7.     [CEReactions, Reflect=accept_charset] attribute DOMString acceptCharset;
  8.     [CEReactions, URL] attribute USVString action;
  9.     [CEReactions, Reflect, ReflectOnly=("on","off"), ReflectMissing="on", ReflectInvalid="on"] attribute DOMString autocomplete;
  10.     [CEReactions] attribute DOMString enctype;
  11.     [CEReactions] attribute DOMString encoding;
  12.     [CEReactions] attribute DOMString method;
  13.     [CEReactions, Reflect] attribute DOMString name;
  14.     [CEReactions, Reflect] attribute boolean noValidate;
  15.     [CEReactions, Reflect] attribute DOMString target;
  16.     [CEReactions, Reflect] attribute DOMString rel;
  17.     [SameObject, PutForwards=value] readonly attribute DOMTokenList relList;
  18.     readonly attribute HTMLFormControlsCollection elements;
  19.     readonly attribute long length;
  20.     [ImplementedAs=item] getter Element (unsigned long index);
  21.     // FIXME: This getter should not have [NotEnumerable].
  22.     [NotEnumerable] getter (RadioNodeList or Element) (DOMString name);
  23.     [ImplementedAs=submitFromJavaScript] void submit();
  24.     [RaisesException] void requestSubmit(optional HTMLElement? submitter = null);
  25.     [CEReactions] void reset();
  26.     boolean checkValidity();
  27.     boolean reportValidity();
  28. };
复制代码
2.2)、blink下form接口实现:

third_party\blink\renderer\core\html\forms\html_form_element.h
third_party\blink\renderer\core\html\forms\html_form_element.cc
用于查找和遍历form元素
  1. #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_HTML_FORM_ELEMENT_H_
  2. #define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_HTML_FORM_ELEMENT_H_
  3. #include "third_party/blink/renderer/core/core_export.h"
  4. #include "third_party/blink/renderer/core/html/forms/html_form_control_element.h"
  5. #include "third_party/blink/renderer/core/html/forms/radio_button_group_scope.h"
  6. #include "third_party/blink/renderer/core/html/html_element.h"
  7. #include "third_party/blink/renderer/core/loader/form_submission.h"
  8. #include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_map.h"
  9. namespace blink {
  10. class DOMTokenList;
  11. class Event;
  12. class HTMLFormControlElement;
  13. class HTMLFormControlsCollection;
  14. class HTMLImageElement;
  15. class ListedElement;
  16. class RelList;
  17. class V8UnionElementOrRadioNodeList;
  18. class CORE_EXPORT HTMLFormElement final : public HTMLElement {
  19.   DEFINE_WRAPPERTYPEINFO();
  20. public:
  21.   enum RelAttribute {
  22.     kNone = 0,
  23.     kNoReferrer = 1 << 0,
  24.     kNoOpener = 1 << 1,
  25.     kOpener = 1 << 2,
  26.   };
  27.   explicit HTMLFormElement(Document&);
  28.   ~HTMLFormElement() override;
  29.   void Trace(Visitor*) const override;
  30.   HTMLFormControlsCollection* elements();
  31.   void GetNamedElements(const AtomicString&, HeapVector<Member<Element>>&);
  32.   unsigned length() const;
  33.   HTMLElement* item(unsigned index);
  34.   String action() const;
  35.   void setAction(const AtomicString&);
  36.   String enctype() const { return attributes_.EncodingType(); }
  37.   void setEnctype(const AtomicString&);
  38.   String encoding() const { return attributes_.EncodingType(); }
  39.   void setEncoding(const AtomicString& value) { setEnctype(value); }
  40.   DOMTokenList& relList() const;
  41.   bool HasRel(RelAttribute relation) const;
  42.   bool ShouldAutocomplete() const;
  43.   void Associate(ListedElement&);
  44.   void Disassociate(ListedElement&);
  45.   void Associate(HTMLImageElement&);
  46.   void Disassociate(HTMLImageElement&);
  47.   void DidAssociateByParser();
  48.   void PrepareForSubmission(const Event*,
  49.                             HTMLFormControlElement* submit_button);
  50.   void submitFromJavaScript();
  51.   void requestSubmit(ExceptionState& exception_state);
  52.   void requestSubmit(HTMLElement* submitter, ExceptionState& exception_state);
  53.   void reset();
  54.   void AttachLayoutTree(AttachContext& context) override;
  55.   void DetachLayoutTree(bool performing_reattach) override;
  56.   void SubmitImplicitly(const Event&, bool from_implicit_submission_trigger);
  57.   String GetName() const;
  58.   bool NoValidate() const;
  59.   const AtomicString& Action() const;
  60.   String method() const;
  61.   void setMethod(const AtomicString&);
  62.   FormSubmission::SubmitMethod Method() const { return attributes_.Method(); }
  63.   // Find the 'default button.'
  64.   // https://html.spec.whatwg.org/C/#default-button
  65.   HTMLFormControlElement* FindDefaultButton() const;
  66.   bool checkValidity();
  67.   bool reportValidity();
  68.   bool MatchesValidityPseudoClasses() const final;
  69.   bool IsValidElement() final;
  70.   RadioButtonGroupScope& GetRadioButtonGroupScope() {
  71.     return radio_button_group_scope_;
  72.   }
  73.   const ListedElement::List& ListedElements(
  74.       bool include_shadow_trees = false) const;
  75.   const HeapVector<Member<HTMLImageElement>>& ImageElements();
  76.   V8UnionElementOrRadioNodeList* AnonymousNamedGetter(const AtomicString& name);
  77.   void InvalidateDefaultButtonStyle() const;
  78.   // 'construct the entry list'
  79.   // https://html.spec.whatwg.org/C/#constructing-the-form-data-set
  80.   // Returns nullptr if this form is already running this function.
  81.   FormData* ConstructEntryList(HTMLFormControlElement* submit_button,
  82.                                const WTF::TextEncoding& encoding);
  83.   uint64_t UniqueRendererFormId() const { return unique_renderer_form_id_; }
  84.   void InvalidateListedElementsIncludingShadowTrees();
  85. private:
  86.   InsertionNotificationRequest InsertedInto(ContainerNode&) override;
  87.   void RemovedFrom(ContainerNode&) override;
  88.   void FinishParsingChildren() override;
  89.   void HandleLocalEvents(Event&) override;
  90.   void ParseAttribute(const AttributeModificationParams&) override;
  91.   bool IsURLAttribute(const Attribute&) const override;
  92.   bool HasLegalLinkAttribute(const QualifiedName&) const override;
  93.   NamedItemType GetNamedItemType() const override {
  94.     return NamedItemType::kName;
  95.   }
  96.   void SubmitDialog(FormSubmission*);
  97.   void ScheduleFormSubmission(const Event*,
  98.                               HTMLFormControlElement* submit_button);
  99.   void CollectListedElements(
  100.       const Node& root,
  101.       ListedElement::List& elements,
  102.       ListedElement::List* elements_including_shadow_trees = nullptr,
  103.       bool in_shadow_tree = false) const;
  104.   void CollectImageElements(Node& root, HeapVector<Member<HTMLImageElement>>&);
  105.   // Returns true if the submission should proceed.
  106.   bool ValidateInteractively();
  107.   // Validates each of the controls, and stores controls of which 'invalid'
  108.   // event was not canceled to the specified vector. Returns true if there
  109.   // are any invalid controls in this form.
  110.   bool CheckInvalidControlsAndCollectUnhandled(ListedElement::List*);
  111.   Element* ElementFromPastNamesMap(const AtomicString&);
  112.   void AddToPastNamesMap(Element*, const AtomicString& past_name);
  113.   void RemoveFromPastNamesMap(HTMLElement&);
  114.   typedef HeapHashMap<AtomicString, Member<Element>> PastNamesMap;
  115.   FormSubmission::Attributes attributes_;
  116.   Member<PastNamesMap> past_names_map_;
  117.   RadioButtonGroupScope radio_button_group_scope_;
  118.   // Do not access listed_elements_ directly. Use ListedElements() instead.
  119.   ListedElement::List listed_elements_;
  120.   // Do not access listed_elements_including_shadow_trees_ directly. Use
  121.   // ListedElements(true) instead.
  122.   ListedElement::List listed_elements_including_shadow_trees_;
  123.   // Do not access image_elements_ directly. Use ImageElements() instead.
  124.   HeapVector<Member<HTMLImageElement>> image_elements_;
  125.   uint64_t unique_renderer_form_id_;
  126.   base::OnceClosure cancel_last_submission_;
  127.   bool is_submitting_ = false;
  128.   bool in_user_js_submit_event_ = false;
  129.   bool is_constructing_entry_list_ = false;
  130.   bool listed_elements_are_dirty_ : 1;
  131.   bool listed_elements_including_shadow_trees_are_dirty_ : 1;
  132.   bool image_elements_are_dirty_ : 1;
  133.   bool has_elements_associated_by_parser_ : 1;
  134.   bool has_elements_associated_by_form_attribute_ : 1;
  135.   bool did_finish_parsing_children_ : 1;
  136.   bool is_in_reset_function_ : 1;
  137.   Member<RelList> rel_list_;
  138.   unsigned rel_attribute_ = 0;
  139. };
  140. }  // namespace blink
  141. #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_HTML_FORM_ELEMENT_H_
复制代码
2.3)、v8下form接口实现:

        out\Debug\gen\third_party\blink\renderer\bindings\core\v8\v8_html_form_element.h
       out\Debug\gen\third_party\blink\renderer\bindings\core\v8\v8_html_form_element.cc
截取部分定义:
  1. void MethodAttributeGetCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
  2.   
  3. RUNTIME_CALL_TIMER_SCOPE_DISABLED_BY_DEFAULT(info.GetIsolate(), "Blink_HTMLFormElement_method_Getter");
  4. BLINK_BINDINGS_TRACE_EVENT("HTMLFormElement.method.get");
  5. v8::Isolate* isolate = info.GetIsolate();
  6. v8::Local<v8::Object> v8_receiver = info.This();
  7. HTMLFormElement* blink_receiver = V8HTMLFormElement::ToWrappableUnsafe(isolate, v8_receiver);
  8. auto&& return_value = blink_receiver->method();
  9. bindings::V8SetReturnValue(info, return_value, isolate, bindings::V8ReturnValue::kNonNullable);
  10. }
  11. void MethodAttributeSetCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
  12.   
  13. RUNTIME_CALL_TIMER_SCOPE_DISABLED_BY_DEFAULT(info.GetIsolate(), "Blink_HTMLFormElement_method_Setter");
  14. BLINK_BINDINGS_TRACE_EVENT("HTMLFormElement.method.set");
  15. v8::Isolate* isolate = info.GetIsolate();
  16. const ExceptionContextType exception_context_type = ExceptionContextType::kAttributeSet;
  17. const char* const class_like_name = "HTMLFormElement";
  18. const char* const property_name = "method";
  19. ExceptionState exception_state(isolate, exception_context_type, class_like_name, property_name);
  20. // [CEReactions]
  21. CEReactionsScope ce_reactions_scope;
  22. v8::Local<v8::Object> v8_receiver = info.This();
  23. HTMLFormElement* blink_receiver = V8HTMLFormElement::ToWrappableUnsafe(isolate, v8_receiver);
  24. v8::Local<v8::Value> v8_property_value = info[0];
  25. auto&& arg1_value = NativeValueTraits<IDLString>::NativeValue(isolate, v8_property_value, exception_state);
  26. if (UNLIKELY(exception_state.HadException())) {
  27.   return;
  28. }
  29. blink_receiver->setMethod(arg1_value);
  30. }
复制代码
2.4)、form_datat数据填充接口:

     FormData用来构建FormSubmission对象重要存储form表单内的元素参数:
      比方: 
 First name: <input type="text" name="fname"><br>
 Last name: <input type="text" name="lname"><br> 
会转换成FirstName=Mickey&LastName=Mouse,末了放到url请求参数内里。
结果:
https://www.runoob.com/try/demo_source/demo-form.php?FirstName=Mickey&LastName=Mouse
hird_party\blink\renderer\core\html\forms\form_data.idl
  1. // https://xhr.spec.whatwg.org/#interface-formdata
  2. typedef (File or USVString) FormDataEntryValue;
  3. [
  4.     Exposed=(Window,Worker)
  5. ] interface FormData {
  6.     [RaisesException] constructor(optional HTMLFormElement form, optional HTMLElement? submitter = null);
  7.     void append(USVString name, USVString value);
  8.     [CallWith=ScriptState] void append(USVString name, Blob value, optional USVString filename);
  9.     [ImplementedAs=deleteEntry] void delete(USVString name);
  10.     FormDataEntryValue? get(USVString name);
  11.     sequence<FormDataEntryValue> getAll(USVString name);
  12.     boolean has(USVString name);
  13.     void set(USVString name, USVString value);
  14.     void set(USVString name, Blob value, optional USVString filename);
  15.     iterable<USVString, FormDataEntryValue>;
  16. };
复制代码
blink和v8定义:
third_party\blink\renderer\core\html\forms\form_data.h
third_party\blink\renderer\core\html\forms\form_data.cc
  1. #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_FORM_DATA_H_
  2. #define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_FORM_DATA_H_
  3. #include "third_party/blink/renderer/bindings/core/v8/iterable.h"
  4. #include "third_party/blink/renderer/bindings/core/v8/v8_sync_iterator_form_data.h"
  5. #include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h"
  6. #include "third_party/blink/renderer/core/core_export.h"
  7. #include "third_party/blink/renderer/core/html/html_element.h"
  8. #include "third_party/blink/renderer/platform/heap/garbage_collected.h"
  9. #include "third_party/blink/renderer/platform/network/encoded_form_data.h"
  10. #include "third_party/blink/renderer/platform/wtf/forward.h"
  11. #include "third_party/blink/renderer/platform/wtf/text/text_encoding.h"
  12. namespace blink {
  13. class Blob;
  14. class File;
  15. class FormControlState;
  16. class HTMLFormElement;
  17. class ScriptState;
  18. class ExecutionContext;
  19. class CORE_EXPORT FormData final : public ScriptWrappable,
  20.                                    public PairSyncIterable<FormData> {
  21.   DEFINE_WRAPPERTYPEINFO();
  22. public:
  23.   static FormData* Create(ExceptionState& exception_state) {
  24.     return MakeGarbageCollected<FormData>();
  25.   }
  26.   static FormData* Create(HTMLFormElement* form,
  27.                           ExceptionState& exception_state);
  28.   static FormData* Create(HTMLFormElement* form,
  29.                           HTMLElement* submitter,
  30.                           ExceptionState& exception_state);
  31.   explicit FormData(const WTF::TextEncoding&);
  32.   // Clones form_data.  This clones |form_data.entries_| Vector, but
  33.   // doesn't clone entries in it because they are immutable.
  34.   FormData(const FormData& form_data);
  35.   FormData();
  36.   void Trace(Visitor*) const override;
  37.   // FormData IDL interface.
  38.   void append(const String& name, const String& value);
  39.   void append(ScriptState*,
  40.               const String& name,
  41.               Blob*,
  42.               const String& filename = String());
  43.   void deleteEntry(const String& name);
  44.   V8FormDataEntryValue* get(const String& name);
  45.   HeapVector<Member<V8FormDataEntryValue>> getAll(const String& name);
  46.   bool has(const String& name);
  47.   void set(const String& name, const String& value);
  48.   void set(const String& name, Blob*, const String& filename = String());
  49.   // Internal functions.
  50.   const WTF::TextEncoding& Encoding() const { return encoding_; }
  51.   std::string Encode(const String& key) const;
  52.   class Entry;
  53.   const HeapVector<Member<const Entry>>& Entries() const { return entries_; }
  54.   size_t size() const { return entries_.size(); }
  55.   void append(const String& name, Blob*, const String& filename = String());
  56.   void AppendFromElement(const String& name, int value);
  57.   void AppendFromElement(const String& name, File* file);
  58.   void AppendFromElement(const String& name, const String& value);
  59.   // This flag is true if this FormData is created with a <form>, and its
  60.   // associated elements contain a non-empty password field.
  61.   bool ContainsPasswordData() const { return contains_password_data_; }
  62.   void SetContainsPasswordData(bool flag) { contains_password_data_ = flag; }
  63.   scoped_refptr<EncodedFormData> EncodeFormData(
  64.       EncodedFormData::EncodingType = EncodedFormData::kFormURLEncoded);
  65.   scoped_refptr<EncodedFormData> EncodeMultiPartFormData();
  66.   void AppendToControlState(FormControlState& state) const;
  67.   static FormData* CreateFromControlState(ExecutionContext& execution_context,
  68.                                           const FormControlState& state,
  69.                                           wtf_size_t& index);
  70. private:
  71.   void SetEntry(const Entry*);
  72.   IterationSource* CreateIterationSource(ScriptState*,
  73.                                          ExceptionState&) override;
  74.   WTF::TextEncoding encoding_;
  75.   // Entry pointers in entries_ never be nullptr.
  76.   HeapVector<Member<const Entry>> entries_;
  77.   bool contains_password_data_ = false;
  78. };
  79. // Represents entry, which is a pair of a name and a value.
  80. // https://xhr.spec.whatwg.org/#concept-formdata-entry
  81. // Entry objects are immutable.
  82. class FormData::Entry final : public GarbageCollected<FormData::Entry> {
  83. public:
  84.   Entry(const String& name, const String& value);
  85.   Entry(const String& name, Blob* blob, const String& filename);
  86.   void Trace(Visitor*) const;
  87.   bool IsString() const { return !blob_; }
  88.   bool isFile() const { return blob_ != nullptr; }
  89.   const String& name() const { return name_; }
  90.   const String& Value() const { return value_; }
  91.   Blob* GetBlob() const { return blob_.Get(); }
  92.   CORE_EXPORT File* GetFile() const;
  93.   const String& Filename() const { return filename_; }
  94. private:
  95.   const String name_;
  96.   const String value_;
  97.   const Member<Blob> blob_;
  98.   const String filename_;
  99. };
  100. }  // namespace blink
  101. #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_FORM_DATA_H_
复制代码
out\Debug\gen\third_party\blink\renderer\bindings\core\v8\v8_form_data.h
out\Debug\gen\third_party\blink\renderer\bindings\core\v8\v8_form_data.cc
截图部分实现:
  1. void KeysOperationCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
  2.   RUNTIME_CALL_TIMER_SCOPE_DISABLED_BY_DEFAULT(info.GetIsolate(), "Blink_FormData_keys");
  3. BLINK_BINDINGS_TRACE_EVENT("FormData.keys");
  4. v8::Isolate* isolate = info.GetIsolate();
  5. v8::Local<v8::Object> v8_receiver = info.This();
  6. FormData* blink_receiver = V8FormData::ToWrappableUnsafe(isolate, v8_receiver);
  7. v8::Local<v8::Context> receiver_context = v8_receiver->GetCreationContextChecked();
  8. ScriptState* receiver_script_state = ScriptState::From(receiver_context);
  9. ScriptState* script_state = receiver_script_state;
  10. const ExceptionContextType exception_context_type = ExceptionContextType::kOperationInvoke;
  11. const char* const class_like_name = "FormData";
  12. const char* const property_name = "keys";
  13. ExceptionState exception_state(isolate, exception_context_type, class_like_name, property_name);
  14. auto&& return_value = blink_receiver->keysForBinding(script_state, exception_state);
  15. if (UNLIKELY(exception_state.HadException())) {
  16.   return;
  17. }
  18. bindings::V8SetReturnValue(info, return_value, blink_receiver);
  19. }
  20. void ValuesOperationCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
  21.   RUNTIME_CALL_TIMER_SCOPE_DISABLED_BY_DEFAULT(info.GetIsolate(), "Blink_FormData_values");
  22. BLINK_BINDINGS_TRACE_EVENT("FormData.values");
  23. v8::Isolate* isolate = info.GetIsolate();
  24. v8::Local<v8::Object> v8_receiver = info.This();
  25. FormData* blink_receiver = V8FormData::ToWrappableUnsafe(isolate, v8_receiver);
  26. v8::Local<v8::Context> receiver_context = v8_receiver->GetCreationContextChecked();
  27. ScriptState* receiver_script_state = ScriptState::From(receiver_context);
  28. ScriptState* script_state = receiver_script_state;
  29. const ExceptionContextType exception_context_type = ExceptionContextType::kOperationInvoke;
  30. const char* const class_like_name = "FormData";
  31. const char* const property_name = "values";
  32. ExceptionState exception_state(isolate, exception_context_type, class_like_name, property_name);
  33. auto&& return_value = blink_receiver->valuesForBinding(script_state, exception_state);
  34. if (UNLIKELY(exception_state.HadException())) {
  35.   return;
  36. }
  37. bindings::V8SetReturnValue(info, return_value, blink_receiver);
  38. }
复制代码
2.5)、form submit 管理类FormSubmission

   网页点击submit会调用到FormSubmission。
third_party\blink\renderer\core\loader\form_submission.h
third_party\blink\renderer\core\loader\form_submission.cc
  1. #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_FORM_SUBMISSION_H_
  2. #define THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_FORM_SUBMISSION_H_
  3. #include "third_party/blink/public/common/tokens/tokens.h"
  4. #include "third_party/blink/public/mojom/frame/policy_container.mojom-blink.h"
  5. #include "third_party/blink/public/mojom/frame/triggering_event_info.mojom-blink-forward.h"
  6. #include "third_party/blink/public/web/web_frame_load_type.h"
  7. #include "third_party/blink/renderer/core/loader/frame_loader_types.h"
  8. #include "third_party/blink/renderer/core/loader/navigation_policy.h"
  9. #include "third_party/blink/renderer/platform/heap/garbage_collected.h"
  10. #include "third_party/blink/renderer/platform/weborigin/kurl.h"
  11. #include "third_party/blink/renderer/platform/heap/member.h"
  12. #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
  13. namespace blink {
  14. class Element;
  15. class EncodedFormData;
  16. class Event;
  17. class Frame;
  18. class HTMLFormControlElement;
  19. class HTMLFormElement;
  20. class LocalDOMWindow;
  21. class ResourceRequest;
  22. class SourceLocation;
  23. class FormSubmission final : public GarbageCollected<FormSubmission> {
  24. public:
  25.   enum SubmitMethod { kGetMethod, kPostMethod, kDialogMethod };
  26.   class Attributes {
  27.     DISALLOW_NEW();
  28.    public:
  29.     Attributes()
  30.         : method_(kGetMethod),
  31.           is_multi_part_form_(false),
  32.           encoding_type_("application/x-www-form-urlencoded") {}
  33.     Attributes(const Attributes&) = delete;
  34.     Attributes& operator=(const Attributes&) = delete;
  35.     SubmitMethod Method() const { return method_; }
  36.     static SubmitMethod ParseMethodType(const String&);
  37.     void UpdateMethodType(const String&);
  38.     static String MethodString(SubmitMethod);
  39.     const String& Action() const { return action_; }
  40.     void ParseAction(const String&);
  41.     const AtomicString& Target() const { return target_; }
  42.     void SetTarget(const AtomicString& target) { target_ = target; }
  43.     const AtomicString& EncodingType() const { return encoding_type_; }
  44.     static AtomicString ParseEncodingType(const String&);
  45.     void UpdateEncodingType(const String&);
  46.     bool IsMultiPartForm() const { return is_multi_part_form_; }
  47.     const String& AcceptCharset() const { return accept_charset_; }
  48.     void SetAcceptCharset(const String& value) { accept_charset_ = value; }
  49.     void CopyFrom(const Attributes&);
  50.    private:
  51.     SubmitMethod method_;
  52.     bool is_multi_part_form_;
  53.     String action_;
  54.     AtomicString target_;
  55.     AtomicString encoding_type_;
  56.     String accept_charset_;
  57.   };
  58.   // Create FormSubmission
  59.   //
  60.   // This returns nullptr if form submission is not allowed for the given
  61.   // arguments. For example, if navigation policy for the event is
  62.   // `kNavigationPolicyLinkPreview`.
  63.   static FormSubmission* Create(HTMLFormElement*,
  64.                                 const Attributes&,
  65.                                 const Event*,
  66.                                 HTMLFormControlElement* submit_button);
  67.   FormSubmission(
  68.       SubmitMethod,
  69.       const KURL& action,
  70.       const AtomicString& target,
  71.       const AtomicString& content_type,
  72.       Element* submitter,
  73.       scoped_refptr<EncodedFormData>,
  74.       const Event*,
  75.       NavigationPolicy navigation_policy,
  76.       mojom::blink::TriggeringEventInfo triggering_event_info,
  77.       ClientNavigationReason reason,
  78.       std::unique_ptr<ResourceRequest> resource_request,
  79.       Frame* target_frame,
  80.       WebFrameLoadType load_type,
  81.       LocalDOMWindow* origin_window,
  82.       const LocalFrameToken& initiator_frame_token,
  83.       std::unique_ptr<SourceLocation> source_location,
  84.       mojo::PendingRemote<mojom::blink::PolicyContainerHostKeepAliveHandle>
  85.           initiator_policy_container_keep_alive_handle);
  86.   // FormSubmission for DialogMethod
  87.   explicit FormSubmission(const String& result);
  88.   void Trace(Visitor*) const;
  89.   void Navigate();
  90.   KURL RequestURL() const;
  91.   SubmitMethod Method() const { return method_; }
  92.   const KURL& Action() const { return action_; }
  93.   EncodedFormData* Data() const { return form_data_.get(); }
  94.   const String& Result() const { return result_; }
  95.   Frame* TargetFrame() const { return target_frame_.Get(); }
  96. private:
  97.   // FIXME: Hold an instance of Attributes instead of individual members.
  98.   SubmitMethod method_;
  99.   KURL action_;
  100.   AtomicString target_;
  101.   AtomicString content_type_;
  102.   Member<Element> submitter_;
  103.   scoped_refptr<EncodedFormData> form_data_;
  104.   NavigationPolicy navigation_policy_;
  105.   mojom::blink::TriggeringEventInfo triggering_event_info_;
  106.   String result_;
  107.   ClientNavigationReason reason_;
  108.   std::unique_ptr<ResourceRequest> resource_request_;
  109.   Member<Frame> target_frame_;
  110.   WebFrameLoadType load_type_;
  111.   Member<LocalDOMWindow> origin_window_;
  112.   LocalFrameToken initiator_frame_token_;
  113.   // Since form submissions are scheduled asynchronously, we need to store the
  114.   // source location when we create the form submission and then pass it over to
  115.   // the `FrameLoadRequest`. Capturing the source location later when creating
  116.   // the `FrameLoadRequest` will not return the correct location.
  117.   std::unique_ptr<SourceLocation> source_location_;
  118.   // Since form submissions are scheduled asynchronously, we need to keep a
  119.   // handle to the initiator PolicyContainerHost. This ensures that it remains
  120.   // available in the browser until we create the NavigationRequest.
  121.   mojo::PendingRemote<mojom::blink::PolicyContainerHostKeepAliveHandle>
  122.       initiator_policy_container_keep_alive_handle_;
  123. };
  124. }  // namespace blink
  125. #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_FORM_SUBMISSION_H_
复制代码
2.6)、submit_input类对应前端<input type="submit":

third_party\blink\renderer\core\html\forms\submit_input_type.h
third_party\blink\renderer\core\html\forms\submit_input_type.cc
  1. #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_SUBMIT_INPUT_TYPE_H_
  2. #define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_SUBMIT_INPUT_TYPE_H_
  3. #include "third_party/blink/renderer/core/html/forms/base_button_input_type.h"
  4. namespace blink {
  5. class SubmitInputType final : public BaseButtonInputType {
  6. public:
  7.   explicit SubmitInputType(HTMLInputElement& element);
  8. private:
  9.   void AppendToFormData(FormData&) const override;
  10.   bool SupportsRequired() const override;
  11.   void HandleDOMActivateEvent(Event&) override;
  12.   bool CanBeSuccessfulSubmitButton() override;
  13.   String DefaultLabel() const override;
  14.   bool IsTextButton() const override;
  15.   void ValueAttributeChanged() override;
  16. };
  17. template <>
  18. struct DowncastTraits<SubmitInputType> {
  19.   static bool AllowFrom(const InputType& type) {
  20.     return type.IsSubmitInputType();
  21.   }
  22. };
  23. }  // namespace blink
  24. #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_SUBMIT_INPUT_TYPE_H_
复制代码
三、看下form表单提交过程:

form表单提交过程:
1、render历程点击提交<input type="submit" value="提交">
2、render历程在HTMLFormElement类中构建 FormSubmission并剖析<input>内容、从而构建出请求参数:FirstName=Mickey&LastName=Mouse 以及
获取method="get"
/*
First name: <input type="text" name="FirstName" value="Mickey"><br>
Last name: <input type="text" name="LastName" value="Mouse"><br>
*/
末了拼接出请求URL
https://www.runoob.com/try/demo_source/demo-form.php?FirstName=Mickey&LastName=Mouse
3、给主历程发送message.set_method_name("CreateNewWindow");
 在新标签中打开https://www.runoob.com/try/demo_source/demo-form.php?FirstName=Mickey&LastName=Mouse。

============================优雅的分割线===================================

1、render历程点击提交<input type="submit" value="提交">

   SubmitInputType::HandleDOMActivateEvent(Event& event)
  1. void SubmitInputType::HandleDOMActivateEvent(Event& event) {
  2.   if (GetElement().IsDisabledFormControl() || !GetElement().Form())
  3.     return;
  4.   // Event handlers can run.
  5.   GetElement().Form()->PrepareForSubmission(&event, &GetElement());
  6.   event.SetDefaultHandled();
  7. }
复制代码

2、HTMLFormElement::ScheduleFormSubmission 函数

调用 FormSubmission* form_submission =
      FormSubmission::Create(this, attributes_, event, submit_button);
  1. void HTMLFormElement::ScheduleFormSubmission(
  2.     const Event* event,
  3.     HTMLFormControlElement* submit_button) {
  4.   LocalFrameView* view = GetDocument().View();
  5.   LocalFrame* frame = GetDocument().GetFrame();
  6.   if (!view || !frame || !frame->GetPage())
  7.     return;
  8.   // https://html.spec.whatwg.org/C/#form-submission-algorithm
  9.   // 2. If form document is not connected, has no associated browsing context,
  10.   // or its active sandboxing flag set has its sandboxed forms browsing
  11.   // context flag set, then abort these steps without doing anything.
  12.   if (!isConnected()) {
  13.     GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
  14.         mojom::ConsoleMessageSource::kJavaScript,
  15.         mojom::ConsoleMessageLevel::kWarning,
  16.         "Form submission canceled because the form is not connected"));
  17.     return;
  18.   }
  19.   if (is_constructing_entry_list_) {
  20.     GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
  21.         mojom::ConsoleMessageSource::kJavaScript,
  22.         mojom::ConsoleMessageLevel::kWarning,
  23.         "Form submission canceled because the form is "
  24.         "constructing entry list"));
  25.     return;
  26.   }
  27.   if (is_submitting_)
  28.     return;
  29.   // Delay dispatching 'close' to dialog until done submitting.
  30.   EventQueueScope scope_for_dialog_close;
  31.   base::AutoReset<bool> submit_scope(&is_submitting_, true);
  32.   if (event && !submit_button) {
  33.     // In a case of implicit submission without a submit button, 'submit'
  34.     // event handler might add a submit button. We search for a submit
  35.     // button again.
  36.     // TODO(tkent): Do we really need to activate such submit button?
  37.     for (ListedElement* listed_element : ListedElements()) {
  38.       auto* control = DynamicTo<HTMLFormControlElement>(listed_element);
  39.       if (!control)
  40.         continue;
  41.       DCHECK(!control->IsActivatedSubmit());
  42.       if (control->IsSuccessfulSubmitButton()) {
  43.         submit_button = control;
  44.         break;
  45.       }
  46.     }
  47.   }
  48.   FormSubmission* form_submission =
  49.       FormSubmission::Create(this, attributes_, event, submit_button);
  50.   if (!form_submission) {
  51.     // Form submission is not allowed for some NavigationPolicies, e.g. Link
  52.     // Preview. If an user triggered such user event for form submission, just
  53.     // ignores it.
  54.     return;
  55.   }
  56.   Frame* target_frame = form_submission->TargetFrame();
  57.   // 'formdata' event handlers might disconnect the form.
  58.   if (!isConnected()) {
  59.     GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
  60.         mojom::ConsoleMessageSource::kJavaScript,
  61.         mojom::ConsoleMessageLevel::kWarning,
  62.         "Form submission canceled because the form is not connected"));
  63.     return;
  64.   }
  65.   if (form_submission->Method() == FormSubmission::kDialogMethod) {
  66.     SubmitDialog(form_submission);
  67.     return;
  68.   }
  69.   DCHECK(form_submission->Method() == FormSubmission::kPostMethod ||
  70.          form_submission->Method() == FormSubmission::kGetMethod);
  71.   DCHECK(form_submission->Data());
  72.   if (form_submission->Action().IsEmpty())
  73.     return;
  74.   if (GetExecutionContext()->IsSandboxed(
  75.           network::mojom::blink::WebSandboxFlags::kForms)) {
  76.     // FIXME: This message should be moved off the console once a solution to
  77.     // https://bugs.webkit.org/show_bug.cgi?id=103274 exists.
  78.     GetExecutionContext()->AddConsoleMessage(
  79.         MakeGarbageCollected<ConsoleMessage>(
  80.             mojom::blink::ConsoleMessageSource::kSecurity,
  81.             mojom::blink::ConsoleMessageLevel::kError,
  82.             "Blocked form submission to '" +
  83.                 form_submission->Action().ElidedString() +
  84.                 "' because the form's frame is sandboxed and the 'allow-forms' "
  85.                 "permission is not set."));
  86.     return;
  87.   }
  88.   if (form_submission->Action().ProtocolIsJavaScript()) {
  89.     // For javascript URLs we need to do the CSP check for 'form-action' here.
  90.     // All other schemes are checked in the browser.
  91.     //
  92.     // TODO(antoniosartori): Should we keep the 'form-action' check for
  93.     // javascript: URLs? For 'frame-src' and 'navigate-to', we do not check
  94.     // javascript: URLs. Reading the specification, it looks like 'form-action'
  95.     // should not apply to javascript: URLs.
  96.     if (!GetExecutionContext()->GetContentSecurityPolicy()->AllowFormAction(
  97.             form_submission->Action())) {
  98.       return;
  99.     }
  100.   }
  101.   UseCounter::Count(GetDocument(), WebFeature::kFormsSubmitted);
  102.   if (MixedContentChecker::IsMixedFormAction(GetDocument().GetFrame(),
  103.                                              form_submission->Action())) {
  104.     UseCounter::Count(GetDocument(), WebFeature::kMixedContentFormsSubmitted);
  105.   }
  106.   if (FastHasAttribute(html_names::kDisabledAttr)) {
  107.     UseCounter::Count(GetDocument(),
  108.                       WebFeature::kFormDisabledAttributePresentAndSubmit);
  109.   }
  110.   if (!target_frame)
  111.     return;
  112.   if (form_submission->Action().ProtocolIsJavaScript()) {
  113.     // For javascript urls, don't post a task to execute the form submission
  114.     // because we already get another task posted for it in
  115.     // Document::ProcessJavascriptUrl. If we post two tasks, the javascript will
  116.     // be run too late according to some tests.
  117.     form_submission->Navigate();
  118.     return;
  119.   }
  120.   FrameScheduler* scheduler = GetDocument().GetFrame()->GetFrameScheduler();
  121.   if (auto* target_local_frame = DynamicTo<LocalFrame>(target_frame)) {
  122.     if (!target_local_frame->IsNavigationAllowed())
  123.       return;
  124.     // Cancel parsing if the form submission is targeted at this frame.
  125.     if (target_local_frame == GetDocument().GetFrame() &&
  126.         !form_submission->Action().ProtocolIsJavaScript()) {
  127.       target_local_frame->GetDocument()->CancelParsing();
  128.     }
  129.     // Use the target frame's frame scheduler. If we can't due to targeting a
  130.     // RemoteFrame, then use the frame scheduler from the frame this form is in.
  131.     scheduler = target_local_frame->GetFrameScheduler();
  132.     // Cancel pending javascript url navigations for the target frame. This new
  133.     // form submission should take precedence over them.
  134.     target_local_frame->GetDocument()->CancelPendingJavaScriptUrls();
  135.     // Cancel any pre-existing attempt to navigate the target frame which was
  136.     // already sent to the browser process so this form submission will take
  137.     // precedence over it.
  138.     target_local_frame->Loader().CancelClientNavigation();
  139.   }
  140.   cancel_last_submission_ =
  141.       target_frame->ScheduleFormSubmission(scheduler, form_submission);
  142. }
复制代码
3、FormSubmission::Create()函数构建FirstName=Mickey&LastName=Mouse,以及打开提交页面方式:

  1. FormSubmission* FormSubmission::Create(HTMLFormElement* form,
  2.                                        const Attributes& attributes,
  3.                                        const Event* event,
  4.                                        HTMLFormControlElement* submit_button) {
  5.   DCHECK(form);
  6.   FormSubmission::Attributes copied_attributes;
  7.   copied_attributes.CopyFrom(attributes);
  8.   if (submit_button) {
  9.     AtomicString attribute_value;
  10.     if (!(attribute_value =
  11.               submit_button->FastGetAttribute(html_names::kFormactionAttr))
  12.              .IsNull())
  13.       copied_attributes.ParseAction(attribute_value);
  14.     if (!(attribute_value =
  15.               submit_button->FastGetAttribute(html_names::kFormenctypeAttr))
  16.              .IsNull())
  17.       copied_attributes.UpdateEncodingType(attribute_value);
  18.     if (!(attribute_value =
  19.               submit_button->FastGetAttribute(html_names::kFormmethodAttr))
  20.              .IsNull())
  21.       copied_attributes.UpdateMethodType(attribute_value);
  22.     if (!(attribute_value =
  23.               submit_button->FastGetAttribute(html_names::kFormtargetAttr))
  24.              .IsNull())
  25.       copied_attributes.SetTarget(attribute_value);
  26.   }
  27.   if (copied_attributes.Method() == kDialogMethod) {
  28.     if (submit_button) {
  29.       return MakeGarbageCollected<FormSubmission>(
  30.           submit_button->ResultForDialogSubmit());
  31.     }
  32.     return MakeGarbageCollected<FormSubmission>("");
  33.   }
  34.   Document& document = form->GetDocument();
  35.   KURL action_url = document.CompleteURL(copied_attributes.Action().empty()
  36.                                              ? document.Url().GetString()
  37.                                              : copied_attributes.Action());
  38.   if ((document.domWindow()->GetSecurityContext().GetInsecureRequestPolicy() &
  39.        mojom::blink::InsecureRequestPolicy::kUpgradeInsecureRequests) !=
  40.           mojom::blink::InsecureRequestPolicy::kLeaveInsecureRequestsAlone &&
  41.       action_url.ProtocolIs("http") &&
  42.       !network::IsUrlPotentiallyTrustworthy(GURL(action_url))) {
  43.     UseCounter::Count(document,
  44.                       WebFeature::kUpgradeInsecureRequestsUpgradedRequestForm);
  45.     action_url.SetProtocol("https");
  46.     if (action_url.Port() == 80)
  47.       action_url.SetPort(443);
  48.   }
  49.   bool is_mailto_form = action_url.ProtocolIs("mailto");
  50.   bool is_multi_part_form = false;
  51.   AtomicString encoding_type = copied_attributes.EncodingType();
  52.   if (copied_attributes.Method() == kPostMethod) {
  53.     is_multi_part_form = copied_attributes.IsMultiPartForm();
  54.     if (is_multi_part_form && is_mailto_form) {
  55.       encoding_type = AtomicString("application/x-www-form-urlencoded");
  56.       is_multi_part_form = false;
  57.     }
  58.   }
  59.   WTF::TextEncoding data_encoding =
  60.       is_mailto_form
  61.           ? UTF8Encoding()
  62.           : FormDataEncoder::EncodingFromAcceptCharset(
  63.                 copied_attributes.AcceptCharset(), document.Encoding());
  64.   //解析<input>构建请求参数FirstName=Mickey&LastName=Mouse
  65.   FormData* dom_form_data = form->ConstructEntryList(
  66.       submit_button, data_encoding.EncodingForFormSubmission());
  67.   DCHECK(dom_form_data);
  68.   scoped_refptr<EncodedFormData> form_data;
  69.   String boundary;
  70.   if (is_multi_part_form) {
  71.     form_data = dom_form_data->EncodeMultiPartFormData();
  72.     boundary = form_data->Boundary().data();
  73.   } else {
  74.     form_data = dom_form_data->EncodeFormData(
  75.         attributes.Method() == kGetMethod
  76.             ? EncodedFormData::kFormURLEncoded
  77.             : EncodedFormData::ParseEncodingType(encoding_type));
  78.     if (copied_attributes.Method() == kPostMethod && is_mailto_form) {
  79.       // Convert the form data into a string that we put into the URL.
  80.       AppendMailtoPostFormDataToURL(action_url, *form_data, encoding_type);
  81.       form_data = EncodedFormData::Create();
  82.     }
  83.   }
  84.   form_data->SetIdentifier(GenerateFormDataIdentifier());
  85.   form_data->SetContainsPasswordData(dom_form_data->ContainsPasswordData());
  86.   if (copied_attributes.Method() != FormSubmission::kPostMethod &&
  87.       !action_url.ProtocolIsJavaScript()) {
  88.     action_url.SetQuery(form_data->FlattenToString());
  89.   }
  90.   std::unique_ptr<ResourceRequest> resource_request =
  91.       std::make_unique<ResourceRequest>(action_url);
  92.   ClientNavigationReason reason = ClientNavigationReason::kFormSubmissionGet;
  93.   if (copied_attributes.Method() == FormSubmission::kPostMethod) {
  94.     reason = ClientNavigationReason::kFormSubmissionPost;
  95.     resource_request->SetHttpMethod(http_names::kPOST);
  96.     resource_request->SetHttpBody(form_data);
  97.     // construct some user headers if necessary
  98.     if (boundary.empty()) {
  99.       resource_request->SetHTTPContentType(encoding_type);
  100.     } else {
  101.       resource_request->SetHTTPContentType(encoding_type +
  102.                                            "; boundary=" + boundary);
  103.     }
  104.   }
  105.   resource_request->SetHasUserGesture(
  106.       LocalFrame::HasTransientUserActivation(form->GetDocument().GetFrame()));
  107.   resource_request->SetFormSubmission(true);
  108.   mojom::blink::TriggeringEventInfo triggering_event_info;
  109.   if (event) {
  110.     triggering_event_info =
  111.         event->isTrusted()
  112.             ? mojom::blink::TriggeringEventInfo::kFromTrustedEvent
  113.             : mojom::blink::TriggeringEventInfo::kFromUntrustedEvent;
  114.     if (event->UnderlyingEvent())
  115.       event = event->UnderlyingEvent();
  116.   } else {
  117.     triggering_event_info = mojom::blink::TriggeringEventInfo::kNotFromEvent;
  118.   }
  119.   FrameLoadRequest frame_request(form->GetDocument().domWindow(),
  120.                                  *resource_request);
  121.   //设置submit打开策略
  122.   NavigationPolicy navigation_policy = NavigationPolicyFromEvent(event);
  123.   if (navigation_policy == kNavigationPolicyLinkPreview) {
  124.     return nullptr;
  125.   }
  126.   frame_request.SetNavigationPolicy(navigation_policy);
  127.   frame_request.SetClientRedirectReason(reason);
  128.   if (submit_button) {
  129.     frame_request.SetSourceElement(submit_button);
  130.   } else {
  131.     frame_request.SetSourceElement(form);
  132.   }
  133.   frame_request.SetTriggeringEventInfo(triggering_event_info);
  134.   AtomicString target_or_base_target = frame_request.CleanNavigationTarget(
  135.       copied_attributes.Target().empty() ? document.BaseTarget()
  136.                                          : copied_attributes.Target());
  137.   if (form->HasRel(HTMLFormElement::kNoReferrer)) {
  138.     frame_request.SetNoReferrer();
  139.     frame_request.SetNoOpener();
  140.   }
  141.   if (form->HasRel(HTMLFormElement::kNoOpener) ||
  142.       (EqualIgnoringASCIICase(target_or_base_target, "_blank") &&
  143.        !form->HasRel(HTMLFormElement::kOpener) &&
  144.        form->GetDocument()
  145.            .domWindow()
  146.            ->GetFrame()
  147.            ->GetSettings()
  148.            ->GetTargetBlankImpliesNoOpenerEnabledWillBeRemoved())) {
  149.     frame_request.SetNoOpener();
  150.   }
  151.   //给主进程发送message.set_method_name("CreateNewWindow");
  152.   Frame* target_frame =
  153.       form->GetDocument()
  154.           .GetFrame()
  155.           ->Tree()
  156.           .FindOrCreateFrameForNavigation(frame_request, target_or_base_target)
  157.           .frame;
  158.   // Apply replacement now, before any async steps, as the result may change.
  159.   WebFrameLoadType load_type = WebFrameLoadType::kStandard;
  160.   LocalFrame* target_local_frame = DynamicTo<LocalFrame>(target_frame);
  161.   if (target_local_frame &&
  162.       target_local_frame->NavigationShouldReplaceCurrentHistoryEntry(
  163.           frame_request, load_type)) {
  164.     load_type = WebFrameLoadType::kReplaceCurrentItem;
  165.   }
  166.   return MakeGarbageCollected<FormSubmission>(
  167.       copied_attributes.Method(), action_url, target_or_base_target,
  168.       encoding_type, frame_request.GetSourceElement(), std::move(form_data),
  169.       event, frame_request.GetNavigationPolicy(), triggering_event_info, reason,
  170.       std::move(resource_request), target_frame, load_type,
  171.       form->GetDocument().domWindow(),
  172.       form->GetDocument().GetFrame()->GetLocalFrameToken(),
  173.       CaptureSourceLocation(form->GetDocument().domWindow()),
  174.       form->GetDocument()
  175.           .domWindow()
  176.           ->GetPolicyContainer()
  177.           ->IssueKeepAliveHandle());
  178. }
复制代码
 3.1)、构建FirstName=Mickey&LastName=Mouse 参数

/ /ConstructEntryList函数遍历form表单位素
  FormData* dom_form_data = form->ConstructEntryList(
      submit_button, data_encoding.EncodingForFormSubmission());
  DCHECK(dom_form_data);
3.2)、FormSubmission::Create调用FindOrCreateFrameForNavigation

用来打开提交新页面。
  Frame* target_frame =
      form->GetDocument()
          .GetFrame()
          ->Tree()
          .FindOrCreateFrameForNavigation(frame_request, target_or_base_target)
          .frame;

3.3)、FindOrCreateFrameForNavigation调用RenderFrameImpl::CreateNewWindow 函数

RenderFrameImpl::CreateNewWindow函数定义(content\renderer\render_frame_impl.cc):
  1. WebView* RenderFrameImpl::CreateNewWindow(
  2.     const WebURLRequest& request,
  3.     const blink::WebWindowFeatures& features,
  4.     const WebString& frame_name,
  5.     WebNavigationPolicy policy,
  6.     network::mojom::WebSandboxFlags sandbox_flags,
  7.     const blink::SessionStorageNamespaceId& session_storage_namespace_id,
  8.     bool& consumed_user_gesture,
  9.     const absl::optional<blink::Impression>& impression,
  10.     const absl::optional<blink::WebPictureInPictureWindowOptions>& pip_options,
  11.     const blink::WebURL& base_url) {
  12.   consumed_user_gesture = false;
  13.   mojom::CreateNewWindowParamsPtr params = mojom::CreateNewWindowParams::New();
  14.   // The user activation check is done at the browser process through
  15.   // |frame_host->CreateNewWindow()| call below.  But the extensions case
  16.   // handled through the following |if| is an exception.
  17.   params->allow_popup = false;
  18.   if (GetContentClient()->renderer()->AllowPopup())
  19.     params->allow_popup = true;
  20.   params->window_container_type = WindowFeaturesToContainerType(features);
  21.   params->session_storage_namespace_id = session_storage_namespace_id;
  22.   if (!features.noopener) {
  23.     params->clone_from_session_storage_namespace_id =
  24.         GetWebView()->GetSessionStorageNamespaceId();
  25.   }
  26.   const std::string& frame_name_utf8 = frame_name.Utf8(
  27.       WebString::UTF8ConversionMode::kStrictReplacingErrorsWithFFFD);
  28.   params->frame_name = frame_name_utf8;
  29.   params->opener_suppressed = features.noopener;
  30.   params->disposition = NavigationPolicyToDisposition(policy);
  31.   if (!request.IsNull()) {
  32.     params->target_url = request.Url();
  33.     // The browser process does not consider empty URLs as valid (partly due to
  34.     // a risk of treating them as a navigation to the privileged NTP in some
  35.     // cases), so treat an attempt to create a window with an empty URL as
  36.     // opening about:blank.
  37.     //
  38.     // Similarly, javascript: URLs should not be sent to the browser process,
  39.     // since they are either handled within the renderer process (if a window is
  40.     // created within the same browsing context group) or ignored (in the
  41.     // noopener case). Use about:blank for the URL in that case as well, to
  42.     // reduce the risk of running them incorrectly.
  43.     if (params->target_url.is_empty() ||
  44.         params->target_url.SchemeIs(url::kJavaScriptScheme)) {
  45.       params->target_url = GURL(url::kAboutBlankURL);
  46.     }
  47.     params->referrer = blink::mojom::Referrer::New(
  48.         blink::WebStringToGURL(request.ReferrerString()),
  49.         request.GetReferrerPolicy());
  50.   }
  51.   params->features = ConvertWebWindowFeaturesToMojoWindowFeatures(features);
  52.   params->is_form_submission = request.IsFormSubmission();
  53.   params->form_submission_post_data =
  54.       blink::GetRequestBodyForWebURLRequest(request);
  55.   params->form_submission_post_content_type = request.HttpContentType().Utf8();
  56.   params->impression = impression;
  57.   if (pip_options) {
  58.     CHECK_EQ(policy, blink::kWebNavigationPolicyPictureInPicture);
  59.     auto pip_mojom_opts = blink::mojom::PictureInPictureWindowOptions::New();
  60.     pip_mojom_opts->width = pip_options->width;
  61.     pip_mojom_opts->height = pip_options->height;
  62.     // TODO(crbug.com/1444658): Remove this from mojom and the browser side.
  63.     pip_mojom_opts->initial_aspect_ratio = 0.0;
  64.     // TODO(crbug.com/1410379): Remove this from mojom and the browser side.
  65.     pip_mojom_opts->lock_aspect_ratio = false;
  66.     params->pip_options = std::move(pip_mojom_opts);
  67.   }
  68.   params->download_policy.ApplyDownloadFramePolicy(
  69.       /*is_opener_navigation=*/false, request.HasUserGesture(),
  70.       // `openee_can_access_opener_origin` only matters for opener navigations,
  71.       // so its value here is irrelevant.
  72.       /*openee_can_access_opener_origin=*/true,
  73.       !GetWebFrame()->IsAllowedToDownload(), GetWebFrame()->IsAdFrame());
  74.   params->initiator_activation_and_ad_status =
  75.       blink::GetNavigationInitiatorActivationAndAdStatus(
  76.           request.HasUserGesture(), GetWebFrame()->IsAdFrame(),
  77.           GetWebFrame()->IsAdScriptInStack());
  78.   // We preserve this information before sending the message since |params| is
  79.   // moved on send.
  80.   bool is_background_tab =
  81.       params->disposition == WindowOpenDisposition::NEW_BACKGROUND_TAB;
  82.   mojom::CreateNewWindowStatus status;
  83.   mojom::CreateNewWindowReplyPtr reply;
  84.   auto* frame_host = GetFrameHost();
  85.   if (!frame_host->CreateNewWindow(std::move(params), &status, &reply)) {
  86.     // The sync IPC failed, e.g. maybe the render process is in the middle of
  87.     // shutting down. Can't create a new window without the browser process,
  88.     // so just bail out.
  89.     return nullptr;
  90.   }
  91.   // If creation of the window was blocked (e.g. because this frame doesn't
  92.   // have user activation), return before consuming user activation. A frame
  93.   // that isn't allowed to open a window  shouldn't be able to consume the
  94.   // activation for the rest of the frame tree.
  95.   if (status == mojom::CreateNewWindowStatus::kBlocked)
  96.     return nullptr;
  97.   // For Android WebView, we support a pop-up like behavior for window.open()
  98.   // even if the embedding app doesn't support multiple windows. In this case,
  99.   // window.open() will return "window" and navigate it to whatever URL was
  100.   // passed. We also don't need to consume user gestures to protect against
  101.   // multiple windows being opened, because, well, the app doesn't support
  102.   // multiple windows.
  103.   // TODO(dcheng): It's awkward that this is plumbed into Blink but not really
  104.   // used much in Blink, except to enable web testing... perhaps this should
  105.   // be checked directly in the browser side.
  106.   if (status == mojom::CreateNewWindowStatus::kReuse) {
  107.     // In this case, treat javascript: URLs as blocked rather than running them
  108.     // in a reused main frame in Android WebView. See https://crbug.com/1083819.
  109.     if (!request.IsNull() && request.Url().ProtocolIs(url::kJavaScriptScheme)) {
  110.       return nullptr;
  111.     }
  112.     return GetWebView();
  113.   }
  114.   // Consume the transient user activation in the current renderer.
  115.   consumed_user_gesture = GetWebFrame()->ConsumeTransientUserActivation(
  116.       blink::UserActivationUpdateSource::kBrowser);
  117.   // If we should ignore the new window (e.g. because of `noopener`), return
  118.   // now that user activation was consumed.
  119.   if (status == mojom::CreateNewWindowStatus::kIgnore)
  120.     return nullptr;
  121.   DCHECK(reply);
  122.   DCHECK_NE(MSG_ROUTING_NONE, reply->main_frame_route_id);
  123.   DCHECK_NE(MSG_ROUTING_NONE, reply->widget_params->routing_id);
  124.   // While this view may be a background extension page, it can spawn a visible
  125.   // render view. So we just assume that the new one is not another background
  126.   // page instead of passing on our own value.
  127.   // TODO(vangelis): Can we tell if the new view will be a background page?
  128.   bool never_composited = false;
  129.   // The initial hidden state for the RenderViewImpl here has to match what the
  130.   // browser will eventually decide for the given disposition. Since we have to
  131.   // return from this call synchronously, we just have to make our best guess
  132.   // and rely on the browser sending a WasHidden / WasShown message if it
  133.   // disagrees.
  134.   mojom::CreateViewParamsPtr view_params = mojom::CreateViewParams::New();
  135.   view_params->opener_frame_token = GetWebFrame()->GetFrameToken();
  136.   view_params->window_was_opened_by_another_window = true;
  137.   view_params->renderer_preferences = GetWebView()->GetRendererPreferences();
  138.   view_params->web_preferences = GetWebView()->GetWebPreferences();
  139.   view_params->replication_state = blink::mojom::FrameReplicationState::New();
  140.   view_params->replication_state->frame_policy.sandbox_flags = sandbox_flags;
  141.   view_params->replication_state->name = frame_name_utf8;
  142.   view_params->devtools_main_frame_token = reply->devtools_main_frame_token;
  143.   view_params->browsing_context_group_info = reply->browsing_context_group_info;
  144.   view_params->color_provider_colors = reply->color_provider_colors;
  145.   auto main_frame_params = mojom::CreateLocalMainFrameParams::New();
  146.   main_frame_params->frame_token = reply->main_frame_token;
  147.   main_frame_params->routing_id = reply->main_frame_route_id;
  148.   main_frame_params->frame = std::move(reply->frame);
  149.   main_frame_params->interface_broker =
  150.       std::move(reply->main_frame_interface_broker);
  151.   main_frame_params->document_token = reply->document_token;
  152.   main_frame_params->policy_container = std::move(reply->policy_container);
  153.   main_frame_params->associated_interface_provider_remote =
  154.       std::move(reply->associated_interface_provider);
  155.   main_frame_params->widget_params = std::move(reply->widget_params);
  156.   main_frame_params->subresource_loader_factories =
  157.       base::WrapUnique(static_cast<blink::PendingURLLoaderFactoryBundle*>(
  158.           CloneLoaderFactories()->Clone().release()));
  159.   view_params->main_frame =
  160.       mojom::CreateMainFrameUnion::NewLocalParams(std::move(main_frame_params));
  161.   view_params->blink_page_broadcast = std::move(reply->page_broadcast);
  162.   view_params->session_storage_namespace_id =
  163.       reply->cloned_session_storage_namespace_id;
  164.   DCHECK(!view_params->session_storage_namespace_id.empty())
  165.       << "Session storage namespace must be populated.";
  166.   view_params->hidden = is_background_tab;
  167.   view_params->never_composited = never_composited;
  168.   WebView* web_view = agent_scheduling_group_->CreateWebView(
  169.       std::move(view_params),
  170.       /*was_created_by_renderer=*/true, base_url);
  171.   if (reply->wait_for_debugger) {
  172.     blink::WebFrameWidget* frame_widget =
  173.         web_view->MainFrame()->ToWebLocalFrame()->LocalRoot()->FrameWidget();
  174.     frame_widget->WaitForDebuggerWhenShown();
  175.   }
  176.   return web_view;
  177. }
复制代码
堆栈图:

  1. @3        content.dll!content::RenderFrameImpl::CreateNewWindow(const blink::WebURLRequest & request, const blink::WebWindowFeatures & features, const blink::WebString & frame_name, blink::WebNavigationPolicy policy, network::mojom::WebSandboxFlags sandbox_flags, const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>> & session_storage_namespace_id, bool & consumed_user_gesture, const std::__Cr::optional<blink::Impression> & impression, const std::__Cr::optional<blink::WebPictureInPictureWindowOptions> & pip_options, const blink::WebURL & base_url) 行 6562        C++        已加载符号。
  2. @2         blink_core.dll!blink::ChromeClientImpl::CreateWindowDelegate(blink::LocalFrame * frame, const blink::FrameLoadRequest & r, const WTF::AtomicString & name, const blink::WebWindowFeatures & features, network::mojom::WebSandboxFlags sandbox_flags, const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>> & session_storage_namespace_id, bool & consumed_user_gesture) 行 342        C++        已加载符号。
  3. @1        blink_core.dll!blink::ChromeClient::CreateWindow(blink::LocalFrame * frame, const blink::FrameLoadRequest & r, const WTF::AtomicString & frame_name, const blink::WebWindowFeatures & features, network::mojom::WebSandboxFlags sandbox_flags, const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>> & session_storage_namespace_id, bool & consumed_user_gesture) 行 88        C++        已加载符号。
  4. @0        blink_core.dll!blink::CreateNewWindow(blink::LocalFrame & opener_frame, blink::FrameLoadRequest & request, const WTF::AtomicString & frame_name) 行 355        C++        已加载符号。
  5. >        blink_core.dll!blink::FrameTree::FindOrCreateFrameForNavigation(blink::FrameLoadRequest & request, const WTF::AtomicString & name) 行 217        C++        已加载符号。
复制代码
3.4)、RenderFrameImpl::CreateNewWindow 调用frame_host->CreateNewWindow 给主历程发送CreateNewWindow的mojom消息。

  mojom::CreateNewWindowStatus status;
  mojom::CreateNewWindowReplyPtr reply;
  auto* frame_host = GetFrameHost();
 //给主历程发送CreateNewWindow mojom消息
  if (!frame_host->CreateNewWindow(std::move(params), &status, &reply)) {
    // The sync IPC failed, e.g. maybe the render process is in the middle of
    // shutting down. Can't create a new window without the browser process,
    // so just bail out.
    return nullptr;
  }

4、主历程收到子历程发送的mojom CreateNewWindow消息:

在RenderFrameHostImpl::CreateNewWindow函数内里处理打开 submit提交URL="https://www.runoob.com/try/demo_source/demo-form.php?FirstName=Mickey&LastName=Mouse"
 src\content\browser\renderer_host\render_frame_host_impl.cc
浏览器打开了一个submit提交的新标签,至此form提交完成。

  1. void RenderFrameHostImpl::CreateNewWindow(
  2.     mojom::CreateNewWindowParamsPtr params,
  3.     CreateNewWindowCallback callback) {
  4.   DCHECK_CURRENTLY_ON(BrowserThread::UI);
  5.   TRACE_EVENT2("navigation", "RenderFrameHostImpl::CreateNewWindow",
  6.                "render_frame_host", this, "url", params->target_url);
  7.   // Only top-most frames can open picture-in-picture windows.
  8.   if (params->disposition == WindowOpenDisposition::NEW_PICTURE_IN_PICTURE &&
  9.       GetParentOrOuterDocumentOrEmbedder()) {
  10.     frame_host_associated_receiver_.ReportBadMessage(
  11.         "Only top-most frames can open picture-in-picture windows.");
  12.     return;
  13.   }
  14.   bool no_javascript_access = false;
  15.   // Filter out URLs to which navigation is disallowed from this context.
  16.   GetProcess()->FilterURL(false, &params->target_url);
  17.   bool effective_transient_activation_state =
  18.       params->allow_popup || HasTransientUserActivation() ||
  19.       (transient_allow_popup_.IsActive() &&
  20.        params->disposition == WindowOpenDisposition::NEW_POPUP);
  21.   // Ignore window creation when sent from a frame that's not active or
  22.   // created.
  23.   bool can_create_window =
  24.       IsActive() && is_render_frame_created() &&
  25.       GetContentClient()->browser()->CanCreateWindow(
  26.           this, GetLastCommittedURL(),
  27.           GetOutermostMainFrame()->GetLastCommittedURL(),
  28.           last_committed_origin_, params->window_container_type,
  29.           params->target_url, params->referrer.To<Referrer>(),
  30.           params->frame_name, params->disposition, *params->features,
  31.           effective_transient_activation_state, params->opener_suppressed,
  32.           &no_javascript_access);
  33.   // If this frame isn't allowed to create a window, return early (before we
  34.   // consume transient user activation).
  35.   if (!can_create_window) {
  36.     std::move(callback).Run(mojom::CreateNewWindowStatus::kBlocked, nullptr);
  37.     return;
  38.   }
  39.   // Otherwise, consume user activation before we proceed. In particular, it is
  40.   // important to do this before we return from the |opener_suppressed| case
  41.   // below.
  42.   // NB: This call will consume activations in the browser and the remote frame
  43.   // proxies for this frame. The initiating renderer will consume its view of
  44.   // the activations after we return.
  45.   // See `owner_` invariants about `IsActive()`, which is implied by
  46.   // `can_create_window`.
  47.   CHECK(owner_);
  48.   bool was_consumed = owner_->UpdateUserActivationState(
  49.       blink::mojom::UserActivationUpdateType::kConsumeTransientActivation,
  50.       blink::mojom::UserActivationNotificationType::kNone);
  51.   // For Android WebView, we support a pop-up like behavior for window.open()
  52.   // even if the embedding app doesn't support multiple windows. In this case,
  53.   // window.open() will return "window" and navigate it to whatever URL was
  54.   // passed.
  55.   if (!GetOrCreateWebPreferences().supports_multiple_windows) {
  56.     std::move(callback).Run(mojom::CreateNewWindowStatus::kReuse, nullptr);
  57.     return;
  58.   }
  59.   // This will clone the sessionStorage for namespace_id_to_clone.
  60.   StoragePartition* storage_partition = GetStoragePartition();
  61.   DOMStorageContextWrapper* dom_storage_context =
  62.       static_cast<DOMStorageContextWrapper*>(
  63.           storage_partition->GetDOMStorageContext());
  64.   scoped_refptr<SessionStorageNamespaceImpl> cloned_namespace;
  65.   if (!params->clone_from_session_storage_namespace_id.empty()) {
  66.     cloned_namespace = SessionStorageNamespaceImpl::CloneFrom(
  67.         dom_storage_context, params->session_storage_namespace_id,
  68.         params->clone_from_session_storage_namespace_id);
  69.   } else {
  70.     cloned_namespace = SessionStorageNamespaceImpl::Create(
  71.         dom_storage_context, params->session_storage_namespace_id);
  72.   }
  73.   if (IsCredentialless() || IsNestedWithinFencedFrame() ||
  74.       CoopSuppressOpener(/*opener=*/this)) {
  75.     params->opener_suppressed = true;
  76.     // TODO(https://crbug.com/1060691) This should be applied to all
  77.     // popups opened with noopener.
  78.     params->frame_name.clear();
  79.   }
  80.   RenderFrameHostImpl* top_level_opener = GetMainFrame();
  81.   int popup_virtual_browsing_context_group =
  82.       params->opener_suppressed
  83.           ? CrossOriginOpenerPolicyAccessReportManager::
  84.                 GetNewVirtualBrowsingContextGroup()
  85.           : top_level_opener->virtual_browsing_context_group();
  86.   int popup_soap_by_default_virtual_browsing_context_group =
  87.       params->opener_suppressed
  88.           ? CrossOriginOpenerPolicyAccessReportManager::
  89.                 GetNewVirtualBrowsingContextGroup()
  90.           : top_level_opener->soap_by_default_virtual_browsing_context_group();
  91.   // If the opener is suppressed or script access is disallowed, we should
  92.   // open the window in a new BrowsingInstance, and thus a new process. That
  93.   // means the current renderer process will not be able to route messages to
  94.   // it. Because of this, we will immediately show and navigate the window
  95.   // in OnCreateNewWindowOnUI, using the params provided here.
  96.   bool is_new_browsing_instance =
  97.       params->opener_suppressed || no_javascript_access;
  98.   DCHECK(IsRenderFrameLive());
  99.   // The non-owning pointer |new_frame_tree| is valid in this stack frame since
  100.   // nothing can delete it until this thread is freed up again.
  101.   FrameTree* new_frame_tree =
  102.       delegate_->CreateNewWindow(this, *params, is_new_browsing_instance,
  103.                                  was_consumed, cloned_namespace.get());
  104.   transient_allow_popup_.Deactivate();
  105.   MaybeRecordAdClickMainFrameNavigationUseCounter(
  106.       /*initiator_frame=*/this, params->initiator_activation_and_ad_status);
  107.   if (is_new_browsing_instance || !new_frame_tree) {
  108.     // Opener suppressed, Javascript access disabled, or delegate did not
  109.     // provide a handle to any windows it created. In these cases, never tell
  110.     // the renderer about the new window.
  111.     std::move(callback).Run(mojom::CreateNewWindowStatus::kIgnore, nullptr);
  112.     return;
  113.   }
  114.   DCHECK(!params->opener_suppressed);
  115.   RenderFrameHostImpl* new_main_rfh =
  116.       new_frame_tree->root()->current_frame_host();
  117.   new_main_rfh->virtual_browsing_context_group_ =
  118.       popup_virtual_browsing_context_group;
  119.   new_main_rfh->soap_by_default_virtual_browsing_context_group_ =
  120.       popup_soap_by_default_virtual_browsing_context_group;
  121.   // COOP and COOP reporter are inherited from the opener to the popup's initial
  122.   // empty document.
  123.   if (IsOpenerSameOriginFrame(/*opener=*/this) &&
  124.       GetMainFrame()->coop_access_report_manager()->coop_reporter()) {
  125.     new_main_rfh->SetCrossOriginOpenerPolicyReporter(
  126.         std::make_unique<CrossOriginOpenerPolicyReporter>(
  127.             GetProcess()->GetStoragePartition(), GetLastCommittedURL(),
  128.             params->referrer->url,
  129.             // TODO(https://crbug.com/1385827): See if we need to send the
  130.             // origin to reporters as well.
  131.             new_main_rfh->cross_origin_opener_policy(), GetReportingSource(),
  132.             isolation_info_.network_anonymization_key()));
  133.   }
  134.   mojo::PendingAssociatedRemote<mojom::Frame> pending_frame_remote;
  135.   mojo::PendingAssociatedReceiver<mojom::Frame> pending_frame_receiver =
  136.       pending_frame_remote.InitWithNewEndpointAndPassReceiver();
  137.   new_main_rfh->SetMojomFrameRemote(std::move(pending_frame_remote));
  138.   mojo::PendingRemote<blink::mojom::BrowserInterfaceBroker>
  139.       browser_interface_broker;
  140.   new_main_rfh->BindBrowserInterfaceBrokerReceiver(
  141.       browser_interface_broker.InitWithNewPipeAndPassReceiver());
  142.   mojo::PendingAssociatedRemote<blink::mojom::AssociatedInterfaceProvider>
  143.       pending_associated_interface_provider;
  144.   new_main_rfh->BindAssociatedInterfaceProviderReceiver(
  145.       pending_associated_interface_provider
  146.           .InitWithNewEndpointAndPassReceiver());
  147.   // With this path, RenderViewHostImpl::CreateRenderView is never called
  148.   // because `blink::WebView` is already created on the renderer side. Thus we
  149.   // need to establish the connection here.
  150.   mojo::PendingAssociatedRemote<blink::mojom::PageBroadcast> page_broadcast;
  151.   mojo::PendingAssociatedReceiver<blink::mojom::PageBroadcast>
  152.       page_broadcast_receiver =
  153.           page_broadcast.InitWithNewEndpointAndPassReceiver();
  154.   auto widget_params =
  155.       new_main_rfh->GetLocalRenderWidgetHost()
  156.           ->BindAndGenerateCreateFrameWidgetParamsForNewWindow();
  157.   new_main_rfh->render_view_host()->BindPageBroadcast(
  158.       std::move(page_broadcast));
  159.   bool wait_for_debugger =
  160.       devtools_instrumentation::ShouldWaitForDebuggerInWindowOpen();
  161.   mojom::CreateNewWindowReplyPtr reply = mojom::CreateNewWindowReply::New(
  162.       new_main_rfh->GetFrameToken(), new_main_rfh->GetRoutingID(),
  163.       std::move(pending_frame_receiver), std::move(widget_params),
  164.       std::move(page_broadcast_receiver), std::move(browser_interface_broker),
  165.       std::move(pending_associated_interface_provider), cloned_namespace->id(),
  166.       new_main_rfh->GetDevToolsFrameToken(), wait_for_debugger,
  167.       new_main_rfh->GetDocumentToken(),
  168.       new_main_rfh->policy_container_host()->CreatePolicyContainerForBlink(),
  169.       blink::BrowsingContextGroupInfo(
  170.           new_main_rfh->GetSiteInstance()->browsing_instance_token(),
  171.           new_main_rfh->GetSiteInstance()->coop_related_group_token()),
  172.       delegate_->GetColorProviderColorMaps());
  173.   std::move(callback).Run(mojom::CreateNewWindowStatus::kSuccess,
  174.                           std::move(reply));
  175.   // The mojom reply callback with kSuccess causes the renderer to create the
  176.   // renderer-side objects.
  177.   new_main_rfh->render_view_host()->RenderViewCreated(new_main_rfh);
  178. }
复制代码
子历程发送消息定义在
F:\code\google\src\out\Debug\gen\content\common\frame.mojom.cc
message.set_method_name("CreateNewWindow");
  1. FrameHostProxy::FrameHostProxy(mojo::MessageReceiverWithResponder* receiver)
  2.     : receiver_(receiver) {
  3. }
  4. bool FrameHostProxy::CreateNewWindow(
  5.     CreateNewWindowParamsPtr param_params, CreateNewWindowStatus* out_param_status, CreateNewWindowReplyPtr* out_param_reply) {
  6. #if BUILDFLAG(MOJO_TRACE_ENABLED)
  7.   TRACE_EVENT_BEGIN1(
  8.     "mojom", "Call content::mojom::FrameHost::CreateNewWindow (sync)", "input_parameters",
  9.     [&](perfetto::TracedValue context){
  10.       auto dict = std::move(context).WriteDictionary();
  11.       perfetto::WriteIntoTracedValueWithFallback(
  12.            dict.AddItem("params"), param_params,
  13.                         "<value of type CreateNewWindowParamsPtr>");
  14.    });
  15. #else
  16.   TRACE_EVENT0("mojom", "FrameHost::CreateNewWindow");
  17. #endif
  18.   
  19.   const bool kExpectsResponse = true;
  20.   const bool kIsSync = true;
  21.   const bool kAllowInterrupt =
  22.       true;
  23.   const bool is_urgent = false;
  24.   
  25.   const uint32_t kFlags =
  26.       ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
  27.       ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
  28.       ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt) |
  29.       ((is_urgent) ? mojo::Message::kFlagIsUrgent : 0);
  30.   
  31.   mojo::Message message(
  32.       internal::kFrameHost_CreateNewWindow_Name, kFlags, 0, 0, nullptr);
  33.   mojo::internal::MessageFragment<
  34.       ::content::mojom::internal::FrameHost_CreateNewWindow_Params_Data> params(
  35.           message);
  36.   params.Allocate();
  37.   mojo::internal::MessageFragment<
  38.       typename decltype(params->params)::BaseType> params_fragment(
  39.           params.message());
  40.   mojo::internal::Serialize<::content::mojom::CreateNewWindowParamsDataView>(
  41.       param_params, params_fragment);
  42.   params->params.Set(
  43.       params_fragment.is_null() ? nullptr : params_fragment.data());
  44.   MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
  45.       params->params.is_null(),
  46.       mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
  47.       "null params in FrameHost.CreateNewWindow request");
  48. #if defined(ENABLE_IPC_FUZZER)
  49.   message.set_interface_name(FrameHost::Name_);
  50.   message.set_method_name("CreateNewWindow");
  51. #endif
  52.   bool result = false;
  53.   std::unique_ptr<mojo::MessageReceiver> responder(
  54.       new FrameHost_CreateNewWindow_HandleSyncResponse(
  55.           &result, out_param_status, out_param_reply));
  56.   ::mojo::internal::SendMojoMessage(*receiver_, message, std::move(responder));
  57. #if BUILDFLAG(MOJO_TRACE_ENABLED)
  58.   TRACE_EVENT_END1(
  59.     "mojom", "FrameHost::CreateNewWindow", "sync_response_parameters",
  60.     [&](perfetto::TracedValue context){
  61.       auto dict = std::move(context).WriteDictionary();
  62.       perfetto::WriteIntoTracedValueWithFallback(
  63.            dict.AddItem("status"), out_param_status,
  64.                         "<value of type CreateNewWindowStatus>");
  65.       perfetto::WriteIntoTracedValueWithFallback(
  66.            dict.AddItem("reply"), out_param_reply,
  67.                         "<value of type CreateNewWindowReplyPtr>");
  68.    });
  69. #endif
  70.   return result;
  71. }
复制代码
总结:至此分析完毕。


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

徐锦洪

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表