AngleSharp by Florian Rappl

<PackageReference Include="AngleSharp" Version="0.8.3" />

.NET API 1,189,376 bytes

 HtmlFormElement

Represents the form element.
using AngleSharp.Dom.Collections; using AngleSharp.Dom.Css; using AngleSharp.Extensions; using AngleSharp.Html; using AngleSharp.Network; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace AngleSharp.Dom.Html { internal sealed class HtmlFormElement : HtmlElement, IHtmlFormElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IElementCssInlineStyle, IDisposable { private static readonly string UsAscii = "us-ascii"; private HtmlFormControlsCollection _elements; private Task<IDocument> _navigationTask; private CancellationTokenSource _cts; public IElement this[int index] { get { return Elements[index]; } } public IElement this[string name] { get { return Elements[name]; } } public string Name { get { return GetOwnAttribute(AttributeNames.Name); } set { SetOwnAttribute(AttributeNames.Name, value); } } public int Length => Elements.Length; public HtmlFormControlsCollection Elements => _elements ?? (_elements = new HtmlFormControlsCollection(this, null)); IHtmlFormControlsCollection IHtmlFormElement.Elements { get { return Elements; } } public string AcceptCharset { get { return GetOwnAttribute(AttributeNames.AcceptCharset); } set { SetOwnAttribute(AttributeNames.AcceptCharset, value); } } public string Action { get { return GetOwnAttribute(AttributeNames.Action); } set { SetOwnAttribute(AttributeNames.Action, value); } } public string Autocomplete { get { return GetOwnAttribute(AttributeNames.AutoComplete); } set { SetOwnAttribute(AttributeNames.AutoComplete, value); } } public string Enctype { get { return CheckEncType(GetOwnAttribute(AttributeNames.Enctype)); } set { SetOwnAttribute(AttributeNames.Enctype, CheckEncType(value)); } } public string Encoding { get { return Enctype; } set { Enctype = value; } } public string Method { get { return GetOwnAttribute(AttributeNames.Method) ?? string.Empty; } set { SetOwnAttribute(AttributeNames.Method, value); } } public bool NoValidate { get { return GetOwnAttribute(AttributeNames.NoValidate) != null; } set { SetOwnAttribute(AttributeNames.NoValidate, value ? string.Empty : null); } } public string Target { get { return GetOwnAttribute(AttributeNames.Target); } set { SetOwnAttribute(AttributeNames.Target, value); } } public HtmlFormElement(Document owner, string prefix = null) : base(owner, Tags.Form, prefix, NodeFlags.Special) { _cts = new CancellationTokenSource(); } public void Dispose() { if (_cts != null) _cts.Cancel(); _cts = null; _navigationTask = null; } public Task<IDocument> Submit() { SubmitForm(this, true); return _navigationTask; } 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() { } private void SubmitForm(HtmlElement from, bool submittedFromSubmitMethod) { Document owner = base.Owner; IBrowsingContext context = owner.Context; if (!owner.ActiveSandboxing.HasFlag(Sandboxes.Forms)) { if (!submittedFromSubmitMethod && !from.Attributes.Any((IAttr m) => m.Name == AttributeNames.FormNoValidate) && NoValidate && !CheckValidity()) this.FireSimpleEvent(EventNames.Invalid, false, false); else { Url url = string.IsNullOrEmpty(Action) ? new Url(owner.DocumentUri) : this.HyperReference(Action); bool flag = false; IBrowsingContext context2 = owner.Context; string target = Target; if (!string.IsNullOrEmpty(target) && (flag = (owner.GetTarget(target) == null))) owner.CreateTarget(target); int num; bool flag2; if (flag) num = 1; else flag2 = (owner.ReadyState != DocumentReadyState.Complete); string scheme = url.Scheme; HttpMethod httpMethod = Method.ToEnum(HttpMethod.Get); if (scheme == KnownProtocols.Http || scheme == KnownProtocols.Https) { switch (httpMethod) { case HttpMethod.Get: MutateActionUrl(url); break; case HttpMethod.Post: SubmitAsEntityBody(url); break; } } else if (scheme == KnownProtocols.Data) { switch (httpMethod) { case HttpMethod.Get: GetActionUrl(url); break; case HttpMethod.Post: PostToData(url); break; } } else if (scheme == KnownProtocols.Mailto) { switch (httpMethod) { case HttpMethod.Get: MailWithHeaders(url); break; case HttpMethod.Post: MailAsBody(url); break; } } else if (scheme == KnownProtocols.Ftp || scheme == KnownProtocols.JavaScript) { GetActionUrl(url); } else { MutateActionUrl(url); } } } } private void PostToData(Url action) { string charset = string.IsNullOrEmpty(AcceptCharset) ? base.Owner.CharacterSet : AcceptCharset; FormDataSet formDataSet = ConstructDataSet(null); string enctype = Enctype; string value = string.Empty; if (enctype.Equals(MimeTypes.UrlencodedForm, StringComparison.OrdinalIgnoreCase)) { using (StreamReader streamReader = new StreamReader(formDataSet.AsUrlEncoded(TextEncoding.Resolve(charset)))) value = streamReader.ReadToEnd(); } else if (enctype.Equals(MimeTypes.MultipartForm, StringComparison.OrdinalIgnoreCase)) { using (StreamReader streamReader2 = new StreamReader(formDataSet.AsMultipart(TextEncoding.Resolve(charset)))) value = streamReader2.ReadToEnd(); } else if (enctype.Equals(MimeTypes.Plain, StringComparison.OrdinalIgnoreCase)) { using (StreamReader streamReader3 = new StreamReader(formDataSet.AsPlaintext(TextEncoding.Resolve(charset)))) value = streamReader3.ReadToEnd(); } if (action.Href.Contains("%%%%")) { value = value.UrlEncode(TextEncoding.Resolve(UsAscii)); action.Href = action.Href.ReplaceFirst("%%%%", value); } else if (action.Href.Contains("%%")) { value = value.UrlEncode(TextEncoding.Utf8); action.Href = action.Href.ReplaceFirst("%%", value); } _navigationTask = NavigateTo(new DocumentRequest(action) { Referer = base.Owner.DocumentUri, Source = this }); } private void MailWithHeaders(Url action) { Stream stream = ConstructDataSet(null).AsUrlEncoded(TextEncoding.Resolve(UsAscii)); string text = string.Empty; using (StreamReader streamReader = new StreamReader(stream)) text = streamReader.ReadToEnd(); action.Query = text.Replace("+", "%20"); GetActionUrl(action); } private void MailAsBody(Url action) { FormDataSet formDataSet = ConstructDataSet(null); string enctype = Enctype; Encoding encoding = TextEncoding.Resolve(UsAscii); string value = string.Empty; if (enctype.Equals(MimeTypes.UrlencodedForm, StringComparison.OrdinalIgnoreCase)) { using (StreamReader streamReader = new StreamReader(formDataSet.AsUrlEncoded(encoding))) value = streamReader.ReadToEnd(); } else if (enctype.Equals(MimeTypes.MultipartForm, StringComparison.OrdinalIgnoreCase)) { using (StreamReader streamReader2 = new StreamReader(formDataSet.AsMultipart(encoding))) value = streamReader2.ReadToEnd(); } else if (enctype.Equals(MimeTypes.Plain, StringComparison.OrdinalIgnoreCase)) { using (StreamReader streamReader3 = new StreamReader(formDataSet.AsPlaintext(encoding))) value = streamReader3.ReadToEnd(); } action.Query = "body=" + value.UrlEncode(encoding); GetActionUrl(action); } private void GetActionUrl(Url action) { _navigationTask = NavigateTo(new DocumentRequest(action) { Referer = base.Owner.DocumentUri, Source = this }); } private void SubmitAsEntityBody(Url action) { string charset = string.IsNullOrEmpty(AcceptCharset) ? base.Owner.CharacterSet : AcceptCharset; FormDataSet formDataSet = ConstructDataSet(null); string enctype = Enctype; string mimeType = null; Stream body = Stream.Null; if (enctype.Equals(MimeTypes.UrlencodedForm, StringComparison.OrdinalIgnoreCase)) { body = formDataSet.AsUrlEncoded(TextEncoding.Resolve(charset)); mimeType = MimeTypes.UrlencodedForm; } else if (enctype.Equals(MimeTypes.MultipartForm, StringComparison.OrdinalIgnoreCase)) { body = formDataSet.AsMultipart(TextEncoding.Resolve(charset)); mimeType = MimeTypes.MultipartForm + "; boundary=" + formDataSet.Boundary; } else if (enctype.Equals(MimeTypes.Plain, StringComparison.OrdinalIgnoreCase)) { body = formDataSet.AsPlaintext(TextEncoding.Resolve(charset)); mimeType = MimeTypes.Plain; } _navigationTask = NavigateTo(new DocumentRequest(action) { Method = HttpMethod.Post, Source = this, Body = body, MimeType = mimeType, Referer = base.Owner.DocumentUri }); } private Task<IDocument> NavigateTo(DocumentRequest request) { if (_navigationTask != null) { _cts.Cancel(); _navigationTask = null; _cts = new CancellationTokenSource(); } return base.Owner.Context.OpenAsync(request, _cts.Token); } private void MutateActionUrl(Url action) { string charset = string.IsNullOrEmpty(AcceptCharset) ? base.Owner.CharacterSet : AcceptCharset; using (StreamReader streamReader = new StreamReader(ConstructDataSet(null).AsUrlEncoded(TextEncoding.Resolve(charset)))) action.Query = streamReader.ReadToEnd(); GetActionUrl(action); } private FormDataSet ConstructDataSet(HtmlElement submitter = null) { FormDataSet formDataSet = new FormDataSet(); foreach (HtmlFormControlElement element in Elements) { if (!(element.ParentElement is IHtmlDataListElement) && !element.IsDisabled) element.ConstructDataSet(formDataSet, submitter); } return formDataSet; } private static string CheckEncType(string encType) { if (!string.IsNullOrEmpty(encType) && (encType.Equals(MimeTypes.Plain, StringComparison.OrdinalIgnoreCase) || encType.Equals(MimeTypes.MultipartForm, StringComparison.OrdinalIgnoreCase))) return encType; return MimeTypes.UrlencodedForm; } } }