AngleSharp by Florian Rappl

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

.NET API 1,171,968 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, 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 GetAttribute(AttributeNames.Name); } set { SetAttribute(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 GetAttribute(AttributeNames.AcceptCharset); } set { SetAttribute(AttributeNames.AcceptCharset, value); } } public string Action { get { return GetAttribute(AttributeNames.Action); } set { SetAttribute(AttributeNames.Action, value); } } public string Autocomplete { get { return GetAttribute(AttributeNames.AutoComplete); } set { SetAttribute(AttributeNames.AutoComplete, value); } } public string Enctype { get { return CheckEncType(GetAttribute(AttributeNames.Enctype)); } set { SetAttribute(AttributeNames.Enctype, CheckEncType(value)); } } public string Encoding { get { return Enctype; } set { Enctype = value; } } public string Method { get { return GetAttribute(AttributeNames.Method) ?? string.Empty; } set { SetAttribute(AttributeNames.Method, value); } } public bool NoValidate { get { return GetAttribute(AttributeNames.NoValidate) != null; } set { SetAttribute(AttributeNames.NoValidate, value ? string.Empty : null); } } public string Target { get { return GetAttribute(AttributeNames.Target); } set { SetAttribute(AttributeNames.Target, value); } } public HtmlFormElement(Document owner) : base(owner, Tags.Form, 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.StandardForm, 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(action, HttpMethod.Get, null, null); } 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.StandardForm, 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(action, HttpMethod.Get, null, null); } private void SubmitAsEntityBody(Url action) { string charset = string.IsNullOrEmpty(AcceptCharset) ? base.Owner.CharacterSet : AcceptCharset; FormDataSet formDataSet = ConstructDataSet(null); string enctype = Enctype; string mime = string.Empty; Stream body = null; if (enctype.Equals(MimeTypes.StandardForm, StringComparison.OrdinalIgnoreCase)) { body = formDataSet.AsUrlEncoded(TextEncoding.Resolve(charset)); mime = MimeTypes.StandardForm; } else if (enctype.Equals(MimeTypes.MultipartForm, StringComparison.OrdinalIgnoreCase)) { body = formDataSet.AsMultipart(TextEncoding.Resolve(charset)); mime = MimeTypes.MultipartForm + "; boundary=" + formDataSet.Boundary; } else if (enctype.Equals(MimeTypes.Plain, StringComparison.OrdinalIgnoreCase)) { body = formDataSet.AsPlaintext(TextEncoding.Resolve(charset)); mime = MimeTypes.Plain; } _navigationTask = NavigateTo(action, HttpMethod.Post, body, mime); } private async Task<IDocument> NavigateTo(Url action, HttpMethod method, Stream body = null, string mime = null) { if (_navigationTask != null) { _cts.Cancel(); _navigationTask = null; _cts = new CancellationTokenSource(); } IRequester requester = Owner.Options.GetRequester(action.Scheme); if (requester != null) { using (IResponse response = await requester.SendAsync(action, body, mime, method, _cts.Token).ConfigureAwait(false)) { return await Owner.Context.OpenAsync(response, _cts.Token).ConfigureAwait(false); } } return null; } 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 string CheckEncType(string encType) { if (!string.IsNullOrEmpty(encType) && (encType.Equals(MimeTypes.Plain, StringComparison.OrdinalIgnoreCase) || encType.Equals(MimeTypes.MultipartForm, StringComparison.OrdinalIgnoreCase))) return encType; return MimeTypes.StandardForm; } } }