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