├── .github └── workflows │ └── dotnet-core.yml ├── .gitignore ├── HtmlGenerator.sln ├── LICENSE.md ├── README.md ├── resources └── screenshots │ └── 1.png ├── samples ├── HtmlGenerator.Sample.csproj └── Program.cs ├── src ├── Attribute.cs ├── Elements │ ├── HtmlAElement.cs │ ├── HtmlAreaElement.cs │ ├── HtmlAudioElement.cs │ ├── HtmlBaseElement.cs │ ├── HtmlButtonElement.cs │ ├── HtmlCanvasElement.cs │ ├── HtmlColElement.cs │ ├── HtmlColgroupElement.cs │ ├── HtmlDataElement.cs │ ├── HtmlDdElement.cs │ ├── HtmlDelElement.cs │ ├── HtmlDetailsElement.cs │ ├── HtmlDialogElement.cs │ ├── HtmlDlElement.cs │ ├── HtmlEmbedElement.cs │ ├── HtmlFormElement.cs │ ├── HtmlHrElement.cs │ ├── HtmlHtmlElement.cs │ ├── HtmlIframeElement.cs │ ├── HtmlImgElement.cs │ ├── HtmlInputElement.cs │ ├── HtmlInsElement.cs │ ├── HtmlLabelElement.cs │ ├── HtmlLiElement.cs │ ├── HtmlLinkElement.cs │ ├── HtmlMapElement.cs │ ├── HtmlMenuElement.cs │ ├── HtmlMenuItemElement.cs │ ├── HtmlMetaElement.cs │ ├── HtmlMeterElement.cs │ ├── HtmlObjectElement.cs │ ├── HtmlOlElement.cs │ ├── HtmlOptgroupElement.cs │ ├── HtmlOptionElement.cs │ ├── HtmlOutputElement.cs │ ├── HtmlParamElement.cs │ ├── HtmlProgressElement.cs │ ├── HtmlQElement.cs │ ├── HtmlScriptElement.cs │ ├── HtmlSelectElement.cs │ ├── HtmlSourceElement.cs │ ├── HtmlStyleElement.cs │ ├── HtmlTextAreaElement.cs │ ├── HtmlThElement.cs │ ├── HtmlTimeElement.cs │ ├── HtmlTrackElement.cs │ └── HtmlVideoElement.cs ├── Extensions │ └── StringExtensions.cs ├── HtmlAttribute.cs ├── HtmlComment.cs ├── HtmlDoctype.cs ├── HtmlDoctypeType.cs ├── HtmlDocument.cs ├── HtmlElement.cs ├── HtmlException.cs ├── HtmlGenerator.csproj ├── HtmlNode.cs ├── HtmlObject.cs ├── HtmlObjectLinkedList.cs ├── HtmlObjectType.cs ├── HtmlSerializeType.cs ├── HtmlText.cs ├── Requires.cs ├── SpecialTag.cs └── Tag.cs └── tests ├── AttributeTests.cs ├── Helpers.cs ├── HtmlAttributeTests.cs ├── HtmlCommentTests.cs ├── HtmlDoctypeTests.cs ├── HtmlDocumentTests.cs ├── HtmlElement.AddTests.cs ├── HtmlElement.ParseTests.cs ├── HtmlElement.ReadTests.cs ├── HtmlElement.RemoveTests.cs ├── HtmlElement.ReplaceTests.cs ├── HtmlElement.SerializeTests.cs ├── HtmlElementTests.cs ├── HtmlExceptionTests.cs ├── HtmlGenerator.Tests.csproj ├── HtmlNodeTests.cs ├── HtmlTextTests.cs └── TagTests.cs /.github/workflows/dotnet-core.yml: -------------------------------------------------------------------------------- 1 | name: .NET Core 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | build: 11 | 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v2 16 | - name: Setup .NET Core 17 | uses: actions/setup-dotnet@v1 18 | with: 19 | dotnet-version: 3.1.101 20 | - name: Install dependencies 21 | run: dotnet restore 22 | - name: Build 23 | run: dotnet build --configuration Release --no-restore 24 | - name: Test 25 | run: dotnet test --no-restore --verbosity normal 26 | - name: Generate coverage report 27 | run: dotnet test /p:CollectCoverage=true /p:CoverletOutput=TestResults/ /p:CoverletOutputFormat=opencover 28 | - name: Upload coverage to Codecov 29 | uses: codecov/codecov-action@v1 30 | with: 31 | file: tests/TestResults/coverage.netcoreapp3.1.opencover.xml 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.gitignore.io/api/visualstudio 2 | 3 | ### VisualStudio ### 4 | ## Ignore Visual Studio temporary files, build results, and 5 | ## files generated by popular Visual Studio add-ons. 6 | 7 | # User-specific files 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Build results 17 | [Dd]ebug/ 18 | [Dd]ebugPublic/ 19 | [Rr]elease/ 20 | [Rr]eleases/ 21 | x64/ 22 | x86/ 23 | bld/ 24 | [Bb]in/ 25 | [Oo]bj/ 26 | [Ll]og/ 27 | 28 | # Visual Studio 2015 cache/options directory 29 | .vs/ 30 | # Uncomment if you have tasks that create the project's static files in wwwroot 31 | #wwwroot/ 32 | 33 | # MSTest test Results 34 | [Tt]est[Rr]esult*/ 35 | [Bb]uild[Ll]og.* 36 | 37 | # NUNIT 38 | *.VisualState.xml 39 | TestResult.xml 40 | resources/coverage/ 41 | coverage.xml 42 | 43 | # Build Results of an ATL Project 44 | [Dd]ebugPS/ 45 | [Rr]eleasePS/ 46 | dlldata.c 47 | 48 | # DNX 49 | project.lock.json 50 | project.fragment.lock.json 51 | artifacts/ 52 | 53 | *_i.c 54 | *_p.c 55 | *_i.h 56 | *.ilk 57 | *.meta 58 | *.obj 59 | *.pch 60 | *.pdb 61 | *.pgc 62 | *.pgd 63 | *.rsp 64 | *.sbr 65 | *.tlb 66 | *.tli 67 | *.tlh 68 | *.tmp 69 | *.tmp_proj 70 | *.log 71 | *.vspscc 72 | *.vssscc 73 | .builds 74 | *.pidb 75 | *.svclog 76 | *.scc 77 | 78 | # Chutzpah Test files 79 | _Chutzpah* 80 | 81 | # Visual C++ cache files 82 | ipch/ 83 | *.aps 84 | *.ncb 85 | *.opendb 86 | *.opensdf 87 | *.sdf 88 | *.cachefile 89 | *.VC.db 90 | *.VC.VC.opendb 91 | 92 | # Visual Studio profiler 93 | *.psess 94 | *.vsp 95 | *.vspx 96 | *.sap 97 | 98 | # TFS 2012 Local Workspace 99 | $tf/ 100 | 101 | # Guidance Automation Toolkit 102 | *.gpState 103 | 104 | # ReSharper is a .NET coding add-in 105 | _ReSharper*/ 106 | *.[Rr]e[Ss]harper 107 | *.DotSettings.user 108 | 109 | # JustCode is a .NET coding add-in 110 | .JustCode 111 | 112 | # TeamCity is a build add-in 113 | _TeamCity* 114 | 115 | # DotCover is a Code Coverage Tool 116 | *.dotCover 117 | 118 | # Visual Studio code coverage results 119 | *.coverage 120 | *.coveragexml 121 | 122 | # NCrunch 123 | _NCrunch_* 124 | .*crunch*.local.xml 125 | nCrunchTemp_* 126 | 127 | # MightyMoose 128 | *.mm.* 129 | AutoTest.Net/ 130 | 131 | # Web workbench (sass) 132 | .sass-cache/ 133 | 134 | # Installshield output folder 135 | [Ee]xpress/ 136 | 137 | # DocProject is a documentation generator add-in 138 | DocProject/buildhelp/ 139 | DocProject/Help/*.HxT 140 | DocProject/Help/*.HxC 141 | DocProject/Help/*.hhc 142 | DocProject/Help/*.hhk 143 | DocProject/Help/*.hhp 144 | DocProject/Help/Html2 145 | DocProject/Help/html 146 | 147 | # Click-Once directory 148 | publish/ 149 | 150 | # Publish Web Output 151 | *.[Pp]ublish.xml 152 | *.azurePubxml 153 | # TODO: Comment the next line if you want to checkin your web deploy settings 154 | # but database connection strings (with potential passwords) will be unencrypted 155 | *.pubxml 156 | *.publishproj 157 | 158 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 159 | # checkin your Azure Web App publish settings, but sensitive information contained 160 | # in these scripts will be unencrypted 161 | PublishScripts/ 162 | 163 | # NuGet Packages 164 | *.nupkg 165 | # The packages folder can be ignored because of Package Restore 166 | **/packages/* 167 | # except build/, which is used as an MSBuild target. 168 | !**/packages/build/ 169 | # Uncomment if necessary however generally it will be regenerated when needed 170 | #!**/packages/repositories.config 171 | # NuGet v3's project.json files produces more ignoreable files 172 | *.nuget.props 173 | *.nuget.targets 174 | 175 | # Microsoft Azure Build Output 176 | csx/ 177 | *.build.csdef 178 | 179 | # Microsoft Azure Emulator 180 | ecf/ 181 | rcf/ 182 | 183 | # Windows Store app package directories and files 184 | AppPackages/ 185 | BundleArtifacts/ 186 | Package.StoreAssociation.xml 187 | _pkginfo.txt 188 | 189 | # Visual Studio cache files 190 | # files ending in .cache can be ignored 191 | *.[Cc]ache 192 | # but keep track of directories ending in .cache 193 | !*.[Cc]ache/ 194 | 195 | # Others 196 | ClientBin/ 197 | ~$* 198 | *~ 199 | *.dbmdl 200 | *.dbproj.schemaview 201 | *.jfm 202 | *.pfx 203 | *.publishsettings 204 | node_modules/ 205 | orleans.codegen.cs 206 | 207 | # Since there are multiple workflows, uncomment next line to ignore bower_components 208 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 209 | #bower_components/ 210 | 211 | # RIA/Silverlight projects 212 | Generated_Code/ 213 | 214 | # Backup & report files from converting an old project file 215 | # to a newer Visual Studio version. Backup files are not needed, 216 | # because we have git ;-) 217 | _UpgradeReport_Files/ 218 | Backup*/ 219 | UpgradeLog*.XML 220 | UpgradeLog*.htm 221 | 222 | # SQL Server files 223 | *.mdf 224 | *.ldf 225 | 226 | # Business Intelligence projects 227 | *.rdl.data 228 | *.bim.layout 229 | *.bim_*.settings 230 | 231 | # Microsoft Fakes 232 | FakesAssemblies/ 233 | 234 | # GhostDoc plugin setting file 235 | *.GhostDoc.xml 236 | 237 | # Node.js Tools for Visual Studio 238 | .ntvs_analysis.dat 239 | 240 | # Visual Studio 6 build log 241 | *.plg 242 | 243 | # Visual Studio 6 workspace options file 244 | *.opt 245 | 246 | # Visual Studio LightSwitch build output 247 | **/*.HTMLClient/GeneratedArtifacts 248 | **/*.DesktopClient/GeneratedArtifacts 249 | **/*.DesktopClient/ModelManifest.xml 250 | **/*.Server/GeneratedArtifacts 251 | **/*.Server/ModelManifest.xml 252 | _Pvt_Extensions 253 | 254 | # Paket dependency manager 255 | .paket/paket.exe 256 | paket-files/ 257 | 258 | # FAKE - F# Make 259 | .fake/ 260 | 261 | # JetBrains Rider 262 | .idea/ 263 | *.sln.iml 264 | 265 | # CodeRush 266 | .cr/ 267 | 268 | # Python Tools for Visual Studio (PTVS) 269 | __pycache__/ 270 | *.pyc 271 | 272 | # Cake - Uncomment if you are using it 273 | # tools/ 274 | 275 | ### VisualStudio Patch ### 276 | build/ -------------------------------------------------------------------------------- /HtmlGenerator.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26124.0 5 | MinimumVisualStudioVersion = 15.0.26124.0 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HtmlGenerator", "src\HtmlGenerator.csproj", "{C89CFB73-7317-40D3-A9F0-59571E4D00CA}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HtmlGenerator.Tests", "tests\HtmlGenerator.Tests.csproj", "{2251172B-0B8A-44E3-A764-7AE93B6AE96E}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HtmlGenerator.Sample", "samples\HtmlGenerator.Sample.csproj", "{AC37A7E4-13DE-4E46-8CBC-6190B633DC6B}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|Any CPU = Debug|Any CPU 15 | Debug|x64 = Debug|x64 16 | Debug|x86 = Debug|x86 17 | Release|Any CPU = Release|Any CPU 18 | Release|x64 = Release|x64 19 | Release|x86 = Release|x86 20 | EndGlobalSection 21 | GlobalSection(SolutionProperties) = preSolution 22 | HideSolutionNode = FALSE 23 | EndGlobalSection 24 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 25 | {C89CFB73-7317-40D3-A9F0-59571E4D00CA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 26 | {C89CFB73-7317-40D3-A9F0-59571E4D00CA}.Debug|Any CPU.Build.0 = Debug|Any CPU 27 | {C89CFB73-7317-40D3-A9F0-59571E4D00CA}.Debug|x64.ActiveCfg = Debug|Any CPU 28 | {C89CFB73-7317-40D3-A9F0-59571E4D00CA}.Debug|x64.Build.0 = Debug|Any CPU 29 | {C89CFB73-7317-40D3-A9F0-59571E4D00CA}.Debug|x86.ActiveCfg = Debug|Any CPU 30 | {C89CFB73-7317-40D3-A9F0-59571E4D00CA}.Debug|x86.Build.0 = Debug|Any CPU 31 | {C89CFB73-7317-40D3-A9F0-59571E4D00CA}.Release|Any CPU.ActiveCfg = Release|Any CPU 32 | {C89CFB73-7317-40D3-A9F0-59571E4D00CA}.Release|Any CPU.Build.0 = Release|Any CPU 33 | {C89CFB73-7317-40D3-A9F0-59571E4D00CA}.Release|x64.ActiveCfg = Release|Any CPU 34 | {C89CFB73-7317-40D3-A9F0-59571E4D00CA}.Release|x64.Build.0 = Release|Any CPU 35 | {C89CFB73-7317-40D3-A9F0-59571E4D00CA}.Release|x86.ActiveCfg = Release|Any CPU 36 | {C89CFB73-7317-40D3-A9F0-59571E4D00CA}.Release|x86.Build.0 = Release|Any CPU 37 | {2251172B-0B8A-44E3-A764-7AE93B6AE96E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 38 | {2251172B-0B8A-44E3-A764-7AE93B6AE96E}.Debug|Any CPU.Build.0 = Debug|Any CPU 39 | {2251172B-0B8A-44E3-A764-7AE93B6AE96E}.Debug|x64.ActiveCfg = Debug|Any CPU 40 | {2251172B-0B8A-44E3-A764-7AE93B6AE96E}.Debug|x64.Build.0 = Debug|Any CPU 41 | {2251172B-0B8A-44E3-A764-7AE93B6AE96E}.Debug|x86.ActiveCfg = Debug|Any CPU 42 | {2251172B-0B8A-44E3-A764-7AE93B6AE96E}.Debug|x86.Build.0 = Debug|Any CPU 43 | {2251172B-0B8A-44E3-A764-7AE93B6AE96E}.Release|Any CPU.ActiveCfg = Release|Any CPU 44 | {2251172B-0B8A-44E3-A764-7AE93B6AE96E}.Release|Any CPU.Build.0 = Release|Any CPU 45 | {2251172B-0B8A-44E3-A764-7AE93B6AE96E}.Release|x64.ActiveCfg = Release|Any CPU 46 | {2251172B-0B8A-44E3-A764-7AE93B6AE96E}.Release|x64.Build.0 = Release|Any CPU 47 | {2251172B-0B8A-44E3-A764-7AE93B6AE96E}.Release|x86.ActiveCfg = Release|Any CPU 48 | {2251172B-0B8A-44E3-A764-7AE93B6AE96E}.Release|x86.Build.0 = Release|Any CPU 49 | {AC37A7E4-13DE-4E46-8CBC-6190B633DC6B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 50 | {AC37A7E4-13DE-4E46-8CBC-6190B633DC6B}.Debug|Any CPU.Build.0 = Debug|Any CPU 51 | {AC37A7E4-13DE-4E46-8CBC-6190B633DC6B}.Debug|x64.ActiveCfg = Debug|Any CPU 52 | {AC37A7E4-13DE-4E46-8CBC-6190B633DC6B}.Debug|x64.Build.0 = Debug|Any CPU 53 | {AC37A7E4-13DE-4E46-8CBC-6190B633DC6B}.Debug|x86.ActiveCfg = Debug|Any CPU 54 | {AC37A7E4-13DE-4E46-8CBC-6190B633DC6B}.Debug|x86.Build.0 = Debug|Any CPU 55 | {AC37A7E4-13DE-4E46-8CBC-6190B633DC6B}.Release|Any CPU.ActiveCfg = Release|Any CPU 56 | {AC37A7E4-13DE-4E46-8CBC-6190B633DC6B}.Release|Any CPU.Build.0 = Release|Any CPU 57 | {AC37A7E4-13DE-4E46-8CBC-6190B633DC6B}.Release|x64.ActiveCfg = Release|Any CPU 58 | {AC37A7E4-13DE-4E46-8CBC-6190B633DC6B}.Release|x64.Build.0 = Release|Any CPU 59 | {AC37A7E4-13DE-4E46-8CBC-6190B633DC6B}.Release|x86.ActiveCfg = Release|Any CPU 60 | {AC37A7E4-13DE-4E46-8CBC-6190B633DC6B}.Release|x86.Build.0 = Release|Any CPU 61 | EndGlobalSection 62 | EndGlobal 63 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | #The MIT License (MIT) 2 | 3 | Copyright (c) 2020 Hugh Bellamy 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # HtmlGenerator 2 | [![Build status](https://ci.appveyor.com/api/projects/status/github/hughbe/html-generator?svg=true)](https://ci.appveyor.com/project/hughbe/html-generator/branch/master) [![Travis Build Status](https://travis-ci.org/hughbe/html-generator.svg?branch=master)](https://travis-ci.org/hughbe/html-generator) 3 | 4 | A library that simplifies generating complex HTML files from C# code. 5 | 6 | ![Sceenshot](https://github.com/hughbe/HtmlGenerator/blob/master/resources/screenshots/1.png "Screenshot 1") 7 | 8 | Installation Instructions 9 | -------------- 10 | #### Nuget 11 | - Run `PM> Install-Package HtmlGenerator` from the Package Manager Console 12 | - Add `using HtmlGenerator;` in all the files you want to use the library. 13 | 14 | #### DLL 15 | - [Download the *.dll file here](https://github.com/hughbe/html-generator/releases/latest) 16 | 17 | Contributions 18 | -------------- 19 | Please submit issues and pull requests for features, bugs and improvements. 20 | -------------------------------------------------------------------------------- /resources/screenshots/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hughbe/html-generator/19bed1137b31bdd5ae7c9f3a1faccfde0da8fc59/resources/screenshots/1.png -------------------------------------------------------------------------------- /samples/HtmlGenerator.Sample.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp3.1 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /samples/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using HtmlGenerator; 3 | 4 | namespace HtmlGeneratorSample 5 | { 6 | class Program 7 | { 8 | static void Main(string[] args) 9 | { 10 | Console.WriteLine("Hello World!"); 11 | } 12 | 13 | public void SendError(string errorMessage, string errorDescription) 14 | { 15 | var html = new HtmlDocument(); 16 | 17 | var head = html.Head; 18 | var body = html.Body; 19 | 20 | head.Add(Tag 21 | .Title 22 | .WithInnerText(errorMessage)); 23 | 24 | head.Add(Tag 25 | .Link 26 | .WithRel("stylesheet") 27 | .WithHref("css/styles.css")); 28 | 29 | body.Add(Tag 30 | .H1 31 | .WithInnerText(errorMessage)); 32 | 33 | body.Add(Tag.Hr); 34 | 35 | body.Add(Tag 36 | .P 37 | .WithInnerText(errorDescription)); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Attribute.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public static class Attribute 4 | { 5 | public static HtmlAttribute Accept(string value) => new HtmlAttribute("accept", value); 6 | public static HtmlAttribute AcceptCharset(string value) => new HtmlAttribute("accept-charset", value); 7 | public static HtmlAttribute AccessKey(string value) => new HtmlAttribute("accesskey", value); 8 | public static HtmlAttribute Action(string value) => new HtmlAttribute("action", value); 9 | public static HtmlAttribute Align => new HtmlAttribute("align"); 10 | public static HtmlAttribute AllowFullScreen => new HtmlAttribute("allowfullscreen"); 11 | public static HtmlAttribute Alt(string value) => new HtmlAttribute("alt", value); 12 | public static HtmlAttribute Async(string value) => new HtmlAttribute("async", value); 13 | public static HtmlAttribute AutoComplete(string value) => new HtmlAttribute("autocomplete", value); 14 | public static HtmlAttribute AutoFocus => new HtmlAttribute("autofocus"); 15 | public static HtmlAttribute AutoPlay(string value) => new HtmlAttribute("autoplay", value); 16 | public static HtmlAttribute AutoSave(string value) => new HtmlAttribute("autosave", value); 17 | 18 | public static HtmlAttribute BgColor(string value) => new HtmlAttribute("bgcolor", value); 19 | public static HtmlAttribute Border(string value) => new HtmlAttribute("border", value); 20 | 21 | public static HtmlAttribute CellPadding(string value) => new HtmlAttribute("cellpadding", value); 22 | public static HtmlAttribute CellSpacing(string value) => new HtmlAttribute("cellspacing", value); 23 | public static HtmlAttribute Charset(string value) => new HtmlAttribute("charset", value); 24 | public static HtmlAttribute Checked => new HtmlAttribute("checked"); 25 | public static HtmlAttribute Cite(string value) => new HtmlAttribute("cite", value); 26 | public static HtmlAttribute Class(string value) => new HtmlAttribute("class", value); 27 | public static HtmlAttribute Color(string value) => new HtmlAttribute("color", value); 28 | public static HtmlAttribute Cols(string value) => new HtmlAttribute("cols", value); 29 | public static HtmlAttribute ColSpan(string value) => new HtmlAttribute("colspan", value); 30 | public static HtmlAttribute Command(string value) => new HtmlAttribute("command", value); 31 | public static HtmlAttribute Compact(string value) => new HtmlAttribute("compact", value); 32 | public static HtmlAttribute Content(string value) => new HtmlAttribute("content", value); 33 | public static HtmlAttribute ContentEditable(string value) => new HtmlAttribute("contenteditable", value); 34 | public static HtmlAttribute ContextMenu(string value) => new HtmlAttribute("contextmenu", value); 35 | public static HtmlAttribute Controls => new HtmlAttribute("controls"); 36 | public static HtmlAttribute Coords(string value) => new HtmlAttribute("coords", value); 37 | public static HtmlAttribute CrossOrigin(string value) => new HtmlAttribute("crossorigin", value); 38 | 39 | public static HtmlAttribute Data(string value) => new HtmlAttribute("data", value); 40 | public static HtmlAttribute DateTime(string value) => new HtmlAttribute("datetime", value); 41 | public static HtmlAttribute Default => new HtmlAttribute("default"); 42 | public static HtmlAttribute DefaultStyle(string value) => new HtmlAttribute("default-style", value); 43 | public static HtmlAttribute Defer(string value) => new HtmlAttribute("defer", value); 44 | public static HtmlAttribute Dir(string value) => new HtmlAttribute("dir", value); 45 | public static HtmlAttribute Disabled => new HtmlAttribute("disabled"); 46 | public static HtmlAttribute Download(string value) => new HtmlAttribute("download", value); 47 | public static HtmlAttribute Draggable(string value) => new HtmlAttribute("draggable", value); 48 | public static HtmlAttribute DropZone(string value) => new HtmlAttribute("dropzone", value); 49 | 50 | public static HtmlAttribute EncType(string value) => new HtmlAttribute("enctype", value); 51 | 52 | public static HtmlAttribute For(string value) => new HtmlAttribute("for", value); 53 | public static HtmlAttribute Form(string value) => new HtmlAttribute("form", value); 54 | public static HtmlAttribute FormAction(string value) => new HtmlAttribute("formaction", value); 55 | public static HtmlAttribute FormEncType(string value) => new HtmlAttribute("formenctype", value); 56 | public static HtmlAttribute FormMethod(string value) => new HtmlAttribute("formmethod", value); 57 | public static HtmlAttribute FormNoValidate => new HtmlAttribute("formnovalidate"); 58 | public static HtmlAttribute FormTarget(string value) => new HtmlAttribute("formtarget", value); 59 | 60 | public static HtmlAttribute Headers(string value) => new HtmlAttribute("headers", value); 61 | public static HtmlAttribute Height(string value) => new HtmlAttribute("height", value); 62 | public static HtmlAttribute Hidden(string value) => new HtmlAttribute("hidden", value); 63 | public static HtmlAttribute High(string value) => new HtmlAttribute("high", value); 64 | public static HtmlAttribute Href(string value) => new HtmlAttribute("href", value); 65 | public static HtmlAttribute HrefLang(string value) => new HtmlAttribute("hreflang", value); 66 | public static HtmlAttribute HttpEquiv(string value) => new HtmlAttribute("http-equiv", value); 67 | 68 | public static HtmlAttribute Icon(string value) => new HtmlAttribute("icon", value); 69 | public static HtmlAttribute Id(string value) => new HtmlAttribute("id", value); 70 | public static HtmlAttribute InputMode(string value) => new HtmlAttribute("inputmode", value); 71 | public static HtmlAttribute Integrity(string value) => new HtmlAttribute("integrity", value); 72 | public static HtmlAttribute IsMap(string value) => new HtmlAttribute("ismap", value); 73 | 74 | public static HtmlAttribute Kind(string value) => new HtmlAttribute("kind", value); 75 | 76 | public static HtmlAttribute Label(string value) => new HtmlAttribute("label", value); 77 | public static HtmlAttribute Lang(string value) => new HtmlAttribute("lang", value); 78 | public static HtmlAttribute List(string value) => new HtmlAttribute("list", value); 79 | public static HtmlAttribute LongDesc(string value) => new HtmlAttribute("longdesc", value); 80 | public static HtmlAttribute Loop(string value) => new HtmlAttribute("loop", value); 81 | public static HtmlAttribute Low(string value) => new HtmlAttribute("low", value); 82 | 83 | public static HtmlAttribute Max(string value) => new HtmlAttribute("max", value); 84 | public static HtmlAttribute MaxLength(string value) => new HtmlAttribute("maxlength", value); 85 | public static HtmlAttribute Media(string value) => new HtmlAttribute("media", value); 86 | public static HtmlAttribute Method(string value) => new HtmlAttribute("method", value); 87 | public static HtmlAttribute Min(string value) => new HtmlAttribute("min", value); 88 | public static HtmlAttribute MinLength(string value) => new HtmlAttribute("minlength", value); 89 | public static HtmlAttribute Multiple => new HtmlAttribute("multiple"); 90 | public static HtmlAttribute Muted(string value) => new HtmlAttribute("muted", value); 91 | 92 | public static HtmlAttribute Name(string value) => new HtmlAttribute("name", value); 93 | public static HtmlAttribute NoValidate => new HtmlAttribute("novalidate"); 94 | public static HtmlAttribute NoWrap(string value) => new HtmlAttribute("nowrap", value); 95 | 96 | public static HtmlAttribute Optimum(string value) => new HtmlAttribute("optimum", value); 97 | public static HtmlAttribute Open(string value) => new HtmlAttribute("open", value); 98 | 99 | public static HtmlAttribute Pattern(string value) => new HtmlAttribute("pattern", value); 100 | public static HtmlAttribute Ping(string value) => new HtmlAttribute("ping", value); 101 | public static HtmlAttribute Placeholder(string value) => new HtmlAttribute("placeholder", value); 102 | public static HtmlAttribute Preload(string value) => new HtmlAttribute("preload", value); 103 | public static HtmlAttribute Poster(string value) => new HtmlAttribute("poster", value); 104 | 105 | public static HtmlAttribute RadioGroup(string value) => new HtmlAttribute("radiogroup", value); 106 | public static HtmlAttribute Readonly => new HtmlAttribute("readonly"); 107 | public static HtmlAttribute Refresh(string value) => new HtmlAttribute("refresh", value); 108 | public static HtmlAttribute Rel(string value) => new HtmlAttribute("rel", value); 109 | public static HtmlAttribute Required => new HtmlAttribute("required"); 110 | public static HtmlAttribute Reversed(string value) => new HtmlAttribute("reversed", value); 111 | public static HtmlAttribute Rows(string value) => new HtmlAttribute("rows", value); 112 | public static HtmlAttribute RowSpan(string value) => new HtmlAttribute("rowspan", value); 113 | 114 | public static HtmlAttribute Sandbox => new HtmlAttribute("sandbox"); 115 | public static HtmlAttribute Seamless => new HtmlAttribute("seamless"); 116 | public static HtmlAttribute Selected => new HtmlAttribute("selected"); 117 | public static HtmlAttribute SelectionDirection(string value) => new HtmlAttribute("selectiondirection", value); 118 | public static HtmlAttribute Scope(string value) => new HtmlAttribute("scope", value); 119 | public static HtmlAttribute Scoped => new HtmlAttribute("scoped"); 120 | public static HtmlAttribute Shape(string value) => new HtmlAttribute("shape", value); 121 | public static HtmlAttribute Size(string value) => new HtmlAttribute("size", value); 122 | public static HtmlAttribute Sizes(string value) => new HtmlAttribute("sizes", value); 123 | public static HtmlAttribute Span(string value) => new HtmlAttribute("span", value); 124 | public static HtmlAttribute SpellCheck(string value) => new HtmlAttribute("spellcheck", value); 125 | public static HtmlAttribute Src(string value) => new HtmlAttribute("src", value); 126 | public static HtmlAttribute SrcDoc(string value) => new HtmlAttribute("srcdoc", value); 127 | public static HtmlAttribute SrcLang(string value) => new HtmlAttribute("srclang", value); 128 | public static HtmlAttribute SrcSet(string value) => new HtmlAttribute("srcset", value); 129 | public static HtmlAttribute Start(string value) => new HtmlAttribute("start", value); 130 | public static HtmlAttribute Step(string value) => new HtmlAttribute("step", value); 131 | public static HtmlAttribute Style(string value) => new HtmlAttribute("style", value); 132 | 133 | public static HtmlAttribute TabIndex(string value) => new HtmlAttribute("tabindex", value); 134 | public static HtmlAttribute Target(string value) => new HtmlAttribute("target", value); 135 | public static HtmlAttribute Text(string value) => new HtmlAttribute("text", value); 136 | public static HtmlAttribute Title(string value) => new HtmlAttribute("title", value); 137 | public static HtmlAttribute Translate(string value) => new HtmlAttribute("translate", value); 138 | public static HtmlAttribute Type(string value) => new HtmlAttribute("type", value); 139 | public static HtmlAttribute TypeMustMatch => new HtmlAttribute("typemustmatch"); 140 | 141 | public static HtmlAttribute UseMap(string value) => new HtmlAttribute("usemap", value); 142 | 143 | public static HtmlAttribute Value(string value) => new HtmlAttribute("value", value); 144 | public static HtmlAttribute Volume(string value) => new HtmlAttribute("volume", value); 145 | 146 | public static HtmlAttribute Width(string value) => new HtmlAttribute("width", value); 147 | public static HtmlAttribute Wrap(string value) => new HtmlAttribute("wrap", value); 148 | 149 | public static HtmlAttribute Xmls(string value) => new HtmlAttribute("xmls", value); 150 | } 151 | } -------------------------------------------------------------------------------- /src/Elements/HtmlAElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlAElement : HtmlElement 4 | { 5 | public HtmlAElement() : base("a") { } 6 | 7 | public HtmlAElement WithDownload(string value) => this.WithAttribute(Attribute.Download(value)); 8 | 9 | public HtmlAElement WithHref(string value) => this.WithAttribute(Attribute.Href(value)); 10 | 11 | public HtmlAElement WithHrefLang(string value) => this.WithAttribute(Attribute.HrefLang(value)); 12 | 13 | public HtmlAElement WithMedia(string value) => this.WithAttribute(Attribute.Media(value)); 14 | 15 | public HtmlAElement WithPing(string value) => this.WithAttribute(Attribute.Ping(value)); 16 | 17 | public HtmlAElement WithRel(string value) => this.WithAttribute(Attribute.Rel(value)); 18 | 19 | public HtmlAElement WithTarget(string value) => this.WithAttribute(Attribute.Target(value)); 20 | 21 | public HtmlAElement WithType(string value) => this.WithAttribute(Attribute.Type(value)); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Elements/HtmlAreaElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlAreaElement : HtmlElement 4 | { 5 | public HtmlAreaElement() : base("area", isVoid: true) { } 6 | 7 | public HtmlAreaElement WithAlt(string value) => this.WithAttribute(Attribute.Alt(value)); 8 | 9 | public HtmlAreaElement WithCoords(string value) => this.WithAttribute(Attribute.Coords(value)); 10 | 11 | public HtmlAreaElement WithDownload(string value) => this.WithAttribute(Attribute.Download(value)); 12 | 13 | public HtmlAreaElement WithHref(string value) => this.WithAttribute(Attribute.Href(value)); 14 | 15 | public HtmlAreaElement WithHrefLang(string value) => this.WithAttribute(Attribute.HrefLang(value)); 16 | 17 | public HtmlAreaElement WithMedia(string value) => this.WithAttribute(Attribute.Media(value)); 18 | 19 | public HtmlAreaElement WithRel(string value) => this.WithAttribute(Attribute.Rel(value)); 20 | 21 | public HtmlAreaElement WithShape(string value) => this.WithAttribute(Attribute.Shape(value)); 22 | 23 | public HtmlAreaElement WithTarget(string value) => this.WithAttribute(Attribute.Target(value)); 24 | 25 | public HtmlAreaElement WithType(string value) => this.WithAttribute(Attribute.Type(value)); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Elements/HtmlAudioElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlAudioElement : HtmlElement 4 | { 5 | public HtmlAudioElement() : base("audio") { } 6 | 7 | public HtmlAudioElement WithAutoPlay(string value) => this.WithAttribute(Attribute.AutoPlay(value)); 8 | 9 | public HtmlAudioElement WithControls() => this.WithAttribute(Attribute.Controls); 10 | 11 | public HtmlAudioElement WithLoop(string value) => this.WithAttribute(Attribute.Loop(value)); 12 | 13 | public HtmlAudioElement WithMuted(string value) => this.WithAttribute(Attribute.Muted(value)); 14 | 15 | public HtmlAudioElement WithPreload(string value) => this.WithAttribute(Attribute.Preload(value)); 16 | 17 | public HtmlAudioElement WithSrc(string value) => this.WithAttribute(Attribute.Src(value)); 18 | 19 | public HtmlAudioElement WithVolume(string value) => this.WithAttribute(Attribute.Volume(value)); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Elements/HtmlBaseElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlBaseElement : HtmlElement 4 | { 5 | public HtmlBaseElement() : base("base", isVoid: true) { } 6 | 7 | public HtmlBaseElement WithHref(string value) => this.WithAttribute(Attribute.Href(value)); 8 | 9 | public HtmlBaseElement WithTarget(string value) => this.WithAttribute(Attribute.Target(value)); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Elements/HtmlButtonElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlButtonElement : HtmlElement 4 | { 5 | public HtmlButtonElement() : base("button") { } 6 | 7 | public HtmlButtonElement WithAutoFocus() => this.WithAttribute(Attribute.AutoFocus); 8 | 9 | public HtmlButtonElement WithDisabled() => this.WithAttribute(Attribute.Disabled); 10 | 11 | public HtmlButtonElement WithForm(string value) => this.WithAttribute(Attribute.Form(value)); 12 | 13 | public HtmlButtonElement WithFormAction(string value) => this.WithAttribute(Attribute.FormAction(value)); 14 | 15 | public HtmlButtonElement WithFormEncType(string value) => this.WithAttribute(Attribute.FormEncType(value)); 16 | 17 | public HtmlButtonElement WithFormMethod(string value) => this.WithAttribute(Attribute.FormMethod(value)); 18 | 19 | public HtmlButtonElement WithFormNoValidate() => this.WithAttribute(Attribute.FormNoValidate); 20 | 21 | public HtmlButtonElement WithFormTarget(string value) => this.WithAttribute(Attribute.FormTarget(value)); 22 | 23 | public HtmlButtonElement WithName(string value) => this.WithAttribute(Attribute.Name(value)); 24 | 25 | public HtmlButtonElement WithType(string value) => this.WithAttribute(Attribute.Type(value)); 26 | 27 | public HtmlButtonElement WithValue(string value) => this.WithAttribute(Attribute.Value(value)); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Elements/HtmlCanvasElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlCanvasElement : HtmlElement 4 | { 5 | public HtmlCanvasElement() : base("canvas") { } 6 | 7 | public HtmlCanvasElement WithHeight(string value) => this.WithAttribute(Attribute.Height(value)); 8 | 9 | public HtmlCanvasElement WithWidth(string value) => this.WithAttribute(Attribute.Width(value)); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Elements/HtmlColElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlColElement : HtmlElement 4 | { 5 | public HtmlColElement() : base("col", isVoid: true) { } 6 | 7 | public HtmlColElement WithSpan(string value) => this.WithAttribute(Attribute.Span(value)); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Elements/HtmlColgroupElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlColgroupElement : HtmlElement 4 | { 5 | public HtmlColgroupElement() : base("colgroup") { } 6 | 7 | public HtmlColgroupElement WithSpan(string value) => this.WithAttribute(Attribute.Span(value)); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Elements/HtmlDataElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlDataElement : HtmlElement 4 | { 5 | public HtmlDataElement() : base("data") { } 6 | 7 | public HtmlDataElement WithValue(string value) => this.WithAttribute(Attribute.Value(value)); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Elements/HtmlDdElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlDdElement : HtmlElement 4 | { 5 | public HtmlDdElement() : base("dd") { } 6 | 7 | public HtmlDdElement WithNoWrap(string value) => this.WithAttribute(Attribute.NoWrap(value)); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Elements/HtmlDelElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlDelElement : HtmlElement 4 | { 5 | public HtmlDelElement() : base("del") { } 6 | 7 | public HtmlDelElement WithCite(string value) => this.WithAttribute(Attribute.Cite(value)); 8 | 9 | public HtmlDelElement WithDateTime(string value) => this.WithAttribute(Attribute.DateTime(value)); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Elements/HtmlDetailsElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlDetailsElement : HtmlElement 4 | { 5 | public HtmlDetailsElement() : base("details") { } 6 | 7 | public HtmlDetailsElement WithOpen(string value) => this.WithAttribute(Attribute.Open(value)); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Elements/HtmlDialogElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlDialogElement : HtmlElement 4 | { 5 | public HtmlDialogElement() : base("dialog") { } 6 | 7 | public HtmlDialogElement WithOpen(string value) => this.WithAttribute(Attribute.Open(value)); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Elements/HtmlDlElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlDlElement : HtmlElement 4 | { 5 | public HtmlDlElement() : base("dl") { } 6 | 7 | public HtmlDlElement WithCompact(string value) => this.WithAttribute(Attribute.Compact(value)); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Elements/HtmlEmbedElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlEmbedElement : HtmlElement 4 | { 5 | public HtmlEmbedElement() : base("embed", isVoid: true) { } 6 | 7 | public HtmlEmbedElement WithHeight(string value) => this.WithAttribute(Attribute.Height(value)); 8 | 9 | public HtmlEmbedElement WithSrc(string value) => this.WithAttribute(Attribute.Src(value)); 10 | 11 | public HtmlEmbedElement WithType(string value) => this.WithAttribute(Attribute.Type(value)); 12 | 13 | public HtmlEmbedElement WithWidth(string value) => this.WithAttribute(Attribute.Width(value)); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Elements/HtmlFormElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlFormElement : HtmlElement 4 | { 5 | public HtmlFormElement() : base("form") { } 6 | 7 | public HtmlFormElement WithAcceptCharset(string value) => this.WithAttribute(Attribute.AcceptCharset(value)); 8 | 9 | public HtmlFormElement WithAction(string value) => this.WithAttribute(Attribute.Action(value)); 10 | 11 | public HtmlFormElement WithAutoComplete(string value) => this.WithAttribute(Attribute.AutoComplete(value)); 12 | 13 | public HtmlFormElement WithEncType(string value) => this.WithAttribute(Attribute.EncType(value)); 14 | 15 | public HtmlFormElement WithMethod(string value) => this.WithAttribute(Attribute.Method(value)); 16 | 17 | public HtmlFormElement WithName(string value) => this.WithAttribute(Attribute.Name(value)); 18 | 19 | public HtmlFormElement WithNoValidate() => this.WithAttribute(Attribute.NoValidate); 20 | 21 | public HtmlFormElement WithTarget(string value) => this.WithAttribute(Attribute.Target(value)); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Elements/HtmlHrElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlHrElement : HtmlElement 4 | { 5 | public HtmlHrElement() : base("hr", isVoid: true) { } 6 | 7 | public HtmlHrElement WithColor(string value) => this.WithAttribute(Attribute.Color(value)); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Elements/HtmlHtmlElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlHtmlElement : HtmlElement 4 | { 5 | public HtmlHtmlElement() : base("html") { } 6 | 7 | public HtmlHtmlElement WithXmls(string value) => this.WithAttribute(Attribute.Xmls(value)); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Elements/HtmlIframeElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlIframeElement : HtmlElement 4 | { 5 | public HtmlIframeElement() : base("iframe") { } 6 | 7 | public HtmlIframeElement WithAllowFullScreen() => this.WithAttribute(Attribute.AllowFullScreen); 8 | 9 | public HtmlIframeElement WithHeight(string value) => this.WithAttribute(Attribute.Height(value)); 10 | 11 | public HtmlIframeElement WithName(string value) => this.WithAttribute(Attribute.Name(value)); 12 | 13 | public HtmlIframeElement WithSandbox() => this.WithAttribute(Attribute.Sandbox); 14 | 15 | public HtmlIframeElement WithSeamless() => this.WithAttribute(Attribute.Seamless); 16 | 17 | public HtmlIframeElement WithSrc(string value) => this.WithAttribute(Attribute.Src(value)); 18 | 19 | public HtmlIframeElement WithSrcDoc(string value) => this.WithAttribute(Attribute.SrcDoc(value)); 20 | 21 | public HtmlIframeElement WithWidth(string value) => this.WithAttribute(Attribute.Width(value)); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Elements/HtmlImgElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlImgElement : HtmlElement 4 | { 5 | public HtmlImgElement() : base("img", isVoid: true) { } 6 | 7 | public HtmlImgElement WithAlt(string value) => this.WithAttribute(Attribute.Alt(value)); 8 | 9 | public HtmlImgElement WithCrossOrigin(string value) => this.WithAttribute(Attribute.CrossOrigin(value)); 10 | 11 | public HtmlImgElement WithHeight(string value) => this.WithAttribute(Attribute.Height(value)); 12 | 13 | public HtmlImgElement WithIsMap(string value) => this.WithAttribute(Attribute.IsMap(value)); 14 | 15 | public HtmlImgElement WithLongDesc(string value) => this.WithAttribute(Attribute.LongDesc(value)); 16 | 17 | public HtmlImgElement WithSizes(string value) => this.WithAttribute(Attribute.Sizes(value)); 18 | 19 | public HtmlImgElement WithSrc(string value) => this.WithAttribute(Attribute.Src(value)); 20 | 21 | public HtmlImgElement WithSrcSet(string value) => this.WithAttribute(Attribute.SrcSet(value)); 22 | 23 | public HtmlImgElement WithWidth(string value) => this.WithAttribute(Attribute.Width(value)); 24 | 25 | public HtmlImgElement WithUseMap(string value) => this.WithAttribute(Attribute.UseMap(value)); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Elements/HtmlInputElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlInputElement : HtmlElement 4 | { 5 | public HtmlInputElement() : base("input", isVoid: true) { } 6 | 7 | public HtmlInputElement WithAccept(string value) => this.WithAttribute(Attribute.Accept(value)); 8 | 9 | public HtmlInputElement WithAutoComplete(string value) => this.WithAttribute(Attribute.AutoComplete(value)); 10 | 11 | public HtmlInputElement WithAutoFocus() => this.WithAttribute(Attribute.AutoFocus); 12 | 13 | public HtmlInputElement WithAutoSave(string value) => this.WithAttribute(Attribute.AutoSave(value)); 14 | 15 | public HtmlInputElement WithChecked() => this.WithAttribute(Attribute.Checked); 16 | 17 | public HtmlInputElement WithDisabled() => this.WithAttribute(Attribute.Disabled); 18 | 19 | public HtmlInputElement WithForm(string value) => this.WithAttribute(Attribute.Form(value)); 20 | 21 | public HtmlInputElement WithFormAction(string value) => this.WithAttribute(Attribute.FormAction(value)); 22 | 23 | public HtmlInputElement WithFormEncType(string value) => this.WithAttribute(Attribute.FormEncType(value)); 24 | 25 | public HtmlInputElement WithFormMethod(string value) => this.WithAttribute(Attribute.FormMethod(value)); 26 | 27 | public HtmlInputElement WithFormNoValidate() => this.WithAttribute(Attribute.FormNoValidate); 28 | 29 | public HtmlInputElement WithFormTarget(string value) => this.WithAttribute(Attribute.FormTarget(value)); 30 | 31 | public HtmlInputElement WithHeight(string value) => this.WithAttribute(Attribute.Height(value)); 32 | 33 | public HtmlInputElement WithInputMode(string value) => this.WithAttribute(Attribute.InputMode(value)); 34 | 35 | public HtmlInputElement WithList(string value) => this.WithAttribute(Attribute.List(value)); 36 | 37 | public HtmlInputElement WithMax(string value) => this.WithAttribute(Attribute.Max(value)); 38 | 39 | public HtmlInputElement WithMaxLength(string value) => this.WithAttribute(Attribute.MaxLength(value)); 40 | 41 | public HtmlInputElement WithMin(string value) => this.WithAttribute(Attribute.Min(value)); 42 | 43 | public HtmlInputElement WithMinLength(string value) => this.WithAttribute(Attribute.MinLength(value)); 44 | 45 | public HtmlInputElement WithMultiple() => this.WithAttribute(Attribute.Multiple); 46 | 47 | public HtmlInputElement WithName(string value) => this.WithAttribute(Attribute.Name(value)); 48 | 49 | public HtmlInputElement WithPattern(string value) => this.WithAttribute(Attribute.Pattern(value)); 50 | 51 | public HtmlInputElement WithPlaceholder(string value) => this.WithAttribute(Attribute.Placeholder(value)); 52 | 53 | public HtmlInputElement WithReadonly() => this.WithAttribute(Attribute.Readonly); 54 | 55 | public HtmlInputElement WithRequired() => this.WithAttribute(Attribute.Required); 56 | 57 | public HtmlInputElement WithSelectionDirection(string value) => this.WithAttribute(Attribute.SelectionDirection(value)); 58 | 59 | public HtmlInputElement WithSize(string value) => this.WithAttribute(Attribute.Size(value)); 60 | 61 | public HtmlInputElement WithSrc(string value) => this.WithAttribute(Attribute.Src(value)); 62 | 63 | public HtmlInputElement WithStep(string value) => this.WithAttribute(Attribute.Step(value)); 64 | 65 | public HtmlInputElement WithType(string value) => this.WithAttribute(Attribute.Type(value)); 66 | 67 | public HtmlInputElement WithValue(string value) => this.WithAttribute(Attribute.Value(value)); 68 | 69 | public HtmlInputElement WithWidth(string value) => this.WithAttribute(Attribute.Width(value)); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/Elements/HtmlInsElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlInsElement : HtmlElement 4 | { 5 | public HtmlInsElement() : base("ins") { } 6 | 7 | public HtmlInsElement WithCite(string value) => this.WithAttribute(Attribute.Cite(value)); 8 | 9 | public HtmlInsElement WithDateTime(string value) => this.WithAttribute(Attribute.DateTime(value)); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Elements/HtmlLabelElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlLabelElement : HtmlElement 4 | { 5 | public HtmlLabelElement() : base("label") { } 6 | 7 | public HtmlLabelElement WithFor(string value) => this.WithAttribute(Attribute.For(value)); 8 | 9 | public HtmlLabelElement WithForm(string value) => this.WithAttribute(Attribute.Form(value)); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Elements/HtmlLiElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlLiElement : HtmlElement 4 | { 5 | public HtmlLiElement() : base("li") { } 6 | 7 | public HtmlLiElement WithValue(string value) => this.WithAttribute(Attribute.Value(value)); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Elements/HtmlLinkElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlLinkElement : HtmlElement 4 | { 5 | public HtmlLinkElement() : base("link", isVoid: true) { } 6 | 7 | public HtmlLinkElement WithCrossOrigin(string value) => this.WithAttribute(Attribute.CrossOrigin(value)); 8 | 9 | public HtmlLinkElement WithHref(string value) => this.WithAttribute(Attribute.Href(value)); 10 | 11 | public HtmlLinkElement WithHrefLang(string value) => this.WithAttribute(Attribute.HrefLang(value)); 12 | 13 | public HtmlLinkElement WithIntegrity(string value) => this.WithAttribute(Attribute.Integrity(value)); 14 | 15 | public HtmlLinkElement WithMedia(string value) => this.WithAttribute(Attribute.Media(value)); 16 | 17 | public HtmlLinkElement WithRel(string value) => this.WithAttribute(Attribute.Rel(value)); 18 | 19 | public HtmlLinkElement WithSizes(string value) => this.WithAttribute(Attribute.Sizes(value)); 20 | 21 | public HtmlLinkElement WithType(string value) => this.WithAttribute(Attribute.Type(value)); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Elements/HtmlMapElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlMapElement : HtmlElement 4 | { 5 | public HtmlMapElement() : base("map") { } 6 | 7 | public HtmlMapElement WithName(string value) => this.WithAttribute(Attribute.Name(value)); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Elements/HtmlMenuElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlMenuElement : HtmlElement 4 | { 5 | public HtmlMenuElement() : base("menu") { } 6 | 7 | public HtmlMenuElement WithLabel(string value) => this.WithAttribute(Attribute.Label(value)); 8 | 9 | public HtmlMenuElement WithType(string value) => this.WithAttribute(Attribute.Type(value)); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Elements/HtmlMenuItemElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlMenuItemElement : HtmlElement 4 | { 5 | public HtmlMenuItemElement() : base("menuitem") { } 6 | 7 | public HtmlMenuItemElement WithChecked() => this.WithAttribute(Attribute.Checked); 8 | 9 | public HtmlMenuItemElement WithCommand(string value) => this.WithAttribute(Attribute.Command(value)); 10 | 11 | public HtmlMenuItemElement WithDefault() => this.WithAttribute(Attribute.Default); 12 | 13 | public HtmlMenuItemElement WithDisabled() => this.WithAttribute(Attribute.Disabled); 14 | 15 | public HtmlMenuItemElement WithIcon(string value) => this.WithAttribute(Attribute.Icon(value)); 16 | 17 | public HtmlMenuItemElement WithLabel(string value) => this.WithAttribute(Attribute.Label(value)); 18 | 19 | public HtmlMenuItemElement WithRadioGroup(string value) => this.WithAttribute(Attribute.RadioGroup(value)); 20 | 21 | public HtmlMenuItemElement WithType(string value) => this.WithAttribute(Attribute.Type(value)); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Elements/HtmlMetaElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlMetaElement : HtmlElement 4 | { 5 | public HtmlMetaElement() : base("meta", isVoid: true) { } 6 | 7 | public HtmlMetaElement WithCharset(string value) => this.WithAttribute(Attribute.Charset(value)); 8 | 9 | public HtmlMetaElement WithContent(string value) => this.WithAttribute(Attribute.Content(value)); 10 | 11 | public HtmlMetaElement WithHttpEquiv(string value) => this.WithAttribute(Attribute.HttpEquiv(value)); 12 | 13 | public HtmlMetaElement WithDefaultStyle(string value) => this.WithAttribute(Attribute.DefaultStyle(value)); 14 | 15 | public HtmlMetaElement WithRefresh(string value) => this.WithAttribute(Attribute.Refresh(value)); 16 | 17 | public HtmlMetaElement WithName(string value) => this.WithAttribute(Attribute.Name(value)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Elements/HtmlMeterElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlMeterElement : HtmlElement 4 | { 5 | public HtmlMeterElement() : base("meter") { } 6 | 7 | public HtmlMeterElement WithForm(string value) => this.WithAttribute(Attribute.Form(value)); 8 | 9 | public HtmlMeterElement WithLow(string value) => this.WithAttribute(Attribute.Low(value)); 10 | 11 | public HtmlMeterElement WithHigh(string value) => this.WithAttribute(Attribute.High(value)); 12 | 13 | public HtmlMeterElement WithMin(string value) => this.WithAttribute(Attribute.Min(value)); 14 | 15 | public HtmlMeterElement WithMax(string value) => this.WithAttribute(Attribute.Max(value)); 16 | 17 | public HtmlMeterElement WithOptimum(string value) => this.WithAttribute(Attribute.Optimum(value)); 18 | 19 | public HtmlMeterElement WithValue(string value) => this.WithAttribute(Attribute.Value(value)); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Elements/HtmlObjectElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlObjectElement : HtmlElement 4 | { 5 | public HtmlObjectElement() : base("object") { } 6 | 7 | public HtmlObjectElement WithData(string value) => this.WithAttribute(Attribute.Data(value)); 8 | 9 | public HtmlObjectElement WithForm(string value) => this.WithAttribute(Attribute.Form(value)); 10 | 11 | public HtmlObjectElement WithHeight(string value) => this.WithAttribute(Attribute.Height(value)); 12 | 13 | public HtmlObjectElement WithName(string value) => this.WithAttribute(Attribute.Name(value)); 14 | 15 | public HtmlObjectElement WithType(string value) => this.WithAttribute(Attribute.Type(value)); 16 | 17 | public HtmlObjectElement WithTypeMustMatch() => this.WithAttribute(Attribute.TypeMustMatch); 18 | 19 | public HtmlObjectElement WithUseMap(string value) => this.WithAttribute(Attribute.UseMap(value)); 20 | 21 | public HtmlObjectElement WithWidth(string value) => this.WithAttribute(Attribute.Width(value)); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Elements/HtmlOlElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlOlElement : HtmlElement 4 | { 5 | public HtmlOlElement() : base("ol") { } 6 | 7 | public HtmlOlElement WithReversed(string value) => this.WithAttribute(Attribute.Reversed(value)); 8 | 9 | public HtmlOlElement WithStart(string value) => this.WithAttribute(Attribute.Start(value)); 10 | 11 | public HtmlOlElement WithType(string value) => this.WithAttribute(Attribute.Type(value)); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Elements/HtmlOptgroupElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlOptgroupElement : HtmlElement 4 | { 5 | public HtmlOptgroupElement() : base("optgroup") { } 6 | 7 | public HtmlOptgroupElement WithDisabled() => this.WithAttribute(Attribute.Disabled); 8 | 9 | public HtmlOptgroupElement WithLabel(string value) => this.WithAttribute(Attribute.Label(value)); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Elements/HtmlOptionElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlOptionElement : HtmlElement 4 | { 5 | public HtmlOptionElement() : base("option") { } 6 | 7 | public HtmlOptionElement WithDisabled() => this.WithAttribute(Attribute.Disabled); 8 | 9 | public HtmlOptionElement WithLabel(string value) => this.WithAttribute(Attribute.Label(value)); 10 | 11 | public HtmlOptionElement WithSelected() => this.WithAttribute(Attribute.Selected); 12 | 13 | public HtmlOptionElement WithValue(string value) => this.WithAttribute(Attribute.Value(value)); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Elements/HtmlOutputElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlOutputElement : HtmlElement 4 | { 5 | public HtmlOutputElement() : base("output") { } 6 | 7 | public HtmlOutputElement WithFor(string value) => this.WithAttribute(Attribute.For(value)); 8 | 9 | public HtmlOutputElement WithForm(string value) => this.WithAttribute(Attribute.Form(value)); 10 | 11 | public HtmlOutputElement WithName(string value) => this.WithAttribute(Attribute.Name(value)); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Elements/HtmlParamElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlParamElement : HtmlElement 4 | { 5 | public HtmlParamElement() : base("param", isVoid: true) { } 6 | 7 | public HtmlParamElement WithName(string value) => this.WithAttribute(Attribute.Name(value)); 8 | 9 | public HtmlParamElement WithValue(string value) => this.WithAttribute(Attribute.Value(value)); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Elements/HtmlProgressElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlProgressElement : HtmlElement 4 | { 5 | public HtmlProgressElement() : base("progress") { } 6 | 7 | public HtmlProgressElement WithMax(string value) => this.WithAttribute(Attribute.Max(value)); 8 | 9 | public HtmlProgressElement WithValue(string value) => this.WithAttribute(Attribute.Value(value)); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Elements/HtmlQElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlQElement : HtmlElement 4 | { 5 | public HtmlQElement() : base("q") { } 6 | 7 | public HtmlQElement WithCite(string value) => this.WithAttribute(Attribute.Cite(value)); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Elements/HtmlScriptElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlScriptElement : HtmlElement 4 | { 5 | public HtmlScriptElement() : base("script") { } 6 | 7 | public HtmlScriptElement WithAsync(string value) => this.WithAttribute(Attribute.Async(value)); 8 | 9 | public HtmlScriptElement WithCrossOrigin(string value) => this.WithAttribute(Attribute.CrossOrigin(value)); 10 | 11 | public HtmlScriptElement WithDefer(string value) => this.WithAttribute(Attribute.Defer(value)); 12 | 13 | public HtmlScriptElement WithIntegrity(string value) => this.WithAttribute(Attribute.Integrity(value)); 14 | 15 | public HtmlScriptElement WithSrc(string value) => this.WithAttribute(Attribute.Src(value)); 16 | 17 | public HtmlScriptElement WithText(string value) => this.WithAttribute(Attribute.Text(value)); 18 | 19 | public HtmlScriptElement WithType(string value) => this.WithAttribute(Attribute.Type(value)); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Elements/HtmlSelectElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlSelectElement : HtmlElement 4 | { 5 | public HtmlSelectElement() : base("select") { } 6 | 7 | public HtmlSelectElement WithAutoFocus() => this.WithAttribute(Attribute.AutoFocus); 8 | 9 | public HtmlSelectElement WithDisabled() => this.WithAttribute(Attribute.Disabled); 10 | 11 | public HtmlSelectElement WithForm(string value) => this.WithAttribute(Attribute.Form(value)); 12 | 13 | public HtmlSelectElement WithMultiple() => this.WithAttribute(Attribute.Multiple); 14 | 15 | public HtmlSelectElement WithName(string value) => this.WithAttribute(Attribute.Name(value)); 16 | 17 | public HtmlSelectElement WithRequired() => this.WithAttribute(Attribute.Required); 18 | 19 | public HtmlSelectElement WithSize(string value) => this.WithAttribute(Attribute.Size(value)); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Elements/HtmlSourceElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlSourceElement : HtmlElement 4 | { 5 | public HtmlSourceElement() : base("source", isVoid: true) { } 6 | 7 | public HtmlSourceElement WithSrc(string value) => this.WithAttribute(Attribute.Src(value)); 8 | 9 | public HtmlSourceElement WithType(string value) => this.WithAttribute(Attribute.Type(value)); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Elements/HtmlStyleElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlStyleElement : HtmlElement 4 | { 5 | public HtmlStyleElement() : base("style") { } 6 | 7 | public HtmlStyleElement WithDisabled() => this.WithAttribute(Attribute.Disabled); 8 | 9 | public HtmlStyleElement WithType(string value) => this.WithAttribute(Attribute.Type(value)); 10 | 11 | public HtmlStyleElement WithMedia(string value) => this.WithAttribute(Attribute.Media(value)); 12 | 13 | public HtmlStyleElement WithScoped() => this.WithAttribute(Attribute.Scoped); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Elements/HtmlTextAreaElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlTextAreaElement : HtmlElement 4 | { 5 | public HtmlTextAreaElement() : base("textarea") { } 6 | 7 | public HtmlTextAreaElement WithAutoComplete(string value) => this.WithAttribute(Attribute.AutoComplete(value)); 8 | 9 | public HtmlTextAreaElement WithAutoFocus() => this.WithAttribute(Attribute.AutoFocus); 10 | 11 | public HtmlTextAreaElement WithCols(string value) => this.WithAttribute(Attribute.Cols(value)); 12 | 13 | public HtmlTextAreaElement WithDisabled() => this.WithAttribute(Attribute.Disabled); 14 | 15 | public HtmlTextAreaElement WithForm(string value) => this.WithAttribute(Attribute.Form(value)); 16 | 17 | public HtmlTextAreaElement WithMaxLength(string value) => this.WithAttribute(Attribute.MaxLength(value)); 18 | 19 | public HtmlTextAreaElement WithMinLength(string value) => this.WithAttribute(Attribute.MinLength(value)); 20 | 21 | public HtmlTextAreaElement WithName(string value) => this.WithAttribute(Attribute.Name(value)); 22 | 23 | public HtmlTextAreaElement WithPlaceholder(string value) => this.WithAttribute(Attribute.Placeholder(value)); 24 | 25 | public HtmlTextAreaElement WithReadonly() => this.WithAttribute(Attribute.Readonly); 26 | 27 | public HtmlTextAreaElement WithRequired() => this.WithAttribute(Attribute.Required); 28 | 29 | public HtmlTextAreaElement WithRows(string value) => this.WithAttribute(Attribute.Rows(value)); 30 | 31 | public HtmlTextAreaElement WithSelectionDirection(string value) => this.WithAttribute(Attribute.SelectionDirection(value)); 32 | 33 | public HtmlTextAreaElement WithWrap(string value) => this.WithAttribute(Attribute.Wrap(value)); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Elements/HtmlThElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlThElement : HtmlElement 4 | { 5 | public HtmlThElement() : base("th") { } 6 | 7 | public HtmlThElement WithColSpan(string value) => this.WithAttribute(Attribute.ColSpan(value)); 8 | 9 | public HtmlThElement WithHeaders(string value) => this.WithAttribute(Attribute.Headers(value)); 10 | 11 | public HtmlThElement WithRowSpan(string value) => this.WithAttribute(Attribute.RowSpan(value)); 12 | 13 | public HtmlThElement WithScope(string value) => this.WithAttribute(Attribute.Scope(value)); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Elements/HtmlTimeElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlTimeElement : HtmlElement 4 | { 5 | public HtmlTimeElement() : base("time") { } 6 | 7 | public HtmlTimeElement WithDateTime(string value) => this.WithAttribute(Attribute.DateTime(value)); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Elements/HtmlTrackElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlTrackElement : HtmlElement 4 | { 5 | public HtmlTrackElement() : base("track", isVoid: true) { } 6 | 7 | public HtmlTrackElement WithDefault() => this.WithAttribute(Attribute.Default); 8 | 9 | public HtmlTrackElement WithKind(string value) => this.WithAttribute(Attribute.Kind(value)); 10 | 11 | public HtmlTrackElement WithLabel(string value) => this.WithAttribute(Attribute.Label(value)); 12 | 13 | public HtmlTrackElement WithSrc(string value) => this.WithAttribute(Attribute.Src(value)); 14 | 15 | public HtmlTrackElement WithSrcLang(string value) => this.WithAttribute(Attribute.SrcLang(value)); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Elements/HtmlVideoElement.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public class HtmlVideoElement : HtmlElement 4 | { 5 | public HtmlVideoElement() : base("video") { } 6 | 7 | public HtmlVideoElement WithAutoPlay(string value) => this.WithAttribute(Attribute.AutoPlay(value)); 8 | 9 | public HtmlVideoElement WithControls() => this.WithAttribute(Attribute.Controls); 10 | 11 | public HtmlVideoElement WithCrossOrigin(string value) => this.WithAttribute(Attribute.CrossOrigin(value)); 12 | 13 | public HtmlVideoElement WithHeight(string value) => this.WithAttribute(Attribute.Height(value)); 14 | 15 | public HtmlVideoElement WithLoop(string value) => this.WithAttribute(Attribute.Loop(value)); 16 | 17 | public HtmlVideoElement WithMuted(string value) => this.WithAttribute(Attribute.Muted(value)); 18 | 19 | public HtmlVideoElement WithPreload(string value) => this.WithAttribute(Attribute.Preload(value)); 20 | 21 | public HtmlVideoElement WithSrc(string value) => this.WithAttribute(Attribute.Src(value)); 22 | 23 | public HtmlVideoElement WithWidth(string value) => this.WithAttribute(Attribute.Width(value)); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Extensions/StringExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator.Extensions 2 | { 3 | public static class StringExtensions 4 | { 5 | public static string ToAsciiLower(this string text) => ToAsciiLower(text, 0, text.Length); 6 | 7 | public static unsafe string ToAsciiLower(this string text, int startIndex, int length) 8 | { 9 | bool hasUpperCase = false; 10 | for (int i = startIndex; i < startIndex + length ; i++) 11 | { 12 | char c = text[i]; 13 | if (c >= 'A' && c <= 'Z') 14 | { 15 | hasUpperCase = true; 16 | break; 17 | } 18 | } 19 | if (!hasUpperCase) 20 | { 21 | return text.Substring(startIndex, length); 22 | } 23 | 24 | char* copy = stackalloc char[length]; 25 | for (int i = startIndex; i < startIndex + length ; i++) 26 | { 27 | char c = text[i]; 28 | if (c >= 'A' && c <= 'Z') 29 | { 30 | copy[i - startIndex] = (char)(c | 0x20); 31 | } 32 | else 33 | { 34 | copy[i - startIndex] = c; 35 | } 36 | } 37 | return new string(copy, 0, length); 38 | } 39 | 40 | public static bool EqualsAsciiOrdinalIgnoreCase(string valueA, string valueB) => EqualsAsciiOrdinalIgnoreCase(valueA, 0, valueA.Length, valueB, 0, valueB.Length); 41 | 42 | public static bool EqualsAsciiOrdinalIgnoreCase(string valueA, int startIndexA, int lengthA, string valueB, int startIndexB, int lengthB) 43 | { 44 | if (lengthA != lengthB) 45 | { 46 | return false; 47 | } 48 | for (int i = 0; i < lengthA; i++) 49 | { 50 | char c1 = valueA[startIndexA + i]; 51 | char c2 = valueB[startIndexB + i]; 52 | if ((c1 | 0x20) != (c2 | 0x20)) 53 | { 54 | return false; 55 | } 56 | } 57 | return true; 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/HtmlAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using HtmlGenerator.Extensions; 4 | 5 | namespace HtmlGenerator 6 | { 7 | public class HtmlAttribute : HtmlObject, IEquatable 8 | { 9 | public HtmlAttribute(string name) 10 | { 11 | Requires.NotNullOrWhitespace(name, nameof(name)); 12 | Name = name.ToAsciiLower(); 13 | } 14 | 15 | public HtmlAttribute(string name, string value) : this(name) 16 | { 17 | SetValue(value); 18 | } 19 | 20 | public override HtmlObjectType ObjectType => HtmlObjectType.Attribute; 21 | 22 | public string Name { get; } 23 | public string Value { get; private set; } 24 | 25 | public bool IsVoid => Value == null; 26 | 27 | public void RemoveFromParent() 28 | { 29 | if (Parent == null) 30 | { 31 | return; 32 | } 33 | Parent.RemoveAttribute(this); 34 | } 35 | 36 | public void SetValue(string value) 37 | { 38 | Requires.NotNull(value, nameof(value)); 39 | Value = value; 40 | } 41 | 42 | public override bool Equals(object obj) => Equals(obj as HtmlAttribute); 43 | 44 | public bool Equals(HtmlAttribute attribute) 45 | { 46 | if (attribute == null) 47 | { 48 | return false; 49 | } 50 | return Name == attribute.Name && Value == attribute.Value; 51 | } 52 | 53 | public override int GetHashCode() => IsVoid ? Name.GetHashCode() : Name.GetHashCode() ^ Value.GetHashCode(); 54 | 55 | public override void Serialize(StringBuilder builder, int depth, HtmlSerializeOptions serializeOptions) 56 | { 57 | int extraLength = IsVoid ? 0 : (3 + Value.Length); 58 | builder.EnsureCapacity(builder.Capacity + Name.Length + extraLength); 59 | builder.Append(Name); 60 | if (!IsVoid) 61 | { 62 | builder.Append('='); 63 | builder.Append('"'); 64 | builder.Append(Value); 65 | builder.Append('"'); 66 | } 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/HtmlComment.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | 4 | namespace HtmlGenerator 5 | { 6 | public class HtmlComment : HtmlNode, IEquatable 7 | { 8 | public HtmlComment(string comment) 9 | { 10 | Requires.NotNull(comment, nameof(comment)); 11 | Comment = comment; 12 | } 13 | 14 | public override HtmlObjectType ObjectType => HtmlObjectType.Comment; 15 | 16 | public string Comment { get; } 17 | 18 | public override bool Equals(object obj) => Equals(obj as HtmlComment); 19 | 20 | public bool Equals(HtmlComment other) => other != null && Comment == other.Comment; 21 | 22 | public override int GetHashCode() => Comment.GetHashCode(); 23 | 24 | public override void Serialize(StringBuilder builder, int depth, HtmlSerializeOptions serializeOptions) 25 | { 26 | AddDepth(builder, depth); 27 | builder.Append('<'); 28 | builder.Append('!'); 29 | builder.Append('-', 2); 30 | builder.Append(Comment); 31 | builder.Append('-', 2); 32 | builder.Append('>'); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/HtmlDoctype.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | 4 | namespace HtmlGenerator 5 | { 6 | public class HtmlDoctype : HtmlNode, IEquatable 7 | { 8 | public HtmlDoctype(HtmlDoctypeType doctype) 9 | { 10 | if (doctype == HtmlDoctypeType.Html5) 11 | { 12 | Doctype = "DOCTYPE html"; 13 | } 14 | else if (doctype == HtmlDoctypeType.Html401Strict) 15 | { 16 | Doctype = "DOCTYPE HTML PUBLIC \" -//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\""; 17 | } 18 | else if (doctype == HtmlDoctypeType.Html401Transitional) 19 | { 20 | Doctype = "DOCTYPE HTML PUBLIC \" -//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\""; 21 | } 22 | else if (doctype == HtmlDoctypeType.Html401Frameset) 23 | { 24 | Doctype = "DOCTYPE HTML PUBLIC \" -//W3C//DTD HTML 4.01 Frameset//EN\" \"http://www.w3.org/TR/html4/frameset.dtd\""; 25 | } 26 | else if (doctype == HtmlDoctypeType.XHtml10Strict) 27 | { 28 | Doctype = "DOCTYPE html PUBLIC \" -//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\""; 29 | } 30 | else if (doctype == HtmlDoctypeType.XHtml10Transitional) 31 | { 32 | Doctype = "DOCTYPE html PUBLIC \" -//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\""; 33 | } 34 | else if (doctype == HtmlDoctypeType.XHtml10Frameset) 35 | { 36 | Doctype = "DOCTYPE html PUBLIC \" -//W3C//DTD XHTML 1.0 Frameset//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd\""; 37 | } 38 | else if (doctype == HtmlDoctypeType.XHtml11) 39 | { 40 | Doctype = "DOCTYPE html PUBLIC \" -//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\""; 41 | } 42 | else 43 | { 44 | throw new ArgumentException("Can't infer the doctype from the HtmlDoctypeType provided.", nameof(doctype)); 45 | } 46 | 47 | _doctypeType = doctype; 48 | } 49 | 50 | public HtmlDoctype(string doctype) 51 | { 52 | Requires.NotNullOrWhitespace(doctype, nameof(doctype)); 53 | Doctype = doctype; 54 | _doctypeType = (HtmlDoctypeType)(-1); 55 | } 56 | 57 | public override HtmlObjectType ObjectType => HtmlObjectType.Doctype; 58 | 59 | public string Doctype { get; } 60 | 61 | private HtmlDoctypeType _doctypeType; 62 | public HtmlDoctypeType DoctypeType 63 | { 64 | get 65 | { 66 | if (_doctypeType == (HtmlDoctypeType)(-1)) 67 | { 68 | if (Doctype == "DOCTYPE html") 69 | { 70 | _doctypeType = HtmlDoctypeType.Html5; 71 | } 72 | else if (Doctype == "DOCTYPE HTML PUBLIC \" -//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\"") 73 | { 74 | _doctypeType = HtmlDoctypeType.Html401Strict; 75 | } 76 | else if (Doctype == "DOCTYPE HTML PUBLIC \" -//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\"") 77 | { 78 | _doctypeType = HtmlDoctypeType.Html401Transitional; 79 | } 80 | else if (Doctype == "DOCTYPE HTML PUBLIC \" -//W3C//DTD HTML 4.01 Frameset//EN\" \"http://www.w3.org/TR/html4/frameset.dtd\"") 81 | { 82 | _doctypeType = HtmlDoctypeType.Html401Frameset; 83 | } 84 | else if (Doctype == "DOCTYPE html PUBLIC \" -//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\"") 85 | { 86 | _doctypeType = HtmlDoctypeType.XHtml10Strict; 87 | } 88 | else if (Doctype == "DOCTYPE html PUBLIC \" -//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"") 89 | { 90 | _doctypeType = HtmlDoctypeType.XHtml10Transitional; 91 | } 92 | else if (Doctype == "DOCTYPE html PUBLIC \" -//W3C//DTD XHTML 1.0 Frameset//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd\"") 93 | { 94 | _doctypeType = HtmlDoctypeType.XHtml10Frameset; 95 | } 96 | else if (Doctype == "DOCTYPE html PUBLIC \" -//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\"") 97 | { 98 | _doctypeType = HtmlDoctypeType.XHtml11; 99 | } 100 | else 101 | { 102 | _doctypeType = HtmlDoctypeType.Custom; 103 | } 104 | } 105 | return _doctypeType; 106 | } 107 | } 108 | 109 | public override bool Equals(object obj) => Equals(obj as HtmlDoctype); 110 | 111 | public bool Equals(HtmlDoctype other) => other != null && Doctype == other.Doctype; 112 | 113 | public override int GetHashCode() => Doctype.GetHashCode(); 114 | 115 | public override void Serialize(StringBuilder builder, int depth, HtmlSerializeOptions serializeOptions) 116 | { 117 | AddDepth(builder, depth); 118 | builder.Append('<'); 119 | builder.Append('!'); 120 | builder.Append(Doctype); 121 | builder.Append('>'); 122 | } 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /src/HtmlDoctypeType.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public enum HtmlDoctypeType 4 | { 5 | Html5, 6 | Html401Strict, 7 | Html401Transitional, 8 | Html401Frameset, 9 | XHtml10Strict, 10 | XHtml10Transitional, 11 | XHtml10Frameset, 12 | XHtml11, 13 | Custom 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/HtmlDocument.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | 4 | namespace HtmlGenerator 5 | { 6 | public class HtmlDocument : HtmlElement, IEquatable 7 | { 8 | public HtmlDocument() : base("html") 9 | { 10 | Doctype = new HtmlDoctype(HtmlDoctypeType.Html5); 11 | } 12 | 13 | public override HtmlObjectType ObjectType => HtmlObjectType.Document; 14 | 15 | private HtmlElement _head = null; 16 | public HtmlElement Head 17 | { 18 | get { return _head; } 19 | set 20 | { 21 | _head?.RemoveFromParent(); 22 | if (value != null) 23 | { 24 | Add(value); 25 | } 26 | _head = value; 27 | } 28 | } 29 | 30 | private HtmlElement _body = null; 31 | public HtmlElement Body 32 | { 33 | get { return _body; } 34 | set 35 | { 36 | _body?.RemoveFromParent(); 37 | if (value != null) 38 | { 39 | Add(value); 40 | } 41 | _body = value; 42 | } 43 | } 44 | 45 | public HtmlDoctype Doctype { get; set; } 46 | 47 | public HtmlDocument AddHead() 48 | { 49 | if (Head != null) 50 | { 51 | throw new InvalidOperationException("Document already has a head element."); 52 | } 53 | Head = HtmlGenerator.Tag.Head; 54 | return this; 55 | } 56 | 57 | public HtmlDocument AddBody() 58 | { 59 | if (Body != null) 60 | { 61 | throw new InvalidOperationException("Document already has a body element."); 62 | } 63 | Body = HtmlGenerator.Tag.Body; 64 | return this; 65 | } 66 | 67 | public override bool Equals(object obj) => Equals(obj as HtmlDocument); 68 | 69 | public bool Equals(HtmlDocument other) 70 | { 71 | if (!base.Equals(other)) 72 | { 73 | return false; 74 | } 75 | if (Doctype == null) 76 | { 77 | return other.Doctype == null; 78 | } 79 | return Doctype.Equals(other.Doctype); 80 | } 81 | 82 | public override int GetHashCode() => Doctype == null ? base.GetHashCode() : (base.GetHashCode() ^ Doctype.GetHashCode()); 83 | 84 | public override void Serialize(StringBuilder builder, int depth, HtmlSerializeOptions serializeOptions) 85 | { 86 | if (Doctype != null) 87 | { 88 | Doctype.Serialize(builder, depth, serializeOptions); 89 | if (serializeOptions != HtmlSerializeOptions.NoFormatting) 90 | { 91 | builder.AppendLine(); 92 | } 93 | } 94 | base.Serialize(builder, depth, serializeOptions); 95 | } 96 | 97 | public static new HtmlDocument Parse(string text) 98 | { 99 | Requires.NotNullOrEmpty(text, nameof(text)); 100 | 101 | Parser parser = new Parser(text, isDocument: true); 102 | if (!parser.Parse()) 103 | { 104 | throw parser.GetException(); 105 | } 106 | return (HtmlDocument)parser.rootElement; 107 | } 108 | 109 | public static bool TryParse(string text, out HtmlDocument document) 110 | { 111 | document = null; 112 | if (text == null || text.Length == 0) 113 | { 114 | return false; 115 | } 116 | 117 | Parser parser = new Parser(text, isDocument: true); 118 | if (parser.Parse()) 119 | { 120 | document = (HtmlDocument)parser.rootElement; 121 | return true; 122 | } 123 | return false; 124 | } 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /src/HtmlException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HtmlGenerator 4 | { 5 | public class HtmlException : Exception 6 | { 7 | public HtmlException() { } 8 | 9 | public HtmlException(string message) : base(message) { } 10 | 11 | public HtmlException(string message, Exception innerException) : base(message, innerException) { } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/HtmlGenerator.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | true 6 | 2.0.0 7 | 8 | 9 | 10 | Hugh Bellamy 11 | HtmlGenerator. 12 | A library that simplifies generating complex HTML files from C# code. 13 | Hugh Bellamy 2020 14 | html;generator;web 15 | https://github.com/hughbe/html-generator 16 | MIT 17 | false 18 | git 19 | https://github.com/hughbe/html-generator 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/HtmlNode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace HtmlGenerator 5 | { 6 | public abstract class HtmlNode : HtmlObject 7 | { 8 | public HtmlNode NextNode => (HtmlNode)_next; 9 | public HtmlNode PreviousNode => (HtmlNode)_previous; 10 | 11 | public void AddAfterSelf(HtmlNode content) 12 | { 13 | Requires.NotNull(content, nameof(content)); 14 | 15 | if (ReferenceEquals(this, content)) 16 | { 17 | throw new InvalidOperationException("Cannot add a node as before itself."); 18 | } 19 | if (ReferenceEquals(this, content.Parent)) 20 | { 21 | throw new InvalidOperationException("The node has already been added to this node."); 22 | } 23 | if (Parent == null) 24 | { 25 | throw new InvalidOperationException("This node does not have a parent."); 26 | } 27 | AddNodeAfter(Parent, this, content); 28 | } 29 | 30 | public void AddAfterSelf(params HtmlNode[] content) => AddAfterSelf((IEnumerable)content); 31 | 32 | public void AddAfterSelf(IEnumerable content) 33 | { 34 | Requires.NotNull(content, nameof(content)); 35 | 36 | HtmlNode current = this; 37 | foreach (HtmlNode node in content) 38 | { 39 | current.AddAfterSelf(node); 40 | current = node; 41 | } 42 | } 43 | 44 | public void AddBeforeSelf(HtmlNode content) 45 | { 46 | Requires.NotNull(content, nameof(content)); 47 | 48 | if (ReferenceEquals(this, content)) 49 | { 50 | throw new InvalidOperationException("Cannot add a node as before itself."); 51 | } 52 | if (ReferenceEquals(this, content.Parent)) 53 | { 54 | throw new InvalidOperationException("The node has already been added to this node."); 55 | } 56 | if (Parent == null) 57 | { 58 | throw new InvalidOperationException("This node does not have a parent."); 59 | } 60 | AddNodeBefore(Parent, this, content); 61 | } 62 | 63 | public void AddBeforeSelf(params HtmlNode[] content) => AddBeforeSelf((IEnumerable)content); 64 | 65 | public void AddBeforeSelf(IEnumerable content) 66 | { 67 | Requires.NotNull(content, nameof(content)); 68 | 69 | HtmlNode current = this; 70 | foreach (HtmlElement element in content) 71 | { 72 | current.AddBeforeSelf(element); 73 | current = element; 74 | } 75 | } 76 | 77 | protected static void AddNodeAfter(HtmlElement parent, HtmlNode previousNode, HtmlNode node) 78 | { 79 | node.RemoveFromParent(); 80 | node.Parent = parent; 81 | parent._nodes.AddAfter(previousNode, node); 82 | } 83 | 84 | protected static void AddNodeBefore(HtmlElement parent, HtmlNode nextNode, HtmlNode node) 85 | { 86 | node.RemoveFromParent(); 87 | node.Parent = parent; 88 | parent._nodes.AddBefore(nextNode, node); 89 | } 90 | 91 | public IEnumerable NextNodes() 92 | { 93 | HtmlObject nextNode = _next; 94 | while (nextNode != null) 95 | { 96 | yield return (HtmlNode)nextNode; 97 | nextNode = nextNode._next; 98 | } 99 | } 100 | 101 | public IEnumerable PreviousNodes() 102 | { 103 | HtmlObject previousNode = _previous; 104 | while (previousNode != null) 105 | { 106 | yield return (HtmlNode)previousNode; 107 | previousNode = previousNode._previous; 108 | } 109 | } 110 | 111 | public void RemoveFromParent() 112 | { 113 | if (Parent == null) 114 | { 115 | return; 116 | } 117 | Parent._nodes.Remove(this); 118 | Parent = null; 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /src/HtmlObject.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | 3 | namespace HtmlGenerator 4 | { 5 | public abstract class HtmlObject 6 | { 7 | public HtmlElement Parent { get; internal set; } 8 | public abstract HtmlObjectType ObjectType { get; } 9 | 10 | public override string ToString() => Serialize(); 11 | 12 | public string Serialize() => Serialize(HtmlSerializeOptions.None); 13 | 14 | public string Serialize(HtmlSerializeOptions serializeOptions) 15 | { 16 | StringBuilder stringBuilder = new StringBuilder(); 17 | Serialize(stringBuilder, 0, serializeOptions); 18 | return stringBuilder.ToString(); 19 | } 20 | 21 | public abstract void Serialize(StringBuilder builder, int depth, HtmlSerializeOptions serializeOptions); 22 | 23 | protected void AddDepth(StringBuilder builder, int depth) => builder.Append(' ', depth * 2); 24 | 25 | internal HtmlObject _previous; 26 | internal HtmlObject _next; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/HtmlObjectLinkedList.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | internal class HtmlObjectLinkedList where T : HtmlObject 4 | { 5 | public T _first; 6 | public T _last; 7 | 8 | public int _count; 9 | 10 | public void AddBefore(T node, T value) 11 | { 12 | if (node != null) 13 | { 14 | value._next = node; 15 | if (node._previous != null) 16 | { 17 | node._previous._next = value; 18 | value._previous = node._previous; 19 | } 20 | node._previous = value; 21 | } 22 | if (node == _first) 23 | { 24 | _first = value; 25 | if (_last == null) 26 | { 27 | _last = _first; 28 | } 29 | } 30 | _count++; 31 | } 32 | 33 | public void AddAfter(T node, T value) 34 | { 35 | if (node != null) 36 | { 37 | value._previous = node; 38 | if (node._next != null) 39 | { 40 | node._next._previous = value; 41 | value._next = node._next; 42 | } 43 | node._next = value; 44 | } 45 | if (node == _last) 46 | { 47 | _last = value; 48 | if (_first == null) 49 | { 50 | _first = _last; 51 | } 52 | } 53 | _count++; 54 | } 55 | 56 | public void Remove(T node) 57 | { 58 | HtmlObject previous = node._previous; 59 | HtmlObject next = node._next; 60 | if (node == _first) 61 | { 62 | _first = (T)next; 63 | } 64 | if (node == _last) 65 | { 66 | _last = (T)previous; 67 | } 68 | if (previous != null) 69 | { 70 | previous._next = next; 71 | } 72 | if (next != null) 73 | { 74 | next._previous = previous; 75 | } 76 | node._previous = null; 77 | node._next = null; 78 | _count--; 79 | } 80 | 81 | public void Clear() 82 | { 83 | HtmlObject current = _first; 84 | while (current != null) 85 | { 86 | HtmlObject next = current._next; 87 | current._previous = null; 88 | current._next = null; 89 | 90 | current = next; 91 | } 92 | _count = 0; 93 | _first = null; 94 | _last = null; 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/HtmlObjectType.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public enum HtmlObjectType 4 | { 5 | Attribute, 6 | Element, 7 | Comment, 8 | Doctype, 9 | Text, 10 | Document 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/HtmlSerializeType.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public enum HtmlSerializeOptions 4 | { 5 | None, 6 | NoFormatting 7 | } 8 | } -------------------------------------------------------------------------------- /src/HtmlText.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | 4 | namespace HtmlGenerator 5 | { 6 | public class HtmlText : HtmlNode, IEquatable 7 | { 8 | public HtmlText(string text) 9 | { 10 | Requires.NotNull(text, nameof(text)); 11 | Text = text; 12 | } 13 | 14 | public override HtmlObjectType ObjectType => HtmlObjectType.Text; 15 | 16 | public string Text { get; } 17 | 18 | public override bool Equals(object obj) => Equals(obj as HtmlText); 19 | 20 | public bool Equals(HtmlText other) => other != null && Text == other.Text; 21 | 22 | public override int GetHashCode() => Text.GetHashCode(); 23 | 24 | public override void Serialize(StringBuilder builder, int depth, HtmlSerializeOptions serializeOptions) => builder.Append(Text); 25 | 26 | public static implicit operator HtmlText(string text) => new HtmlText(text); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Requires.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HtmlGenerator 4 | { 5 | public static class Requires 6 | { 7 | public static void NotNull(object value, string paramName) 8 | { 9 | if (value == null) 10 | { 11 | throw new ArgumentNullException(paramName); 12 | } 13 | } 14 | 15 | public static void NotNullOrEmpty(string value, string paramName) 16 | { 17 | NotNull(value, paramName); 18 | if (string.IsNullOrEmpty(value)) 19 | { 20 | throw new ArgumentException("Argument cannot be empty.", paramName); 21 | } 22 | } 23 | 24 | public static void NotNullOrWhitespace(string value, string paramName) 25 | { 26 | NotNull(value, paramName); 27 | if (string.IsNullOrWhiteSpace(value)) 28 | { 29 | throw new ArgumentException("Argument cannot be empty or whitespace.", paramName); 30 | } 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/SpecialTag.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public static partial class Tag 4 | { 5 | public static HtmlLinkElement Css(string src) => new HtmlLinkElement().WithRel("stylesheet").WithHref(src); 6 | 7 | public static HtmlElement Header1(string innerText) => Tag.H1.WithInnerText(innerText); 8 | public static HtmlElement Header2(string innerText) => Tag.H2.WithInnerText(innerText); 9 | public static HtmlElement Header3(string innerText) => Tag.H3.WithInnerText(innerText); 10 | public static HtmlElement Header4(string innerText) => Tag.H4.WithInnerText(innerText); 11 | public static HtmlElement Header5(string innerText) => Tag.H5.WithInnerText(innerText); 12 | public static HtmlElement Header6(string innerText) => Tag.H6.WithInnerText(innerText); 13 | public static HtmlAElement Hyperlink(string href, string innerText) => new HtmlAElement().WithHref(href).WithInnerText(innerText); 14 | 15 | public static HtmlImgElement Image(string src) => Image(src, ""); 16 | public static HtmlImgElement Image(string src, string alt) => new HtmlImgElement().WithSrc(src).WithAlt(alt); 17 | 18 | public static HtmlScriptElement Javascript(string src) => new HtmlScriptElement().WithSrc(src); 19 | 20 | public static HtmlLiElement ListItem(string innerText) => new HtmlLiElement().WithInnerText(innerText); 21 | 22 | public static HtmlMetaElement Metadata(string name, string content) => new HtmlMetaElement().WithName(name).WithContent(content); 23 | 24 | public static HtmlElement Paragraph(string innerText) => Tag.P.WithInnerText(innerText); 25 | 26 | public static HtmlElement Custom(string elementTag) => Custom(elementTag, false); 27 | public static HtmlElement Custom(string elementTag, bool isVoid) => new HtmlElement(elementTag, isVoid); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Tag.cs: -------------------------------------------------------------------------------- 1 | namespace HtmlGenerator 2 | { 3 | public static partial class Tag 4 | { 5 | public static HtmlAElement A => new HtmlAElement(); 6 | public static HtmlElement Abbr => new HtmlElement("abbr"); 7 | public static HtmlElement Address => new HtmlElement("address"); 8 | public static HtmlAreaElement Area => new HtmlAreaElement(); 9 | public static HtmlElement Article => new HtmlElement("article"); 10 | public static HtmlAudioElement Audio => new HtmlAudioElement(); 11 | 12 | public static HtmlElement B => new HtmlElement("b"); 13 | public static HtmlBaseElement Base => new HtmlBaseElement(); 14 | public static HtmlElement Bdi => new HtmlElement("bdi"); 15 | public static HtmlElement Body => new HtmlElement("body"); 16 | public static HtmlElement Br => new HtmlElement("br", isVoid: true); 17 | public static HtmlButtonElement Button => new HtmlButtonElement(); 18 | 19 | public static HtmlCanvasElement Canvas => new HtmlCanvasElement(); 20 | public static HtmlElement Caption => new HtmlElement("caption"); 21 | public static HtmlElement Cite => new HtmlElement("cite"); 22 | public static HtmlElement Code => new HtmlElement("code"); 23 | public static HtmlColElement Col => new HtmlColElement(); 24 | public static HtmlColgroupElement Colgroup => new HtmlColgroupElement(); 25 | 26 | public static HtmlDataElement Data => new HtmlDataElement(); 27 | public static HtmlElement Datalist => new HtmlElement("datalist"); 28 | public static HtmlDdElement Dd => new HtmlDdElement(); 29 | public static HtmlDelElement Del => new HtmlDelElement(); 30 | public static HtmlDetailsElement Details => new HtmlDetailsElement(); 31 | public static HtmlElement Dfn => new HtmlElement("dfn"); 32 | public static HtmlDialogElement Dialog => new HtmlDialogElement(); 33 | public static HtmlElement Div => new HtmlElement("div"); 34 | public static HtmlDlElement Dl => new HtmlDlElement(); 35 | public static HtmlElement Dt => new HtmlElement("dt"); 36 | 37 | public static HtmlElement Em => new HtmlElement("em"); 38 | public static HtmlEmbedElement Embed => new HtmlEmbedElement(); 39 | 40 | public static HtmlElement Fieldset => new HtmlElement("fieldset"); 41 | public static HtmlElement FigCaption => new HtmlElement("figcaption"); 42 | public static HtmlElement Figure => new HtmlElement("figure"); 43 | public static HtmlElement Footer => new HtmlElement("footer"); 44 | public static HtmlFormElement Form => new HtmlFormElement(); 45 | 46 | public static HtmlElement H1 => new HtmlElement("h1"); 47 | public static HtmlElement H2 => new HtmlElement("h2"); 48 | public static HtmlElement H3 => new HtmlElement("h3"); 49 | public static HtmlElement H4 => new HtmlElement("h4"); 50 | public static HtmlElement H5 => new HtmlElement("h5"); 51 | public static HtmlElement H6 => new HtmlElement("h6"); 52 | public static HtmlElement Head => new HtmlElement("head"); 53 | public static HtmlElement Header => new HtmlElement("header"); 54 | public static HtmlHrElement Hr => new HtmlHrElement(); 55 | public static HtmlHtmlElement Html => new HtmlHtmlElement(); 56 | 57 | public static HtmlElement I => new HtmlElement("i"); 58 | public static HtmlIframeElement Iframe => new HtmlIframeElement(); 59 | public static HtmlImgElement Img => new HtmlImgElement(); 60 | public static HtmlInputElement Input => new HtmlInputElement(); 61 | public static HtmlInsElement Ins => new HtmlInsElement(); 62 | 63 | public static HtmlElement Kbd => new HtmlElement("kbd"); 64 | 65 | public static HtmlLabelElement Label => new HtmlLabelElement(); 66 | public static HtmlElement Legend => new HtmlElement("legend"); 67 | public static HtmlLiElement Li => new HtmlLiElement(); 68 | public static HtmlLinkElement Link => new HtmlLinkElement(); 69 | 70 | public static HtmlElement Main => new HtmlElement("main"); 71 | public static HtmlMapElement Map => new HtmlMapElement(); 72 | public static HtmlElement Mark => new HtmlElement("mark"); 73 | public static HtmlMenuElement Menu => new HtmlMenuElement(); 74 | public static HtmlMenuItemElement MenuItem => new HtmlMenuItemElement(); 75 | public static HtmlMetaElement Meta => new HtmlMetaElement(); 76 | public static HtmlMeterElement Meter => new HtmlMeterElement(); 77 | 78 | public static HtmlElement Nav => new HtmlElement("nav"); 79 | public static HtmlElement Noscript => new HtmlElement("noscript"); 80 | 81 | public static HtmlObjectElement Object => new HtmlObjectElement(); 82 | public static HtmlOlElement Ol => new HtmlOlElement(); 83 | public static HtmlOptgroupElement Optgroup => new HtmlOptgroupElement(); 84 | public static HtmlOptionElement Option => new HtmlOptionElement(); 85 | public static HtmlOutputElement Output => new HtmlOutputElement(); 86 | 87 | public static HtmlElement P => new HtmlElement("p"); 88 | public static HtmlParamElement Param => new HtmlParamElement(); 89 | public static HtmlElement Pre => new HtmlElement("pre"); 90 | public static HtmlProgressElement Progress => new HtmlProgressElement(); 91 | 92 | public static HtmlQElement Q => new HtmlQElement(); 93 | 94 | public static HtmlElement Rp => new HtmlElement("rp"); 95 | public static HtmlElement Rt => new HtmlElement("rt"); 96 | public static HtmlElement Rtc => new HtmlElement("rtc"); 97 | public static HtmlElement Ruby => new HtmlElement("ruby"); 98 | 99 | public static HtmlElement Samp => new HtmlElement("samp"); 100 | public static HtmlScriptElement Script => new HtmlScriptElement(); 101 | public static HtmlElement Section => new HtmlElement("section"); 102 | public static HtmlSelectElement Select => new HtmlSelectElement(); 103 | public static HtmlElement Small => new HtmlElement("small"); 104 | public static HtmlSourceElement Source => new HtmlSourceElement(); 105 | public static HtmlElement Span => new HtmlElement("span"); 106 | public static HtmlElement Strong => new HtmlElement("strong"); 107 | public static HtmlStyleElement Style => new HtmlStyleElement(); 108 | public static HtmlElement Sub => new HtmlElement("sub"); 109 | public static HtmlElement Summary => new HtmlElement("summary"); 110 | public static HtmlElement Sup => new HtmlElement("sup"); 111 | 112 | public static HtmlElement Table => new HtmlElement("table"); 113 | public static HtmlElement Tbody => new HtmlElement("tbody"); 114 | public static HtmlElement Td => new HtmlElement("td"); 115 | public static HtmlElement Template => new HtmlElement("template"); 116 | public static HtmlTextAreaElement TextArea => new HtmlTextAreaElement(); 117 | public static HtmlElement Tfoot => new HtmlElement("tfoot"); 118 | public static HtmlThElement Th => new HtmlThElement(); 119 | public static HtmlElement Thead => new HtmlElement("thead"); 120 | public static HtmlTimeElement Time => new HtmlTimeElement(); 121 | public static HtmlElement Title => new HtmlElement("title"); 122 | public static HtmlElement Tr => new HtmlElement("tr"); 123 | public static HtmlTrackElement Track => new HtmlTrackElement(); 124 | 125 | public static HtmlElement U => new HtmlElement("u"); 126 | public static HtmlElement Ul => new HtmlElement("ul"); 127 | 128 | public static HtmlElement Var => new HtmlElement("var"); 129 | public static HtmlVideoElement Video => new HtmlVideoElement(); 130 | 131 | public static HtmlElement Wbr => new HtmlElement("wbr"); 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /tests/AttributeTests.cs: -------------------------------------------------------------------------------- 1 | using Xunit; 2 | 3 | namespace HtmlGenerator.Tests 4 | { 5 | public class AttributeTests 6 | { 7 | [Fact] 8 | public void AttributeConstructors() 9 | { 10 | VerifyAttribute(Attribute.Accept("value"), "accept", "value"); 11 | VerifyAttribute(Attribute.AcceptCharset("value"), "accept-charset", "value"); 12 | VerifyAttribute(Attribute.AccessKey("value"), "accesskey", "value"); 13 | VerifyAttribute(Attribute.Action("value"), "action", "value"); 14 | VerifyAttribute(Attribute.Align, "align", null); 15 | VerifyAttribute(Attribute.AllowFullScreen, "allowfullscreen", null); 16 | VerifyAttribute(Attribute.Alt("value"), "alt", "value"); 17 | VerifyAttribute(Attribute.Async("value"), "async", "value"); 18 | VerifyAttribute(Attribute.AutoComplete("value"), "autocomplete", "value"); 19 | VerifyAttribute(Attribute.AutoFocus, "autofocus", null); 20 | VerifyAttribute(Attribute.AutoPlay("value"), "autoplay", "value"); 21 | VerifyAttribute(Attribute.AutoSave("value"), "autosave", "value"); 22 | 23 | VerifyAttribute(Attribute.BgColor("value"), "bgcolor", "value"); 24 | VerifyAttribute(Attribute.Border("value"), "border", "value"); 25 | 26 | VerifyAttribute(Attribute.CellPadding("value"), "cellpadding", "value"); 27 | VerifyAttribute(Attribute.CellSpacing("value"), "cellspacing", "value"); 28 | VerifyAttribute(Attribute.Charset("value"), "charset", "value"); 29 | VerifyAttribute(Attribute.Checked, "checked", null); 30 | VerifyAttribute(Attribute.Cite("value"), "cite", "value"); 31 | VerifyAttribute(Attribute.Class("value"), "class", "value"); 32 | VerifyAttribute(Attribute.Color("value"), "color", "value"); 33 | VerifyAttribute(Attribute.Cols("value"), "cols", "value"); 34 | VerifyAttribute(Attribute.ColSpan("value"), "colspan", "value"); 35 | VerifyAttribute(Attribute.Command("value"), "command", "value"); 36 | VerifyAttribute(Attribute.Compact("value"), "compact", "value"); 37 | VerifyAttribute(Attribute.Content("value"), "content", "value"); 38 | VerifyAttribute(Attribute.ContentEditable("value"), "contenteditable", "value"); 39 | VerifyAttribute(Attribute.ContextMenu("value"), "contextmenu", "value"); 40 | VerifyAttribute(Attribute.Controls, "controls", null); 41 | VerifyAttribute(Attribute.Coords("value"), "coords", "value"); 42 | VerifyAttribute(Attribute.CrossOrigin("value"), "crossorigin", "value"); 43 | 44 | VerifyAttribute(Attribute.Data("value"), "data", "value"); 45 | VerifyAttribute(Attribute.DateTime("value"), "datetime", "value"); 46 | VerifyAttribute(Attribute.Default, "default", null); 47 | VerifyAttribute(Attribute.DefaultStyle("value"), "default-style", "value"); 48 | VerifyAttribute(Attribute.Defer("value"), "defer", "value"); 49 | VerifyAttribute(Attribute.Dir("value"), "dir", "value"); 50 | VerifyAttribute(Attribute.Disabled, "disabled", null); 51 | VerifyAttribute(Attribute.Download("value"), "download", "value"); 52 | VerifyAttribute(Attribute.Draggable("value"), "draggable", "value"); 53 | VerifyAttribute(Attribute.DropZone("value"), "dropzone", "value"); 54 | 55 | VerifyAttribute(Attribute.EncType("value"), "enctype", "value"); 56 | 57 | VerifyAttribute(Attribute.For("value"), "for", "value"); 58 | VerifyAttribute(Attribute.Form("value"), "form", "value"); 59 | VerifyAttribute(Attribute.FormAction("value"), "formaction", "value"); 60 | VerifyAttribute(Attribute.FormEncType("value"), "formenctype", "value"); 61 | VerifyAttribute(Attribute.FormMethod("value"), "formmethod", "value"); 62 | VerifyAttribute(Attribute.FormNoValidate, "formnovalidate", null); 63 | VerifyAttribute(Attribute.FormTarget("value"), "formtarget", "value"); 64 | 65 | VerifyAttribute(Attribute.Headers("value"), "headers", "value"); 66 | VerifyAttribute(Attribute.Height("value"), "height", "value"); 67 | VerifyAttribute(Attribute.Hidden("value"), "hidden", "value"); 68 | VerifyAttribute(Attribute.High("value"), "high", "value"); 69 | VerifyAttribute(Attribute.Href("value"), "href", "value"); 70 | VerifyAttribute(Attribute.HrefLang("value"), "hreflang", "value"); 71 | VerifyAttribute(Attribute.HttpEquiv("value"), "http-equiv", "value"); 72 | 73 | VerifyAttribute(Attribute.Icon("value"), "icon", "value"); 74 | VerifyAttribute(Attribute.Id("value"), "id", "value"); 75 | VerifyAttribute(Attribute.InputMode("value"), "inputmode", "value"); 76 | VerifyAttribute(Attribute.Integrity("value"), "integrity", "value"); 77 | VerifyAttribute(Attribute.IsMap("value"), "ismap", "value"); 78 | 79 | VerifyAttribute(Attribute.Kind("value"), "kind", "value"); 80 | 81 | VerifyAttribute(Attribute.Label("value"), "label", "value"); 82 | VerifyAttribute(Attribute.Lang("value"), "lang", "value"); 83 | VerifyAttribute(Attribute.List("value"), "list", "value"); 84 | VerifyAttribute(Attribute.LongDesc("value"), "longdesc", "value"); 85 | VerifyAttribute(Attribute.Loop("value"), "loop", "value"); 86 | VerifyAttribute(Attribute.Low("value"), "low", "value"); 87 | 88 | 89 | VerifyAttribute(Attribute.Max("value"), "max", "value"); 90 | VerifyAttribute(Attribute.MaxLength("value"), "maxlength", "value"); 91 | VerifyAttribute(Attribute.Media("value"), "media", "value"); 92 | VerifyAttribute(Attribute.Method("value"), "method", "value"); 93 | VerifyAttribute(Attribute.Min("value"), "min", "value"); 94 | VerifyAttribute(Attribute.MinLength("value"), "minlength", "value"); 95 | VerifyAttribute(Attribute.Multiple, "multiple", null); 96 | VerifyAttribute(Attribute.Muted("value"), "muted", "value"); 97 | 98 | VerifyAttribute(Attribute.Name("value"), "name", "value"); 99 | VerifyAttribute(Attribute.NoValidate, "novalidate", null); 100 | VerifyAttribute(Attribute.NoWrap("value"), "nowrap", "value"); 101 | 102 | VerifyAttribute(Attribute.Open("value"), "open", "value"); 103 | VerifyAttribute(Attribute.Optimum("value"), "optimum", "value"); 104 | 105 | VerifyAttribute(Attribute.Pattern("value"), "pattern", "value"); 106 | VerifyAttribute(Attribute.Ping("value"), "ping", "value"); 107 | VerifyAttribute(Attribute.Placeholder("value"), "placeholder", "value"); 108 | VerifyAttribute(Attribute.Poster("value"), "poster", "value"); 109 | VerifyAttribute(Attribute.Preload("value"), "preload", "value"); 110 | 111 | VerifyAttribute(Attribute.RadioGroup("value"), "radiogroup", "value"); 112 | VerifyAttribute(Attribute.Readonly, "readonly", null); 113 | VerifyAttribute(Attribute.Refresh("value"), "refresh", "value"); 114 | VerifyAttribute(Attribute.Rel("value"), "rel", "value"); 115 | VerifyAttribute(Attribute.Required, "required", null); 116 | VerifyAttribute(Attribute.Reversed("value"), "reversed", "value"); 117 | VerifyAttribute(Attribute.Rows("value"), "rows", "value"); 118 | VerifyAttribute(Attribute.RowSpan("value"), "rowspan", "value"); 119 | 120 | VerifyAttribute(Attribute.Sandbox, "sandbox", null); 121 | VerifyAttribute(Attribute.Scope("value"), "scope", "value"); 122 | VerifyAttribute(Attribute.Scoped, "scoped", null); 123 | VerifyAttribute(Attribute.Seamless, "seamless", null); 124 | VerifyAttribute(Attribute.Selected, "selected", null); 125 | VerifyAttribute(Attribute.SelectionDirection("value"), "selectiondirection", "value"); 126 | VerifyAttribute(Attribute.Shape("value"), "shape", "value"); 127 | VerifyAttribute(Attribute.Size("value"), "size", "value"); 128 | VerifyAttribute(Attribute.Sizes("value"), "sizes", "value"); 129 | VerifyAttribute(Attribute.Span("value"), "span", "value"); 130 | VerifyAttribute(Attribute.SpellCheck("value"), "spellcheck", "value"); 131 | VerifyAttribute(Attribute.Src("value"), "src", "value"); 132 | VerifyAttribute(Attribute.SrcDoc("value"), "srcdoc", "value"); 133 | VerifyAttribute(Attribute.SrcLang("value"), "srclang", "value"); 134 | VerifyAttribute(Attribute.SrcSet("value"), "srcset", "value"); 135 | VerifyAttribute(Attribute.Start("value"), "start", "value"); 136 | VerifyAttribute(Attribute.Step("value"), "step", "value"); 137 | VerifyAttribute(Attribute.Style("value"), "style", "value"); 138 | 139 | VerifyAttribute(Attribute.TabIndex("value"), "tabindex", "value"); 140 | VerifyAttribute(Attribute.Target("value"), "target", "value"); 141 | VerifyAttribute(Attribute.Text("value"), "text", "value"); 142 | VerifyAttribute(Attribute.Title("value"), "title", "value"); 143 | VerifyAttribute(Attribute.Translate("value"), "translate", "value"); 144 | VerifyAttribute(Attribute.Type("value"), "type", "value"); 145 | VerifyAttribute(Attribute.TypeMustMatch, "typemustmatch", null); 146 | 147 | VerifyAttribute(Attribute.UseMap("value"), "usemap", "value"); 148 | 149 | VerifyAttribute(Attribute.Value("value"), "value", "value"); 150 | VerifyAttribute(Attribute.Volume("value"), "volume", "value"); 151 | 152 | VerifyAttribute(Attribute.Width("value"), "width", "value"); 153 | VerifyAttribute(Attribute.Wrap("value"), "wrap", "value"); 154 | 155 | VerifyAttribute(Attribute.Xmls("value"), "xmls", "value"); 156 | } 157 | 158 | private static void VerifyAttribute(HtmlAttribute attribute, string name, string value) 159 | { 160 | Assert.Equal(name, attribute.Name); 161 | Assert.Equal(value, attribute.Value); 162 | Assert.Equal(value == null, attribute.IsVoid); 163 | Assert.Null(attribute.Parent); 164 | } 165 | } 166 | } 167 | -------------------------------------------------------------------------------- /tests/Helpers.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using Xunit; 4 | 5 | namespace HtmlGenerator.Tests 6 | { 7 | public static class Helpers 8 | { 9 | public static void SerializeIgnoringFormatting(HtmlElement element, string expected) 10 | { 11 | expected = expected.Replace("\r\n", "\n").Replace("\n", Environment.NewLine); 12 | Assert.Equal(expected, element.ToString()); 13 | Assert.Equal(expected, element.Serialize()); 14 | Assert.Equal(expected.Replace(Environment.NewLine, ""), element.Serialize(HtmlSerializeOptions.NoFormatting)); 15 | } 16 | } 17 | 18 | public class CustomHtmlObject : HtmlObject 19 | { 20 | public override HtmlObjectType ObjectType => HtmlObjectType.Element; 21 | 22 | public override void Serialize(StringBuilder builder, int depth, HtmlSerializeOptions serializeOptions) { } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tests/HtmlAttributeTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Xunit; 4 | 5 | namespace HtmlGenerator.Tests 6 | { 7 | public class HtmlAttributeTests 8 | { 9 | [Theory] 10 | [InlineData("name", "name")] 11 | [InlineData("NaMe", "name")] 12 | public void Ctor_String(string name, string expectedName) 13 | { 14 | HtmlAttribute attribute = new HtmlAttribute(name); 15 | Assert.Equal(expectedName, attribute.Name); 16 | Assert.Null(attribute.Value); 17 | Assert.True(attribute.IsVoid); 18 | } 19 | 20 | [Theory] 21 | [InlineData("name", "", "name")] 22 | [InlineData("name", " \r \t \n", "name")] 23 | [InlineData("name", "value", "name")] 24 | [InlineData("NaMe", "VaLuE", "name")] 25 | public void Ctor_String_String(string name, string value, string expectedName) 26 | { 27 | HtmlAttribute attribute = new HtmlAttribute(name, value); 28 | Assert.Equal(expectedName, attribute.Name); 29 | Assert.Equal(value, attribute.Value); 30 | Assert.False(attribute.IsVoid); 31 | } 32 | 33 | [Fact] 34 | public void Ctor_NullName_ThrowsArgumentNullException() 35 | { 36 | Assert.Throws("name", () => new HtmlAttribute(null)); 37 | Assert.Throws("name", () => new HtmlAttribute(null, "value")); 38 | } 39 | 40 | [Theory] 41 | [InlineData("")] 42 | [InlineData("\t \r \n")] 43 | public void Ctor_WhitespaceName_ThrowsArgumentException(string name) 44 | { 45 | Assert.Throws("name", () => new HtmlAttribute(name)); 46 | Assert.Throws("name", () => new HtmlAttribute(name, "value")); 47 | } 48 | 49 | [Fact] 50 | public void Ctor_NullValue_ThrowsArgumentNullException() 51 | { 52 | Assert.Throws("value", () => new HtmlAttribute("name", null)); 53 | } 54 | 55 | [Fact] 56 | public void ObjectType_Get_ReturnsAttribute() 57 | { 58 | HtmlAttribute attribute = new HtmlAttribute("Attribute"); 59 | Assert.Equal(HtmlObjectType.Attribute, attribute.ObjectType); 60 | } 61 | 62 | [Fact] 63 | public void RemoveFromParent_FirstChild() 64 | { 65 | HtmlAttribute attribute1 = new HtmlAttribute("attribute1"); 66 | HtmlAttribute attribute2 = new HtmlAttribute("attribute2"); 67 | HtmlAttribute attribute3 = new HtmlAttribute("attribute3"); 68 | HtmlElement element = new HtmlElement("element", attribute1, attribute2, attribute3); 69 | 70 | attribute1.RemoveFromParent(); 71 | Assert.Null(attribute1.Parent); 72 | Assert.Equal(new HtmlAttribute[] { attribute2, attribute3 }, element.Attributes()); 73 | } 74 | 75 | [Fact] 76 | public void RemoveFromParent_LastChild() 77 | { 78 | HtmlAttribute attribute1 = new HtmlAttribute("attribute1"); 79 | HtmlAttribute attribute2 = new HtmlAttribute("attribute2"); 80 | HtmlAttribute attribute3 = new HtmlAttribute("attribute3"); 81 | HtmlElement element = new HtmlElement("element", attribute1, attribute2, attribute3); 82 | 83 | attribute3.RemoveFromParent(); 84 | Assert.Null(attribute3.Parent); 85 | Assert.Equal(new HtmlAttribute[] { attribute1, attribute2 }, element.Attributes()); 86 | } 87 | 88 | [Fact] 89 | public void RemoveFromParent_MiddleChild() 90 | { 91 | HtmlAttribute attribute1 = new HtmlAttribute("attribute1"); 92 | HtmlAttribute attribute2 = new HtmlAttribute("attribute2"); 93 | HtmlAttribute attribute3 = new HtmlAttribute("attribute3"); 94 | HtmlElement element = new HtmlElement("element", attribute1, attribute2, attribute3); 95 | 96 | attribute2.RemoveFromParent(); 97 | Assert.Null(attribute2.Parent); 98 | Assert.Equal(new HtmlAttribute[] { attribute1, attribute3 }, element.Attributes()); 99 | } 100 | 101 | [Fact] 102 | public void RemoveFromParent_NoParent_DoesNothing() 103 | { 104 | HtmlAttribute attribute = new HtmlAttribute("attribute"); 105 | attribute.RemoveFromParent(); 106 | 107 | Assert.Null(attribute.Parent); 108 | } 109 | 110 | [Theory] 111 | [InlineData("Value")] 112 | [InlineData(" \r \n \t")] 113 | [InlineData("")] 114 | public void SetValue(string value) 115 | { 116 | HtmlAttribute attribute = new HtmlAttribute("attribute"); 117 | attribute.SetValue(value); 118 | Assert.Equal(value, attribute.Value); 119 | } 120 | 121 | [Fact] 122 | public void SetValue_NullValue_ThrowsArgumentNullException() 123 | { 124 | HtmlAttribute attribute = new HtmlAttribute("a ttribute"); 125 | Assert.Throws("value", () => attribute.SetValue(null)); 126 | } 127 | 128 | public static IEnumerable Equals_TestData() 129 | { 130 | yield return new object[] { new HtmlAttribute("name"), new HtmlAttribute("name"), true }; 131 | yield return new object[] { new HtmlAttribute("name"), new HtmlAttribute("other-name"), false }; 132 | yield return new object[] { new HtmlAttribute("name"), new HtmlAttribute("name", "value"), false }; 133 | 134 | yield return new object[] { new HtmlAttribute("name", "value"), new HtmlAttribute("name"), false }; 135 | yield return new object[] { new HtmlAttribute("name", "value"), new HtmlAttribute("name", "value"), true }; 136 | yield return new object[] { new HtmlAttribute("name", "value"), new HtmlAttribute("name", "Value"), false }; 137 | yield return new object[] { new HtmlAttribute("name", "value"), new HtmlAttribute("name", "other-value"), false }; 138 | 139 | yield return new object[] { new HtmlAttribute("name"), new object(), false }; 140 | yield return new object[] { new HtmlAttribute("name"), null, false }; 141 | } 142 | 143 | [Theory] 144 | [MemberData(nameof(Equals_TestData))] 145 | public void Equals_ReturnsExpected(HtmlAttribute attribute, object other, bool expected) 146 | { 147 | if (other is HtmlAttribute || other == null) 148 | { 149 | Assert.Equal(expected, attribute.GetHashCode().Equals(other?.GetHashCode())); 150 | Assert.Equal(expected, attribute.Equals((HtmlAttribute)other)); 151 | } 152 | Assert.Equal(expected, attribute.Equals(other)); 153 | } 154 | 155 | public static IEnumerable ToString_TestData() 156 | { 157 | yield return new object[] { new HtmlAttribute("name"), "name" }; 158 | yield return new object[] { new HtmlAttribute("name", "value"), "name=\"value\"" }; 159 | yield return new object[] { new HtmlAttribute("name", "Value"), "name=\"Value\"" }; 160 | } 161 | 162 | [Theory] 163 | [MemberData(nameof(ToString_TestData))] 164 | public void ToString_ReturnsExpected(HtmlAttribute attribute, string expected) 165 | { 166 | Assert.Equal(expected, attribute.ToString()); 167 | Assert.Equal(expected, attribute.Serialize()); 168 | Assert.Equal(expected, attribute.Serialize(HtmlSerializeOptions.None)); 169 | Assert.Equal(expected, attribute.Serialize(HtmlSerializeOptions.NoFormatting)); 170 | } 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /tests/HtmlCommentTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Xunit; 4 | 5 | namespace HtmlGenerator.Tests 6 | { 7 | public class HtmlCommentTests 8 | { 9 | [Theory] 10 | [InlineData("")] 11 | [InlineData(" \t \r \n")] 12 | [InlineData("comment")] 13 | [InlineData("CoMmEnT")] 14 | public void Ctor_String(string comment) 15 | { 16 | HtmlComment htmlComment = new HtmlComment(comment); 17 | Assert.Equal(comment, htmlComment.Comment); 18 | } 19 | 20 | [Fact] 21 | public void Ctor_NullComment_ThrowsArgumentNullException() 22 | { 23 | Assert.Throws("comment", () => new HtmlComment(null)); 24 | } 25 | 26 | [Fact] 27 | public void ObjectType_Get_ReturnsComment() 28 | { 29 | HtmlComment comment = new HtmlComment("comment"); 30 | Assert.Equal(HtmlObjectType.Comment, comment.ObjectType); 31 | } 32 | 33 | public static IEnumerable Equals_TestData() 34 | { 35 | yield return new object[] { new HtmlComment("comment"), new HtmlComment("comment"), true }; 36 | yield return new object[] { new HtmlComment("comment"), new HtmlComment("other-comment"), false }; 37 | yield return new object[] { new HtmlComment("comment"), new HtmlComment("COMMENT"), false }; 38 | 39 | yield return new object[] { new HtmlComment("comment"), new object(), false }; 40 | yield return new object[] { new HtmlComment("comment"), null, false }; 41 | } 42 | 43 | [Theory] 44 | [MemberData(nameof(Equals_TestData))] 45 | public void Equals_ReturnsExpected(HtmlComment comment, object other, bool expected) 46 | { 47 | if (other is HtmlComment || other == null) 48 | { 49 | Assert.Equal(expected, comment.GetHashCode().Equals(other?.GetHashCode())); 50 | Assert.Equal(expected, comment.Equals((HtmlComment)other)); 51 | } 52 | Assert.Equal(expected, comment.Equals(other)); 53 | } 54 | 55 | public static IEnumerable ToString_TestData() 56 | { 57 | yield return new object[] { new HtmlComment(""), "" }; 58 | yield return new object[] { new HtmlComment("comment"), "" }; 59 | yield return new object[] { new HtmlComment("COMMENT"), "" }; 60 | } 61 | 62 | [Theory] 63 | [MemberData(nameof(ToString_TestData))] 64 | public void ToString_ReturnsExpected(HtmlComment comment, string expected) 65 | { 66 | Assert.Equal(expected, comment.ToString()); 67 | Assert.Equal(expected, comment.Serialize()); 68 | Assert.Equal(expected, comment.Serialize(HtmlSerializeOptions.None)); 69 | Assert.Equal(expected, comment.Serialize(HtmlSerializeOptions.NoFormatting)); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /tests/HtmlDoctypeTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Xunit; 4 | 5 | namespace HtmlGenerator.Tests 6 | { 7 | public class HtmlDoctypeTests 8 | { 9 | [Theory] 10 | [InlineData(HtmlDoctypeType.Html5, "DOCTYPE html")] 11 | [InlineData(HtmlDoctypeType.Html401Strict, "DOCTYPE HTML PUBLIC \" -//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\"")] 12 | [InlineData(HtmlDoctypeType.Html401Transitional, "DOCTYPE HTML PUBLIC \" -//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\"")] 13 | [InlineData(HtmlDoctypeType.Html401Frameset, "DOCTYPE HTML PUBLIC \" -//W3C//DTD HTML 4.01 Frameset//EN\" \"http://www.w3.org/TR/html4/frameset.dtd\"")] 14 | [InlineData(HtmlDoctypeType.XHtml10Strict, "DOCTYPE html PUBLIC \" -//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\"")] 15 | [InlineData(HtmlDoctypeType.XHtml10Transitional, "DOCTYPE html PUBLIC \" -//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"")] 16 | [InlineData(HtmlDoctypeType.XHtml10Frameset, "DOCTYPE html PUBLIC \" -//W3C//DTD XHTML 1.0 Frameset//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd\"")] 17 | [InlineData(HtmlDoctypeType.XHtml11, "DOCTYPE html PUBLIC \" -//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\"")] 18 | public void Ctor_HtmlDoctypeType(HtmlDoctypeType doctype, string expectedDoctype) 19 | { 20 | HtmlDoctype htmlDoctype = new HtmlDoctype(doctype); 21 | Assert.Equal(expectedDoctype, htmlDoctype.Doctype); 22 | Assert.Equal(doctype, htmlDoctype.DoctypeType); 23 | } 24 | 25 | [Theory] 26 | [InlineData(HtmlDoctypeType.Html5 - 1)] 27 | [InlineData(HtmlDoctypeType.Custom)] 28 | [InlineData(HtmlDoctypeType.Custom + 1)] 29 | public void Ctor_NotSupportedHtmlDoctypeType_ThrowsArgumentException(HtmlDoctypeType doctype) 30 | { 31 | Assert.Throws("doctype", () => new HtmlDoctype(doctype)); 32 | } 33 | 34 | [Theory] 35 | [InlineData("doctype", HtmlDoctypeType.Custom)] 36 | [InlineData("DOCTYPE", HtmlDoctypeType.Custom)] 37 | [InlineData("DOCTYPE html", HtmlDoctypeType.Html5)] 38 | [InlineData("DOCTYPE HTML PUBLIC \" -//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\"", HtmlDoctypeType.Html401Strict)] 39 | [InlineData("DOCTYPE HTML PUBLIC \" -//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\"", HtmlDoctypeType.Html401Transitional)] 40 | [InlineData("DOCTYPE HTML PUBLIC \" -//W3C//DTD HTML 4.01 Frameset//EN\" \"http://www.w3.org/TR/html4/frameset.dtd\"", HtmlDoctypeType.Html401Frameset)] 41 | [InlineData("DOCTYPE html PUBLIC \" -//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\"", HtmlDoctypeType.XHtml10Strict)] 42 | [InlineData("DOCTYPE html PUBLIC \" -//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"", HtmlDoctypeType.XHtml10Transitional)] 43 | [InlineData("DOCTYPE html PUBLIC \" -//W3C//DTD XHTML 1.0 Frameset//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd\"", HtmlDoctypeType.XHtml10Frameset)] 44 | [InlineData("DOCTYPE html PUBLIC \" -//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\"", HtmlDoctypeType.XHtml11)] 45 | public void Ctor_String(string doctype, HtmlDoctypeType expectedDoctypeType) 46 | { 47 | HtmlDoctype htmlDoctype = new HtmlDoctype(doctype); 48 | Assert.Equal(doctype, htmlDoctype.Doctype); 49 | Assert.Equal(expectedDoctypeType, htmlDoctype.DoctypeType); 50 | } 51 | 52 | [Fact] 53 | public void Ctor_NullDoctype_ThrowsArgumentNullException() 54 | { 55 | Assert.Throws("doctype", () => new HtmlDoctype(null)); 56 | } 57 | 58 | [Theory] 59 | [InlineData("")] 60 | [InlineData(" \r \t \n ")] 61 | public void Ctor_EmptyOrWhitespaceDoctype_ThrowsArgumentException(string doctype) 62 | { 63 | Assert.Throws("doctype", () => new HtmlDoctype(doctype)); 64 | } 65 | 66 | [Fact] 67 | public void ObjectType_Get_ReturnsDoctype() 68 | { 69 | HtmlDoctype doctype = new HtmlDoctype("doctype"); 70 | Assert.Equal(HtmlObjectType.Doctype, doctype.ObjectType); 71 | } 72 | 73 | public static IEnumerable Equals_TestData() 74 | { 75 | yield return new object[] { new HtmlDoctype("doctype"), new HtmlDoctype("doctype"), true }; 76 | yield return new object[] { new HtmlDoctype("doctype"), new HtmlDoctype("other-doctype"), false }; 77 | yield return new object[] { new HtmlDoctype("doctype"), new HtmlDoctype("DOCTYPE"), false }; 78 | 79 | yield return new object[] { new HtmlDoctype("doctype"), new object(), false }; 80 | yield return new object[] { new HtmlDoctype("doctype"), null, false }; 81 | } 82 | 83 | [Theory] 84 | [MemberData(nameof(Equals_TestData))] 85 | public void Equals_ReturnsExpected(HtmlDoctype doctype, object other, bool expected) 86 | { 87 | if (other is HtmlDoctype || other == null) 88 | { 89 | Assert.Equal(expected, doctype.GetHashCode().Equals(other?.GetHashCode())); 90 | Assert.Equal(expected, doctype.Equals((HtmlDoctype)other)); 91 | } 92 | Assert.Equal(expected, doctype.Equals(other)); 93 | } 94 | 95 | public static IEnumerable ToString_TestData() 96 | { 97 | yield return new object[] { new HtmlDoctype("doctype"), "" }; 98 | yield return new object[] { new HtmlDoctype("DOCTYPE"), "" }; 99 | } 100 | 101 | [Theory] 102 | [MemberData(nameof(ToString_TestData))] 103 | public void ToString_ReturnsExpected(HtmlDoctype doctype, string expected) 104 | { 105 | Assert.Equal(expected, doctype.ToString()); 106 | Assert.Equal(expected, doctype.Serialize()); 107 | Assert.Equal(expected, doctype.Serialize(HtmlSerializeOptions.None)); 108 | Assert.Equal(expected, doctype.Serialize(HtmlSerializeOptions.NoFormatting)); 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /tests/HtmlDocumentTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Xunit; 4 | 5 | namespace HtmlGenerator.Tests 6 | { 7 | public class HtmlDocumentTests 8 | { 9 | [Fact] 10 | public void Ctor() 11 | { 12 | HtmlDocument document = new HtmlDocument(); 13 | Assert.Equal("html", document.Tag); 14 | Assert.False(document.IsVoid); 15 | Assert.True(document.IsEmpty); 16 | 17 | Assert.Null(document.Head); 18 | Assert.Null(document.Body); 19 | } 20 | 21 | [Fact] 22 | public void ObjectType_Get_ReturnsDocument() 23 | { 24 | HtmlDocument document = new HtmlDocument(); 25 | Assert.Equal(HtmlObjectType.Document, document.ObjectType); 26 | } 27 | 28 | [Fact] 29 | public void Doctype_Get_ReturnsExpected() 30 | { 31 | HtmlDocument document = new HtmlDocument(); 32 | Assert.Equal(new HtmlDoctype(HtmlDoctypeType.Html5), document.Doctype); 33 | } 34 | 35 | public static IEnumerable Doctype_TestData() 36 | { 37 | yield return new object[] { new HtmlDoctype(HtmlDoctypeType.Html5) }; 38 | yield return new object[] { new HtmlDoctype("doctype") }; 39 | yield return new object[] { null }; 40 | } 41 | 42 | [Theory] 43 | [MemberData(nameof(Doctype_TestData))] 44 | public void Doctype_Set_Get_ReturnsExpected(HtmlDoctype value) 45 | { 46 | HtmlDocument document = new HtmlDocument(); 47 | document.Doctype = value; 48 | Assert.Equal(value, document.Doctype); 49 | } 50 | 51 | [Fact] 52 | public void Head_SetExisting_NonNull_RemovesElement() 53 | { 54 | HtmlElement value = Tag.Head.WithClass("class"); 55 | HtmlDocument document = new HtmlDocument() { Head = Tag.Head }; 56 | document.Head = value; 57 | Assert.Equal(new HtmlElement[] { value }, document.Elements()); 58 | Assert.Equal(value, document.Head); 59 | } 60 | 61 | [Fact] 62 | public void Head_SetExisting_Null_RemovesElement() 63 | { 64 | HtmlDocument document = new HtmlDocument() { Head = Tag.Head }; 65 | document.Head = null; 66 | Assert.True(document.IsEmpty); 67 | Assert.Null(document.Head); 68 | } 69 | 70 | [Fact] 71 | public void Head_SetNonExisting_Null_RemovesElement() 72 | { 73 | HtmlDocument document = new HtmlDocument() { Head = null }; 74 | document.Head = null; 75 | Assert.True(document.IsEmpty); 76 | Assert.Null(document.Head); 77 | } 78 | 79 | [Fact] 80 | public void AddHead_DocumentHasBody_ThrowsInvalidOperationException() 81 | { 82 | HtmlDocument document = new HtmlDocument() { Head = Tag.Head }; 83 | Assert.Throws(() => document.AddHead()); 84 | } 85 | 86 | [Fact] 87 | public void Body_SetExisting_NonNull_RemovesElement() 88 | { 89 | HtmlElement value = Tag.Body.WithClass("class"); 90 | HtmlDocument document = new HtmlDocument() { Body = Tag.Body }; 91 | document.Body = value; 92 | Assert.Equal(new HtmlElement[] { value }, document.Elements()); 93 | Assert.Equal(value, document.Body); 94 | } 95 | 96 | [Fact] 97 | public void Body_SetExisting_Null_RemovesElement() 98 | { 99 | HtmlDocument document = new HtmlDocument() { Body = Tag.Body }; 100 | document.Body = null; 101 | Assert.True(document.IsEmpty); 102 | Assert.Null(document.Body); 103 | } 104 | 105 | [Fact] 106 | public void Body_SetNonExisting_Null_RemovesElement() 107 | { 108 | HtmlDocument document = new HtmlDocument() { Body = null }; 109 | document.Body = null; 110 | Assert.True(document.IsEmpty); 111 | Assert.Null(document.Body); 112 | } 113 | 114 | [Fact] 115 | public void AddBody_DocumentHasBody_ThrowsInvalidOperationException() 116 | { 117 | HtmlDocument document = new HtmlDocument() { Body = Tag.Body }; 118 | Assert.Throws(() => document.AddBody()); 119 | } 120 | 121 | public static IEnumerable Equals_TestData() 122 | { 123 | yield return new object[] { new HtmlDocument(), new HtmlDocument(), true }; 124 | yield return new object[] { new HtmlDocument(), new HtmlDocument().WithClass("class"), false }; 125 | 126 | yield return new object[] { new HtmlDocument() { Doctype = null }, new HtmlDocument() { Doctype = null }, true }; 127 | yield return new object[] { new HtmlDocument() { Doctype = null }, new HtmlDocument() { Doctype = new HtmlDoctype(HtmlDoctypeType.Html5) }, false }; 128 | yield return new object[] { new HtmlDocument() { Doctype = new HtmlDoctype(HtmlDoctypeType.Html5) }, new HtmlDocument() { Doctype = null }, false }; 129 | yield return new object[] { new HtmlDocument() { Doctype = new HtmlDoctype(HtmlDoctypeType.Html5) }, new HtmlDocument() { Doctype = new HtmlDoctype(HtmlDoctypeType.Html401Frameset) }, false }; 130 | } 131 | 132 | [Theory] 133 | [MemberData(nameof(Equals_TestData))] 134 | public void Equals_Invoke_ReturnsExpected(HtmlDocument document, object other, bool expected) 135 | { 136 | if (other is HtmlDocument || other == null) 137 | { 138 | if (expected) 139 | { 140 | Assert.Equal(expected, document.GetHashCode().Equals(other?.GetHashCode())); 141 | } 142 | Assert.Equal(expected, document.Equals((HtmlDocument)other)); 143 | } 144 | Assert.Equal(expected, document.Equals(other)); 145 | } 146 | 147 | [Theory] 148 | [MemberData(nameof(Doctype_TestData))] 149 | public void Serialize_NullDoctype_NotIncluded(HtmlDoctype doctype) 150 | { 151 | HtmlDocument document = new HtmlDocument(); 152 | document.Doctype = doctype; 153 | 154 | string expectedDocType = doctype == null ? string.Empty : doctype + Environment.NewLine; 155 | Helpers.SerializeIgnoringFormatting(document, string.Format(@"{0}", expectedDocType)); 156 | } 157 | 158 | [Fact] 159 | public void Serialize_EmptyHtmlDocument() 160 | { 161 | HtmlDocument document = new HtmlDocument(); 162 | Helpers.SerializeIgnoringFormatting(document, @" 163 | "); 164 | } 165 | 166 | [Fact] 167 | public void Serialize_Complex() 168 | { 169 | HtmlDocument document = new HtmlDocument().AddHead().AddBody(); 170 | document.Head.Add(Tag.Title.WithInnerText("Title")); 171 | document.Body.Add(Tag.Header1("Header1").WithClass("aClass")); 172 | document.Body.Add(Tag.Br); 173 | document.Body.Add(Tag.Paragraph("Paragraph").WithAttribute(Attribute.AllowFullScreen)); 174 | 175 | Helpers.SerializeIgnoringFormatting(document, @" 176 | 177 | 178 | Title 179 | 180 | 181 |

