HtmlFormElement
sealed class HtmlFormElement : HtmlElement, IHtmlFormElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, IConstructableFormElement, IConstructableElement, IConstructableNode
Represents the form element.
using AngleSharp.Browser;
using AngleSharp.Dom;
using AngleSharp.Dom.Events;
using AngleSharp.Html.Construction;
using AngleSharp.Html.Forms;
using AngleSharp.Html.Forms.Submitters;
using AngleSharp.Io;
using AngleSharp.Text;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace AngleSharp.Html.Dom
{
[System.Runtime.CompilerServices.NullableContext(1)]
[System.Runtime.CompilerServices.Nullable(0)]
internal sealed class HtmlFormElement : HtmlElement, IHtmlFormElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, IConstructableFormElement, IConstructableElement, IConstructableNode
{
[System.Runtime.CompilerServices.Nullable(2)]
private HtmlFormControlsCollection _elements;
[System.Runtime.CompilerServices.Nullable(2)]
public IElement this[int index] {
[System.Runtime.CompilerServices.NullableContext(2)]
get {
return Elements[index];
}
}
[System.Runtime.CompilerServices.Nullable(2)]
public IElement this[string name] {
[return: System.Runtime.CompilerServices.Nullable(2)]
get {
return Elements[name];
}
}
[System.Runtime.CompilerServices.Nullable(2)]
public string Name {
[System.Runtime.CompilerServices.NullableContext(2)]
get {
return this.GetOwnAttribute(AttributeNames.Name);
}
[System.Runtime.CompilerServices.NullableContext(2)]
set {
this.SetOwnAttribute(AttributeNames.Name, value, false);
}
}
public int Length => Elements.Length;
public HtmlFormControlsCollection Elements => _elements ?? (_elements = new HtmlFormControlsCollection(this, null));
IHtmlFormControlsCollection IHtmlFormElement.Elements {
get {
return Elements;
}
}
[System.Runtime.CompilerServices.Nullable(2)]
public string AcceptCharset {
[System.Runtime.CompilerServices.NullableContext(2)]
get {
return this.GetOwnAttribute(AttributeNames.AcceptCharset);
}
[System.Runtime.CompilerServices.NullableContext(2)]
set {
this.SetOwnAttribute(AttributeNames.AcceptCharset, value, false);
}
}
public string Action {
get {
return this.GetOwnAttribute(AttributeNames.Action) ?? base.Owner.DocumentUri;
}
set {
this.SetOwnAttribute(AttributeNames.Action, value, false);
}
}
[System.Runtime.CompilerServices.Nullable(2)]
public string Autocomplete {
[System.Runtime.CompilerServices.NullableContext(2)]
get {
return this.GetOwnAttribute(AttributeNames.AutoComplete);
}
[System.Runtime.CompilerServices.NullableContext(2)]
set {
this.SetOwnAttribute(AttributeNames.AutoComplete, value, false);
}
}
public string Enctype {
get {
return this.GetOwnAttribute(AttributeNames.Enctype).ToEncodingType() ?? MimeTypeNames.UrlencodedForm;
}
[param: System.Diagnostics.CodeAnalysis.AllowNull]
set {
this.SetOwnAttribute(AttributeNames.Enctype, value, false);
}
}
public string Encoding {
get {
return Enctype;
}
set {
Enctype = value;
}
}
public string Method {
get {
return this.GetOwnAttribute(AttributeNames.Method).ToFormMethod() ?? FormMethodNames.Get;
}
set {
this.SetOwnAttribute(AttributeNames.Method, value, false);
}
}
public bool NoValidate {
get {
return this.GetBoolAttribute(AttributeNames.NoValidate);
}
set {
this.SetBoolAttribute(AttributeNames.NoValidate, value);
}
}
public string Target {
get {
return this.GetOwnAttribute(AttributeNames.Target) ?? string.Empty;
}
set {
this.SetOwnAttribute(AttributeNames.Target, value, false);
}
}
public HtmlFormElement(Document owner, [System.Runtime.CompilerServices.Nullable(2)] string prefix = null)
: base(owner, TagNames.Form, prefix, NodeFlags.Special)
{
}
public Task<IDocument> SubmitAsync()
{
DocumentRequest submission = GetSubmission();
return base.Context.ResolveTargetContext(Target).NavigateToAsync(submission, default(CancellationToken));
}
public Task<IDocument> SubmitAsync(IHtmlElement sourceElement)
{
DocumentRequest submission = GetSubmission(sourceElement);
return base.Context.ResolveTargetContext(Target).NavigateToAsync(submission, default(CancellationToken));
}
public DocumentRequest GetSubmission()
{
return SubmitForm(this, true);
}
public DocumentRequest GetSubmission(IHtmlElement sourceElement)
{
return SubmitForm(sourceElement ?? this, false);
}
public void Reset()
{
foreach (HtmlFormControlElement element in Elements) {
element.Reset();
}
}
public bool CheckValidity()
{
IEnumerable<HtmlFormControlElement> invalidControls = GetInvalidControls();
bool result = true;
foreach (HtmlFormControlElement item in invalidControls) {
if (!item.FireSimpleEvent(EventNames.Invalid, false, true))
result = false;
}
return result;
}
private IEnumerable<HtmlFormControlElement> GetInvalidControls()
{
foreach (HtmlFormControlElement element in Elements) {
if (element.WillValidate && !element.CheckValidity())
yield return element;
}
}
public bool ReportValidity()
{
IEnumerable<HtmlFormControlElement> invalidControls = GetInvalidControls();
bool result = true;
bool flag = false;
foreach (HtmlFormControlElement item in invalidControls) {
if (!item.FireSimpleEvent(EventNames.Invalid, false, true)) {
if (!flag) {
item.DoFocus();
flag = true;
}
result = false;
}
}
return result;
}
public void RequestAutocomplete()
{
}
[return: System.Runtime.CompilerServices.Nullable(2)]
private DocumentRequest SubmitForm(IHtmlElement from, bool submittedFromSubmitMethod)
{
Document owner = base.Owner;
if ((owner.ActiveSandboxing & Sandboxes.Forms) != Sandboxes.Forms) {
if (submittedFromSubmitMethod || from.HasAttribute(AttributeNames.FormNoValidate) || NoValidate || CheckValidity()) {
Url url = string.IsNullOrEmpty(Action) ? new Url(owner.DocumentUri) : this.HyperReference(Action);
string scheme = url.Scheme;
HttpMethod method = Method.ToEnum(HttpMethod.Get);
return SubmitForm(method, scheme, url, from);
}
this.FireSimpleEvent(EventNames.Invalid, false, false);
}
return null;
}
private DocumentRequest SubmitForm(HttpMethod method, string scheme, Url action, IHtmlElement submitter)
{
if (scheme.IsOneOf(ProtocolNames.Http, ProtocolNames.Https)) {
switch (method) {
case HttpMethod.Get:
return MutateActionUrl(action, submitter);
case HttpMethod.Post:
return SubmitAsEntityBody(action, submitter);
}
} else if (scheme.Is(ProtocolNames.Data)) {
switch (method) {
case HttpMethod.Get:
return GetActionUrl(action);
case HttpMethod.Post:
return PostToData(action, submitter);
}
} else if (scheme.Is(ProtocolNames.Mailto)) {
switch (method) {
case HttpMethod.Get:
return MailWithHeaders(action, submitter);
case HttpMethod.Post:
return MailAsBody(action, submitter);
}
} else if (scheme.IsOneOf(ProtocolNames.Ftp, ProtocolNames.JavaScript)) {
return GetActionUrl(action);
}
return MutateActionUrl(action, submitter);
}
private DocumentRequest PostToData(Url action, IHtmlElement submitter)
{
string charset = string.IsNullOrEmpty(AcceptCharset) ? base.Owner.CharacterSet : AcceptCharset;
FormDataSet formDataSet = ConstructDataSet(submitter);
string enctype = Enctype;
IHtmlEncoder service = base.Owner.Context.GetService<IHtmlEncoder>();
string s = string.Empty;
using (StreamReader streamReader = new StreamReader(formDataSet.CreateBody(enctype, charset, service)))
s = streamReader.ReadToEnd();
if (action.Href.Contains("%%%%")) {
s = TextEncoding.UsAscii.GetBytes(s).UrlEncode();
action.Href = action.Href.ReplaceFirst("%%%%", s);
} else if (action.Href.Contains("%%")) {
s = TextEncoding.Utf8.GetBytes(s).UrlEncode();
action.Href = action.Href.ReplaceFirst("%%", s);
}
return GetActionUrl(action);
}
private DocumentRequest MailWithHeaders(Url action, IHtmlElement submitter)
{
Stream stream = ConstructDataSet(submitter).AsUrlEncoded(TextEncoding.UsAscii);
string text = string.Empty;
using (StreamReader streamReader = new StreamReader(stream))
text = streamReader.ReadToEnd();
action.Query = text.Replace("+", "%20");
return GetActionUrl(action);
}
private DocumentRequest MailAsBody(Url action, IHtmlElement submitter)
{
FormDataSet formDataSet = ConstructDataSet(submitter);
string enctype = Enctype;
Encoding usAscii = TextEncoding.UsAscii;
IHtmlEncoder service = base.Owner.Context.GetService<IHtmlEncoder>();
Stream stream = formDataSet.CreateBody(enctype, usAscii, service);
string s = string.Empty;
using (StreamReader streamReader = new StreamReader(stream))
s = streamReader.ReadToEnd();
action.Query = "body=" + usAscii.GetBytes(s).UrlEncode();
return GetActionUrl(action);
}
private DocumentRequest GetActionUrl(Url action)
{
return DocumentRequest.Get(action, this, base.Owner.DocumentUri);
}
private DocumentRequest SubmitAsEntityBody(Url url, IHtmlElement submitter)
{
string charset = string.IsNullOrEmpty(AcceptCharset) ? base.Owner.CharacterSet : AcceptCharset;
FormDataSet formDataSet = ConstructDataSet(submitter);
string enctype = Enctype;
IHtmlEncoder service = base.Owner.Context.GetService<IHtmlEncoder>();
Stream stream = formDataSet.CreateBody(enctype, charset, service);
if (enctype.Isi(MimeTypeNames.MultipartForm))
return DocumentRequest.PostAsMultipart(url, stream, formDataSet.Boundary);
return DocumentRequest.Post(url, stream, enctype, this, base.Owner.DocumentUri);
}
private DocumentRequest MutateActionUrl(Url action, IHtmlElement submitter)
{
string charset = string.IsNullOrEmpty(AcceptCharset) ? base.Owner.CharacterSet : AcceptCharset;
FormDataSet formDataSet = ConstructDataSet(submitter);
Encoding encoding = TextEncoding.Resolve(charset);
using (StreamReader streamReader = new StreamReader(formDataSet.AsUrlEncoded(encoding)))
action.Query = streamReader.ReadToEnd();
return GetActionUrl(action);
}
private FormDataSet ConstructDataSet(IHtmlElement submitter)
{
FormDataSet formDataSet = new FormDataSet();
foreach (HtmlFormControlElement node in this.GetNodes<HtmlFormControlElement>(true, null)) {
if (!node.IsDisabled && !(node.ParentElement is IHtmlDataListElement) && node.Form == this)
node.ConstructDataSet(formDataSet, submitter);
}
return formDataSet;
}
}
}