001package Torello.HTML; 002 003import Torello.HTML.helper.AttrRegEx; 004 005import Torello.Java.StringParse; 006import Torello.Java.StrCmpr; 007import Torello.Java.StrFilter; 008 009import Torello.HTML.NodeSearch.CSSStrException; 010import Torello.HTML.NodeSearch.TextComparitor; 011 012import Torello.JavaDoc.LinkJavaSource; 013 014import static Torello.JavaDoc.Entity.METHOD; 015import static Torello.JavaDoc.Entity.FIELD; 016 017import java.util.Vector; 018import java.util.Properties; 019import java.util.Map; 020 021import java.util.regex.Pattern; 022import java.util.regex.Matcher; 023 024import java.util.stream.Stream; 025 026import javax.management.AttributeNotFoundException; 027 028import java.util.function.Predicate; 029 030/** 031 * Represents an HTML Element Tag, and is the flagship class of the Java-HTML Library. 032 * 033 * <EMBED CLASS='external-html' DATA-FILE-ID=TAG_NODE> 034 * <EMBED CLASS='external-html' DATA-FILE-ID=HTML_NODE_SUB_IMG> 035 * 036 * @see TextNode 037 * @see CommentNode 038 * @see HTMLNode 039 */ 040@Torello.JavaDoc.JDHeaderBackgroundImg(EmbedTagFileID="HTML_NODE_SUBCLASS") 041public final class TagNode 042 extends HTMLNode 043 implements CharSequence, java.io.Serializable, Cloneable, Comparable<TagNode> 044{ 045 /** <EMBED CLASS='external-html' DATA-FILE-ID=SVUID> */ 046 public static final long serialVersionUID = 1; 047 048 049 // ******************************************************************************************** 050 // ******************************************************************************************** 051 // NON-STATIC FIELDS 052 // ******************************************************************************************** 053 // ******************************************************************************************** 054 055 056 /** <EMBED CLASS='external-html' DATA-FILE-ID=TAGNODE_TOK> */ 057 public final String tok; 058 059 /** <EMBED CLASS='external-html' DATA-FILE-ID=TAGNODE_IS_CLOSING> */ 060 public final boolean isClosing; 061 062 063 064 // ******************************************************************************************** 065 // ******************************************************************************************** 066 // Package-Private Constructors - NO ERROR CHECKING DONE WHATSOEVER 067 // ******************************************************************************************** 068 // ******************************************************************************************** 069 070 071 // ONLY USED BY THE "TagNodeHelpers" and in conjunction with "Generate Element String" 072 // 073 // It presumes that the node was properly constructed and needs to error-checking 074 // It is only used for opening TagNode's 075 076 TagNode(String tok, String str) 077 { 078 super(str); 079 080 this.tok = HTMLTags.getTag_MEM_HEAP_CHECKOUT_COPY(tok); 081 this.isClosing = false; 082 } 083 084 085 // USED-INTERNALLY - bypasses all checks. used when creating new HTML Element-Names 086 // ONLY: class 'HTMLTags' via method 'addTag(...)' shall ever invoke this constructor. 087 // 088 // NOTE: This only became necessary because of the MEM_COPY_HEAP optimization. This 089 // optimization expects that there is already a TagNode with element 'tok' in 090 // the TreeSet, which is always OK - except for the method that CREATES NEW HTML 091 // TAGS... a.k.a. HTMLTags.addTag(String). 092 093 TagNode(String token, TC openOrClosed) 094 { 095 super("<" + ((openOrClosed == TC.ClosingTags) ? "/" : "") + token + ">"); 096 097 // ONLY CHANGE CASE HERE, NOT IN PREVIOUS-LINE. PAY ATTENTION. 098 this.tok = token.toLowerCase(); 099 100 this.isClosing = (openOrClosed == TC.ClosingTags) ? true : false; 101 } 102 103 104 // ******************************************************************************************** 105 // ******************************************************************************************** 106 // Public Constructors 107 // ******************************************************************************************** 108 // ******************************************************************************************** 109 110 111 /** 112 * <EMBED CLASS='external-html' DATA-FILE-ID=TN_C_DESC_1> 113 * 114 * @param s Any valid HTML tag, for instance: {@code <H1>, <A HREF="somoe url">, 115 * <DIV ID="some id">} etc... 116 * 117 * @throws MalformedTagNodeException If the passed {@code String} wasn't valid - meaning <I>it 118 * did not match the regular-expression {@code parser}.</I> 119 * 120 * @throws HTMLTokException If the {@code String} found where the usual HTML token-element is 121 * situated <I>is not a valid HTML element</I> then the {@code HTMLTokException} will be 122 * thrown. 123 * 124 * @see HTMLTags#getTag_MEM_HEAP_CHECKOUT_COPY(String) 125 */ 126 public TagNode(String s) 127 { 128 super(s); 129 130 // If the second character of the string is a forward-slash, this must be a closing-element 131 // For Example: </SPAN>, </DIV>, </A>, etc... 132 133 isClosing = s.charAt(1) == '/'; 134 135 // This is the Element & Attribute Matcher used by the RegEx Parser. If this Matcher 136 // doesn't find a match, the parameter 's' cannot be a valid HTML Element. NOTE: The 137 // results of this matcher are also used to retrieve attribute-values, but here below, 138 // its results are ignored. 139 140 Matcher m = HTMLRegEx.P1.matcher(s); 141 142 if (! m.find()) throw new MalformedTagNodeException( 143 "The parser's regular-expression did not match the constructor-string.\n" + 144 "The exact input-string was: [" + s + "]\n" + 145 "NOTE: The parameter-string is included as a field (ex.str) to this Exception.", s 146 ); 147 148 if ((m.start() != 0) || (m.end() != s.length())) 149 150 throw new MalformedTagNodeException( 151 "The parser's regular-expression did not match the entire-string-length of the " + 152 "string-parameter to this constructor: m.start()=" + m.start() + ", m.end()=" + 153 m.end() + ".\nHowever, the length of the Input-Parameter String was " + 154 '[' + s.length() + "]\nThe exact input-string was: [" + s + "]\nNOTE: The " + 155 "parameter-string is included as a field (ex.str) to this Exception.", s 156 ); 157 158 // MINOR/MAJOR IMPROVEMENT... REUSE THE "ALLOCATED STRING TOKEN" from HTMLTag's class 159 // THINK: Let the Garbage Collector take out as many duplicate-strings as is possible.. 160 // AND SOONER. DECEMBER 2019: "Optimization" or ... "Improvement" 161 // 162 // Get a copy of the 'tok' string that was already allocated on the heap; (OPTIMIZATON) 163 // 164 // NOTE: There are already myriad strings for the '.str' field. 165 // 166 // ALSO: Don't pay much attention to this line if it doesn't make sense... it's not 167 // that important. If the HTML Token found was not a valid HTML5 token, this field 168 // will be null. 169 // 170 // Java 14+ has String.intern() - that's what this is.... 171 172 this.tok = HTMLTags.getTag_MEM_HEAP_CHECKOUT_COPY(m.group(1)); 173 174 // Now do the usual error check. 175 if (this.tok == null) throw new HTMLTokException( 176 "The HTML Tag / Token Element that is specified by the input string " + 177 "[" + m.group(1).toLowerCase() + "] is not a valid HTML Element Name.\n" + 178 "The exact input-string was: [" + s + "]" 179 ); 180 } 181 182 /** 183 * Convenience Constructor. 184 * <BR />Invokes: {@link #TagNode(String, Properties, Iterable, SD, boolean)} 185 * <BR />Passes: null to the Boolean / Key-Only Attributes {@code Iterable} 186 */ 187 public TagNode( 188 String tok, 189 Properties attributes, 190 SD quotes, 191 boolean addEndingForwardSlash 192 ) 193 { 194 this( 195 tok, 196 GeneralPurpose.generateElementString( 197 tok, 198 attributes, 199 null, // keyOnlyAttributes, 200 quotes, 201 addEndingForwardSlash 202 )); 203 } 204 205 /** 206 * <EMBED CLASS='external-html' DATA-FILE-ID=TN_C_DESC_2> 207 * @param tok <EMBED CLASS='external-html' DATA-FILE-ID=TN_C_TOK> 208 * @param attributes <EMBED CLASS='external-html' DATA-FILE-ID=TN_C_ATTRIBUTES> 209 * @param keyOnlyAttributes <EMBED CLASS='external-html' DATA-FILE-ID=TN_C_KO_ATTRIBUTES> 210 * @param quotes <EMBED CLASS='external-html' DATA-FILE-ID=TN_C_QUOTES> 211 * @param addEndingForwardSlash <EMBED CLASS='external-html' DATA-FILE-ID=TN_C_AEFS> 212 * @throws InnerTagKeyException <EMBED CLASS='external-html' DATA-FILE-ID=IT_KEY_EX_PROP_TN> 213 * @throws QuotesException <EMBED CLASS='external-html' DATA-FILE-ID=QEX> 214 * 215 * @throws HTMLTokException if an invalid HTML 4 or 5 token is not present 216 * <B>(check is {@code CASE_INSENSITIVE})</B>, or a token which has been registered with class 217 * {@code HTMLTags}. 218 * 219 * @see InnerTagKeyException#check(String, String) 220 * @see QuotesException#check(String, SD, String) 221 */ 222 public TagNode( 223 String tok, 224 Properties attributes, 225 Iterable<String> keyOnlyAttributes, 226 SD quotes, 227 boolean addEndingForwardSlash 228 ) 229 { 230 this( 231 tok, 232 GeneralPurpose.generateElementString 233 (tok, attributes, keyOnlyAttributes, quotes, addEndingForwardSlash) 234 ); 235 } 236 237 238 // ******************************************************************************************** 239 // ******************************************************************************************** 240 // HTMLNode Overidden - Loop & Stream Optimization Methods 241 // ******************************************************************************************** 242 // ******************************************************************************************** 243 244 245 /** 246 * This method identifies that {@code 'this'} instance of (abstract parent-class) 247 * {@link HTMLNode} is, indeed, an instance of sub-class {@code TagNode}. 248 * 249 * <BR /><BR /><B CLASS=JDDescLabel>Final Method:</B> 250 * 251 * <BR />This method is final, and cannot be modified by sub-classes. 252 * 253 * @return This method shall always return {@code TRUE} It overrides the parent-class 254 * {@code HTMLNode} method {@link #isTagNode()}, which always returns {@code FALSE}. 255 */ 256 @Override 257 public final boolean isTagNode() { return true; } 258 259 /** 260 * <EMBED CLASS='external-html' DATA-FILE-ID=TN_IF_TN_DESC> 261 * <BR /><BR /><B CLASS=JDDescLabel>Final Method:</B> 262 * <BR />This method is final, and cannot be modified by sub-classes. 263 * @return <EMBED CLASS='external-html' DATA-FILE-ID=TN_IF_TN_RET> 264 */ 265 @Override 266 public final TagNode ifTagNode() { return this; } 267 268 /** 269 * <EMBED CLASS='external-html' DATA-FILE-ID=TN_OPENTAG_PWA_DESC> 270 * <BR /><BR /><B CLASS=JDDescLabel>Final Method:</B> 271 * <BR />This method is final, and cannot be modified by sub-classes. 272 * @return <EMBED CLASS='external-html' DATA-FILE-ID=TN_OPENTAG_PWA_RET> 273 */ 274 @Override 275 public final TagNode openTagPWA() 276 { 277 // Closing TagNode's simply may not have attributes 278 if (this.isClosing) return null; 279 280 // A TagNode whose '.str' field is not AT LEAST 4 characters LONGER than the length of the 281 // HTML-Tag / Token, simply cannot have an attribute. 282 // 283 // NOTE: Below is the shortest possible HTML tag that could have an attribute. 284 // COMPUTE: '<' + TOK.LENGTH + SPACE + 'c' + '>' 285 286 if (this.str.length() < (this.tok.length() + 4)) return null; 287 288 // This TagNode is an opening HTML tag (like <DIV ...>, rather than </DIV>), 289 // and there are at least two additional characters after the token, such as: <DIV A...> 290 // It is not guaranteed that this tag has attributes, but it is possibly - based on these 291 /// optimization methods, and further investigation would have merit. 292 293 return this; 294 } 295 296 /** 297 * This is a loop-optimization method that makes finding opening {@code TagNode's} - <B>with 298 * attribute-</B><B STYLE='color: red;'>values</B> - quites a bit faster. All {@link HTMLNode} 299 * subclasses implement this method, but only {@code TagNode} instances will ever return a 300 * non-null value. 301 * 302 * <BR /><BR /><B CLASS=JDDescLabel>Final Method:</B> 303 * 304 * <BR />This method is final, and cannot be modified by sub-classes. 305 * 306 * @return Returns null if and only if {@code 'this'} instance' {@link #isClosing} field is 307 * false. When a non-null return-value is acheived, that value will always be {@code 'this'} 308 * instance. 309 */ 310 @Override 311 public final TagNode openTag() 312 { return isClosing ? null : this; } 313 314 /** 315 * This method is an optimization method that overrides the one by the same name in class 316 * {@link HTMLNode}. 317 * 318 * {@inheritdoc} 319 */ 320 @Override 321 public boolean isOpenTagPWA() 322 { 323 if (this.isClosing) return false; 324 if (this.str.length() < (this.tok.length() + 4)) return false; 325 return true; 326 } 327 328 /** 329 * This method is an optimization method that overrides the one by the same name in class 330 * {@link HTMLNode}. 331 * 332 * {@inheritdoc} 333 */ 334 @Override 335 public boolean isOpenTag() 336 { return ! isClosing; } 337 338 339 // ******************************************************************************************** 340 // ******************************************************************************************** 341 // isTag 342 // ******************************************************************************************** 343 // ******************************************************************************************** 344 345 346 /** 347 * <EMBED CLASS='external-html' DATA-FILE-ID=TN_IS_TAG1_DESC> 348 * @param possibleTags A non-null list of potential HTML tags to be checked again {@link #tok} 349 * @return <EMBED CLASS='external-html' DATA-FILE-ID=TN_IS_TAG1_RET> 350 * @see #tok 351 */ 352 public boolean isTag(String... possibleTags) 353 { 354 for (String htmlTag : possibleTags) if (htmlTag.equalsIgnoreCase(this.tok)) return true; 355 return false; 356 } 357 358 /** 359 * <EMBED CLASS='external-html' DATA-FILE-ID=TN_IS_TAG_EX1_DESC> 360 * @param possibleTags A non-null list of potential HTML tags to be checked again {@link #tok} 361 * @return <EMBED CLASS='external-html' DATA-FILE-ID=TN_IS_TAG_EX1_RET> 362 * @see #tok 363 * @see #isTag(String[]) 364 */ 365 public boolean isTagExcept(String... possibleTags) 366 { 367 for (String htmlTag : possibleTags) if (htmlTag.equalsIgnoreCase(this.tok)) return false; 368 return true; 369 } 370 371 /** 372 * <EMBED CLASS='external-html' DATA-FILE-ID=TN_IS_TAG2_DESC> 373 * @param tagCriteria <EMBED CLASS='external-html' DATA-FILE-ID=TN_IS_TAG2_PARAM> 374 * @param possibleTags A non-null list of potential HTML tags to be checked again {@link #tok} 375 * @return <EMBED CLASS='external-html' DATA-FILE-ID=TN_IS_TAG2_RET> 376 * @see #tok 377 */ 378 @LinkJavaSource(handle="IsTag", name="isTag") 379 public boolean isTag(TC tagCriteria, String... possibleTags) 380 { return IsTag.isTag(this, tagCriteria, possibleTags); } 381 382 /** 383 * <EMBED CLASS='external-html' DATA-FILE-ID=TN_IS_TAG_EX2_DESC> 384 * @param tagCriteria <EMBED CLASS='external-html' DATA-FILE-ID=TN_IS_TAG_EX2_PARAM> 385 * @param possibleTags A non-null list of potential HTML tags to be checked again {@link #tok} 386 * @return <EMBED CLASS='external-html' DATA-FILE-ID=TN_IS_TAG_EX2_RET> 387 * @see #tok 388 */ 389 @LinkJavaSource(handle="IsTag", name="isTagExcept") 390 public boolean isTagExcept(TC tagCriteria, String... possibleTags) 391 { return IsTag.isTagExcept(this, tagCriteria, possibleTags); } 392 393 394 // ******************************************************************************************** 395 // ******************************************************************************************** 396 // Main Method 'AV' 397 // ******************************************************************************************** 398 // ******************************************************************************************** 399 400 401 /** 402 * <EMBED CLASS='external-html' DATA-FILE-ID=TN_AV_DESC> 403 * <EMBED CLASS='external-html' DATA-FILE-ID=TN_AV_DESC_EXAMPLE> 404 * @param innerTagAttribute <EMBED CLASS='external-html' DATA-FILE-ID=TN_AV_ITA> 405 * @return <EMBED CLASS='external-html' DATA-FILE-ID=TN_AV_RET> 406 * @see StringParse#ifQuotesStripQuotes(String) 407 */ 408 @LinkJavaSource(handle="GetSetAttr", name="AV") 409 public String AV(String innerTagAttribute) 410 { return GetSetAttr.AV(this, innerTagAttribute, false); } 411 412 /** 413 * Identical to {@link #AV(String)}, except that if the 414 * Attribute-<B STYLE='color: red;'>value</B> had quotes surrounding it, those are included in 415 * the returned {@code String}. 416 */ 417 // To-Do, finish this after brekfast 418 // public String preserveQuotesAV(String innerTagAttribute) 419 // { return GetSetAttr.AV(this, innerTagAttribute, true); } 420 421 /** 422 * <B STYLE='color: red;'>AVOPT: Attribute-Value - Optimized</B> 423 * 424 * <BR /><BR /> This is an "optimized" version of method {@link #AV(String)}. This method does 425 * the exact same thing as {@code AV(...)}, but leaves out parameter-checking and 426 * error-checking. This is used internally (and repeatedly) by the NodeSearch Package Search 427 * Loops. 428 * 429 * @param innerTagAttribute This is the inner-tag / attribute <B STYLE='color: red;'>name</B> 430 * whose <B STYLE='color: red;'>value</B> is hereby being requested. 431 * 432 * @return {@code String}-<B STYLE='color: red;'>value</B> of this inner-tag / attribute. 433 * 434 * @see StringParse#ifQuotesStripQuotes(String) 435 * @see #str 436 */ 437 @LinkJavaSource(handle="AttrRegEx", entity=FIELD, name="KEY_VALUE_REGEX") 438 public String AVOPT(String innerTagAttribute) 439 { 440 // COPIED DIRECTLY FROM class TagNode, leaves off initial tests. 441 442 // Matches "Attribute / Inner-Tag Key-Value" Pairs. 443 Matcher m = AttrRegEx.KEY_VALUE_REGEX.matcher(this.str); 444 445 // This loop iterates the KEY_VALUE PAIRS THAT HAVE BEEN FOUND. 446 /// NOTE: The REGEX Matches on Key-Value Pairs. 447 448 while (m.find()) 449 450 // m.group(2) is the "KEY" of the Attribute KEY-VALUE Pair 451 // m.group(3) is the "VALUE" of the Attribute. 452 453 if (m.group(2).equalsIgnoreCase(innerTagAttribute)) 454 return StringParse.ifQuotesStripQuotes(m.group(3)); 455 456 // This means the attribute name provided to parameter 'innerTagAttribute' was not found. 457 return null; 458 } 459 460 461 // ******************************************************************************************** 462 // ******************************************************************************************** 463 // Attribute Modify-Value methods 464 // ******************************************************************************************** 465 // ******************************************************************************************** 466 467 468 /** 469 * <EMBED CLASS='external-html' DATA-FILE-ID=TN_SET_AV_DESC> 470 * @param attribute <EMBED CLASS='external-html' DATA-FILE-ID=TN_SET_AV_ATTR> 471 * 472 * @param value Any valid attribute-<B STYLE='color: red;'>value</B>. This parameter may not 473 * be null, or a {@code NullPointerException} will throw. 474 * 475 * @param quote <EMBED CLASS='external-html' DATA-FILE-ID=TN_SET_AV_QUOTE> 476 * @throws InnerTagKeyException <EMBED CLASS='external-html' DATA-FILE-ID=IT_KEY_EX_TN> 477 * @throws QuotesException <EMBED CLASS='external-html' DATA-FILE-ID=QEX> 478 * @throws ClosingTagNodeException <EMBED CLASS='external-html' DATA-FILE-ID=CTNEX> 479 * 480 * @throws HTMLTokException If an invalid HTML 4 or 5 token is not present 481 * (<B>{@code CASE_INSENSITIVE}</B>). 482 * 483 * @return <EMBED CLASS='external-html' DATA-FILE-ID=TN_SET_AV_RET> 484 * @see ClosingTagNodeException#check(TagNode) 485 * @see #setAV(Properties, SD) 486 * @see #str 487 * @see #isClosing 488 */ 489 @LinkJavaSource(handle="GetSetAttr", name="setAV", paramCount=4) 490 public TagNode setAV(String attribute, String value, SD quote) 491 { return GetSetAttr.setAV(this, attribute, value, quote); } 492 493 /** 494 * <EMBED CLASS='external-html' DATA-FILE-ID=TN_SET_AV2_DESC> 495 * @param attributes These are the new attribute <B STYLE='color: red;'>key-value</B> pairs to 496 * be inserted. 497 * 498 * @param defaultQuote <EMBED CLASS='external-html' DATA-FILE-ID=TN_SET_AV2_DQ_PARAM> 499 * @throws InnerTagKeyException <EMBED CLASS='external-html' DATA-FILE-ID=IT_KEY_EX_PROP_TN> 500 * 501 * @throws QuotesException if there are "quotes within quotes" problems, due to the 502 * <B STYLE='color: red;'>values</B> of the <B STYLE='color: red;'>key-value</B> pairs. 503 * 504 * @throws HTMLTokException if an invalid HTML 4 or 5 token is not present 505 * <B>({@code CASE_INSENSITIVE})</B> 506 * 507 * @throws ClosingTagNodeException <EMBED CLASS='external-html' DATA-FILE-ID=CTNEX> 508 * 509 * @return <EMBED CLASS='external-html' DATA-FILE-ID=TN_SET_AV2_RET> 510 * @see ClosingTagNodeException#check(TagNode) 511 * @see #setAV(String, String, SD) 512 * @see #isClosing 513 */ 514 @LinkJavaSource(handle="GetSetAttr", name="setAV", paramCount=3) 515 public TagNode setAV(Properties attributes, SD defaultQuote) 516 { return GetSetAttr.setAV(this, attributes, defaultQuote); } 517 518 /** 519 * <EMBED CLASS='external-html' DATA-FILE-ID=TN_APD_AV_DESC> 520 * @param attribute <EMBED CLASS=external-html DATA-FILE-ID=TN_APD_AV_P_ATTR> 521 * @param appendStr <EMBED CLASS=external-html DATA-FILE-ID=TN_APD_AV_P_APDSTR> 522 * @param startOrEnd <EMBED CLASS=external-html DATA-FILE-ID=TN_APD_AV_P_S_OR_E> 523 * @param quote <EMBED CLASS=external-html DATA-FILE-ID=TGND_QUOTE_EXPL> 524 * <EMBED CLASS=external-html DATA-FILE-ID=TN_APD_AV_P_QXTRA> 525 * @return <EMBED CLASS=external-html DATA-FILE-ID=TN_APD_AV_RET> 526 * @see #AV(String) 527 * @see #setAV(String, String, SD) 528 * @see ClosingTagNodeException#check(TagNode) 529 * @throws ClosingTagNodeException <EMBED CLASS='external-html' DATA-FILE-ID=CTNEX> 530 * 531 * @throws QuotesException The <B><A HREF=#QUOTEEX>rules</A></B> for quotation usage apply 532 * here too, and see that explanation for how how this exception could be thrown. 533 */ 534 @LinkJavaSource(handle="GetSetAttr", name="appendToAV") 535 public TagNode appendToAV(String attribute, String appendStr, boolean startOrEnd, SD quote) 536 { return GetSetAttr.appendToAV(this, attribute, appendStr, startOrEnd, quote); } 537 538 539 // ******************************************************************************************** 540 // ******************************************************************************************** 541 // Attribute Removal Operations 542 // ******************************************************************************************** 543 // ******************************************************************************************** 544 545 546 /** 547 * Convenience Method. 548 * <BR />See Documentation: {@link #removeAttributes(String[])} 549 */ 550 @LinkJavaSource(handle="RemoveAttributes", name="removeAttributes") 551 public TagNode remove(String attributeName) 552 { 553 return RemoveAttributes.removeAttributes 554 (this, (String attr) -> ! attr.equalsIgnoreCase(attributeName)); 555 } 556 557 /** 558 * <EMBED CLASS='external-html' DATA-FILE-ID=TN_REM_ATTR_DESC> 559 * @param attributes <EMBED CLASS='external-html' DATA-FILE-ID=TN_REM_ATTR_ATTR> 560 * @return <EMBED CLASS='external-html' DATA-FILE-ID=TN_REM_ATTR_RET> 561 * @throws ClosingTagNodeException <EMBED CLASS='external-html' DATA-FILE-ID=CTNEX> 562 * @see ClosingTagNodeException#check(TagNode) 563 */ 564 @LinkJavaSource(handle="RemoveAttributes", name="removeAttributes") 565 public TagNode removeAttributes(String... attributes) 566 { 567 return RemoveAttributes.removeAttributes 568 (this, (String attr) -> StrCmpr.equalsNAND_CI(attr, attributes)); 569 } 570 571 /** 572 * Filter's attributes using an Attribute-<B STYLE='color:red'>Name</B> 573 * {@code String-Predicate} 574 * 575 * @param attrNameTest Any Java {@code String-Predicate}. It will be used to test whether or 576 * not to keep or filter/reject an attribute from {@code 'this' TagNode}. 577 * 578 * <BR /><BR /><B STYLE='color: red;'>NOTE:</B> Like all filter-{@code Predicate's}, this 579 * test's expected behavior is such that it should return {@code TRUE} when it would like to 580 * keep an attribute having a particular <B STYLE='color: red;'>name</B>, and return 581 * {@code FALSE} when it would like to see the attribute removed from the HTML Tag. 582 * 583 * @return Removes any Attributes whoe <B STYLE='color: red;'>name</B> as per the rules of the 584 * User-Provided {@code String-Predicate} parameter {@code 'attrNameTest'}. As with all 585 * {@code TagNode} modification operations, if any changes are, indeed, made to a new instance 586 * of {@code TagNode} will be created and returned. 587 */ 588 @LinkJavaSource(handle="RemoveAttributes", name="removeAttributes") 589 public TagNode removeAttributes(Predicate<String> attrNameTest) 590 { return RemoveAttributes.removeAttributes(this, attrNameTest); } 591 592 /** 593 * <EMBED CLASS='external-html' DATA-FILE-ID=TN_REM_ALL_AV_DESC> 594 * @return <EMBED CLASS=external-html DATA-FILE-ID=TN_REM_ALL_AV_RET> 595 * @throws ClosingTagNodeException <EMBED CLASS=external-html DATA-FILE-ID=CTNEX> 596 * @see ClosingTagNodeException#check(TagNode) 597 * @see #getInstance(String, TC) 598 * @see TC#OpeningTags 599 */ 600 public TagNode removeAllAV() 601 { 602 ClosingTagNodeException.check(this); 603 604 // NOTE: We *CANNOT* use the 'tok' field to instantiate the TagNode here, because the 'tok' 605 // String-field is *ALWAYS* guaranteed to be in a lower-case format. The 'str' 606 // String-field, however uses the original case that was found on the HTML Document by the 607 // parser (or in the Constructor-Parameters that were passed to construct 'this' instance 608 // of TagNode. 609 610 return getInstance(this.str.substring(1, 1 + tok.length()), TC.OpeningTags); 611 } 612 613 614 // ******************************************************************************************** 615 // ******************************************************************************************** 616 // Retrieve all attributes 617 // ******************************************************************************************** 618 // ******************************************************************************************** 619 620 621 /** 622 * Convenience Method. 623 * <BR />See Documentation: {@link #allAV(boolean, boolean)} 624 * <BR />Attribute-<B STYLE='color: red;'>names</B> will be in lower-case. 625 */ 626 @LinkJavaSource(handle="RetrieveAllAttr", name="allAV") 627 public Properties allAV() 628 { return RetrieveAllAttr.allAV(this, false, false); } 629 630 /** 631 * <EMBED CLASS='external-html' DATA-FILE-ID=TN_ALL_AV_DESC> 632 * @param keepQuotes <EMBED CLASS='external-html' DATA-FILE-ID=TN_ALL_AV_KQ_PARAM> 633 * @param preserveKeysCase <EMBED CLASS='external-html' DATA-FILE-ID=TN_ALL_AV_PKC_PARAM> 634 * <EMBED CLASS='external-html' DATA-FILE-ID=TAGNODE_PRESERVE_C> 635 * @return <EMBED CLASS='external-html' DATA-FILE-ID=TN_ALL_AV_RET> 636 * @see StringParse#ifQuotesStripQuotes(String) 637 */ 638 @LinkJavaSource(handle="RetrieveAllAttr", name="allAV") 639 public Properties allAV(boolean keepQuotes, boolean preserveKeysCase) 640 { return RetrieveAllAttr.allAV(this, keepQuotes, preserveKeysCase); } 641 642 /** 643 * Convenience Method. 644 * <BR />See Documentation: {@link #allAN(boolean, boolean)} 645 * <BR />Attribute-<B STYLE='color: red;'>names</B> will be in lower-case 646 */ 647 @LinkJavaSource(handle="RetrieveAllAttr", name="allAN") 648 public Stream<String> allAN() 649 { return RetrieveAllAttr.allAN(this, false, false); } 650 651 /** 652 * This method will only return a list of attribute-<B STYLE='color: red;'>names</B>. The 653 * attribute-<B STYLE="color: red">values</B> shall <B>NOT</B> be included in the result. The 654 * {@code String's} returned can have their "case-preserved" by passing {@code TRUE} to the 655 * input boolean parameter {@code 'preserveKeysCase'}. 656 * 657 * @param preserveKeysCase If this is parameter receives {@code TRUE} then the case of the 658 * attribute-<B STYLE='color: red;'>names</B> shall be preserved. 659 * 660 * <EMBED CLASS='external-html' DATA-FILE-ID=TAGNODE_PRESERVE_C> 661 * 662 * @param includeKeyOnlyAttributes When this parameter receives {@code TRUE}, then any 663 * "Boolean Attributes" or "Key-Only, No-Value-Assignment" Inner-Tags will <B>ALSO</B> be 664 * included in the {@code Stream<String>} returned by this method. 665 * 666 * @return an instance of {@code Stream<String>} containing all 667 * attribute-<B STYLE='color: red;'>names</B> identified in {@code 'this'} instance of 668 * {@code TagNode}. A {@code java.util.stream.Stream} is used because it's contents can easily 669 * be converted to just about any data-type. 670 * 671 * <EMBED CLASS='external-html' DATA-FILE-ID=STRMCNVT> 672 * 673 * <BR /><B>NOTE:</B> This method shall never return {@code 'null'} - even if there are no 674 * attribute <B STYLE='color: red;'>key-value</B> pairs contained by {@code 'this' TagNode}. 675 * If there are strictly zero attributes, an empty {@code Stream} shall be returned, instead. 676 * 677 * @see #allKeyOnlyAttributes(boolean) 678 * @see #allAN() 679 */ 680 @LinkJavaSource(handle="RetrieveAllAttr", name="allAN") 681 public Stream<String> allAN(boolean preserveKeysCase, boolean includeKeyOnlyAttributes) 682 { return RetrieveAllAttr.allAN(this, preserveKeysCase, includeKeyOnlyAttributes); } 683 684 685 // ******************************************************************************************** 686 // ******************************************************************************************** 687 // Key only attributes 688 // ******************************************************************************************** 689 // ******************************************************************************************** 690 691 692 /** 693 * <EMBED CLASS='external-html' DATA-FILE-ID=TN_ALL_KOA_DESC> 694 * @param preserveKeysCase <EMBED CLASS='external-html' DATA-FILE-ID=TN_ALL_KOA_PKC> 695 * <EMBED CLASS='external-html' DATA-FILE-ID=TAGNODE_PRESERVE_C> 696 * @return <EMBED CLASS='external-html' DATA-FILE-ID=TN_ALL_KOA_RET> 697 * <EMBED CLASS='external-html' DATA-FILE-ID=STRMCNVT> 698 */ 699 @LinkJavaSource(handle="KeyOnlyAttributes", name="allKeyOnlyAttributes") 700 public Stream<String> allKeyOnlyAttributes(boolean preserveKeysCase) 701 { return KeyOnlyAttributes.allKeyOnlyAttributes(this, preserveKeysCase); } 702 703 /** 704 * <EMBED CLASS='external-html' DATA-FILE-ID=TN_HAS_KOA_DESC> 705 * @param keyOnlyAttribute <EMBED CLASS='external-html' DATA-FILE-ID=TN_HAS_KOA_KOA> 706 * @return <EMBED CLASS='external-html' DATA-FILE-ID=TN_HAS_KOA_RET> 707 * @throws IllegalArgumentException <EMBED CLASS='external-html' DATA-FILE-ID=TN_HAS_KOA_IAEX> 708 */ 709 @LinkJavaSource(handle="KeyOnlyAttributes", name="hasKeyOnlyAttribute") 710 public boolean hasKeyOnlyAttribute(String keyOnlyAttribute) 711 { return KeyOnlyAttributes.hasKeyOnlyAttribute(this, keyOnlyAttribute); } 712 713 714 // ******************************************************************************************** 715 // ******************************************************************************************** 716 // testAV 717 // ******************************************************************************************** 718 // ******************************************************************************************** 719 720 721 /** 722 * Convenience Method. 723 * <BR />See Documentation: {@link #testAV(String, Predicate)} 724 * <BR />Passes: {@code String.equalsIgnoreCase(attributeValue)} to the Test-{@code Predicate} 725 */ 726 @LinkJavaSource(handle="HasAndTest", name="testAV") 727 @LinkJavaSource(handle="AttrRegEx", entity=FIELD, name="KEY_VALUE_REGEX") 728 public boolean testAV(String attributeName, String attributeValue) 729 { 730 return HasAndTest.testAV 731 (this, attributeName, (String s) -> s.equalsIgnoreCase(attributeValue)); 732 } 733 734 /** 735 * Convenience Method. 736 * <BR />See Documentation: {@link #testAV(String, Predicate)} 737 * <BR />Passes: {@code attributeValueTest.asPredicate()} to the Test-{@code Predicate} 738 */ 739 @LinkJavaSource(handle="HasAndTest", name="testAV") 740 @LinkJavaSource(handle="AttrRegEx", entity=FIELD, name="KEY_VALUE_REGEX") 741 public boolean testAV(String attributeName, Pattern attributeValueTest) 742 { return HasAndTest.testAV(this, attributeName, attributeValueTest.asPredicate()); } 743 744 /** 745 * Convenience Method. 746 * <BR />See Documentation: {@link #testAV(String, Predicate)} 747 * <BR />Passes: {@link TextComparitor#test(String, String[])} to the Test-{@code Predicate} 748 */ 749 @LinkJavaSource(handle="HasAndTest", name="testAV") 750 @LinkJavaSource(handle="AttrRegEx", entity=FIELD, name="KEY_VALUE_REGEX") 751 public boolean testAV 752 (String attributeName, TextComparitor attributeValueTester, String... compareStrs) 753 { 754 return HasAndTest.testAV 755 (this, attributeName, (String s) -> attributeValueTester.test(s, compareStrs)); 756 } 757 758 /** 759 * <EMBED CLASS='external-html' DATA-FILE-ID=TN_TEST_AV_DESC> 760 * @param attributeName <EMBED CLASS='external-html' DATA-FILE-ID=TN_TEST_AV_PARAM> 761 * @param attributeValueTest Any {@code java.util.function.Predicate<String>} 762 * @return <EMBED CLASS='external-html' DATA-FILE-ID=TN_TEST_AV_RET> 763 * @see StringParse#ifQuotesStripQuotes(String) 764 */ 765 @LinkJavaSource(handle="HasAndTest", name="testAV") 766 @LinkJavaSource(handle="AttrRegEx", entity=FIELD, name="KEY_VALUE_REGEX") 767 public boolean testAV(String attributeName, Predicate<String> attributeValueTest) 768 { return HasAndTest.testAV(this, attributeName, attributeValueTest); } 769 770 771 // ******************************************************************************************** 772 // ******************************************************************************************** 773 // has-attribute boolean-logic methods 774 // ******************************************************************************************** 775 // ******************************************************************************************** 776 777 778 /** 779 * Convenience Method. 780 * <BR />See Documentation: {@link #hasXOR(boolean, String...)} 781 * <BR />Passes: AND Boolean Logic 782 * <BR />Checks that <B STYLE='color: red;'><I>all</I></B> Attributes are found 783 */ 784 @LinkJavaSource(handle="HasAndTest", name="hasLogicOp") 785 @LinkJavaSource(handle="AttrRegEx", entity=FIELD, name="KEY_VALUE_REGEX") 786 public boolean hasAND(boolean checkAttributeStringsForErrors, String... attributes) 787 { 788 // First-Function: Tells the logic to *IGNORE* intermediate matches (returns NULL) 789 // (This is *AND*, so wait until all attributes have been found, or at 790 // the very least all tags in the element tested, and failed. 791 // 792 // Second-Function: At the End of the Loops, all Attributes have either been found, or 793 // at least all attributes in 'this' tag have been tested. Note that the 794 // first-function is only called on a MATCH, and that 'AND' requires to 795 // defer a response until all attributes have been tested.. Here, simply 796 // RETURN WHETHER OR NOT the MATCH-COUNT equals the number of matches in 797 // the user-provided String-array. 798 799 return HasAndTest.hasLogicOp( 800 this, 801 checkAttributeStringsForErrors, 802 (int matchCount) -> null, 803 (int matchCount) -> (matchCount == attributes.length), 804 attributes 805 ); 806 } 807 808 /** 809 * Convenience Method. 810 * <BR />See Documentation: {@link #hasXOR(boolean, String...)} 811 * <BR />Passes: OR Boolean Logic 812 * <BR />Checks that <B STYLE='color: red;'><I>at least one</I></B> of the Attributes match 813 */ 814 @LinkJavaSource(handle="HasAndTest", name="hasLogicOp") 815 @LinkJavaSource(handle="AttrRegEx", entity=FIELD, name="KEY_VALUE_REGEX") 816 public boolean hasOR(boolean checkAttributeStringsForErrors, String... attributes) 817 { 818 // First-Function: Tells the logic to return TRUE on any match IMMEDIATELY 819 // 820 // Second-Function: At the End of the Loops, all Attributes have been tested. SINCE the 821 // previous function returns on match immediately, AND SINCE this is an 822 // OR, therefore FALSE must be returned (since there were no matches!) 823 824 return HasAndTest.hasLogicOp( 825 this, 826 checkAttributeStringsForErrors, 827 (int matchCount) -> true, 828 (int matchCount) -> false, 829 attributes 830 ); 831 } 832 833 /** 834 * Convenience Method. 835 * <BR />See Documentation: {@link #hasXOR(boolean, String...)} 836 * <BR />Passes: NAND Boolean Logic 837 * <R />Checks that <B STYLE='color: red;'><I>none</I></B> of the Attributes match 838 */ 839 @LinkJavaSource(handle="HasAndTest", name="hasLogicOp") 840 @LinkJavaSource(handle="AttrRegEx", entity=FIELD, name="KEY_VALUE_REGEX") 841 public boolean hasNAND(boolean checkAttributeStringsForErrors, String... attributes) 842 { 843 // First-Function: Tells the logic to return FALSE on any match IMMEDIATELY 844 // 845 // Second-Function: At the End of the Loops, all Attributes have been tested. SINCE 846 // the previous function returns on match immediately, AND SINCE this is 847 // a NAND, therefore TRUE must be returned (since there were no matches!) 848 849 return HasAndTest.hasLogicOp( 850 this, 851 checkAttributeStringsForErrors, 852 (int matchCount) -> false, 853 (int matchCount) -> true, 854 attributes 855 ); 856 } 857 858 /** 859 * <BR />Passes: XOR Boolean Logic 860 * <BR />Checks that <B STYLE='color: red;'><I>precisely-one</I></B> Attribute is found 861 * <BR /><BR /><IMG SRC='doc-files/img/hasAND.png' CLASS=JDIMG ALT=Example> 862 * 863 * @param checkAttributeStringsForErrors 864 * <EMBED CLASS='external-html' DATA-FILE-ID=TAGNODE_HAS_BOOL> 865 * 866 * <BR /><BR /><B>NOTE:</B> If this method is passed a zero-length {@code String}-array to the 867 * {@code 'attributes'} parameter, this method shall exit immediately and return {@code FALSE}. 868 * 869 * @throws InnerTagKeyException If any of the {@code 'attributes'} are not valid HTML 870 * attributes, <I><B>and</B></I> the user has passed {@code TRUE} to parameter 871 * {@code checkAttributeStringsForErrors}. 872 * 873 * @throws NullPointerException If any of the {@code 'attributes'} are null. 874 * @throws ClosingTagNodeException <EMBED CLASS='external-html' DATA-FILE-ID=CTNEX> 875 * @throws IllegalArgumentException If the {@code 'attributes'} parameter has length zero. 876 * @see InnerTagKeyException#check(String[]) 877 */ 878 @LinkJavaSource(handle="HasAndTest", name="hasLogicOp") 879 @LinkJavaSource(handle="AttrRegEx", entity=FIELD, name="KEY_VALUE_REGEX") 880 public boolean hasXOR(boolean checkAttributeStringsForErrors, String... attributes) 881 { 882 // First-Function: Tells the logic to IGNORE the FIRST MATCH, and any matches afterwards 883 // should produce a FALSE result immediately 884 // (XOR means ==> one-and-only-one) 885 // 886 // Second-Function: At the End of the Loops, all Attributes have been tested. Just 887 // return whether or not the match-count is PRECISELY ONE. 888 889 return HasAndTest.hasLogicOp( 890 this, 891 checkAttributeStringsForErrors, 892 (int matchCount) -> (matchCount == 1) ? null : false, 893 (int matchCount) -> (matchCount == 1), 894 attributes 895 ); 896 } 897 898 899 // ******************************************************************************************** 900 // ******************************************************************************************** 901 // has methods - extended, variable attribute-names 902 // ******************************************************************************************** 903 // ******************************************************************************************** 904 905 906 /** 907 * Convenience Method. 908 * <BR />See Documentation: {@link #has(Predicate)} 909 * <BR />Passes: {@code String.equalsIgnoreCase(attributeName)} as the test-{@code Predicate} 910 */ 911 @LinkJavaSource(handle="HasAndTest", name="has") 912 @LinkJavaSource(handle="AttrRegEx", entity=FIELD, name="KEY_VALUE_REGEX") 913 public boolean has(String attributeName) 914 { return HasAndTest.has(this, (String s) -> s.equalsIgnoreCase(attributeName)); } 915 916 /** 917 * Convenience Method. 918 * <BR />See Documentation: {@link #has(Predicate)} 919 * <BR />Passes: {@code Pattern.asPredicate()} 920 */ 921 @LinkJavaSource(handle="HasAndTest", name="has") 922 @LinkJavaSource(handle="AttrRegEx", entity=FIELD, name="KEY_VALUE_REGEX") 923 public boolean has(Pattern attributeNameRegExTest) 924 { return HasAndTest.has(this, attributeNameRegExTest.asPredicate()); } 925 926 /** 927 * Convenience Method. 928 * <BR />See Documentation: {@link #has(Predicate)} 929 * <BR />Passes: {@link TextComparitor#test(String, String[])} as the test-{@code Predicate} 930 */ 931 @LinkJavaSource(handle="HasAndTest", name="has") 932 @LinkJavaSource(handle="AttrRegEx", entity=FIELD, name="KEY_VALUE_REGEX") 933 public boolean has(TextComparitor tc, String... compareStrs) 934 { return HasAndTest.has(this, (String s) -> tc.test(s, compareStrs)); } 935 936 /** 937 * <EMBED CLASS='external-html' DATA-FILE-ID=TN_HAS_DESC2> 938 * <EMBED CLASS='external-html' DATA-FILE-ID=TAGNODE_HAS_NOTE> 939 * @param attributeNameTest <EMBED CLASS='external-html' DATA-FILE-ID=TN_HAS_ANT> 940 * @return <EMBED CLASS='external-html' DATA-FILE-ID=TN_HAS_RET2> 941 * @see StrFilter 942 */ 943 @LinkJavaSource(handle="HasAndTest", name="has") 944 @LinkJavaSource(handle="AttrRegEx", entity=FIELD, name="KEY_VALUE_REGEX") 945 public boolean has(Predicate<String> attributeNameTest) 946 { return HasAndTest.has(this, attributeNameTest); } 947 948 949 // ******************************************************************************************** 950 // ******************************************************************************************** 951 // hasValue(...) methods 952 // ******************************************************************************************** 953 // ******************************************************************************************** 954 955 956 /** 957 * Convenience Method. 958 * <BR />See Documentation: {@link #hasValue(Predicate, boolean, boolean)} 959 * <BR />Passes: {@code String.equals(attributeValue)} as the test-{@code Predicate} 960 */ 961 @LinkJavaSource(handle="HasAndTest", name="hasValue") 962 @LinkJavaSource(handle="AttrRegEx", entity=FIELD, name="KEY_VALUE_REGEX") 963 public Map.Entry<String, String> hasValue 964 (String attributeValue, boolean retainQuotes, boolean preserveKeysCase) 965 { 966 return HasAndTest.hasValue 967 (this, (String s) -> attributeValue.equals(s), retainQuotes, preserveKeysCase); 968 } 969 970 /** 971 * Convenience Method. 972 * <BR />See Documentation: {@link #hasValue(Predicate, boolean, boolean)} 973 * <BR />Passes: {@code attributeValueRegExTest.asPredicate()} 974 */ 975 @LinkJavaSource(handle="HasAndTest", name="hasValue") 976 @LinkJavaSource(handle="AttrRegEx", entity=FIELD, name="KEY_VALUE_REGEX") 977 public Map.Entry<String, String> hasValue 978 (Pattern attributeValueRegExTest, boolean retainQuotes, boolean preserveKeysCase) 979 { 980 return HasAndTest.hasValue 981 (this, attributeValueRegExTest.asPredicate(), retainQuotes, preserveKeysCase); 982 } 983 984 /** 985 * Convenience Method. 986 * <BR />See Documentation: {@link #hasValue(Predicate, boolean, boolean)} 987 * <BR />Passes: {@link TextComparitor#test(String, String[])} as the test-{@code Predicate} 988 */ 989 @LinkJavaSource(handle="HasAndTest", name="hasValue") 990 @LinkJavaSource(handle="AttrRegEx", entity=FIELD, name="KEY_VALUE_REGEX") 991 public Map.Entry<String, String> hasValue( 992 boolean retainQuotes, boolean preserveKeysCase, TextComparitor attributeValueTester, 993 String... compareStrs 994 ) 995 { 996 return HasAndTest.hasValue( 997 this, 998 (String s) -> attributeValueTester.test(s, compareStrs), 999 retainQuotes, 1000 preserveKeysCase 1001 ); 1002 } 1003 1004 /** 1005 * <EMBED CLASS='external-html' DATA-FILE-ID=TN_HASVAL_DESC2> 1006 * <EMBED CLASS='external-html' DATA-FILE-ID=TN_HASVAL_DNOTE> 1007 * @param attributeValueTest <EMBED CLASS='external-html' DATA-FILE-ID=TN_HASVAL_AVT> 1008 * @param retainQuotes <EMBED CLASS='external-html' DATA-FILE-ID=TN_HASVAL_RQ> 1009 * @param preserveKeysCase <EMBED CLASS='external-html' DATA-FILE-ID=TN_HASVAL_PKC> 1010 * <EMBED CLASS='external-html' DATA-FILE-ID=TAGNODE_PRESERVE_C> 1011 * @return <EMBED CLASS='external-html' DATA-FILE-ID=TN_HASVAL_RET2> 1012 * @see StrFilter 1013 */ 1014 @LinkJavaSource(handle="HasAndTest", name="hasValue") 1015 @LinkJavaSource(handle="AttrRegEx", entity=FIELD, name="KEY_VALUE_REGEX") 1016 public Map.Entry<String, String> hasValue 1017 (Predicate<String> attributeValueTest, boolean retainQuotes, boolean preserveKeysCase) 1018 { return HasAndTest.hasValue(this, attributeValueTest, retainQuotes, preserveKeysCase); } 1019 1020 1021 // ******************************************************************************************** 1022 // ******************************************************************************************** 1023 // getInstance() 1024 // ******************************************************************************************** 1025 // ******************************************************************************************** 1026 1027 1028 /** 1029 * <EMBED CLASS='external-html' DATA-FILE-ID=TN_GETINST_DESC> 1030 * @param tok Any valid HTML tag. 1031 * @param openOrClosed <EMBED CLASS='external-html' DATA-FILE-ID=TN_GETINST_OOC> 1032 * @return An instance of this class 1033 * 1034 * @throws IllegalArgumentException If parameter {@code TC openOrClose} is {@code null} or 1035 * {@code TC.Both} 1036 * 1037 * @throws HTMLTokException If the parameter {@code String tok} is not a valid HTML-tag 1038 * 1039 * @throws SingletonException If the token requested is a {@code singleton} (self-closing) tag, 1040 * but the Tag-Criteria {@code 'TC'} parameter is requesting a closing-version of the tag. 1041 * 1042 * @see HTMLTags#hasTag(String, TC) 1043 * @see HTMLTags#isSingleton(String) 1044 */ 1045 public static TagNode getInstance(String tok, TC openOrClosed) 1046 { 1047 if (openOrClosed == null) 1048 throw new NullPointerException("The value of openOrClosed cannot be null."); 1049 1050 if (openOrClosed == TC.Both) 1051 throw new IllegalArgumentException("The value of openOrClosed cannot be TC.Both."); 1052 1053 if (HTMLTags.isSingleton(tok) && (openOrClosed == TC.ClosingTags)) 1054 1055 throw new SingletonException( 1056 "The value of openOrClosed is TC.ClosingTags, but unfortunately you have asked " + 1057 "for a [" + tok + "] HTML element, which is a singleton element, and therefore " + 1058 "cannot have a closing-tag instance." 1059 ); 1060 1061 TagNode ret = HTMLTags.hasTag(tok, openOrClosed); 1062 1063 if (ret == null) 1064 throw new HTMLTokException 1065 ("The HTML-Tag provided isn't valid!\ntok: " + tok + "\nTC: " + openOrClosed); 1066 1067 return ret; 1068 } 1069 1070 1071 // ******************************************************************************************** 1072 // ******************************************************************************************** 1073 // Methods for "CSS Classes" 1074 // ******************************************************************************************** 1075 // ******************************************************************************************** 1076 1077 1078 /** 1079 * Convenience Method. 1080 * <BR />Invokes: {@link #cssClasses()} 1081 * <BR />Catches-Exception 1082 */ 1083 public Stream<String> cssClassesNOCSE() 1084 { try { return cssClasses(); } catch (CSSStrException e) { return Stream.empty(); } } 1085 1086 /** 1087 * <EMBED CLASS='external-html' DATA-FILE-ID=TN_CSS_CL_DESC> 1088 * @return <EMBED CLASS='external-html' DATA-FILE-ID=TN_CSS_CL_RET> 1089 * <EMBED CLASS='external-html' DATA-FILE-ID=STRMCNVT> 1090 * @throws CSSStrException <EMBED CLASS='external-html' DATA-FILE-ID=TN_CSS_CL_CSSSE> 1091 * @see #cssClasses() 1092 * @see #AV(String) 1093 * @see StringParse#WHITE_SPACE_REGEX 1094 * @see CSSStrException#check(Stream) 1095 */ 1096 @LinkJavaSource(handle="ClassIDStyle", name="cssClasses") 1097 public Stream<String> cssClasses() 1098 { return ClassIDStyle.cssClasses(this); } 1099 1100 /** 1101 * <EMBED CLASS='external-html' DATA-FILE-ID=TN_SET_CSS_CL_DESC> 1102 * @param quote <EMBED CLASS='external-html' DATA-FILE-ID=TGND_QUOTE_EXPL> 1103 * @param appendOrClobber <EMBED CLASS='external-html' DATA-FILE-ID=TN_SET_CSS_CL_AOC> 1104 * @param cssClasses <EMBED CLASS='external-html' DATA-FILE-ID=TN_SET_CSS_CL_CCL> 1105 * @return <EMBED CLASS='external-html' DATA-FILE-ID=TN_SET_CSS_CL_RET> 1106 * 1107 * @throws CSSStrException This exception shall throw if any of the {@code 'cssClasses'} in the 1108 * var-args {@code String...} parameter do not meet the HTML 5 CSS {@code Class} naming rules. 1109 * 1110 * @throws ClosingTagNodeException <EMBED CLASS=external-html DATA-FILE-ID=CTNEX> 1111 * @throws QuotesException <EMBED CLASS=external-html DATA-FILE-ID=TN_SET_CSS_CL_QEX> 1112 * @see CSSStrException#check(String[]) 1113 * @see CSSStrException#VALID_CSS_CLASS_OR_NAME_TOKEN 1114 * @see #appendToAV(String, String, boolean, SD) 1115 * @see #setAV(String, String, SD) 1116 */ 1117 @LinkJavaSource(handle="ClassIDStyle", name="setCSSClasses") 1118 public TagNode setCSSClasses(SD quote, boolean appendOrClobber, String... cssClasses) 1119 { return ClassIDStyle.setCSSClasses(this, quote, appendOrClobber, cssClasses); } 1120 1121 /** 1122 * <EMBED CLASS='external-html' DATA-FILE-ID=TN_APD_CSS_CL_DESC> 1123 * @param cssClass This is the CSS-{@code Class} name that is being inserted into 1124 * {@code 'this'} instance of {@code TagNode} 1125 * 1126 * @param quote <EMBED CLASS=external-html DATA-FILE-ID=TGND_QUOTE_EXPL> 1127 * @return A new {@code TagNode} with updated CSS {@code Class} Name(s) 1128 * @throws CSSStrException <EMBED CLASS=external-html DATA-FILE-ID=TN_APD_CSS_CL_CSSSE> 1129 * @throws ClosingTagNodeException <EMBED CLASS=external-html DATA-FILE-ID=CTNEX> 1130 * @throws QuotesException <EMBED CLASS=external-html DATA-FILE-ID=TN_APD_CSS_CL_QEX> 1131 * @see CSSStrException#check(String[]) 1132 * @see #setAV(String, String, SD) 1133 * @see #appendToAV(String, String, boolean, SD) 1134 */ 1135 @LinkJavaSource(handle="ClassIDStyle", name="appendCSSClass") 1136 public TagNode appendCSSClass(String cssClass, SD quote) 1137 { return ClassIDStyle.appendCSSClass(this, cssClass, quote); } 1138 1139 1140 // ******************************************************************************************** 1141 // ******************************************************************************************** 1142 // Methods for "CSS Style" 1143 // ******************************************************************************************** 1144 // ******************************************************************************************** 1145 1146 1147 /** 1148 * <EMBED CLASS='external-html' DATA-FILE-ID=TN_CSS_STYLE_DESC> 1149 * <EMBED CLASS='external-html' DATA-FILE-ID=TN_CSS_STYLE_DESCEX> 1150 * @return <EMBED CLASS='external-html' DATA-FILE-ID=TN_CSS_STYLE_RET> 1151 */ 1152 @LinkJavaSource(handle="ClassIDStyle", name="cssStyle") 1153 @LinkJavaSource(handle="AttrRegEx", entity=FIELD, name="CSS_INLINE_STYLE_REGEX") 1154 public Properties cssStyle() 1155 { return ClassIDStyle.cssStyle(this); } 1156 1157 /** 1158 * <EMBED CLASS='external-html' DATA-FILE-ID=TN_SET_CSS_STY_DESC> 1159 * @param p <EMBED CLASS=external-html DATA-FILE-ID=TN_SET_CSS_STY_P> 1160 * @param quote <EMBED CLASS=external-html DATA-FILE-ID=TGND_QUOTE_EXPL> 1161 * @param appendOrClobber <EMBED CLASS=external-html DATA-FILE-ID=TN_SET_CSS_STY_AOC> 1162 * @return <EMBED CLASS=external-html DATA-FILE-ID=TN_SET_CSS_STY_RET> 1163 * @throws ClosingTagNodeException <EMBED CLASS=external-html DATA-FILE-ID=CTNEX> 1164 * @throws CSSStrException If there is an invalid CSS Style Property Name. 1165 * 1166 * @throws QuotesException If the style-element's quotation marks are incompatible with any 1167 * and all quotation marks employed by the style-element definitions. 1168 * 1169 * @see CSSStrException#VALID_CSS_CLASS_OR_NAME_TOKEN 1170 * @see #appendToAV(String, String, boolean, SD) 1171 * @see #setAV(String, String, SD) 1172 */ 1173 @LinkJavaSource(handle="ClassIDStyle", name="setCSSStyle") 1174 public TagNode setCSSStyle(Properties p, SD quote, boolean appendOrClobber) 1175 { return ClassIDStyle.setCSSStyle(this, p, quote, appendOrClobber); } 1176 1177 1178 // ******************************************************************************************** 1179 // ******************************************************************************************** 1180 // Methods for "CSS ID" 1181 // ******************************************************************************************** 1182 // ******************************************************************************************** 1183 1184 1185 /** 1186 * Convenience Method. 1187 * <BR />Invokes: {@link #AV(String)} 1188 * <BR />Passes: {@code String "id"}, the CSS-ID attribute-<B STYLE='color: red;'>name</B> 1189 */ 1190 public String getID() 1191 { 1192 String id = AV("ID"); 1193 return (id == null) ? null : id.trim(); 1194 } 1195 1196 /** 1197 * This merely sets the current CSS {@code 'ID'} Attribute <B STYLE='color: red;'>Value</B>. 1198 * 1199 * @param id This is the new CSS {@code 'ID'} attribute-<B STYLE='color: red;'>value</B> that 1200 * the user would like applied to {@code 'this'} instance of {@code TagNode}. 1201 * 1202 * @param quote <EMBED CLASS='external-html' DATA-FILE-ID=TGND_QUOTE_EXPL> 1203 * 1204 * @return Returns a new instance of {@code TagNode} that has an updated {@code 'ID'} 1205 * attribute-<B STYLE='color: red;'>value</B>. 1206 * 1207 * @throws IllegalArgumentException This exception shall throw if an invalid 1208 * {@code String}-token has been passed to parameter {@code 'id'}. 1209 * 1210 * <BR /><BR /><B>BYPASS NOTE:</B> If the user would like to bypass this exception-check, for 1211 * instance because he / she is using a CSS Pre-Processor, then applying the general-purpose 1212 * method {@code TagNode.setAV("id", "some-new-id")} ought to suffice. This other method will 1213 * not apply validity checking, beyond scanning for the usual "quotes-within-quotes" problems, 1214 * which is always disallowed. 1215 * 1216 * @throws ClosingTagNodeException <EMBED CLASS='external-html' DATA-FILE-ID=CTNEX> 1217 * 1218 * @see CSSStrException#VALID_CSS_CLASS_OR_NAME_TOKEN 1219 * @see #setAV(String, String, SD) 1220 */ 1221 public TagNode setID(String id, SD quote) 1222 { 1223 if (! CSSStrException.VALID_CSS_CLASS_OR_NAME_TOKEN_PRED.test(id)) 1224 1225 throw new IllegalArgumentException( 1226 "The id parameter provide: [" + id + "], does not conform to the standard CSS " + 1227 "Names.\nEither try using the generic TagNode.setAV(\"id\", yourNewId, quote); " + 1228 "method to bypass this check, or change the value passed to the 'id' parameter " + 1229 "here." 1230 ); 1231 1232 return setAV("id", id.trim(), quote); 1233 } 1234 1235 1236 // ******************************************************************************************** 1237 // ******************************************************************************************** 1238 // Attributes that begin with "data-..." 1239 // ******************************************************************************************** 1240 // ******************************************************************************************** 1241 1242 1243 /** 1244 * Convenience Method. 1245 * <BR />See Documentation: {@link #AV(String)} 1246 * <BR />Passes: {@code "data-"} prepended to parameter {@code 'dataName'} for the 1247 * attribute-<B STYLE='color:red'>name</B> 1248 */ 1249 @LinkJavaSource(handle="GetSetAttr", name="AV") 1250 public String dataAV(String dataName) 1251 { return GetSetAttr.AV(this, "data-" + dataName, false); } 1252 1253 /** 1254 * <EMBED CLASS='external-html' DATA-FILE-ID=TN_REM_DATTR_DESC> 1255 * @return <EMBED CLASS=external-html DATA-FILE-ID=TN_REM_DATTR_RET> 1256 * @throws ClosingTagNodeException <EMBED CLASS=external-html DATA-FILE-ID=TN_REM_DATTR_CTNEX> 1257 */ 1258 @LinkJavaSource(handle="RemoveAttributes", name="removeAttributes") 1259 public TagNode removeDataAttributes() 1260 { 1261 return RemoveAttributes.removeAttributes 1262 (this, (String attr) -> ! StrCmpr.startsWithIgnoreCase(attr, "data-") ); 1263 } 1264 1265 /** 1266 * Convenience Method. 1267 * <BR />See Documentation: {@link #getDataAV(boolean)} 1268 * <BR />Attribute-<B STYLE='color: red;'>names</B> will be in lower-case 1269 */ 1270 @LinkJavaSource(handle="DataAttributes", name="getDataAV") 1271 @LinkJavaSource(handle="AttrRegEx", entity=FIELD, name="DATA_ATTRIBUTE_REGEX") 1272 public Properties getDataAV() 1273 { return DataAttributes.getDataAV(this, false); } 1274 1275 /** 1276 * <EMBED CLASS='external-html' DATA-FILE-ID=TN_GET_DATA_AV_DESC> 1277 * @param preserveKeysCase <EMBED CLASS='external-html' DATA-FILE-ID=TN_GET_DATA_AV_PAR> 1278 * <EMBED CLASS='external-html' DATA-FILE-ID=TAGNODE_PRESERVE_C> 1279 * @return <EMBED CLASS='external-html' DATA-FILE-ID=TN_GET_DATA_AV_RET> 1280 */ 1281 @LinkJavaSource(handle="DataAttributes", name="getDataAV") 1282 @LinkJavaSource(handle="AttrRegEx", entity=FIELD, name="DATA_ATTRIBUTE_REGEX") 1283 public Properties getDataAV(boolean preserveKeysCase) 1284 { return DataAttributes.getDataAV(this, preserveKeysCase); } 1285 1286 /** 1287 * Convenience Method. 1288 * <BR />See Documentation: {@link #getDataAN(boolean)} 1289 * <BR />Attribute-<B STYLE='color: red;'>names</B> will be in lower-case 1290 */ 1291 public Stream<String> getDataAN() 1292 { return DataAttributes.getDataAN(this, false); } 1293 1294 /** 1295 * <EMBED CLASS='external-html' DATA-FILE-ID=TN_GET_DATA_AN_DESC> 1296 * @param preserveKeysCase <EMBED CLASS='external-html' DATA-FILE-ID=TN_GET_DATA_AN_PAR> 1297 * <EMBED CLASS='external-html' DATA-FILE-ID=TAGNODE_PRESERVE_C> 1298 * @return <EMBED CLASS='external-html' DATA-FILE-ID=TN_GET_DATA_AN_RET> 1299 * <EMBED CLASS='external-html' DATA-FILE-ID=STRMCNVT> 1300 */ 1301 @LinkJavaSource(handle="DataAttributes", name="getDataAN") 1302 @LinkJavaSource(handle="AttrRegEx", entity=FIELD, name="DATA_ATTRIBUTE_REGEX") 1303 public Stream<String> getDataAN(boolean preserveKeysCase) 1304 { return DataAttributes.getDataAN(this, preserveKeysCase); } 1305 1306 1307 // ******************************************************************************************** 1308 // ******************************************************************************************** 1309 // Java Methods 1310 // ******************************************************************************************** 1311 // ******************************************************************************************** 1312 1313 1314 /** 1315 * <EMBED CLASS='external-html' DATA-FILE-ID=TN_TOSTR_AV_DESC> 1316 * @return <EMBED CLASS='external-html' DATA-FILE-ID=TN_TOSTR_AV_RET> 1317 * @see HTMLNode#toString() 1318 */ 1319 @LinkJavaSource(handle="GeneralPurpose", name="toStringAV") 1320 public String toStringAV() 1321 { return GeneralPurpose.toStringAV(this); } 1322 1323 /** 1324 * Java's {@code interface Cloneable} requirements. This instantiates a new {@code TagNode} 1325 * with identical <SPAN STYLE='color: red;'>{@code String str}</SPAN> fields, and also 1326 * identical <SPAN STYLE='color: red;'>{@code boolean isClosing}</SPAN> and 1327 * <SPAN STYLE='color: red;'>{@code String tok}</SPAN> fields. 1328 * 1329 * @return A new {@code TagNode} whose internal fields are identical to this one. 1330 */ 1331 public TagNode clone() { return new TagNode(str); } 1332 1333 /** 1334 * <EMBED CLASS='external-html' DATA-FILE-ID=TN_COMPARETO_DESC> 1335 * @param n Any other {@code TagNode} to be compared to {@code 'this' TagNode} 1336 * @return An integer that fulfils Java's {@code Comparable} interface-method requirements. 1337 */ 1338 public int compareTo(TagNode n) 1339 { 1340 // Utilize the standard "String.compare(String)" method with the '.tok' string field. 1341 // All 'tok' fields are stored as lower-case strings. 1342 int compare1 = this.tok.compareTo(n.tok); 1343 1344 // Comparison #1 will be non-zero if the two TagNode's being compared had different 1345 // .tok fields 1346 if (compare1 != 0) return compare1; 1347 1348 // If the '.tok' fields were the same, use the 'isClosing' field for comparison instead. 1349 // This comparison will only be used if they are different. 1350 if (this.isClosing != n.isClosing) return (this.isClosing == false) ? -1 : 1; 1351 1352 // Finally try using the entire element '.str' String field, instead. 1353 return this.str.length() - n.str.length(); 1354 } 1355 1356 1357 // ******************************************************************************************** 1358 // ******************************************************************************************** 1359 // toUpperCase 1360 // ******************************************************************************************** 1361 // ******************************************************************************************** 1362 1363 1364 /** 1365 * <EMBED CLASS=defs DATA-CASE=Upper DATA-CAPITAL=""> 1366 * <EMBED CLASS='external-html' DATA-FILE-ID=TN_TO_UPLOW_1_DESC> 1367 * @param justTag_Or_TagAndAttributeNames 1368 * <EMBED CLASS='external-html' DATA-FILE-ID=TN_TO_UPLOW_1_PARAM> 1369 * @return <EMBED CLASS='external-html' DATA-FILE-ID=TN_TO_UPLOW_1_RET> 1370 */ 1371 @LinkJavaSource(handle="CaseChange", name="toCaseInternal", paramCount=3) 1372 public TagNode toUpperCase(boolean justTag_Or_TagAndAttributeNames) 1373 { 1374 return CaseChange.toCaseInternal 1375 (this, justTag_Or_TagAndAttributeNames, String::toUpperCase); 1376 } 1377 1378 /** 1379 * Convenience Method. 1380 * <BR />See Documentation: {@link #toUpperCase(boolean, Predicate)} 1381 * <BR />Passes: {@code StrCmpr.equalsXOR_CI(attrName, attributeNames)} 1382 * @see StrCmpr#equalsXOR_CI(String, String...) 1383 */ 1384 @LinkJavaSource(handle="CaseChange", name="toCaseInternal", paramCount=4) 1385 @LinkJavaSource(handle="AttrRegEx", entity=FIELD, name="KEY_VALUE_REGEX") 1386 public TagNode toUpperCase(boolean tag, String... attributeNames) 1387 { 1388 return CaseChange.toCaseInternal( 1389 this, 1390 tag, 1391 (String attrName) -> StrCmpr.equalsXOR_CI(attrName, attributeNames), 1392 String::toUpperCase 1393 ); 1394 } 1395 1396 /** 1397 * <EMBED CLASS=defs DATA-CASE=Upper DATA-CAPITAL=""> 1398 * <EMBED CLASS='external-html' DATA-FILE-ID=TN_TO_UPLOW_2_DESC> 1399 * @param tag Indicates whether or not the Tag-Name should be capitalized 1400 * @param attrNameTest <EMBED CLASS='external-html' DATA-FILE-ID=TN_TO_UPLOW_2_PARAM> 1401 * @return <EMBED CLASS='external-html' DATA-FILE-ID=TN_TO_UPLOW_2_RET> 1402 */ 1403 @LinkJavaSource(handle="CaseChange", name="toCaseInternal", paramCount=4) 1404 @LinkJavaSource(handle="AttrRegEx", entity=FIELD, name="KEY_VALUE_REGEX") 1405 public TagNode toUpperCase(boolean tag, Predicate<String> attrNameTest) 1406 { return CaseChange.toCaseInternal(this, tag, attrNameTest, String::toUpperCase); } 1407 1408 1409 // ******************************************************************************************** 1410 // ******************************************************************************************** 1411 // toLowerCase 1412 // ******************************************************************************************** 1413 // ******************************************************************************************** 1414 1415 1416 /** 1417 * <EMBED CLASS=defs DATA-CASE=Lower DATA-CAPITAL="de-"> 1418 * <EMBED CLASS='external-html' DATA-FILE-ID=TN_TO_UPLOW_1_DESC> 1419 * @param justTag_Or_TagAndAttributeNames 1420 * <EMBED CLASS='external-html' DATA-FILE-ID=TN_TO_UPLOW_1_PARAM> 1421 * @return <EMBED CLASS='external-html' DATA-FILE-ID=TN_TO_UPLOW_1_RET> 1422 */ 1423 @LinkJavaSource(handle="CaseChange", name="toCaseInternal", paramCount=3) 1424 public TagNode toLowerCase(boolean justTag_Or_TagAndAttributeNames) 1425 { 1426 return CaseChange.toCaseInternal 1427 (this, justTag_Or_TagAndAttributeNames, String::toLowerCase); 1428 } 1429 1430 /** 1431 * Convenience Method. 1432 * <BR />See Documentation: {@link #toLowerCase(boolean, Predicate)} 1433 * <BR />Passes: {@code StrCmpr.equalsXOR_CI(attrName, attributeNames)} 1434 * @see StrCmpr#equalsXOR_CI(String, String...) 1435 */ 1436 @LinkJavaSource(handle="CaseChange", name="toCaseInternal", paramCount=4) 1437 @LinkJavaSource(handle="AttrRegEx", entity=FIELD, name="KEY_VALUE_REGEX") 1438 public TagNode toLowerCase(boolean tag, String... attributeNames) 1439 { 1440 return CaseChange.toCaseInternal( 1441 this, 1442 tag, 1443 (String attrName) -> StrCmpr.equalsXOR_CI(attrName, attributeNames), 1444 String::toLowerCase 1445 ); 1446 } 1447 1448 /** 1449 * <EMBED CLASS=defs DATA-CASE=Lower DATA-CAPITAL="de-"> 1450 * <EMBED CLASS='external-html' DATA-FILE-ID=TN_TO_UPLOW_2_DESC> 1451 * @param tag Indicates whether or not the Tag-Name should be decapitalized 1452 * @param attrNameTest <EMBED CLASS='external-html' DATA-FILE-ID=TN_TO_UPLOW_2_PARAM> 1453 * @return <EMBED CLASS='external-html' DATA-FILE-ID=TN_TO_UPLOW_2_RET> 1454 */ 1455 @LinkJavaSource(handle="CaseChange", name="toCaseInternal", paramCount=4) 1456 @LinkJavaSource(handle="AttrRegEx", entity=FIELD, name="KEY_VALUE_REGEX") 1457 public TagNode toLowerCase(boolean tag, Predicate<String> attrNameTest) 1458 { return CaseChange.toCaseInternal(this, tag, attrNameTest, String::toLowerCase); } 1459 1460 1461 // ******************************************************************************************** 1462 // ******************************************************************************************** 1463 // Attribute-Value Quotation-Marks - REMOVE 1464 // ******************************************************************************************** 1465 // ******************************************************************************************** 1466 1467 1468 /** 1469 * Convenience Method. 1470 * <BR />See Documentation: {@link #removeAVQuotes(Predicate)} 1471 * <BR />Removes Quotation-Marks from <B STYLE='color: red;'>Value</B> whose Inner-Tag 1472 * <B STYLE='color: red;'>Name</B> matches {@code 'attributeName'} 1473 */ 1474 @LinkJavaSource(handle="QuotationMarks", name="removeAVQuotes") 1475 public TagNode removeAVQuotes(String attributeName) 1476 { 1477 return QuotationMarks.removeAVQuotes 1478 (this, (String attr) -> attr.equalsIgnoreCase(attributeName)); 1479 } 1480 1481 /** 1482 * Convenience Method. 1483 * <BR />See Documentation: {@link #removeAVQuotes(Predicate)} 1484 * <BR />Removes Quotation-Marks from all Inner-Tag <B STYLE='color: red;'>Values</B> 1485 */ 1486 @LinkJavaSource(handle="QuotationMarks", name="removeAVQuotes") 1487 public TagNode removeAllAVQuotes() 1488 { return QuotationMarks.removeAVQuotes(this, (String attr) -> true); } 1489 1490 /** 1491 * <EMBED CLASS='external-html' DATA-FILE-ID=TN_REM_QUOTES_DESC> 1492 * @param attrNameTest <EMBED CLASS='external-html' DATA-FILE-ID=TN_REM_QUOTES_PARAM> 1493 * @return <EMBED CLASS='external-html' DATA-FILE-ID=TN_REM_QUOTES_RET> 1494 * @throws QuotesException If the resulting <CODE>TagNode</CODE> contains Quotation-Errors 1495 */ 1496 @LinkJavaSource(handle="QuotationMarks", name="removeAVQuotes") 1497 public TagNode removeAVQuotes(Predicate<String> attrNameTest) 1498 { return QuotationMarks.removeAVQuotes(this, attrNameTest); } 1499 1500 1501 // ******************************************************************************************** 1502 // ******************************************************************************************** 1503 // Attribute-Value Quotation-Marks - SET 1504 // ******************************************************************************************** 1505 // ******************************************************************************************** 1506 1507 1508 /** 1509 * Convenience Method. 1510 * <BR />See Documentation: {@link #setAVQuotes(Predicate, SD)}} 1511 * <BR />Set Quotation-Marks for the Attribute whose <B STYLE='color: red;'>Name</B> matches 1512 * {@code 'attributeName'} 1513 */ 1514 @LinkJavaSource(handle="QuotationMarks", name="setAVQuotes") 1515 public TagNode setAVQuotes(String attributeName, SD quote) 1516 { 1517 return QuotationMarks.setAVQuotes 1518 (this, (String attr) -> attr.equalsIgnoreCase(attributeName), quote); 1519 } 1520 1521 /** 1522 * Convenience Method. 1523 * <BR />See Documentation: {@link #setAVQuotes(Predicate, SD)}} 1524 * <BR />Set the Quotation-Marks which are used with all Attribute's contained by 1525 * {@code 'this'} Tag. 1526 */ 1527 @LinkJavaSource(handle="QuotationMarks", name="setAVQuotes") 1528 public TagNode setAllAVQuotes(SD quote) 1529 { return QuotationMarks.setAVQuotes(this, (String attr) -> true, quote); } 1530 1531 /** 1532 * <EMBED CLASS='external-html' DATA-FILE-ID=TN_SET_QUOTES_DESC> 1533 * @param attrNameTest <EMBED CLASS='external-html' DATA-FILE-ID=TN_SET_QUOTES_PARAM> 1534 * @param quote The new Quotation-Mark to apply 1535 * @return <EMBED CLASS='external-html' DATA-FILE-ID=TN_SET_QUOTES_RET> 1536 * @throws QuotesException If the resulting <CODE>TagNode</CODE> contains Quotation-Errors 1537 * @throws NullPointerException If either parameter is passed null. 1538 */ 1539 @LinkJavaSource(handle="QuotationMarks", name="setAVQuotes") 1540 public TagNode setAVQuotes(Predicate<String> attrNameTest, SD quote) 1541 { return QuotationMarks.setAVQuotes(this, attrNameTest, quote); } 1542 1543 1544 // ******************************************************************************************** 1545 // ******************************************************************************************** 1546 // Attribute-Value Quotation-Marks - GET 1547 // ******************************************************************************************** 1548 // ******************************************************************************************** 1549 1550}