Header1

182 |
183 |

Paragraph

184 | 185 | "); 186 | } 187 | } 188 | } 189 | -------------------------------------------------------------------------------- /tests/HtmlElement.RemoveTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using Xunit; 4 | 5 | namespace HtmlGenerator.Tests 6 | { 7 | public partial class HtmlElementTests 8 | { 9 | [Fact] 10 | public void RemoveAll_NonVoidElement() 11 | { 12 | HtmlElement parent = new HtmlElement("parent", new HtmlElement("element"), new HtmlComment("comment"), new HtmlAttribute("attribute1"), new HtmlAttribute("attribute2")); 13 | 14 | parent.RemoveAll(); 15 | Assert.Empty(parent.Nodes()); 16 | Assert.Empty(parent.Attributes()); 17 | 18 | // Make sure we can remove from an empty element 19 | parent.RemoveAll(); 20 | Assert.Empty(parent.Nodes()); 21 | Assert.Empty(parent.Attributes()); 22 | } 23 | 24 | [Fact] 25 | public void RemoveAll_VoidElement() 26 | { 27 | HtmlElement parent = new HtmlElement("parent", new HtmlAttribute("attribute")); 28 | 29 | parent.RemoveAll(); 30 | Assert.Empty(parent.Nodes()); 31 | Assert.Empty(parent.Attributes()); 32 | } 33 | 34 | [Fact] 35 | public void RemoveAttributes() 36 | { 37 | HtmlElement parent = new HtmlElement("parent", new HtmlElement("element"), new HtmlComment("comment"), new HtmlAttribute("attribute1"), new HtmlAttribute("attribute2")); 38 | 39 | parent.RemoveAttributes(); 40 | Assert.Equal(2, parent.Nodes().Count()); 41 | Assert.Empty(parent.Attributes()); 42 | 43 | // Make sure we can remove from an empty element 44 | parent.RemoveAttributes(); 45 | Assert.Equal(2, parent.Nodes().Count()); 46 | Assert.Empty(parent.Attributes()); 47 | } 48 | 49 | [Fact] 50 | public void RemoveAttributes_VoidElement_ThrowsInvalidOperationException() 51 | { 52 | HtmlElement parent = new HtmlElement("parent", isVoid: true); 53 | Assert.Throws(() => parent.RemoveAttributes()); 54 | } 55 | 56 | [Fact] 57 | public void RemoveNodes() 58 | { 59 | HtmlElement parent = new HtmlElement("parent", new HtmlElement("element"), new HtmlComment("comment"), new HtmlAttribute("attribute1"), new HtmlAttribute("attribute2")); 60 | 61 | parent.RemoveNodes(); 62 | Assert.Empty(parent.Nodes()); 63 | Assert.Equal(2, parent.Attributes().Count()); 64 | 65 | // Make sure we can remove from an empty element 66 | parent.RemoveNodes(); 67 | Assert.Empty(parent.Nodes()); 68 | Assert.Equal(2, parent.Attributes().Count()); 69 | } 70 | 71 | [Fact] 72 | public void RemoveNodes_VoidElement_ThrowsInvalidOperationException() 73 | { 74 | HtmlElement parent = new HtmlElement("parent", isVoid: true); 75 | 76 | Assert.Throws(() => parent.RemoveNodes()); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /tests/HtmlElement.ReplaceTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using Xunit; 5 | 6 | namespace HtmlGenerator.Tests 7 | { 8 | public partial class HtmlElementTests 9 | { 10 | [Theory] 11 | [MemberData(nameof(Objects_TestData))] 12 | public void ReplaceAll(HtmlObject[] content) 13 | { 14 | HtmlElement parent = new HtmlElement("parent", new HtmlElement("element"), new HtmlAttribute("attribute1"), new HtmlAttribute("attribute2"), new HtmlComment("comment")); 15 | 16 | parent.ReplaceAll(content); 17 | Assert.Equal(content.OfType().ToArray(), parent.Elements().ToArray()); 18 | Assert.Equal(content.OfType().ToArray(), parent.Attributes().ToArray()); 19 | Assert.Equal(parent.Elements().Count() + parent.Attributes().Count(), parent.ElementsAndAttributes().Count()); 20 | Assert.Equal(parent.Nodes().Count() + parent.Attributes().Count(), parent.NodesAndAttributes().Count()); 21 | } 22 | 23 | [Fact] 24 | public void ReplaceAll_ParamsHtmlObject_AttributeToVoidElement() 25 | { 26 | HtmlElement parent = new HtmlElement("parent", isVoid: true); 27 | parent.Add(new HtmlAttribute("attribute")); 28 | 29 | HtmlAttribute[] attributes = new HtmlAttribute[] { new HtmlAttribute("attribute1"), new HtmlAttribute("attribute2") }; 30 | parent.ReplaceAll(attributes); 31 | Assert.Equal(attributes, parent.Attributes()); 32 | } 33 | 34 | [Fact] 35 | public void ReplaceAll_IEnumerableHtmlObject_AttributeToVoidElement() 36 | { 37 | HtmlElement parent = new HtmlElement("parent", isVoid: true); 38 | parent.Add(new HtmlAttribute("attribute")); 39 | 40 | HtmlAttribute[] attributes = new HtmlAttribute[] { new HtmlAttribute("attribute1"), new HtmlAttribute("attribute2") }; 41 | parent.ReplaceAll((IEnumerable)attributes); 42 | Assert.Equal(attributes, parent.Attributes()); 43 | } 44 | 45 | [Fact] 46 | public void ReplaceAll_NullContent_ThrowsArgumentNullException() 47 | { 48 | HtmlElement parent = new HtmlElement("parent"); 49 | 50 | Assert.Throws("content", () => parent.ReplaceAll(null)); 51 | Assert.Throws("content", () => parent.ReplaceAll((IEnumerable)null)); 52 | } 53 | 54 | [Fact] 55 | public void ReplaceAll_SameElementInContent_ThrowsInvalidOperationException() 56 | { 57 | HtmlElement parent = new HtmlElement("parent"); 58 | 59 | Assert.Throws(() => parent.ReplaceAll(new HtmlObject[] { parent })); 60 | Assert.Throws(() => parent.ReplaceAll((IEnumerable)new HtmlObject[] { parent })); 61 | } 62 | 63 | [Fact] 64 | public void ReplaceAll_ContentNotNodeOrAttribute_ThrowsArgumentException() 65 | { 66 | HtmlElement parent = new HtmlElement("parent"); 67 | 68 | Assert.Throws("content", () => parent.ReplaceAll(new HtmlObject[] { new CustomHtmlObject() })); 69 | Assert.Throws("content", () => parent.ReplaceAll((IEnumerable)new HtmlObject[] { new CustomHtmlObject() })); 70 | } 71 | 72 | [Fact] 73 | public void ReplaceAll_DuplicateElementInContents_ThrowsInvalidOperationException() 74 | { 75 | HtmlElement parent = new HtmlElement("parent"); 76 | HtmlElement element = new HtmlElement("element"); 77 | parent.Add(element); 78 | 79 | Assert.Throws(() => parent.ReplaceAll(new HtmlObject[] { element })); 80 | Assert.Throws(() => parent.ReplaceAll((IEnumerable)new HtmlObject[] { element })); 81 | } 82 | 83 | [Fact] 84 | public void ReplaceAll_DuplicateAttributeInContents_ThrowsInvalidOperationException() 85 | { 86 | HtmlElement parent = new HtmlElement("parent"); 87 | HtmlAttribute attribute = new HtmlAttribute("attribute"); 88 | parent.Add(attribute); 89 | 90 | Assert.Throws(() => parent.ReplaceAll(new HtmlObject[] { attribute })); 91 | Assert.Throws(() => parent.ReplaceAll((IEnumerable)new HtmlObject[] { attribute })); 92 | } 93 | 94 | [Fact] 95 | public void ReplaceAll_ElementToVoidElement_ThrowsInvalidOperationException() 96 | { 97 | HtmlElement parent = new HtmlElement("parent", isVoid: true); 98 | HtmlElement element = new HtmlElement("element"); 99 | 100 | Assert.Throws(() => parent.ReplaceAll(new HtmlObject[] { element })); 101 | Assert.Throws(() => parent.ReplaceAll((IEnumerable)new HtmlObject[] { element })); 102 | } 103 | 104 | [Theory] 105 | [MemberData(nameof(Attributes_TestData))] 106 | public void ReplaceAttributes_ParamsHtmlAttribute(HtmlAttribute[] attributes) 107 | { 108 | HtmlElement parent = new HtmlElement("parent", new HtmlElement("element"), new HtmlAttribute("attribute1"), new HtmlAttribute("attribute2")); 109 | parent.ReplaceAttributes(attributes); 110 | Assert.Single(parent.Elements()); 111 | Assert.Equal(attributes, parent.Attributes().ToArray()); 112 | Assert.Equal(1 + attributes.Length, parent.ElementsAndAttributes().Count()); 113 | } 114 | 115 | [Fact] 116 | public void ReplaceAttributes_ParamsHtmlAttribute_VoidElement() 117 | { 118 | HtmlElement parent = new HtmlElement("parent", isVoid: true); 119 | parent.Add(new HtmlAttribute("attribute")); 120 | 121 | HtmlAttribute[] attributes = new HtmlAttribute[] { new HtmlAttribute("attribute1"), new HtmlAttribute("attribute2") }; 122 | parent.ReplaceAttributes(attributes); 123 | Assert.Equal(attributes, parent.Attributes()); 124 | } 125 | 126 | [Theory] 127 | [MemberData(nameof(Attributes_TestData))] 128 | public void ReplaceAttributes_IEnumerableHtmlAttribute(HtmlAttribute[] attributes) 129 | { 130 | HtmlElement element = new HtmlElement("parent", new HtmlElement("h1"), new HtmlAttribute("attribute1"), new HtmlAttribute("attribute2")); 131 | element.ReplaceAttributes((IEnumerable)attributes); 132 | Assert.Single(element.Elements()); 133 | Assert.Equal(attributes, element.Attributes().ToArray()); 134 | Assert.Equal(1 + attributes.Length, element.ElementsAndAttributes().Count()); 135 | } 136 | 137 | [Fact] 138 | public void ReplaceAttributes_IEnumerableHtmlAttribute_VoidElement() 139 | { 140 | HtmlElement parent = new HtmlElement("br", isVoid: true); 141 | parent.Add(new HtmlAttribute("attribute1")); 142 | 143 | HtmlAttribute[] attributes = new HtmlAttribute[] { new HtmlAttribute("attribute2"), new HtmlAttribute("c") }; 144 | parent.ReplaceAttributes((IEnumerable)attributes); 145 | Assert.Equal(attributes, parent.Attributes()); 146 | } 147 | 148 | [Fact] 149 | public void ReplaceAttributes_NullAttributes_ThrowsArgumentNullException() 150 | { 151 | HtmlElement parent = new HtmlElement("parent"); 152 | 153 | Assert.Throws("attributes", () => parent.ReplaceAttributes(null)); 154 | Assert.Throws("attributes", () => parent.ReplaceAttributes((IEnumerable)null)); 155 | } 156 | 157 | [Fact] 158 | public void ReplaceAttributes_NullAttributeInAttributes_ThrowsArgumentNullException() 159 | { 160 | HtmlElement parent = new HtmlElement("parent"); 161 | 162 | Assert.Throws("content", () => parent.ReplaceAttributes(new HtmlAttribute[] { null })); 163 | Assert.Throws("content", () => parent.ReplaceAttributes((IEnumerable)new HtmlAttribute[] { null })); 164 | } 165 | 166 | [Fact] 167 | public void ReplaceAttributes_DuplicateAttributeInAttribues_ThrowsInvalidOperationException() 168 | { 169 | HtmlElement parent = new HtmlElement("parent"); 170 | HtmlAttribute attribute = new HtmlAttribute("attribute"); 171 | parent.Add(attribute); 172 | 173 | Assert.Throws(() => parent.ReplaceAttributes(new HtmlAttribute[] { attribute })); 174 | Assert.Throws(() => parent.ReplaceAttributes((IEnumerable)new HtmlAttribute[] { attribute })); 175 | } 176 | 177 | public static IEnumerable Elements_TestData() 178 | { 179 | yield return new object[] { new HtmlElement[0] }; 180 | yield return new object[] { new HtmlElement[] { new HtmlElement("element1") } }; 181 | yield return new object[] { new HtmlElement[] { new HtmlElement("element1"), new HtmlElement("element2") } }; 182 | yield return new object[] { new HtmlElement[] { new HtmlElement("element1"), new HtmlElement("element2"), new HtmlElement("element1") } }; 183 | } 184 | 185 | [Theory] 186 | [MemberData(nameof(Elements_TestData))] 187 | public void ReplaceNodesParamsHtmlElement(HtmlElement[] elements) 188 | { 189 | HtmlElement parent = new HtmlElement("parent", new HtmlElement("element"), new HtmlAttribute("attribute1"), new HtmlAttribute("attribute2")); 190 | 191 | parent.ReplaceNodes(elements); 192 | Assert.Equal(elements, parent.Elements().ToArray()); 193 | Assert.Equal(2, parent.Attributes().Count()); 194 | Assert.Equal(elements.Length + 2, parent.ElementsAndAttributes().Count()); 195 | } 196 | 197 | [Theory] 198 | [MemberData(nameof(Elements_TestData))] 199 | public void ReplaceNodesIEnumerableHtmlElement(HtmlElement[] elements) 200 | { 201 | HtmlElement parent = new HtmlElement("parent", new HtmlElement("element"), new HtmlAttribute("attribute1"), new HtmlAttribute("attribute2")); 202 | 203 | parent.ReplaceNodes(elements); 204 | Assert.Equal(elements, parent.Elements().ToArray()); 205 | Assert.Equal(2, parent.Attributes().Count()); 206 | Assert.Equal(elements.Length + 2, parent.ElementsAndAttributes().Count()); 207 | } 208 | 209 | [Fact] 210 | public void ReplaceNodesNullElements_ThrowsArgumentNullException() 211 | { 212 | HtmlElement parent = new HtmlElement("parent"); 213 | 214 | Assert.Throws("nodes", () => parent.ReplaceNodes(null)); 215 | Assert.Throws("nodes", () => parent.ReplaceNodes((IEnumerable)null)); 216 | } 217 | 218 | [Fact] 219 | public void ReplaceNodes_NullElementInNodes_ThrowsArgumentNullException() 220 | { 221 | HtmlElement parent = new HtmlElement("parent"); 222 | 223 | Assert.Throws("content", () => parent.ReplaceNodes(new HtmlNode[] { null })); 224 | Assert.Throws("content", () => parent.ReplaceNodes((IEnumerable)new HtmlNode[] { null })); 225 | } 226 | 227 | [Fact] 228 | public void ReplaceNodes_SameNodeInNodes_ThrowsInvalidOperationException() 229 | { 230 | HtmlElement parent = new HtmlElement("element"); 231 | 232 | Assert.Throws(() => parent.ReplaceNodes(new HtmlNode[] { parent })); 233 | Assert.Throws(() => parent.ReplaceNodes((IEnumerable)new HtmlNode[] { parent })); 234 | } 235 | 236 | [Fact] 237 | public void ReplaceNodes_DuplicateElementInNodes_ThrowsInvalidOperationException() 238 | { 239 | HtmlElement parent = new HtmlElement("parent"); 240 | HtmlElement element = new HtmlElement("element"); 241 | parent.Add(element); 242 | 243 | Assert.Throws(() => parent.ReplaceNodes(new HtmlNode[] { element })); 244 | Assert.Throws(() => parent.ReplaceNodes((IEnumerable)new HtmlNode[] { element })); 245 | } 246 | 247 | [Fact] 248 | public void ReplaceNodes_NodeToVoidElement_ThrowsInvalidOperationException() 249 | { 250 | HtmlElement parent = new HtmlElement("parent", isVoid: true); 251 | HtmlElement element = new HtmlElement("element"); 252 | 253 | Assert.Throws(() => parent.ReplaceNodes(new HtmlNode[] { element })); 254 | Assert.Throws(() => parent.ReplaceNodes((IEnumerable)new HtmlNode[] { element })); 255 | } 256 | } 257 | } 258 | -------------------------------------------------------------------------------- /tests/HtmlElement.SerializeTests.cs: -------------------------------------------------------------------------------- 1 | using Xunit; 2 | 3 | namespace HtmlGenerator.Tests 4 | { 5 | public class HtmlElementSerializeTests 6 | { 7 | [Fact] 8 | public void VoidElement_OneVoidAttribute() 9 | { 10 | HtmlElement element = new HtmlElement("element", isVoid: true); 11 | element.Add(new HtmlAttribute("void")); 12 | Helpers.SerializeIgnoringFormatting(element, ""); 13 | } 14 | 15 | [Fact] 16 | public void VoidElement_OneNonVoidAttribute() 17 | { 18 | HtmlElement element = new HtmlElement("element", isVoid: true); 19 | element.Add(new HtmlAttribute("name", "value")); 20 | Helpers.SerializeIgnoringFormatting(element, ""); 21 | } 22 | 23 | [Fact] 24 | public void VoidElement_MultipleAttributes() 25 | { 26 | HtmlElement element = new HtmlElement("element", isVoid: true); 27 | element.Add(new HtmlAttribute("void"), new HtmlAttribute("name", "value")); 28 | Helpers.SerializeIgnoringFormatting(element, ""); 29 | } 30 | 31 | [Fact] 32 | public void VoidElement_NoAttributes() 33 | { 34 | HtmlElement voidElement = new HtmlElement("element", isVoid: true); 35 | Helpers.SerializeIgnoringFormatting(voidElement, ""); 36 | } 37 | 38 | [Fact] 39 | public void NonVoidElement_NoAttributes_NoInnerText_NoChildren() 40 | { 41 | HtmlElement element = new HtmlElement("element"); 42 | Helpers.SerializeIgnoringFormatting(element, ""); 43 | } 44 | 45 | [Fact] 46 | public void NonVoidElement_OneVoidAttribute_NoInnerText_NoChildren() 47 | { 48 | HtmlElement element = new HtmlElement("element", new HtmlAttribute("void")); 49 | Helpers.SerializeIgnoringFormatting(element, ""); 50 | } 51 | 52 | [Fact] 53 | public void NonVoidElement_OneNonVoidAttribute_NoInnerText_NoChildren() 54 | { 55 | HtmlElement element = new HtmlElement("element", new HtmlAttribute("name", "value")); 56 | Helpers.SerializeIgnoringFormatting(element, ""); 57 | } 58 | 59 | [Fact] 60 | public void NonVoidElement_MultipleAttributes_NoInnerText_NoChildren() 61 | { 62 | HtmlElement element = new HtmlElement("element", new HtmlAttribute("void"), new HtmlAttribute("name", "value")); 63 | Helpers.SerializeIgnoringFormatting(element, ""); 64 | } 65 | 66 | [Fact] 67 | public void NonVoidElement_NoAttributes_InnerText_NoChildren() 68 | { 69 | HtmlElement element = new HtmlElement("element").WithInnerText("InnerText"); 70 | Helpers.SerializeIgnoringFormatting(element, "InnerText"); 71 | } 72 | 73 | [Fact] 74 | public void NonVoidElement_MultipleAttributes_InnerText_NoChildren() 75 | { 76 | HtmlElement element = new HtmlElement("element", new HtmlAttribute("void"), new HtmlAttribute("name", "value")).WithInnerText("InnerText"); 77 | Helpers.SerializeIgnoringFormatting(element, "InnerText"); 78 | } 79 | 80 | [Fact] 81 | public void NonVoidElement_NoAttributes_NoInnerText_OneVoidChild() 82 | { 83 | HtmlElement element = new HtmlElement("parent", new HtmlObject[] 84 | { 85 | new HtmlElement("element", isVoid: true) 86 | }); 87 | Helpers.SerializeIgnoringFormatting(element, @" 88 | 89 | "); 90 | } 91 | 92 | [Fact] 93 | public void NonVoidElement_NoAttributes_NoInnerText_OneNonVoidChild() 94 | { 95 | HtmlElement element = new HtmlElement("parent", new HtmlObject[] 96 | { 97 | new HtmlElement("element") 98 | }); 99 | Helpers.SerializeIgnoringFormatting(element, @" 100 | 101 | "); 102 | } 103 | 104 | [Fact] 105 | public void NonVoidElement_NoAttributes_NoInnerText_MultipleChild() 106 | { 107 | HtmlElement element = new HtmlElement("parent", new HtmlObject[] 108 | { 109 | new HtmlElement("element1", isVoid: true), 110 | new HtmlElement("element2") 111 | }); 112 | Helpers.SerializeIgnoringFormatting(element, @" 113 | 114 | 115 | "); 116 | } 117 | 118 | [Fact] 119 | public void NonVoidElement_NoAttributes_InnerTextFirst_OneVoidChild() 120 | { 121 | HtmlElement element = new HtmlElement("parent", new HtmlObject[] 122 | { 123 | new HtmlText("text"), 124 | new HtmlElement("element", isVoid: true) 125 | }); 126 | Helpers.SerializeIgnoringFormatting(element, @"text"); 127 | } 128 | 129 | [Fact] 130 | public void NonVoidElement_NoAttributes_InnerTextFirst_OneNonVoidChild() 131 | { 132 | HtmlElement element = new HtmlElement("parent", new HtmlObject[] 133 | { 134 | new HtmlText("text"), 135 | new HtmlElement("element") 136 | }); 137 | Helpers.SerializeIgnoringFormatting(element, @"text"); 138 | } 139 | 140 | [Fact] 141 | public void NonVoidElement_NoAttributes_InnerTextFirst_MultipleChildrenNextVoid() 142 | { 143 | HtmlElement element = new HtmlElement("parent", new HtmlObject[] 144 | { 145 | new HtmlText("text"), 146 | new HtmlElement("element1", isVoid: true), 147 | new HtmlElement("element2") 148 | }); 149 | Helpers.SerializeIgnoringFormatting(element, @"text"); 150 | } 151 | 152 | [Fact] 153 | public void NonVoidElement_NoAttributes_InnerTextFirst_MultipleChildrenNextNonVoid() 154 | { 155 | HtmlElement element = new HtmlElement("parent", new HtmlObject[] 156 | { 157 | new HtmlText("text"), 158 | new HtmlElement("element1"), 159 | new HtmlElement("element2", isVoid: true) 160 | }); 161 | Helpers.SerializeIgnoringFormatting(element, @"text"); 162 | } 163 | 164 | [Fact] 165 | public void NonVoidElement_NoAttributes_InnerTextMiddle_MultipleChildrenFirstVoid() 166 | { 167 | HtmlElement element = new HtmlElement("parent", new HtmlObject[] 168 | { 169 | new HtmlElement("element1", isVoid: true), 170 | new HtmlText("text"), 171 | new HtmlElement("element2") 172 | }); 173 | Helpers.SerializeIgnoringFormatting(element, @"text"); 174 | } 175 | 176 | [Fact] 177 | public void NonVoidElement_NoAttributes_InnerTextMiddle_MultipleChildrenFirstNonVoid() 178 | { 179 | HtmlElement element = new HtmlElement("parent", new HtmlObject[] 180 | { 181 | new HtmlElement("element1"), 182 | new HtmlText("text"), 183 | new HtmlElement("element2",isVoid: true) 184 | }); 185 | Helpers.SerializeIgnoringFormatting(element, @"text"); 186 | } 187 | 188 | [Fact] 189 | public void NonVoidElement_NoAttributes_InnerTextLast_OneNonVoidChild() 190 | { 191 | HtmlElement element = new HtmlElement("parent", new HtmlObject[] 192 | { 193 | new HtmlElement("element"), 194 | new HtmlText("text") 195 | }); 196 | Helpers.SerializeIgnoringFormatting(element, @"text"); 197 | } 198 | 199 | [Fact] 200 | public void NonVoidElement_NoAttributes_InnerTextLast_OneVoidChild() 201 | { 202 | HtmlElement element = new HtmlElement("parent", new HtmlObject[] 203 | { 204 | new HtmlElement("element", isVoid: true), 205 | new HtmlText("text") 206 | }); 207 | Helpers.SerializeIgnoringFormatting(element, @"text"); 208 | } 209 | 210 | [Fact] 211 | public void NonVoidElement_NoAttributes_InnerTextLast_MultipleChildrenPreviousVoid() 212 | { 213 | HtmlElement element = new HtmlElement("parent", new HtmlObject[] 214 | { 215 | new HtmlElement("element1"), 216 | new HtmlElement("element2", isVoid: true), 217 | new HtmlText("text") 218 | }); 219 | Helpers.SerializeIgnoringFormatting(element, @"text"); 220 | } 221 | 222 | [Fact] 223 | public void NonVoidElement_NoAttributes_InnerTextLast_MultipleChildrenPreviousNonVoid() 224 | { 225 | HtmlElement element = new HtmlElement("parent", new HtmlObject[] 226 | { 227 | new HtmlElement("element1", isVoid: true), 228 | new HtmlElement("element2"), 229 | new HtmlText("text") 230 | }); 231 | Helpers.SerializeIgnoringFormatting(element, @"text"); 232 | } 233 | 234 | [Fact] 235 | public void NonVoidElement_NoAttributes_NoInnerText_MultipleChildren() 236 | { 237 | HtmlElement element = new HtmlElement("parent", new HtmlObject[] 238 | { 239 | new HtmlElement("element1", isVoid: true), 240 | new HtmlElement("element2"), 241 | new HtmlElement("element3", new HtmlObject[] 242 | { 243 | new HtmlElement("element").WithInnerText("InnerText"), 244 | new HtmlElement("element4", new HtmlAttribute("name", "value")), 245 | }) 246 | }); 247 | Helpers.SerializeIgnoringFormatting(element, @" 248 | 249 | 250 | 251 | InnerText 252 | 253 | 254 | "); 255 | } 256 | 257 | [Fact] 258 | public void NonVoidElement_Attributes_InnerText_MultipleChildren() 259 | { 260 | HtmlElement element = new HtmlElement("parent", new HtmlObject[] 261 | { 262 | new HtmlText("Inner"), 263 | new HtmlAttribute("void"), 264 | new HtmlAttribute("name", "value"), 265 | new HtmlElement("element1", isVoid: true), 266 | new HtmlElement("element2"), 267 | new HtmlElement("element3", new HtmlElement[] 268 | { 269 | new HtmlElement("element").WithInnerText("InnerText"), 270 | new HtmlElement("element4", new HtmlAttribute("name", "value")), 271 | }) 272 | }); 273 | Helpers.SerializeIgnoringFormatting(element, @"Inner 274 | 275 | InnerText 276 | 277 | 278 | "); 279 | } 280 | } 281 | } 282 | -------------------------------------------------------------------------------- /tests/HtmlElementTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using Xunit; 5 | 6 | namespace HtmlGenerator.Tests 7 | { 8 | public partial class HtmlElementTests 9 | { 10 | [Theory] 11 | [InlineData("html", "html")] 12 | [InlineData("HtMl", "html")] 13 | [InlineData("no-such-tag", "no-such-tag")] 14 | public void Ctor_String(string tag, string expectedTag) 15 | { 16 | HtmlElement element = new HtmlElement(tag); 17 | Assert.Equal(expectedTag, element.Tag); 18 | Assert.False(element.IsVoid); 19 | Assert.Empty(element.Elements()); 20 | Assert.Empty(element.Attributes()); 21 | Assert.Empty(element.ElementsAndAttributes()); 22 | } 23 | 24 | [Theory] 25 | [InlineData("html", true, "html")] 26 | [InlineData("HtMl", false, "html")] 27 | [InlineData("no-such-tag", false, "no-such-tag")] 28 | public void Ctor_String_Bool(string tag, bool isVoid, string expectedTag) 29 | { 30 | HtmlElement element = new HtmlElement(tag, isVoid); 31 | Assert.Equal(expectedTag, element.Tag); 32 | Assert.Equal(isVoid, element.IsVoid); 33 | Assert.Empty(element.Elements()); 34 | Assert.Empty(element.Attributes()); 35 | Assert.Empty(element.ElementsAndAttributes()); 36 | } 37 | 38 | public static IEnumerable Objects_TestData() 39 | { 40 | yield return new object[] { new HtmlObject[0] }; 41 | yield return new object[] { new HtmlObject[] { new HtmlAttribute("attribute1") } }; 42 | yield return new object[] { new HtmlObject[] { new HtmlElement("h1") } }; 43 | yield return new object[] { new HtmlObject[] { new HtmlComment("comment") } }; 44 | yield return new object[] { new HtmlObject[] { new HtmlAttribute("attribute1"), new HtmlElement("h1") } }; 45 | yield return new object[] { new HtmlObject[] { new HtmlAttribute("attribute1"), new HtmlComment("comment") } }; 46 | yield return new object[] { new HtmlObject[] { new HtmlComment("comment"), new HtmlElement("h1") } }; 47 | yield return new object[] { new HtmlObject[] { new HtmlComment("attribute1"), new HtmlAttribute("attribute"), new HtmlElement("element") } }; 48 | yield return new object[] { new HtmlObject[] { new HtmlAttribute("attribute1"), new HtmlElement("h1"), new HtmlElement("h1"), new HtmlAttribute("attribute2") } }; 49 | } 50 | 51 | [Theory] 52 | [MemberData(nameof(Objects_TestData))] 53 | public void Ctor_String_ParamsHtmlObject(HtmlObject[] content) 54 | { 55 | HtmlElement element = new HtmlElement("element", content); 56 | Assert.Equal("element", element.Tag); 57 | Assert.False(element.IsVoid); 58 | Assert.Equal(content.OfType().ToArray(), element.Elements().ToArray()); 59 | Assert.Equal(content.OfType().ToArray(), element.Attributes().ToArray()); 60 | Assert.Equal(content.OfType().ToArray(), element.Nodes().ToArray()); 61 | Assert.Equal(element.Elements().Count() + element.Attributes().Count(), element.ElementsAndAttributes().Count()); 62 | Assert.Equal(content.Length, element.NodesAndAttributes().Count()); 63 | } 64 | 65 | [Fact] 66 | public void Ctor_NullTag_ThrowsArgumentNullException() 67 | { 68 | Assert.Throws("tag", () => new HtmlElement(null)); 69 | Assert.Throws("tag", () => new HtmlElement(null, isVoid: false)); 70 | Assert.Throws("tag", () => new HtmlElement(null, new HtmlObject[0])); 71 | } 72 | 73 | [Theory] 74 | [InlineData("")] 75 | [InlineData(" \r \n \t")] 76 | public void Ctor_EmptyOrWhitespaceTag_ThrowsArgumentException(string tag) 77 | { 78 | Assert.Throws("tag", () => new HtmlElement(tag)); 79 | Assert.Throws("tag", () => new HtmlElement(tag, isVoid: false)); 80 | Assert.Throws("tag", () => new HtmlElement(tag, new HtmlObject[0])); 81 | } 82 | 83 | [Fact] 84 | public void ObjectType_Get_ReturnsElement() 85 | { 86 | HtmlElement element = new HtmlElement("element"); 87 | Assert.Equal(HtmlObjectType.Element, element.ObjectType); 88 | } 89 | 90 | public static IEnumerable Equals_TestData() 91 | { 92 | // Tag 93 | yield return new object[] { new HtmlElement("element"), new HtmlElement("element"), true }; 94 | yield return new object[] { new HtmlElement("element"), new HtmlElement("other-element"), false }; 95 | 96 | // Void 97 | yield return new object[] { new HtmlElement("element", isVoid: true), new HtmlElement("element", isVoid: true), true }; 98 | yield return new object[] { new HtmlElement("element", isVoid: true), new HtmlElement("element", isVoid: false), false }; 99 | 100 | // InnerText 101 | yield return new object[] { new HtmlElement("element").WithInnerText("Inner Text"), new HtmlElement("element").WithInnerText("Inner Text"), true }; 102 | yield return new object[] { new HtmlElement("element").WithInnerText("Inner Text"), new HtmlElement("element").WithInnerText("inner text"), false }; 103 | yield return new object[] { new HtmlElement("element").WithInnerText("Inner Text"), new HtmlElement("element").WithInnerText("other-inner-text"), false }; 104 | 105 | // Elements 106 | yield return new object[] 107 | { 108 | new HtmlElement("element1", new HtmlElement("element2"), new HtmlAttribute("attribute")), 109 | new HtmlElement("element1", new HtmlElement("element2"), new HtmlAttribute("attribute")), 110 | true 111 | }; 112 | yield return new object[] 113 | { 114 | new HtmlElement("element", new HtmlElement("element2"), new HtmlAttribute("attribute")), 115 | new HtmlElement("element", new HtmlElement("other-element"), new HtmlAttribute("attribute")), 116 | false 117 | }; 118 | yield return new object[] 119 | { 120 | new HtmlElement("element", new HtmlElement("element2"), new HtmlAttribute("attribute")), 121 | new HtmlElement("element", new HtmlAttribute("attribute")), 122 | false 123 | }; 124 | 125 | // Attributes 126 | yield return new object[] 127 | { 128 | new HtmlElement("element1", new HtmlElement("element2"), new HtmlAttribute("attribute")), 129 | new HtmlElement("element1", new HtmlElement("element2"), new HtmlAttribute("other-attribute")), 130 | false 131 | }; 132 | yield return new object[] 133 | { 134 | new HtmlElement("element1", new HtmlElement("element2"), new HtmlAttribute("attribute")), 135 | new HtmlElement("element1", new HtmlElement("element2")), 136 | false 137 | }; 138 | 139 | // Other 140 | yield return new object[] { new HtmlElement("element"), new object(), false }; 141 | yield return new object[] { new HtmlElement("element"), null, false }; 142 | } 143 | 144 | [Theory] 145 | [MemberData(nameof(Equals_TestData))] 146 | public void Equals_Invoke_ReturnsExpected(HtmlElement element, object other, bool expected) 147 | { 148 | Assert.Equal(element.GetHashCode(), element.GetHashCode()); 149 | if (other is HtmlElement || other == null) 150 | { 151 | Assert.Equal(expected, element.Equals((HtmlElement)other)); 152 | } 153 | Assert.Equal(expected, element.Equals(other)); 154 | } 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /tests/HtmlExceptionTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Xunit; 3 | 4 | namespace HtmlGenerator.Tests 5 | { 6 | public class HtmlExceptionTests 7 | { 8 | [Fact] 9 | public void Ctor_Default() 10 | { 11 | HtmlException exception = new HtmlException(); 12 | Assert.Equal("Exception of type 'HtmlGenerator.HtmlException' was thrown.", exception.Message); 13 | Assert.Null(exception.InnerException); 14 | } 15 | 16 | [Theory] 17 | [InlineData(null)] 18 | [InlineData("")] 19 | [InlineData(" \t \r \n")] 20 | [InlineData("mesage")] 21 | public void Ctor_String(string message) 22 | { 23 | HtmlException exception = new HtmlException(message); 24 | Assert.Equal(message ?? "Exception of type 'HtmlGenerator.HtmlException' was thrown.", exception.Message); 25 | Assert.Null(exception.InnerException); 26 | } 27 | 28 | [Theory] 29 | [InlineData(null)] 30 | [InlineData("")] 31 | [InlineData(" \t \r \n")] 32 | [InlineData("mesage")] 33 | public void Ctor_String_Exception(string message) 34 | { 35 | Exception innerException = new InvalidOperationException(); 36 | HtmlException exception = new HtmlException(message, innerException); 37 | Assert.Equal(message ?? "Exception of type 'HtmlGenerator.HtmlException' was thrown.", exception.Message); 38 | Assert.Same(innerException, exception.InnerException); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /tests/HtmlGenerator.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | false 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /tests/HtmlNodeTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Xunit; 4 | 5 | namespace HtmlGenerator.Tests 6 | { 7 | public class HtmlNodeTests 8 | { 9 | [Fact] 10 | public void AddAfterSelf_HtmlNode() 11 | { 12 | HtmlElement parent = new HtmlElement("parent"); 13 | HtmlElement child1 = new HtmlElement("child1"); 14 | parent.Add(child1); 15 | 16 | // Element 17 | HtmlElement child2 = new HtmlElement("child2"); 18 | child1.AddAfterSelf(child2); 19 | Assert.Equal(parent, child2.Parent); 20 | Assert.Equal(new HtmlElement[] { child1, child2 }, parent.Elements()); 21 | 22 | // Comment 23 | HtmlComment comment = new HtmlComment("comment"); 24 | child1.AddAfterSelf(comment); 25 | Assert.Equal(parent, comment.Parent); 26 | Assert.Equal(new HtmlObject[] { child1, comment, child2 }, parent.Nodes()); 27 | } 28 | 29 | [Fact] 30 | public void AddAfterSelf_ParamsHtmlObject() 31 | { 32 | HtmlElement parent = new HtmlElement("parent"); 33 | HtmlElement child1 = new HtmlElement("child1"); 34 | parent.Add(child1); 35 | 36 | // Element 37 | HtmlElement child2 = new HtmlElement("child2"); 38 | HtmlElement child3 = new HtmlElement("child3"); 39 | child1.AddAfterSelf(new HtmlElement[] { child2, child3 }); 40 | 41 | Assert.Equal(parent, child2.Parent); 42 | Assert.Equal(parent, child3.Parent); 43 | Assert.Equal(new HtmlElement[] { child1, child2, child3 }, parent.Elements()); 44 | } 45 | 46 | [Fact] 47 | public void AddAfterSelf_ParamsHtmlObject_Empty() 48 | { 49 | HtmlElement parent = new HtmlElement("html"); 50 | HtmlElement element = new HtmlElement("body"); 51 | element.AddAfterSelf(new HtmlElement[0]); 52 | Assert.Empty(parent.Elements()); 53 | Assert.Empty(parent.Attributes()); 54 | } 55 | 56 | [Fact] 57 | public void AddAfterSelf_IEnumerableHtmlObject() 58 | { 59 | HtmlElement parent = new HtmlElement("parent"); 60 | HtmlElement child1 = new HtmlElement("child1"); 61 | parent.Add(child1); 62 | 63 | HtmlElement child2 = new HtmlElement("child2"); 64 | HtmlElement child3 = new HtmlElement("child3"); 65 | child1.AddAfterSelf((IEnumerable)new HtmlElement[] { child2, child3 }); 66 | 67 | Assert.Equal(parent, child2.Parent); 68 | Assert.Equal(parent, child3.Parent); 69 | Assert.Equal(new HtmlElement[] { child1, child2, child3 }, parent.Elements()); 70 | } 71 | 72 | [Fact] 73 | public void AddAfterSelf_IEnumerableHtmlObject_Empty() 74 | { 75 | HtmlElement parent = new HtmlElement("html"); 76 | HtmlElement element = new HtmlElement("body"); 77 | element.AddAfterSelf((IEnumerable)new HtmlElement[0]); 78 | Assert.Empty(parent.Elements()); 79 | Assert.Empty(parent.Attributes()); 80 | } 81 | 82 | [Fact] 83 | public void AddAfterSelf_NullContent_ThrowsArgumentNullException() 84 | { 85 | HtmlElement element = new HtmlElement("element"); 86 | 87 | Assert.Throws("content", () => element.AddAfterSelf((HtmlElement)null)); 88 | Assert.Throws("content", () => element.AddAfterSelf((HtmlElement[])null)); 89 | Assert.Throws("content", () => element.AddAfterSelf((IEnumerable)null)); 90 | } 91 | 92 | [Fact] 93 | public void AddAfterSelf_NullObjectInContent_ThrowsArgumentNullException() 94 | { 95 | HtmlElement element = new HtmlElement("element"); 96 | 97 | Assert.Throws("content", () => element.AddAfterSelf(new HtmlElement[] { null })); 98 | Assert.Throws("content", () => element.AddAfterSelf((IEnumerable)new HtmlElement[] { null })); 99 | } 100 | 101 | [Fact] 102 | public void AddAfterSelf_SameElement_ThrowsInvalidOperationException() 103 | { 104 | HtmlElement element = new HtmlElement("html"); 105 | 106 | Assert.Throws(() => element.AddAfterSelf(element)); 107 | Assert.Throws(() => element.AddAfterSelf(new HtmlElement[] { element })); 108 | Assert.Throws(() => element.AddAfterSelf((IEnumerable)new HtmlElement[] { element })); 109 | } 110 | 111 | [Fact] 112 | public void AddAfterSelf_DuplicateElement_ThrowsInvalidOperationException() 113 | { 114 | HtmlElement parent = new HtmlElement("parent"); 115 | HtmlElement element = new HtmlElement("child"); 116 | parent.Add(element); 117 | 118 | Assert.Throws(() => parent.AddAfterSelf(element)); 119 | Assert.Throws(() => parent.AddAfterSelf(new HtmlElement[] { element })); 120 | Assert.Throws(() => parent.AddAfterSelf((IEnumerable)new HtmlElement[] { element })); 121 | } 122 | 123 | [Fact] 124 | public void AddAfterSelf_ElementToVoidElement_ThrowsInvalidOperationException() 125 | { 126 | HtmlElement element = new HtmlElement("br", isVoid: true); 127 | HtmlElement newElement = new HtmlElement("p"); 128 | 129 | Assert.Throws(() => element.AddAfterSelf(newElement)); 130 | Assert.Throws(() => element.AddAfterSelf(new HtmlElement[] { newElement })); 131 | Assert.Throws(() => element.AddAfterSelf((IEnumerable)new HtmlElement[] { newElement })); 132 | } 133 | 134 | [Fact] 135 | public void AddBeforeSelf_HtmlNode() 136 | { 137 | HtmlElement parent = new HtmlElement("parent"); 138 | HtmlElement child1 = new HtmlElement("child1"); 139 | parent.Add(child1); 140 | 141 | // Element 142 | HtmlElement child2 = new HtmlElement("child2"); 143 | child1.AddBeforeSelf(child2); 144 | Assert.Equal(parent, child2.Parent); 145 | Assert.Equal(new HtmlElement[] { child2, child1 }, parent.Elements()); 146 | 147 | // Comment 148 | HtmlComment comment = new HtmlComment("comment"); 149 | child1.AddBeforeSelf(comment); 150 | Assert.Equal(parent, comment.Parent); 151 | Assert.Equal(new HtmlObject[] { child2, comment, child1 }, parent.Nodes()); 152 | } 153 | 154 | [Fact] 155 | public void AddBeforeSelf_ParamsHtmlObject() 156 | { 157 | HtmlElement parent = new HtmlElement("parent"); 158 | HtmlElement child1 = new HtmlElement("child1"); 159 | parent.Add(child1); 160 | 161 | // Element 162 | HtmlElement child2 = new HtmlElement("child2"); 163 | HtmlElement child3 = new HtmlElement("child3"); 164 | child1.AddBeforeSelf(new HtmlElement[] { child2, child3 }); 165 | 166 | Assert.Equal(parent, child2.Parent); 167 | Assert.Equal(parent, child3.Parent); 168 | Assert.Equal(new HtmlElement[] { child3, child2, child1 }, parent.Elements()); 169 | } 170 | 171 | [Fact] 172 | public void AddBeforeSelf_ParamsHtmlObject_Empty() 173 | { 174 | HtmlElement parent = new HtmlElement("html"); 175 | HtmlElement element = new HtmlElement("body"); 176 | element.AddAfterSelf(new HtmlElement[0]); 177 | Assert.Empty(parent.Elements()); 178 | Assert.Empty(parent.Attributes()); 179 | } 180 | 181 | [Fact] 182 | public void AddBeforeSelf_IEnumerableHtmlObject() 183 | { 184 | HtmlElement parent = new HtmlElement("parent"); 185 | HtmlElement child1 = new HtmlElement("child1"); 186 | parent.Add(child1); 187 | 188 | HtmlElement child2 = new HtmlElement("child2"); 189 | HtmlElement child3 = new HtmlElement("child3"); 190 | child1.AddBeforeSelf((IEnumerable)new HtmlElement[] { child2, child3 }); 191 | 192 | Assert.Equal(parent, child2.Parent); 193 | Assert.Equal(parent, child3.Parent); 194 | Assert.Equal(new HtmlElement[] { child3, child2, child1 }, parent.Elements()); 195 | } 196 | 197 | [Fact] 198 | public void AddBeforeSelf_IEnumerableHtmlObject_Empty() 199 | { 200 | HtmlElement parent = new HtmlElement("html"); 201 | HtmlElement element = new HtmlElement("body"); 202 | element.AddAfterSelf((IEnumerable)new HtmlElement[0]); 203 | Assert.Empty(parent.Elements()); 204 | Assert.Empty(parent.Attributes()); 205 | } 206 | 207 | [Fact] 208 | public void AddBeforeSelf_NullContent_ThrowsArgumentNullException() 209 | { 210 | HtmlElement element = new HtmlElement("element"); 211 | 212 | Assert.Throws("content", () => element.AddBeforeSelf((HtmlElement)null)); 213 | Assert.Throws("content", () => element.AddBeforeSelf((HtmlElement[])null)); 214 | Assert.Throws("content", () => element.AddBeforeSelf((IEnumerable)null)); 215 | } 216 | 217 | [Fact] 218 | public void AddBeforeSelf_NullObjectInContent_ThrowsArgumentNullException() 219 | { 220 | HtmlElement element = new HtmlElement("element"); 221 | 222 | Assert.Throws("content", () => element.AddBeforeSelf(new HtmlElement[] { null })); 223 | Assert.Throws("content", () => element.AddBeforeSelf((IEnumerable)new HtmlElement[] { null })); 224 | } 225 | 226 | [Fact] 227 | public void AddBeforeSelf_SameElement_ThrowsInvalidOperationException() 228 | { 229 | HtmlElement element = new HtmlElement("html"); 230 | 231 | Assert.Throws(() => element.AddBeforeSelf(element)); 232 | Assert.Throws(() => element.AddBeforeSelf(new HtmlElement[] { element })); 233 | Assert.Throws(() => element.AddBeforeSelf((IEnumerable)new HtmlElement[] { element })); 234 | } 235 | 236 | [Fact] 237 | public void AddBeforeSelf_DuplicateElement_ThrowsInvalidOperationException() 238 | { 239 | HtmlElement parent = new HtmlElement("parent"); 240 | HtmlElement element = new HtmlElement("child"); 241 | parent.Add(element); 242 | 243 | Assert.Throws(() => parent.AddBeforeSelf(element)); 244 | Assert.Throws(() => parent.AddBeforeSelf(new HtmlElement[] { element })); 245 | Assert.Throws(() => parent.AddBeforeSelf((IEnumerable)new HtmlElement[] { element })); 246 | } 247 | 248 | [Fact] 249 | public void AddBeforeSelf_ElementToVoidElement_ThrowsInvalidOperationException() 250 | { 251 | HtmlElement element = new HtmlElement("br", isVoid: true); 252 | HtmlElement newElement = new HtmlElement("p"); 253 | 254 | Assert.Throws(() => element.AddBeforeSelf(newElement)); 255 | Assert.Throws(() => element.AddBeforeSelf(new HtmlElement[] { newElement })); 256 | Assert.Throws(() => element.AddBeforeSelf((IEnumerable)new HtmlElement[] { newElement })); 257 | } 258 | 259 | [Fact] 260 | public void NextNode_Get_ReturnsExpected() 261 | { 262 | HtmlElement element1 = new HtmlElement("element1"); 263 | HtmlComment comment = new HtmlComment("comment"); 264 | HtmlElement element2 = new HtmlElement("element2"); 265 | HtmlElement parent = new HtmlElement("parent", element1, comment, element2); 266 | 267 | Assert.Equal(comment, element1.NextNode); 268 | Assert.Equal(element2, comment.NextNode); 269 | Assert.Null(element2.NextNode); 270 | } 271 | 272 | [Fact] 273 | public void NextNode_IgnoresAttributes() 274 | { 275 | HtmlElement element1 = new HtmlElement("element1"); 276 | HtmlComment comment = new HtmlComment("comment"); 277 | HtmlElement element2 = new HtmlElement("element2"); 278 | HtmlElement parent = new HtmlElement("parent", element1, comment, new HtmlAttribute("attribute"), element2); 279 | 280 | Assert.Equal(element2, comment.NextNode); 281 | } 282 | 283 | [Fact] 284 | public void NextNode_NoParent_ReturnsNull() 285 | { 286 | HtmlElement element = new HtmlElement("element"); 287 | Assert.Null(element.NextNode); 288 | } 289 | 290 | [Fact] 291 | public void NextNodes_ReturnsExpected() 292 | { 293 | HtmlElement element1 = new HtmlElement("element1"); 294 | HtmlComment comment = new HtmlComment("comment"); 295 | HtmlElement element2 = new HtmlElement("element2"); 296 | HtmlElement parent = new HtmlElement("parent", element1, comment, element2); 297 | 298 | Assert.Equal(new HtmlNode[] { comment, element2 }, element1.NextNodes()); 299 | Assert.Equal(new HtmlNode[] { element2 }, comment.NextNodes()); 300 | Assert.Empty(element2.NextNodes()); 301 | } 302 | 303 | [Fact] 304 | public void NextNodes_IgnoresAttributes() 305 | { 306 | HtmlElement element1 = new HtmlElement("element1"); 307 | HtmlComment comment = new HtmlComment("comment"); 308 | HtmlElement element2 = new HtmlElement("element2"); 309 | HtmlElement parent = new HtmlElement("parent", element1, comment, new HtmlAttribute("attribute"), element2); 310 | 311 | Assert.Equal(new HtmlElement[] { element2 }, comment.NextNodes()); 312 | } 313 | 314 | [Fact] 315 | public void NextNodes_NoParent_ReturnsEmpty() 316 | { 317 | HtmlElement element = new HtmlElement("element"); 318 | Assert.Empty(element.NextNodes()); 319 | } 320 | 321 | [Fact] 322 | public void PreviousNode_Get_ReturnsExpected() 323 | { 324 | HtmlElement element1 = new HtmlElement("element1"); 325 | HtmlComment comment = new HtmlComment("comment"); 326 | HtmlElement element2 = new HtmlElement("element2"); 327 | HtmlElement parent = new HtmlElement("parent", element1, comment, element2); 328 | 329 | Assert.Null(element1.PreviousNode); 330 | Assert.Equal(element1, comment.PreviousNode); 331 | Assert.Equal(comment, element2.PreviousNode); 332 | } 333 | 334 | [Fact] 335 | public void PreviousNode_IgnoresAttributes() 336 | { 337 | HtmlElement element1 = new HtmlElement("element1"); 338 | HtmlComment comment = new HtmlComment("comment"); 339 | HtmlElement element2 = new HtmlElement("element2"); 340 | HtmlElement parent = new HtmlElement("parent", element1, comment, new HtmlAttribute("attribute"), element2); 341 | 342 | Assert.Equal(comment, element2.PreviousNode); 343 | } 344 | 345 | [Fact] 346 | public void PreviousNode_NoParent_ReturnsNull() 347 | { 348 | HtmlElement element = new HtmlElement("element"); 349 | Assert.Null(element.PreviousNode); 350 | } 351 | 352 | [Fact] 353 | public void PreviousNodes_ReturnsExpected() 354 | { 355 | HtmlElement element1 = new HtmlElement("element1"); 356 | HtmlComment comment = new HtmlComment("comment"); 357 | HtmlElement element2 = new HtmlElement("element2"); 358 | HtmlElement parent = new HtmlElement("parent", element1, comment, element2); 359 | 360 | Assert.Empty(element1.PreviousNodes()); 361 | Assert.Equal(new HtmlNode[] { element1 }, comment.PreviousNodes()); 362 | Assert.Equal(new HtmlNode[] { comment, element1 }, element2.PreviousNodes()); 363 | } 364 | 365 | [Fact] 366 | public void PreviousNodes_IgnoresAttributes() 367 | { 368 | HtmlElement element1 = new HtmlElement("element1"); 369 | HtmlComment comment = new HtmlComment("comment"); 370 | HtmlElement element2 = new HtmlElement("element2"); 371 | HtmlElement parent = new HtmlElement("parent", element1, comment, new HtmlAttribute("attribute"), element2); 372 | 373 | Assert.Equal(new HtmlNode[] { comment, element1 }, element2.PreviousNodes()); 374 | } 375 | 376 | [Fact] 377 | public void PreviousNodes_NoParent_ReturnsEmpty() 378 | { 379 | HtmlElement element = new HtmlElement("element"); 380 | Assert.Empty(element.PreviousNodes()); 381 | } 382 | 383 | [Fact] 384 | public void RemoveFromParent_OnlyChild_Works() 385 | { 386 | HtmlElement child = new HtmlElement("h1"); 387 | HtmlElement parent = new HtmlElement("div", child); 388 | 389 | child.RemoveFromParent(); 390 | Assert.Null(child.Parent); 391 | Assert.Empty(parent.Elements()); 392 | Assert.False(parent.HasElements); 393 | } 394 | 395 | [Fact] 396 | public void RemoveFromParent_FirstChild_Works() 397 | { 398 | HtmlElement child1 = new HtmlElement("h1"); 399 | HtmlElement child2 = new HtmlElement("h2"); 400 | HtmlElement child3 = new HtmlElement("h3"); 401 | HtmlElement parent = new HtmlElement("div", child1, child2, child3); 402 | 403 | // Updates Elements 404 | child1.RemoveFromParent(); 405 | Assert.Null(child1.Parent); 406 | Assert.Equal(new HtmlElement[] { child2, child3 }, parent.Elements()); 407 | Assert.True(parent.HasElements); 408 | 409 | // Updates LinkedList 410 | Assert.Null(child1.PreviousNode); 411 | Assert.Null(child1.NextNode); 412 | 413 | Assert.Null(child2.PreviousNode); 414 | Assert.Equal(child3, child2.NextNode); 415 | 416 | Assert.Equal(child2, child3.PreviousNode); 417 | Assert.Null(child3.NextNode); 418 | } 419 | 420 | [Fact] 421 | public void RemoveFromParent_LastChild_Works() 422 | { 423 | HtmlElement child1 = new HtmlElement("h1"); 424 | HtmlElement child2 = new HtmlElement("h2"); 425 | HtmlElement child3 = new HtmlElement("h3"); 426 | HtmlElement parent = new HtmlElement("div", child1, child2, child3); 427 | 428 | // Updates Elements 429 | child3.RemoveFromParent(); 430 | Assert.Null(child3.Parent); 431 | Assert.Equal(new HtmlElement[] { child1, child2 }, parent.Elements()); 432 | Assert.True(parent.HasElements); 433 | 434 | // Updates LinkedList 435 | Assert.Null(child1.PreviousNode); 436 | Assert.Equal(child2, child1.NextNode); 437 | 438 | Assert.Equal(child1, child2.PreviousNode); 439 | Assert.Null(child2.NextNode); 440 | 441 | Assert.Null(child3.PreviousNode); 442 | Assert.Null(child3.NextNode); 443 | } 444 | 445 | [Fact] 446 | public void RemoveFromParent_MiddleChild_Works() 447 | { 448 | HtmlElement child1 = new HtmlElement("h1"); 449 | HtmlElement child2 = new HtmlElement("h2"); 450 | HtmlElement child3 = new HtmlElement("h3"); 451 | HtmlElement parent = new HtmlElement("div", child1, child2, child3); 452 | 453 | // Updates Elements 454 | child2.RemoveFromParent(); 455 | Assert.Null(child2.Parent); 456 | Assert.Equal(new HtmlElement[] { child1, child3 }, parent.Elements()); 457 | Assert.True(parent.HasElements); 458 | 459 | // Updates LinkedList 460 | Assert.Null(child1.PreviousNode); 461 | Assert.Equal(child3, child1.NextNode); 462 | 463 | Assert.Null(child2.PreviousNode); 464 | Assert.Null(child2.NextNode); 465 | 466 | Assert.Equal(child1, child3.PreviousNode); 467 | Assert.Null(child3.NextNode); 468 | } 469 | 470 | [Fact] 471 | public void RemoveFromParent_NoParent_DoesNothing() 472 | { 473 | HtmlElement element = new HtmlElement("html"); 474 | element.RemoveFromParent(); 475 | 476 | Assert.Null(element.Parent); 477 | } 478 | } 479 | } 480 | -------------------------------------------------------------------------------- /tests/HtmlTextTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Xunit; 4 | 5 | namespace HtmlGenerator.Tests 6 | { 7 | public class HtmlTextTests 8 | { 9 | [Theory] 10 | [InlineData("")] 11 | [InlineData(" \t \r \n")] 12 | [InlineData("text")] 13 | [InlineData("TeXt")] 14 | public void Ctor_String(string text) 15 | { 16 | HtmlText htmlText = new HtmlText(text); 17 | Assert.Equal(text, htmlText.Text); 18 | } 19 | 20 | [Fact] 21 | public void Ctor_NullText_ThrowsArgumentNullException() 22 | { 23 | Assert.Throws("text", () => new HtmlText(null)); 24 | } 25 | 26 | [Theory] 27 | [InlineData("")] 28 | [InlineData(" \t \r \n")] 29 | [InlineData("text")] 30 | [InlineData("TeXt")] 31 | public void ImplicitOperator_String(string text) 32 | { 33 | HtmlText htmlText = text; 34 | Assert.Equal(text, htmlText.Text); 35 | } 36 | 37 | [Fact] 38 | public void ImplicitOperator_NullString_ThrowsArgumentNullException() 39 | { 40 | Assert.Throws("text", () => { HtmlText text = (string)null; }); 41 | } 42 | 43 | [Fact] 44 | public void ObjectType_Get_ReturnsText() 45 | { 46 | HtmlText text = new HtmlText("text"); 47 | Assert.Equal(HtmlObjectType.Text, text.ObjectType); 48 | } 49 | 50 | public static IEnumerable Equals_TestData() 51 | { 52 | yield return new object[] { new HtmlText("text"), new HtmlText("text"), true }; 53 | yield return new object[] { new HtmlText("text"), new HtmlText("other-text"), false }; 54 | yield return new object[] { new HtmlText("text"), new HtmlText("TEXT"), false }; 55 | 56 | yield return new object[] { new HtmlText("text"), new object(), false }; 57 | yield return new object[] { new HtmlText("text"), null, false }; 58 | } 59 | 60 | [Theory] 61 | [MemberData(nameof(Equals_TestData))] 62 | public void Equals_ReturnsExpected(HtmlText text, object other, bool expected) 63 | { 64 | if (other is HtmlText || other == null) 65 | { 66 | Assert.Equal(expected, text.GetHashCode().Equals(other?.GetHashCode())); 67 | Assert.Equal(expected, text.Equals((HtmlText)other)); 68 | } 69 | Assert.Equal(expected, text.Equals(other)); 70 | } 71 | 72 | public static IEnumerable ToString_TestData() 73 | { 74 | yield return new object[] { new HtmlText(""), "" }; 75 | yield return new object[] { new HtmlText(" \r \t \n "), " \r \t \n " }; 76 | yield return new object[] { new HtmlText("text"), "text" }; 77 | yield return new object[] { new HtmlText("TEXT"), "TEXT" }; 78 | } 79 | 80 | [Theory] 81 | [MemberData(nameof(ToString_TestData))] 82 | public void ToString_ReturnsExpected(HtmlText text, string expected) 83 | { 84 | Assert.Equal(expected, text.ToString()); 85 | Assert.Equal(expected, text.Serialize()); 86 | Assert.Equal(expected, text.Serialize(HtmlSerializeOptions.None)); 87 | Assert.Equal(expected, text.Serialize(HtmlSerializeOptions.NoFormatting)); 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /tests/TagTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Reflection; 4 | using Xunit; 5 | 6 | namespace HtmlGenerator.Tests 7 | { 8 | public class TagTests 9 | { 10 | [Fact] 11 | public void TagConstructors() 12 | { 13 | VerifyElement(Tag.A, "a", false, "Download", "Href", "HrefLang", "Media", "Ping", "Rel", "Target", "Type"); 14 | VerifyElement(Tag.Abbr, "abbr", false); 15 | VerifyElement(Tag.Address, "address", false); 16 | VerifyElement(Tag.Area, "area", true, "Alt", "Coords", "Download", "Href", "HrefLang", "Media", "Rel", "Shape", "Target", "Type"); 17 | VerifyElement(Tag.Article, "article", false); 18 | VerifyElement(Tag.Audio, "audio", false, "AutoPlay", "Controls", "Loop", "Muted", "Preload", "Src", "Volume"); 19 | 20 | VerifyElement(Tag.B, "b", false); 21 | VerifyElement(Tag.Base, "base", true, "Href", "Target"); 22 | VerifyElement(Tag.Bdi, "bdi", false); 23 | VerifyElement(Tag.Body, "body", false); 24 | VerifyElement(Tag.Br, "br", true); 25 | VerifyElement(Tag.Button, "button", false, "AutoFocus", "Disabled", "Form", "FormAction", "FormEncType", "FormMethod", "FormNoValidate", "FormTarget", "Name", "Type", "Value"); 26 | 27 | VerifyElement(Tag.Canvas, "canvas", false, "Height", "Width"); 28 | VerifyElement(Tag.Caption, "caption", false); 29 | VerifyElement(Tag.Cite, "cite", false); 30 | VerifyElement(Tag.Code, "code", false); 31 | VerifyElement(Tag.Col, "col", true, "Span"); 32 | VerifyElement(Tag.Colgroup, "colgroup", false, "Span"); 33 | 34 | VerifyElement(Tag.Data, "data", false, "Value"); 35 | VerifyElement(Tag.Datalist, "datalist", false); 36 | VerifyElement(Tag.Dd, "dd", false, "NoWrap"); 37 | VerifyElement(Tag.Del, "del", false, "Cite", "DateTime"); 38 | VerifyElement(Tag.Details, "details", false, "Open"); 39 | VerifyElement(Tag.Dfn, "dfn", false); 40 | VerifyElement(Tag.Dialog, "dialog", false, "Open"); 41 | VerifyElement(Tag.Div, "div", false); 42 | VerifyElement(Tag.Dl, "dl", false, "Compact"); 43 | VerifyElement(Tag.Dt, "dt", false); 44 | 45 | VerifyElement(Tag.Em, "em", false); 46 | VerifyElement(Tag.Embed, "embed", true, "Height", "Src", "Type", "Width"); 47 | 48 | VerifyElement(Tag.Fieldset, "fieldset", false); 49 | VerifyElement(Tag.FigCaption, "figcaption", false); 50 | VerifyElement(Tag.Figure, "figure", false); 51 | VerifyElement(Tag.Footer, "footer", false); 52 | VerifyElement(Tag.Form, "form", false, "AcceptCharset", "Action", "AutoComplete", "EncType", "Method", "Name", "NoValidate", "Target"); 53 | 54 | VerifyElement(Tag.H1, "h1", false); 55 | VerifyElement(Tag.H2, "h2", false); 56 | VerifyElement(Tag.H3, "h3", false); 57 | VerifyElement(Tag.H4, "h4", false); 58 | VerifyElement(Tag.H5, "h5", false); 59 | VerifyElement(Tag.H6, "h6", false); 60 | VerifyElement(Tag.Head, "head", false); 61 | VerifyElement(Tag.Header, "header", false); 62 | VerifyElement(Tag.Hr, "hr", true, "Color"); 63 | VerifyElement(Tag.Html, "html", false, "Xmls"); 64 | 65 | VerifyElement(Tag.I, "i", false); 66 | VerifyElement(Tag.Iframe, "iframe", false, "AllowFullScreen", "Height", "Name", "Sandbox", "Seamless", "Src", "SrcDoc", "Width"); 67 | VerifyElement(Tag.Img, "img", true, "Alt", "CrossOrigin", "Height", "IsMap", "LongDesc", "Sizes", "Src", "SrcSet", "Width", "UseMap"); 68 | VerifyElement(Tag.Input, "input", true, "Accept", "AutoComplete", "AutoFocus", "AutoSave", "Checked", "Disabled", "Form", "FormAction", "FormEncType", "FormMethod", "FormNoValidate", "FormTarget", "Height", "InputMode", "List", "Max", "MaxLength", "Min", "MinLength", "Multiple", "Name", "Pattern", "Placeholder", "Readonly", "Required", "SelectionDirection", "Size", "Src", "Step", "Type", "Value", "Width"); 69 | VerifyElement(Tag.Ins, "ins", false, "Cite", "DateTime"); 70 | 71 | VerifyElement(Tag.Kbd, "kbd", false); 72 | 73 | VerifyElement(Tag.Label, "label", false, "For", "Form"); 74 | VerifyElement(Tag.Legend, "legend", false); 75 | VerifyElement(Tag.Li, "li", false, "Value"); 76 | VerifyElement(Tag.Link, "link", true, "CrossOrigin", "Href", "HrefLang", "Integrity", "Media", "Rel", "Sizes", "Type"); 77 | 78 | VerifyElement(Tag.Main, "main", false); 79 | VerifyElement(Tag.Map, "map", false, "Name"); 80 | VerifyElement(Tag.Mark, "mark", false); 81 | VerifyElement(Tag.Menu, "menu", false, "Label", "Type"); 82 | VerifyElement(Tag.MenuItem, "menuitem", false, "Checked", "Command", "Default", "Disabled", "Icon", "Label", "RadioGroup", "Type"); 83 | VerifyElement(Tag.Meta, "meta", true, "Charset", "Content", "HttpEquiv", "DefaultStyle", "Refresh", "Name"); 84 | VerifyElement(Tag.Meter, "meter", false, "Form", "Low", "High", "Min", "Max", "Optimum", "Value"); 85 | 86 | VerifyElement(Tag.Nav, "nav", false); 87 | VerifyElement(Tag.Noscript, "noscript", false); 88 | 89 | VerifyElement(Tag.Object, "object", false, "Data", "Form", "Height", "Name", "Type", "TypeMustMatch", "UseMap", "Width"); 90 | VerifyElement(Tag.Ol, "ol", false, "Reversed", "Start", "Type"); 91 | VerifyElement(Tag.Optgroup, "optgroup", false, "Disabled", "Label"); 92 | VerifyElement(Tag.Option, "option", false, "Disabled", "Label", "Selected", "Value"); 93 | VerifyElement(Tag.Output, "output", false, "For", "Form", "Name"); 94 | 95 | VerifyElement(Tag.P, "p", false); 96 | VerifyElement(Tag.Param, "param", true, "Name", "Value"); 97 | VerifyElement(Tag.Pre, "pre", false); 98 | VerifyElement(Tag.Progress, "progress", false, "Max", "Value"); 99 | 100 | VerifyElement(Tag.Q, "q", false, "Cite"); 101 | 102 | VerifyElement(Tag.Rp, "rp", false); 103 | VerifyElement(Tag.Rt, "rt", false); 104 | VerifyElement(Tag.Rtc, "rtc", false); 105 | VerifyElement(Tag.Ruby, "ruby", false); 106 | 107 | VerifyElement(Tag.Samp, "samp", false); 108 | VerifyElement(Tag.Script, "script", false, "Async", "CrossOrigin", "Defer", "Integrity", "Src", "Text", "Type"); 109 | VerifyElement(Tag.Section, "section", false); 110 | VerifyElement(Tag.Select, "select", false, "AutoFocus", "Disabled", "Form", "Multiple", "Name", "Required", "Size"); 111 | VerifyElement(Tag.Small, "small", false); 112 | VerifyElement(Tag.Source, "source", true, "Src", "Type"); 113 | VerifyElement(Tag.Span, "span", false); 114 | VerifyElement(Tag.Strong, "strong", false); 115 | VerifyElement(Tag.Style, "style", false, "Disabled", "Type", "Media", "Scoped"); 116 | VerifyElement(Tag.Sub, "sub", false); 117 | VerifyElement(Tag.Summary, "summary", false); 118 | VerifyElement(Tag.Sup, "sup", false); 119 | 120 | VerifyElement(Tag.Table, "table", false); 121 | VerifyElement(Tag.Tbody, "tbody", false); 122 | VerifyElement(Tag.Td, "td", false); 123 | VerifyElement(Tag.Template, "template", false); 124 | VerifyElement(Tag.TextArea, "textarea", false, "AutoComplete", "AutoFocus", "Cols", "Disabled", "Form", "MaxLength", "MinLength", "Name", "Placeholder", "Readonly", "Required", "Rows", "SelectionDirection", "Wrap"); 125 | VerifyElement(Tag.Tfoot, "tfoot", false); 126 | VerifyElement(Tag.Th, "th", false, "ColSpan", "Headers", "RowSpan", "Scope"); 127 | VerifyElement(Tag.Thead, "thead", false); 128 | VerifyElement(Tag.Time, "time", false, "DateTime"); 129 | VerifyElement(Tag.Tr, "tr", false); 130 | VerifyElement(Tag.Track, "track", true, "Default", "Kind", "Label", "Src", "SrcLang"); 131 | 132 | VerifyElement(Tag.U, "u", false); 133 | VerifyElement(Tag.Ul, "ul", false); 134 | 135 | VerifyElement(Tag.Var, "var", false); 136 | VerifyElement(Tag.Video, "video", false, "AutoPlay", "Controls", "CrossOrigin", "Height", "Loop", "Muted", "Preload", "Src", "Width"); 137 | 138 | VerifyElement(Tag.Wbr, "wbr", false); 139 | } 140 | 141 | [Fact] 142 | public void Css() 143 | { 144 | HtmlElement css = Tag.Css("styles.css"); 145 | VerifyElement(css, "link", true); 146 | 147 | Helpers.SerializeIgnoringFormatting(css, ""); 148 | } 149 | 150 | [Fact] 151 | public void Header1() 152 | { 153 | HtmlElement header1 = Tag.Header1("Text"); 154 | VerifyElement(header1, "h1", false); 155 | 156 | Helpers.SerializeIgnoringFormatting(header1, "

