1 /** 2 * Copyright © DiamondMVC 2019 3 * License: MIT (https://github.com/DiamondMVC/Diamond/blob/master/LICENSE) 4 * Author: Jacob Jensen (bausshf) 5 */ 6 module diamond.dom.domparsersettings; 7 8 import std..string : toLower; 9 10 import diamond.core.collections; 11 12 /// Wrapper around dom parser settings. 13 abstract class DomParserSettings 14 { 15 private: 16 /// Boolean determining whether the parser is strict or not. 17 bool _strictParsing; 18 /// HashSet of tags that can has flexible content, such as the HTML <script> tag. 19 HashSet!string _flexibleTags; 20 /// Boolean determining whether the parser allows self-closing tags or not. 21 bool _allowSelfClosingTags; 22 /// HashSet of self-closing tags. 23 HashSet!string _selfClosingTags; 24 /// HashSet of standard tags. 25 HashSet!string _standardTags; 26 /// Tags to repair within the head section. 27 HashSet!string _headRepairTags; 28 /// Tags to repair within the body section. 29 HashSet!string _bodyRepairTags; 30 31 protected 32 { 33 /** 34 * Creates a new dom parser setting. 35 * Params: 36 * strictParsing = Boolean determining whether the parser is strict or not. 37 * flexibleTags = An array of tags that can has flexible content, such as the HTML <script> tag. 38 * allowSelfClosingTags = Boolean determining whether the parser allows self-closing tags or not. 39 * selfClosingTags = An array of tags that can be self-closed. 40 * standardTags = An array of standard tags. These are only relevant if self-closing tags are allowed. 41 * headRepairTags = An array of tags that can be repaired within the head section. 42 * bodyRepairTags = An array of tags that can be repaired within the body section. 43 */ 44 this 45 ( 46 bool strictParsing, 47 string[] flexibleTags, 48 bool allowSelfClosingTags, 49 string[] selfClosingTags, 50 string[] standardTags, 51 string[] headRepairTags, 52 string[] bodyRepairTags 53 ) @safe 54 { 55 _strictParsing = strictParsing; 56 57 _flexibleTags = new HashSet!string; 58 59 if (flexibleTags && flexibleTags.length) 60 { 61 foreach (tag; flexibleTags) 62 { 63 _flexibleTags.add(tag.toLower); 64 } 65 } 66 67 _allowSelfClosingTags = allowSelfClosingTags; 68 69 if (_allowSelfClosingTags) 70 { 71 _selfClosingTags = new HashSet!string; 72 73 if (selfClosingTags && selfClosingTags.length) 74 { 75 foreach (tag; selfClosingTags) 76 { 77 _selfClosingTags.add(tag.toLower); 78 } 79 } 80 81 _standardTags = new HashSet!string; 82 83 if (standardTags && standardTags.length) 84 { 85 foreach (tag; standardTags) 86 { 87 _standardTags.add(tag.toLower); 88 } 89 } 90 } 91 92 _headRepairTags = new HashSet!string; 93 94 if (headRepairTags && headRepairTags.length) 95 { 96 foreach (tag; headRepairTags) 97 { 98 _headRepairTags.add(tag.toLower); 99 } 100 } 101 102 _bodyRepairTags = new HashSet!string; 103 104 if (bodyRepairTags && bodyRepairTags.length) 105 { 106 foreach (tag; bodyRepairTags) 107 { 108 _bodyRepairTags.add(tag.toLower); 109 } 110 } 111 } 112 } 113 114 public: 115 final: 116 @property 117 { 118 /// Gets a boolean determining whether the parser is strict or not. 119 bool strictParsing() @safe { return _strictParsing; } 120 121 /// Gets a boolean determining whether the parser allwos self-closing tags or not. 122 bool allowSelfClosingTags() @safe { return _allowSelfClosingTags; } 123 } 124 125 /** 126 * Checks whether a specific tag is flexible or not. 127 * Params: 128 * tagName = The name of the tag to validate. 129 * Returns: 130 * True if the tag is flexible, false otherwise. 131 */ 132 bool isFlexibleTag(string tagName) @safe 133 { 134 if (!_flexibleTags) 135 { 136 return false; 137 } 138 139 return _flexibleTags.has(tagName.toLower); 140 } 141 142 /** 143 * Checks whether a specific tag is self-closing or not. 144 * Params: 145 * tagName = The name of the tag to validate. 146 * Returns: 147 * True if the tag is self-closing, false otherwise. 148 */ 149 bool isSelfClosingTag(string tagName) @safe 150 { 151 if (!_selfClosingTags) 152 { 153 return false; 154 } 155 156 return _selfClosingTags.has(tagName.toLower); 157 } 158 159 /** 160 * Checks whether a specific tag is standard or not. 161 * Params: 162 * tagName = The name of the tag to validate. 163 * Returns: 164 * True if the tag is standard, false otherwise. 165 */ 166 bool isStandardTag(string tagName) @safe 167 { 168 if (!_standardTags) 169 { 170 return false; 171 } 172 173 return _standardTags.has(tagName.toLower); 174 } 175 176 /** 177 * Checks whether a specific tag is located in the head section or not. 178 * Params: 179 * tagName = The name of the tag to validate. 180 * Returns: 181 * True if the tag is located in the head section, false otherwise. 182 */ 183 bool isHeadTag(string tagName) @safe 184 { 185 if (!_headRepairTags) 186 { 187 return false; 188 } 189 190 return _headRepairTags.has(tagName); 191 } 192 193 /** 194 * Checks whether a specific tag is located in the body section or not. 195 * Params: 196 * tagName = The name of the tag to validate. 197 * Returns: 198 * True if the tag is located in the body section, false otherwise. 199 */ 200 bool isBodyTag(string tagName) @safe 201 { 202 if (!_bodyRepairTags) 203 { 204 return false; 205 } 206 207 return _bodyRepairTags.has(tagName); 208 } 209 }