AngleSharp by Florian Rappl

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

.NET API 737,792 bytes

 HTMLFormElement

public sealed class HTMLFormElement : HTMLElement
Represents the form element.
using AngleSharp.DOM.Collections; using System; using System.IO; using System.Text; using System.Threading; using System.Threading.Tasks; namespace AngleSharp.DOM.Html { [DOM("HTMLFormElement")] public sealed class HTMLFormElement : HTMLElement { private Task _plannedNavigation; private CancellationTokenSource _cancel; private HTMLFormControlsCollection _elements; public Element this[int index] { get { return _elements[index]; } } public object this[string name] { get { return _elements[name]; } } [DOM("name")] public string Name { get { return GetAttribute("name"); } set { SetAttribute("name", value); } } [DOM("length")] public int Length { get { return _elements.Length; } } [DOM("elements")] public HTMLFormControlsCollection Elements { get { return _elements; } } [DOM("acceptCharset")] public string AcceptCharset { get { return GetAttribute("acceptCharset"); } set { SetAttribute("acceptCharset", value); } } [DOM("action")] public string Action { get { return GetAttribute("action"); } set { SetAttribute("action", value); } } [DOM("autocomplete")] public PowerState Autocomplete { get { return Element.ToEnum(GetAttribute("autocomplete"), PowerState.On); } set { SetAttribute("autocomplete", value.ToString()); } } [DOM("enctype")] public string Enctype { get { return CheckEncType(GetAttribute("enctype")); } set { SetAttribute("enctype", CheckEncType(value)); } } [DOM("encoding")] public string Encoding { get { return Enctype; } set { Enctype = value; } } [DOM("method")] public HttpMethod Method { get { return Element.ToEnum(GetAttribute("method"), HttpMethod.Get); } set { SetAttribute("method", value.ToString()); } } [DOM("noValidate")] public bool NoValidate { get { return GetAttribute("novalidate") != null; } set { SetAttribute("novalidate", value ? string.Empty : null); } } [DOM("target")] public string Target { get { return GetAttribute("target"); } set { SetAttribute("target", value); } } public Task PlannedNavigation => _plannedNavigation; protected internal override bool IsSpecial => true; internal HTMLFormElement() { _cancel = new CancellationTokenSource(); _name = "form"; _elements = new HTMLFormControlsCollection(this); } [DOM("submit")] public void Submit() { SubmitForm(this, true); } [DOM("reset")] public void Reset() { foreach (HTMLFormControlElement element in _elements) { element.Reset(); } } [DOM("checkValidity")] public bool CheckValidity() { foreach (HTMLFormControlElement element in _elements) { if (!element.CheckValidity()) return false; } return true; } private void SubmitForm(HTMLElement from, bool submittedFromSubmitMethod) { Document ownerDocument = base.OwnerDocument; if (!submittedFromSubmitMethod && from.Attributes[AttributeNames.FormNoValidate] == null && NoValidate && !CheckValidity()) FireSimpleEvent(EventNames.Invalid); else { string text = Action; if (string.IsNullOrEmpty(text)) text = ownerDocument.DocumentUri; if (!Location.IsAbsolute(text)) text = Location.MakeAbsolute(from.BaseURI, text); Location location = new Location(text); string a = location.Protocol.TrimEnd(new char[1] { ':' }); if (a == KnownProtocols.Http || a == KnownProtocols.Https) { if (Method == HttpMethod.Get) MutateActionUrl(location); else if (Method == HttpMethod.Post) { SubmitAsEntityBody(location); } } else if (a == KnownProtocols.Data) { if (Method == HttpMethod.Get) GetActionUrl(location); else if (Method == HttpMethod.Post) { PostToData(location); } } else if (a == KnownProtocols.Mailto) { if (Method == HttpMethod.Get) MailWithHeaders(location); else if (Method == HttpMethod.Post) { MailAsBody(location); } } else if (a == KnownProtocols.Ftp || a == KnownProtocols.JavaScript) { GetActionUrl(location); } else { MutateActionUrl(location); } } } private void PostToData(Location action) { string charset = string.IsNullOrEmpty(AcceptCharset) ? base.OwnerDocument.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(DocumentEncoding.Resolve(charset)))) value = streamReader.ReadToEnd(); } else if (enctype.Equals(MimeTypes.MultipartForm, StringComparison.OrdinalIgnoreCase)) { using (StreamReader streamReader2 = new StreamReader(formDataSet.AsMultipart(DocumentEncoding.Resolve(charset)))) value = streamReader2.ReadToEnd(); } else if (enctype.Equals(MimeTypes.Plain, StringComparison.OrdinalIgnoreCase)) { using (StreamReader streamReader3 = new StreamReader(formDataSet.AsPlaintext(DocumentEncoding.Resolve(charset)))) value = streamReader3.ReadToEnd(); } if (action.Href.Contains("%%%%")) { value = value.UrlEncode(System.Text.Encoding.GetEncoding("us-ascii")); action.Href = action.Href.ReplaceFirst("%%%%", value); } else if (action.Href.Contains("%%")) { value = value.UrlEncode(System.Text.Encoding.UTF8); action.Href = action.Href.ReplaceFirst("%%", value); } _plannedNavigation = NavigateTo(action.ToUri(), HttpMethod.Get, null, null); } private void MailWithHeaders(Location action) { FormDataSet formDataSet = ConstructDataSet(null); Stream stream = formDataSet.AsUrlEncoded(System.Text.Encoding.GetEncoding("us-ascii")); string text = string.Empty; using (StreamReader streamReader = new StreamReader(stream)) text = streamReader.ReadToEnd(); action.Search = text.Replace("+", "%20"); GetActionUrl(action); } private void MailAsBody(Location action) { FormDataSet formDataSet = ConstructDataSet(null); string enctype = Enctype; Encoding encoding = System.Text.Encoding.GetEncoding("us-ascii"); 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.Search = "body=" + value.UrlEncode(encoding); GetActionUrl(action); } private void GetActionUrl(Location action) { _plannedNavigation = NavigateTo(action.ToUri(), HttpMethod.Get, null, null); } private void SubmitAsEntityBody(Location action) { string charset = string.IsNullOrEmpty(AcceptCharset) ? base.OwnerDocument.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(DocumentEncoding.Resolve(charset)); mime = MimeTypes.StandardForm; } else if (enctype.Equals(MimeTypes.MultipartForm, StringComparison.OrdinalIgnoreCase)) { body = formDataSet.AsMultipart(DocumentEncoding.Resolve(charset)); mime = MimeTypes.MultipartForm + "; boundary=" + formDataSet.Boundary; } else if (enctype.Equals(MimeTypes.Plain, StringComparison.OrdinalIgnoreCase)) { body = formDataSet.AsPlaintext(DocumentEncoding.Resolve(charset)); mime = MimeTypes.Plain; } _plannedNavigation = NavigateTo(action.ToUri(), HttpMethod.Post, body, mime); } private async Task NavigateTo(Uri action, HttpMethod method, Stream body = null, string mime = null) { if (_plannedNavigation != null) { _cancel.Cancel(); _plannedNavigation = null; _cancel = new CancellationTokenSource(); } Stream stream = await _owner.Options.SendAsync(action, body, mime, method, _cancel.Token, false); (_owner as HTMLDocument)?.Load(stream); } private void MutateActionUrl(Location action) { string charset = string.IsNullOrEmpty(AcceptCharset) ? base.OwnerDocument.CharacterSet : AcceptCharset; FormDataSet formDataSet = ConstructDataSet(null); Stream stream = formDataSet.AsUrlEncoded(DocumentEncoding.Resolve(charset)); using (StreamReader streamReader = new StreamReader(stream)) action.Search = streamReader.ReadToEnd(); GetActionUrl(action); } private FormDataSet ConstructDataSet(HTMLElement submitter = null) { FormDataSet formDataSet = new FormDataSet(); foreach (HTMLFormControlElement element in _elements) { if (!(element.ParentElement is HTMLDataListElement) && !element.Disabled) 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; } } }