Text

"); 157 | } 158 | 159 | [Fact] 160 | public void Header2() 161 | { 162 | HtmlElement header2 = Tag.Header2("Text"); 163 | VerifyElement(header2, "h2", false); 164 | 165 | Helpers.SerializeIgnoringFormatting(header2, "

Text

"); 166 | } 167 | 168 | [Fact] 169 | public void Header3() 170 | { 171 | HtmlElement header3 = Tag.Header3("Text"); 172 | VerifyElement(header3, "h3", false); 173 | 174 | Helpers.SerializeIgnoringFormatting(header3, "

Text

"); 175 | } 176 | 177 | [Fact] 178 | public void Header4() 179 | { 180 | HtmlElement header4 = Tag.Header4("Text"); 181 | VerifyElement(header4, "h4", false); 182 | 183 | Helpers.SerializeIgnoringFormatting(header4, "

Text

"); 184 | } 185 | 186 | [Fact] 187 | public void Header5() 188 | { 189 | HtmlElement header5 = Tag.Header5("Text"); 190 | VerifyElement(header5, "h5", false); 191 | 192 | Helpers.SerializeIgnoringFormatting(header5, "
Text
"); 193 | } 194 | 195 | [Fact] 196 | public void Header6() 197 | { 198 | HtmlElement header6 = Tag.Header6("Text"); 199 | VerifyElement(header6, "h6", false); 200 | 201 | Helpers.SerializeIgnoringFormatting(header6, "
Text
"); 202 | } 203 | 204 | [Fact] 205 | public void Hyperlink() 206 | { 207 | HtmlElement a = Tag.Hyperlink("index.html", "Text"); 208 | VerifyElement(a, "a", false); 209 | 210 | Helpers.SerializeIgnoringFormatting(a, "Text"); 211 | } 212 | 213 | [Fact] 214 | public void Image_String() 215 | { 216 | HtmlElement img = Tag.Image("img.jpeg"); 217 | VerifyElement(img, "img", true); 218 | 219 | Helpers.SerializeIgnoringFormatting(img, "\"\""); 220 | } 221 | 222 | [Fact] 223 | public void Image_String_String() 224 | { 225 | HtmlElement img = Tag.Image("img.jpeg", "alt-text"); 226 | VerifyElement(img, "img", true); 227 | 228 | Helpers.SerializeIgnoringFormatting(img, "\"alt-text\""); 229 | } 230 | 231 | [Fact] 232 | public void Javascript() 233 | { 234 | HtmlElement script = Tag.Javascript("scripts.js"); 235 | VerifyElement(script, "script", false); 236 | 237 | Helpers.SerializeIgnoringFormatting(script, ""); 238 | } 239 | 240 | [Fact] 241 | public void ListItem() 242 | { 243 | HtmlElement li = Tag.ListItem("Text"); 244 | VerifyElement(li, "li", false); 245 | 246 | Helpers.SerializeIgnoringFormatting(li, "
  • Text
  • "); 247 | } 248 | 249 | [Fact] 250 | public void Meta() 251 | { 252 | HtmlElement meta = Tag.Metadata("Name", "Content"); 253 | VerifyElement(meta, "meta", true); 254 | 255 | Helpers.SerializeIgnoringFormatting(meta, ""); 256 | } 257 | 258 | [Fact] 259 | public void Paragraph() 260 | { 261 | HtmlElement p = Tag.Paragraph("Text"); 262 | VerifyElement(p, "p", false); 263 | 264 | Helpers.SerializeIgnoringFormatting(p, "

    Text

    "); 265 | } 266 | 267 | [Fact] 268 | public void Custom_String() 269 | { 270 | HtmlElement custom = Tag.Custom("tag"); 271 | VerifyElement(custom, "tag", false); 272 | } 273 | 274 | [Theory] 275 | [InlineData(true)] 276 | [InlineData(false)] 277 | public void Custom_String_Bool(bool isVoid) 278 | { 279 | HtmlElement custom = Tag.Custom("tag", isVoid); 280 | VerifyElement(custom, "tag", isVoid); 281 | } 282 | 283 | private static void VerifyElement(HtmlElement element, string tag, bool isVoid, params string[] attributeNames) 284 | { 285 | Assert.Equal(tag, element.Tag); 286 | Assert.Equal(isVoid, element.IsVoid); 287 | Assert.Null(element.Parent); 288 | 289 | foreach (string attributeName in attributeNames) 290 | { 291 | bool attributeIsVoid = typeof(Attribute).GetMethod(attributeName) == null; 292 | MethodInfo method = element.GetType().GetMethod("With" + attributeName); 293 | if (attributeIsVoid) 294 | { 295 | HtmlAttribute expectedAttribute = (HtmlAttribute)typeof(Attribute).GetProperty(attributeName).GetValue(null); 296 | 297 | Assert.Empty(method.GetParameters()); 298 | Assert.Same(element, method.Invoke(element, new object[0])); 299 | 300 | HtmlAttribute actualAttribute; 301 | Assert.True(element.TryGetAttribute(expectedAttribute.Name, out actualAttribute)); 302 | Assert.Equal(expectedAttribute, actualAttribute); 303 | } 304 | else 305 | { 306 | HtmlAttribute expectedAttribute = (HtmlAttribute)typeof(Attribute).GetMethod(attributeName).Invoke(null, new object[] { "value" }); 307 | 308 | Assert.Equal(new Type[] { typeof(string) }, method.GetParameters().Select(parameter => parameter.ParameterType)); 309 | Assert.Same(element, method.Invoke(element, new object[] { "value" })); 310 | 311 | HtmlAttribute actualAttribute; 312 | Assert.True(element.TryGetAttribute(expectedAttribute.Name, out actualAttribute)); 313 | Assert.Equal(expectedAttribute, actualAttribute); 314 | } 315 | } 316 | } 317 | 318 | [Fact] 319 | public void WithInnerText() 320 | { 321 | HtmlElement element = new HtmlElement("element"); 322 | Assert.Same(element, element.WithInnerText("InnerText")); 323 | Assert.Equal(new HtmlNode[] { new HtmlText("InnerText") }, element.Nodes()); 324 | } 325 | 326 | [Fact] 327 | public void WithElement_WithElements() 328 | { 329 | HtmlElement element = new HtmlElement("html"); 330 | 331 | HtmlElement element1 = new HtmlElement("h1"); 332 | Assert.Same(element, element.WithChild(element1)); 333 | Assert.Equal(new HtmlElement[] { element1 }, element.Elements()); 334 | 335 | HtmlElement element2 = new HtmlElement("h2"); 336 | Assert.Same(element, element.WithChildren(new HtmlElement[] { element2 })); 337 | Assert.Equal(new HtmlElement[] { element1, element2 }, element.Elements()); 338 | } 339 | 340 | [Fact] 341 | public void WithAttribute_WithAttributes() 342 | { 343 | HtmlElement element = new HtmlElement("html"); 344 | 345 | HtmlAttribute attribute1 = new HtmlAttribute("Attribute1"); 346 | Assert.Same(element, element.WithAttribute(attribute1)); 347 | Assert.Equal(new HtmlAttribute[] { attribute1 }, element.Attributes()); 348 | 349 | HtmlAttribute attribute2 = new HtmlAttribute("Attribute2"); 350 | Assert.Same(element, element.WithAttributes(new HtmlAttribute[] { attribute2 })); 351 | Assert.Equal(new HtmlAttribute[] { attribute1, attribute2 }, element.Attributes()); 352 | } 353 | 354 | [Fact] 355 | public void WithAccessKey() 356 | { 357 | HtmlElement element = new HtmlElement("html"); 358 | Assert.Same(element, element.WithAccessKey("value")); 359 | Assert.Equal(Attribute.AccessKey("value"), element.Attributes().First()); 360 | } 361 | 362 | [Fact] 363 | public void WithClass() 364 | { 365 | HtmlElement element = new HtmlElement("html"); 366 | Assert.Same(element, element.WithClass("value")); 367 | Assert.Equal(Attribute.Class("value"), element.Attributes().First()); 368 | } 369 | 370 | [Fact] 371 | public void WithContentEditable() 372 | { 373 | HtmlElement element = new HtmlElement("html"); 374 | Assert.Same(element, element.WithContentEditable("value")); 375 | Assert.Equal(Attribute.ContentEditable("value"), element.Attributes().First()); 376 | } 377 | 378 | [Fact] 379 | public void WithContextMenu() 380 | { 381 | HtmlElement element = new HtmlElement("html"); 382 | Assert.Same(element, element.WithContextMenu("value")); 383 | Assert.Equal(Attribute.ContextMenu("value"), element.Attributes().First()); 384 | } 385 | 386 | [Fact] 387 | public void WithDir() 388 | { 389 | HtmlElement element = new HtmlElement("html"); 390 | Assert.Same(element, element.WithDir("value")); 391 | Assert.Equal(Attribute.Dir("value"), element.Attributes().First()); 392 | } 393 | 394 | [Fact] 395 | public void WithHidden() 396 | { 397 | HtmlElement element = new HtmlElement("html"); 398 | Assert.Same(element, element.WithHidden("value")); 399 | Assert.Equal(Attribute.Hidden("value"), element.Attributes().First()); 400 | } 401 | 402 | [Fact] 403 | public void WithId() 404 | { 405 | HtmlElement element = new HtmlElement("html"); 406 | Assert.Same(element, element.WithId("value")); 407 | Assert.Equal(Attribute.Id("value"), element.Attributes().First()); 408 | } 409 | 410 | [Fact] 411 | public void WithLang() 412 | { 413 | HtmlElement element = new HtmlElement("html"); 414 | Assert.Same(element, element.WithLang("value")); 415 | Assert.Equal(Attribute.Lang("value"), element.Attributes().First()); 416 | } 417 | 418 | [Fact] 419 | public void WithSpellCheck() 420 | { 421 | HtmlElement element = new HtmlElement("html"); 422 | Assert.Same(element, element.WithSpellCheck("value")); 423 | Assert.Equal(Attribute.SpellCheck("value"), element.Attributes().First()); 424 | } 425 | 426 | [Fact] 427 | public void WithStyle() 428 | { 429 | HtmlElement element = new HtmlElement("html"); 430 | Assert.Same(element, element.WithStyle("value")); 431 | Assert.Equal(Attribute.Style("value"), element.Attributes().First()); 432 | } 433 | 434 | [Fact] 435 | public void WithTabIndex() 436 | { 437 | HtmlElement element = new HtmlElement("html"); 438 | Assert.Same(element, element.WithTabIndex("value")); 439 | Assert.Equal(Attribute.TabIndex("value"), element.Attributes().First()); 440 | } 441 | } 442 | } 443 | --------------------------------------------------------------------------------