001package Torello.HTML; 002 003import Torello.Java.*; 004import java.util.*; 005 006/** 007 * <CODE>AUM (Attribute Update Mode) - Documentation.</CODE><BR /><BR /> 008 * <EMBED CLASS='external-html' DATA-FILE-ID=AUM> 009 * 010 * @see Attributes#update(Vector, AUM, String, String, SD) 011 * @see Attributes#update(Vector, AUM, int, int, String, String, SD) 012 * @see Attributes#update(Vector, AUM, int[], String, String, SD) 013 */ 014public enum AUM 015{ 016 /** 017 * {@code Set}, when used as an Attribute Update Method, tells the HTML Element Attribute 018 * Update Logic to either <B>1)</B> replace the current 019 * attribute-<B STYLE="color: red;">value</B> with the new text-{@code String}, or <B>2)</B> If 020 * there is no attribute <B STYLE="color: red;">key-value</B> with the provided inner-tag 021 * <B STYLE="color: red;">name</B>, then to create a new attribute for the HTML Element for the 022 * provided attribute-<B STYLE="color: red;">key</B> and <B STYLE="color: red;">value</B> and 023 * insert this attribute <B STYLE="color: red;">key-value</B> pair into the element. 024 * 025 * <BR /><BR />Here is how the HTML Element Attribute Update is Performed: 026 * 027 * <DIV CLASS="SNIP">{@code 028 * // String cur = tn.AV(innerTag); int i; 029 * case Set: return tn.setAV(innerTag, innerTagValue, quote); 030 * }</DIV> 031 * 032 * <DIV CLASS="EXAMPLE-SCROLL">{@code 033 * // Example 1 034 * String innerTag = "target"; 035 * String innerTagValue = "_BLANK"; 036 * AUM mode = AUM.Set; 037 * TagNode tn = new TagNode("<A HREF='nextIndex.html'>"); 038 * TagNode newTN = mode.update(tn, innerTag, innerTagValue, SD.SingleQuote); 039 * // newTN.str ==> <A HREF='nextIndex.html' target='_BLANK'> 040 * // New 'target' attribute key-value pair inserted into HTML Element 041 * 042 * // Example 2 043 * String innerTag = "target"; 044 * String innerTagValue = "_BLANK"; 045 * AUM mode = AUM.Set; 046 * TagNode tn = new TagNode("<A HREF='nextIndex.html' TARGET='_Self'>"); 047 * TagNode newTN = mode.update(tn, innerTag, innerTagValue, SD.SingleQuote); 048 * // newTN.str ==> <A HREF='nextIndex.html' target='_BLANK'> 049 * // Old 'target' attribute key-value pair is replaced with new value 050 * }</DIV> 051 * 052 * @see #update(TagNode, String, String, SD) 053 * @see HTMLNode#str 054 */ 055 Set, 056 057 /** 058 * {@code Replace} when used as an Attribute Update Method, tells the HTML Element Attribute 059 * Update Logic to <I><B>replace</I></B> any attribute <B STYLE="color: red;">key-value</B> 060 * pair that the Element contains; <B><I>however</I></B> if there is no current 061 * <B STYLE="color: red;">key-value</B> pair that has the provided attribute 062 * <B STYLE="color: red;">name</B>, then the HTML Element Node should be skipped, and left 063 * un-modified. 064 * 065 * <BR /><BR />Here is how the HTML Element Attribute Update is Performed: 066 * 067 * <DIV CLASS="SNIP">{@code 068 * // String cur = tn.AV(innerTag); int i; 069 * case Replace: if (cur != null) return tn.setAV(innerTag, innerTagValue, quote); 070 * return null; 071 * }</DIV> 072 * 073 * <DIV CLASS="EXAMPLE-SCROLL">{@code 074 * // Example 1 075 * String innerTag = "style"; 076 * String innerTagValue = "color: red;"; 077 * AUM mode = AUM.Replace; 078 * TagNode tn = new TagNode("<A HREF='nextIndex.html' STYLE='font-weight: bold;'>"); 079 * TagNode newTN = mode.update(tn, innerTag, innerTagValue, SD.SingleQuote); 080 * // newTN.str ==> <A HREF='nextIndex.html' style='color: red;'> 081 * // Old 'style' attribute key-value pair is replaced with new value 082 * 083 * // Example 2 084 * String innerTag = "style"; 085 * String innerTagValue = "color: red;"; 086 * AUM mode = AUM.Replace; 087 * TagNode tn = new TagNode("<A HREF='nextIndex.html'>"); 088 * TagNode newTN = mode.update(tn, innerTag, innerTagValue, SD.SingleQuote); 089 * // newTN ==> null 090 * // NOTE: HTML Element left unchanged, because it did not actually 091 * // have a 'style' attribute in the first place. 092 * // A return value of 'null' implies this AUM does not result 093 * // in a replacement or update for the TagNode passed. 094 * }</DIV> 095 * 096 * @see #update(TagNode, String, String, SD) 097 * @see HTMLNode#str 098 */ 099 Replace, 100 101 /** 102 * {@code RemoveSubString} when used as an Attribute Update Method, tells the HTML Element 103 * Attribute Update Logic to <I><B>remove</I></B> the first copy found of a provided sub-string 104 * from the attribute-<B STYLE="color: red;">value</B> whose attribute 105 * <B STYLE="color: red;">name</B> matches the provided inner-tag 106 * <B STYLE="color: red;">name</B>. 107 * 108 * <BR /><BR /><DIV CLASS="MISC_HILITE"> 109 * <B>For Instance:</B> If AUM.RemoveSubString were used with an HTML Element 110 * that looked like: <SPAN STYLE="color: lightbrown; font-weight: bold;"> 111 * <BR />{@code <DIV CLASS='MyClass MyPage Corporation123'>}</SPAN> 112 * 113 * <BR /><BR /> 114 * <B>Where:</B> {@code innerTag = "CLASS"} and {@code innerTagValue = "Corporation123"} 115 * 116 * <BR /><BR /><B>Then:</B> The HTML Element would be updated to: 117 * <SPAN STYLE="color: blue; font-weight: bold;"> 118 * <BR />{@code <DIV CLASS='MyClass MyPage '>} 119 * </SPAN> 120 * 121 * <BR /><BR /><B>NOTE:</B> This uses Java's {@code String.indexOf(...)} method, and will only 122 * remove the first-instance of the substring. 123 * 124 * <BR /><BR /><B>ALSO:</B> There is a remaining 'extra-space' that was not removed along with 125 * the {@code 'corporation123'} String. Keep in mind white-space when using java to modify text. 126 * </DIV> 127 * 128 * <BR /><BR />Here is how the HTML Element Attribute Update is Performed: 129 * 130 * <DIV CLASS="SNIP">{@code 131 * // String cur = tn.AV(innerTag); int i; 132 * case RemoveSubString: if (cur != null) if ((i = cur.indexOf(innerTagValue)) != -1) 133 * return tn.setAV(innerTag, cur.replace(innerTagValue, ""), quote); 134 * return null; 135 * }</DIV> 136 * 137 * @see #update(TagNode, String, String, SD) 138 * @see HTMLNode#str 139 */ 140 RemoveSubString, 141 142 /** 143 * This performs the exact same routine as {@code AUM.RemoveSubstring}, however the 144 * text-{@code String} comparison ignores case for the alphabetic letters a..z. This HTML 145 * Element Update Routine, just like the {@code AUM.RemoveSubstring}, also only removes the 146 * first instance found of the provided substring. 147 * 148 * <BR /><BR /><DIV CLASS="MISC_HILITE"> 149 * <B>For Instance:</B> If AUM.RemoveSubString_CI were used with an HTML Element 150 * that looked like: <SPAN STYLE="color: lightbrown; font-weight: bold;"> 151 * <BR />{@code <DIV CLASS='MyClass MyPage Corporation123' STYLE='FONT-WEIGHT: BOLD; COLOR: 152 * RED;'>}</SPAN> 153 * 154 * <BR /><BR /> 155 * <B>Where:</B> {@code innerTag = "STYLE"} and {@code innerTagValue = "color: red;"} 156 * 157 * <BR /><BR /><B>Then:</B> The HTML Element would be updated to: 158 * <SPAN STYLE="color: blue; font-weight: bold;"> 159 * <BR />{@code <DIV CLASS='MyClass MyPage Corporation123'STYLE='FONT-WEIGHT: BOLD; '>}</SPAN> 160 * 161 * <BR /><BR /><B>NOTE:</B> This uses java's {@code StrCmpr.indexOfIgnoreCase(...)} method, and 162 * will only remove the first-instance of the substring (ignoring case). In the original HTML 163 * Element, the words 'COLOR' and 'RED' were capitalized. Using this 'Case-Insensitive' 164 * removal, the user can catch any version. This, fortunately, is how CSS 'Style' Attributes 165 * work! 166 * 167 * <BR /><BR /><B>ALSO:</B> There is a remaining 'extra-space' that was not removed along with 168 * the 'corporation123' string. Keep in mind white-space when using java to modify text. 169 * </DIV> 170 * 171 * <BR /><BR />Here is how the HTML Element Attribute Update is Performed: 172 * 173 * <DIV CLASS="SNIP">{@code 174 * // String cur = tn.AV(innerTag); int i; 175 * case RemoveSubString_CI: if (cur != null) if ((i = StrCmpr.indexOfIgnoreCase(cur, innerTagValue)) != -1) 176 * return tn.setAV(innerTag, cur.substring(0, i) + cur.substring(i + innerTagValue.length()), quote); 177 * return null; 178 * }</DIV> 179 * 180 * @see #update(TagNode, String, String, SD) 181 * @see HTMLNode#str 182 */ 183 RemoveSubString_CI, 184 185 /** 186 * {@code ConcatToStart} when used as an Attribute Update Method, tells the HTML Element 187 * Attribute Update Logic to <I><B>concatenate</I></B> the provided 188 * attribute-<B STYLE="color: red;">value</B> to <I><B>an already in place</B></I> 189 * attribute-<B STYLE="color: red;">value</B> before the beginning of the current 190 * attribute-<B STYLE="color: red;">value</B> {@code String}. <B><I>However</I></B> if there is 191 * no current <B STYLE="color: red;">key-value</B> pair that has the provided attribute 192 * <B STYLE="color: red;">name</B>, then the HTML Element Node should be skipped, and left 193 * un-modified. 194 * 195 * <BR /><BR />Here is how the HTML Element Attribute Update is Performed: 196 * 197 * <DIV CLASS="SNIP">{@code 198 * // String cur = tn.AV(innerTag); int i; 199 * case ConcatToStart: if (cur != null) return tn.setAV(innerTag, innerTagValue + cur, quote); 200 * return null; 201 * }</DIV> 202 * 203 * <BR /><DIV CLASS="EXAMPLE-SCROLL">{@code 204 * // Example 1 205 * String innerTag = "id"; 206 * String innerTagValue = "JAVA-AUM-"; 207 * AUM mode = AUM.ConcatToStart; 208 * TagNode tn = new TagNode("<IMG SRC='img-123.jpg' ID='MyPage'>"); 209 * TagNode newTN = mode.update(tn, innerTag, innerTagValue, SD.SingleQuote); 210 * // newTN.str ==> <IMG SRC='img-123.jpg' id='JAVA-AUM-MyPage'> 211 * 212 * // Example 2 213 * String innerTag = "id"; 214 * String innerTagValue = "JAVA-AUM-"; 215 * AUM mode = AUM.ConcatToStart; 216 * TagNode tn = new TagNode("<IMG SRC='img-123.jpg'>"); 217 * TagNode newTN = mode.update(tn, innerTag, innerTagValue, SD.SingleQuote); 218 * // newTN ==> null 219 * // NOTE: HTML Element left unchanged, because it did not actually 220 * // have an 'id' attribute in the first place. 221 * // A return value of 'null' implies this AUM does not result 222 * // in a replacement or update for the TagNode passed. 223 * }</DIV> 224 * 225 * @see #update(TagNode, String, String, SD) 226 * @see HTMLNode#str 227 */ 228 ConcatToStart, 229 230 /** 231 * {@code ConcatToStart} when used as an Attribute Update Method, tells the HTML Element 232 * Attribute Update Logic to <I><B>concatenate</I></B> the provided 233 * attribute-<B STYLE="color: red;">value</B> to <I><B>an already in place</B></I> 234 * attribute-<B STYLE="color: red;">value</B> before the beginning of the current 235 * attribute-<B STYLE="color: red;">value</B> {@code String}. If there is no current 236 * <B STYLE="color: red;">key-value</B> pair that has the provided attribute 237 * <B STYLE="color: red;">name</B>, a new Inner-Tag <B STYLE="color: red;">key-value</B> pair 238 * should be added to the HTML Element Node using the provided 239 * <B STYLE="color: red;">key</B>-{@code String} and 240 * <B STYLE="color: red;">value</B>-{@code String}. 241 * 242 * <BR /><BR />Here is how the HTML Element Attribute Update is Performed: 243 * 244 * <DIV CLASS="SNIP">{@code 245 * // String cur = tn.AV(innerTag); int i; 246 * case ConcatToStartOrSet: if (cur != null) return tn.setAV(innerTag, innerTagValue + cur, quote); 247 * return tn.setAV(innerTag, innerTagValue, quote); 248 * }</DIV> 249 * 250 * <DIV CLASS="EXAMPLE-SCROLL">{@code 251 * // Example 1 252 * String innerTag = "alt"; 253 * String innerTagValue = "This is a personal photo."; 254 * AUM mode = AUM.ConcatToStartOrSet; 255 * TagNode tn = new TagNode("<IMG SRC='img-123.jpg'>"); 256 * TagNode newTN = mode.update(tn, innerTag, innerTagValue, SD.SingleQuote); 257 * // newTN.str ==> <IMG SRC='img-123.jpg' alt='This is a personal photo.'> 258 * // The original TagNode did not have an 'alt' Inner-Tag, but 259 * // because this AUM has the "OrSet" requirement, when a TagNode 260 * // that's lacking the requested Inner-Tag, the AUM.update method 261 * // will not return null, but instead create a new attribute 262 * // key-value pair, and set the value to the requested parameter. 263 * 264 * // Example 2 265 * String innerTag = "alt"; 266 * String innerTagValue = "This is a personal photo."; 267 * AUM mode = AUM.ConcatToStartOrSet; 268 * TagNode tn = new TagNode("<IMG SRC='img-123.jpg' ALT='Bob Wilson'>"); 269 * TagNode newTN = mode.update(tn, innerTag, innerTagValue, SD.SingleQuote); 270 * // newTN.str ==> <IMG SRC='img-123.jpg' alt='This is a personal photo.Bob Wilson'> 271 * // NOTE: There is no space between the period, and the beginning of the 272 * // next sentence in the ALT Inner-Tag above! 273 * }</DIV> 274 * 275 * @see #update(TagNode, String, String, SD) 276 * @see Torello.HTML.HTMLNode#str 277 */ 278 ConcatToStartOrSet, 279 280 /** 281 * This {@code AUM} enumerated type is precisely identical to the one named 282 * {@code ConcatToStart} - <I><B>except</B></I> that in the case where the inner-tag 283 * <B STYLE="color: red;">value</B> is appended, a space is added immediately after the newly 284 * added {@code String}-<B STYLE="color: red;">value</B> token. 285 * 286 * <BR /><BR /><SPAN STYLE="color: red;"><B>NOTE:</B></SPAN> The primary reason for adding 287 * this surprisingly subtle and minor difference is to remind users that keeping up with spaces 288 * when tweaking HTML inner-tags can be a bug source. 289 * 290 * <BR /><BR />Here is how the HTML Element Attribute Update is Performed: 291 * 292 * <DIV CLASS="SNIP">{@code 293 * // String cur = tn.AV(innerTag); int i; 294 * case ConcatToStartAddSpace: if (cur != null) return tn.setAV(innerTag, innerTagValue + ' ' + cur, quote); 295 * return null; 296 * }</DIV> 297 * 298 * <DIV CLASS="EXAMPLE-SCROLL">{@code 299 * // Example 1 300 * String innerTag = "id"; 301 * String innerTagValue = "JAVA-AUM"; 302 * AUM mode = AUM.ConcatToStartAddSpace; 303 * TagNode tn = new TagNode("<IMG SRC='img-123.jpg' ID='MyPage'>"); 304 * TagNode newTN = mode.update(tn, innerTag, innerTagValue, SD.SingleQuote); 305 * // newTN.str ==> <IMG SRC='img-123.jpg' id='JAVA-AUM MyPage'> 306 * 307 * // Example 2 308 * String innerTag = "id"; 309 * String innerTagValue = "JAVA-AUM"; 310 * AUM mode = AUM.ConcatToStartAddSpace; 311 * TagNode tn = new TagNode("<IMG SRC='img-123.jpg'>"); 312 * TagNode newTN = mode.update(tn, innerTag, innerTagValue, SD.SingleQuote); 313 * // newTN ==> null 314 * // NOTE: HTML Element left unchanged, because it did not actually 315 * // have an 'id' attribute in the first place. 316 * // A return value of 'null' implies this AUM does not result 317 * // in a replacement or update for the TagNode passed. 318 * }</DIV> 319 * 320 * @see #update(TagNode, String, String, SD) 321 * @see Torello.HTML.HTMLNode#str 322 */ 323 ConcatToStartAddSpace, 324 325 /** 326 * This {@code AUM} enumerated type is precisely identical to the one named 327 * {@code ConcatToStartOrSet} - <I><B>except</B></I> that in the case where the inner-tag 328 * <B STYLE="color: red;">value</B> is appended (concatenated), a space is added immediately 329 * after the newly added {@code String}-<B STYLE="color: red;">value</B> token. 330 * 331 * <BR /><BR /><B>NOTE:</B> If there were no inner-tag <B STYLE="color: red;">key-value</B> 332 * pair, and a new one was added - then an extra space would, hopefully this is obvious, 333 * <I>then an extra space would not be needed</I>, and therefore it is not added. 334 * 335 * <BR /><BR />Here is how the HTML Element Attribute Update is Performed: 336 * 337 * <DIV CLASS="SNIP">{@code 338 * // String cur = tn.AV(innerTag); int i; 339 * case ConcatToStartOrSetAddSpace: if (cur != null) return tn.setAV(innerTag, innerTagValue + ' ' + cur, quote); 340 * return tn.setAV(innerTag, innerTagValue, quote); 341 * }</DIV> 342 * 343 * <DIV CLASS="EXAMPLE-SCROLL">{@code 344 * // Example 1 345 * String innerTag = "alt"; 346 * String innerTagValue = "This is a personal photo."; 347 * AUM mode = AUM.ConcatToStartOrSetAddSpace; 348 * TagNode tn = new TagNode("<IMG SRC='img-123.jpg' ALT='Company XYZ'>"); 349 * TagNode newTN = mode.update(tn, innerTag, innerTagValue, SD.SingleQuote); 350 * // newTN.str ==> <IMG SRC='img-123.jpg' alt='This is a personal photo. Company XYZ'> 351 * 352 * // Example 2 353 * String innerTag = "alt"; 354 * String innerTagValue = "This is a personal photo."; 355 * AUM mode = AUM.ConcatToStartOrSetAddSpace; 356 * TagNode tn = new TagNode("<IMG SRC='img-123.jpg'>"); 357 * TagNode newTN = mode.update(tn, innerTag, innerTagValue, SD.SingleQuote); 358 * // newTN.str ==> <IMG SRC='img-123.jpg' alt='This is a personal photo.'> 359 * }</DIV> 360 * 361 * @see #update(TagNode, String, String, SD) 362 * @see Torello.HTML.HTMLNode#str 363 */ 364 ConcatToStartOrSetAddSpace, 365 366 /** 367 * {@code ConcatToEnd} when used as an Attribute Update Method, tells the HTML Element 368 * Attribute Update Logic to <I><B>concatenate</I></B> the provided 369 * attribute-<B STYLE="color: red;">value</B> to <I><B>an already in place</B></I> 370 * attribute-<B STYLE="color: red;">value</B> at the end of the current 371 * attribute-<B STYLE="color: red;">value</B> {@code String}. <B><I>However</I></B> if there 372 * is no current <B STYLE="color: red;">key-value</B> pair that has the provided attribute 373 * <B STYLE="color: red;">name</B>, then the HTML Element Node should be skipped, and left 374 * un-modified. 375 * 376 * <BR /><BR />Here is how the HTML Element Attribute Update is Performed: 377 * 378 * <DIV CLASS="SNIP">{@code 379 * // String cur = tn.AV(innerTag); int i; 380 * case ConcatToEnd: if (cur != null) return tn.setAV(innerTag, cur + innerTagValue, quote); 381 * return null; 382 * }</DIV> 383 * 384 * <DIV CLASS="EXAMPLE-SCROLL">{@code 385 * // Example 1 386 * String innerTag = "alt"; 387 * String innerTagValue = "Photo of Friends"; 388 * AUM mode = AUM.ConcatToEnd; 389 * TagNode tn = new TagNode("<IMG SRC='img-123.jpg' ID='MyPage'>"); 390 * TagNode newTN = mode.update(tn, innerTag, innerTagValue, SD.SingleQuote); 391 * // newTN ==> null 392 * // NOTE: HTML Element left unchanged, because it did not actually 393 * // have an 'alt' attribute in the first place. 394 * // A return value of 'null' implies this AUM does not result 395 * // in a replacement or update for the TagNode passed. 396 * 397 * // Example 2 398 * String innerTag = "alt"; 399 * String innerTagValue = " - Photo of Friends"; 400 * AUM mode = AUM.ConcatToEnd; 401 * TagNode tn = new TagNode("<IMG SRC='img-123.jpg' ALT='Bob Wilson'>"); 402 * TagNode newTN = mode.update(tn, innerTag, innerTagValue, SD.SingleQuote); 403 * // newTN.str ==> <IMG SRC='img-123.jpg' alt='Bob Wilson - Photo of Friends'> 404 * }</DIV> 405 * 406 * @see #update(TagNode, String, String, SD) 407 * @see Torello.HTML.HTMLNode#str 408 */ 409 ConcatToEnd, 410 411 /** 412 * {@code ConcatToEnd} when used as an Attribute Update Method, tells the HTML Element 413 * Attribute Update Logic to <I><B>concatenate</I></B> the provided 414 * attribute-<B STYLE="color: red;">value</B> to <I><B>an already in place</B></I> 415 * attribute-<B STYLE="color: red;">value</B> at the end of the current 416 * attribute-<B STYLE="color: red;">value</B> {@code String}. If there is no current 417 * <B STYLE="color: red;">key-value</B> pair that has the provided attribute 418 * <B STYLE="color: red;">name</B>, a new Inner-Tag <B STYLE="color: red;">key-value</B> pair 419 * should be added to the HTML Element Node using the provided 420 * <B STYLE="color: red;">key</B>-{@code String} and 421 * <B STYLE="color: red;">value</B>-{@code String}. 422 * 423 * <BR /><BR />Here is how the HTML Element Attribute Update is Performed: 424 * 425 * <DIV CLASS="SNIP">{@code 426 * // String cur = tn.AV(innerTag); int i; 427 * case ConcatToEndOrSet: if (cur != null) return tn.setAV(innerTag, cur + innerTagValue, quote); 428 * return tn.setAV(innerTag, innerTagValue, quote); 429 * }</DIV> 430 * 431 * <DIV CLASS="EXAMPLE-SCROLL">{@code 432 * // Example 1 433 * String innerTag = "alt"; 434 * String innerTagValue = " - This is a personal photo."; 435 * AUM mode = AUM.ConcatToEndOrSet; 436 * TagNode tn = new TagNode("<IMG SRC='img-123.jpg' ALT='Larry'>"); 437 * TagNode newTN = mode.update(tn, innerTag, innerTagValue, SD.SingleQuote); 438 * // newTN.str ==> <IMG SRC='img-123.jpg' alt='Larry - This is a personal photo.'> 439 * // NOTE: There is no space between the period, and the beginning of 440 * // the next sentence in the ALT Inner-Tag above! 441 * 442 * // Example 2 443 * String innerTag = "alt"; 444 * String innerTagValue = "This is a personal photo."; 445 * AUM mode = AUM.ConcatToEndOrSet; 446 * TagNode tn = new TagNode("<IMG SRC='img-123.jpg'>"); 447 * TagNode newTN = mode.update(tn, innerTag, innerTagValue, SD.SingleQuote); 448 * // newTN.str ==> <IMG SRC='img-123.jpg' alt='This is a personal photo.'> 449 * // The original TagNode did not have an 'alt' Inner-Tag, but 450 * // because this AUM has the "OrSet" requirement, when a TagNode 451 * // that's lacking the requested Inner-Tag, the AUM.update method 452 * // will not return null, but instead create a new attribute 453 * // key-value pair, and set the value to the requested parameter. 454 * }</DIV> 455 * 456 * @see #update(TagNode, String, String, SD) 457 * @see Torello.HTML.HTMLNode#str 458 */ 459 ConcatToEndOrSet, 460 461 /** 462 * This {@code AUM} enumerated type is precisely identical to the one named {@code ConcatToEnd} 463 * - <I><B>except</B></I> that in the case where the inner-tag <B STYLE="color: red;">value</B> 464 * is appended, a space is added immediately before the newly added 465 * {@code String}-<B STYLE="color: red;">value</B> token. 466 * 467 * <BR /><BR /><SPAN STYLE="color: red;">NOTE:</SPAN> The primary reason for adding this 468 * surprisingly subtle and minor difference is to remind users that keeping up with spaces when 469 * tweaking HTML inner-tags can be a bug source. 470 * 471 * <BR /><BR />Here is how the HTML Element Attribute Update is Performed: 472 * 473 * <DIV CLASS="SNIP">{@code 474 * // String cur = tn.AV(innerTag); int i; 475 * case ConcatToEndAddSpace: 476 * if (cur != null) return tn.setAV(innerTag, cur + ' ' + innerTagValue, quote); 477 * return null; 478 * }</DIV> 479 * 480 * <DIV CLASS="EXAMPLE-SCROLL">{@code 481 * // Example 1 482 * String innerTag = "id"; 483 * String innerTagValue = "JAVA-AUM-EXAMPLE"; 484 * AUM mode = AUM.ConcatToEndAddSpace; 485 * TagNode tn = new TagNode("<IMG SRC='img-123.jpg'>"); 486 * TagNode newTN = mode.update(tn, innerTag, innerTagValue, SD.SingleQuote); 487 * // newTN ==> null 488 * // NOTE: HTML Element left unchanged, because it did not actually 489 * // have an 'id' attribute in the first place. 490 * // A return value of 'null' implies this AUM does not result 491 * // in a replacement or update for the TagNode passed. 492 * 493 * // Example 2 494 * String innerTag = "id"; 495 * String innerTagValue = "JAVA-AUM-EXAMPLE"; 496 * AUM mode = AUM.ConcatToEndAddSpace; 497 * TagNode tn = new TagNode("<IMG SRC='img-123.jpg' ID='MyClass'>"); 498 * TagNode newTN = mode.update(tn, innerTag, innerTagValue, SD.SingleQuote); 499 * // newTN.str ==> <IMG SRC='img-123.jpg' id='MyClass JAVA-AUM-EXAMPLE'> 500 * }</DIV> 501 * 502 * @see #update(TagNode, String, String, SD) 503 * @see Torello.HTML.HTMLNode#str 504 */ 505 ConcatToEndAddSpace, 506 507 /** 508 * This {@code AUM} enumerated type is precisely identical to the one named {@code ConcatToEnd} 509 * - <I><B>except</B></I> that in the case where the inner-tag <B STYLE="color: red;">value</B> 510 * is appended, a space is added immediately before the newly added 511 * {@code String}-<B STYLE="color: red;">value</B> token. 512 * 513 * <BR /><BR /><B>NOTE:</B> If there were no inner-tag <B STYLE="color: red;">key-value</B> 514 * pair, and a new one was added - then an extra space would, hopefully this is obvious, 515 * <I>then an extra space would not be needed</I>, and therefore it is not added. 516 * 517 * <BR /><BR />Here is how the HTML Element Attribute Update is Performed: 518 * 519 * <DIV CLASS="SNIP">{@code 520 * // String cur = tn.AV(innerTag); int i; 521 * case ConcatToEndOrSetAddSpace: 522 * if (cur != null) return tn.setAV(innerTag, cur + ' ' + innerTagValue, quote); 523 * return tn.setAV(innerTag, innerTagValue, quote); 524 * }</DIV> 525 * 526 * <DIV CLASS="EXAMPLE-SCROLL">{@code 527 * // Example 1 528 * String innerTag = "alt"; 529 * String innerTagValue = "This is a corporate photo."; 530 * AUM mode = AUM.ConcatToEndOrSetAddSpace; 531 * TagNode tn = new TagNode("<IMG SRC='img-123.jpg'>"); 532 * TagNode newTN = mode.update(tn, innerTag, innerTagValue, SD.SingleQuote); 533 * // newTN.str ==> <IMG SRC='img-123.jpg' alt='This is a corporate photo.'> 534 * 535 * // Example 2 536 * String innerTag = "alt"; 537 * String innerTagValue = "This is a corporate photo."; 538 * AUM mode = AUM.ConcatToEndOrSetAddSpace; 539 * TagNode tn = new TagNode("<IMG SRC='img-123.jpg' ALT='Bob'>"); 540 * TagNode newTN = mode.update(tn, innerTag, innerTagValue, SD.SingleQuote); 541 * // newTN.str ==> <IMG SRC='img-123.jpg' alt='Bob - This is a corporate photo.' 542 * }</DIV> 543 * 544 * @see #update(TagNode, String, String, SD) 545 * @see Torello.HTML.HTMLNode#str 546 */ 547 ConcatToEndOrSetAddSpace; 548 549 /** 550 * This performs the Update corresponding to the Attribute-Update-Mode for the particular 551 * AUM instance for {@code 'this'} enumerated-type object reference. 552 * 553 * @param tn This HTML Element TagNode on which the update shall be performed. 554 * @param innerTag The Inner-Tag Key Name to look for inside the HTML Element. 555 * @param innerTagValue The Inner-Tag Value to update, remove, concatenate, append or set. 556 * 557 * @param quote This is a major issue in HTML / Java Programming. The best thing to do is 558 * to not try to solve this problem at the lower-level, but rather propagate it up. 559 * 560 * @return a newly updated or modified TagNode reference object. If the update mode did not 561 * permit an attribute removal, update, or addition, then 'null' shall be returned. Again, 562 * if 'null' is returned, it means the TagNode did not change - or, rather - <I>did not need 563 * to be changed as per the requirements of the chosen Attribute Update Method (AUM).</I> 564 */ 565 public final TagNode update(TagNode tn, String innerTag, String innerTagValue, SD quote) 566 { 567 String cur = tn.AV(innerTag); 568 int i; 569 570 switch (this) 571 { 572 case Set: 573 return tn.setAV(innerTag, innerTagValue, quote); 574 575 case Replace: 576 if (cur != null) return tn.setAV(innerTag, innerTagValue, quote); 577 return null; 578 579 case RemoveSubString: 580 581 if ((cur != null) && ((i = cur.indexOf(innerTagValue)) != -1)) 582 return tn.setAV(innerTag, cur.replace(innerTagValue, ""), quote); 583 584 return null; 585 586 case RemoveSubString_CI: 587 588 if ((cur != null) && ((i = StrIndexOf.first_CI(cur, innerTagValue)) != -1)) 589 return tn.setAV(innerTag, cur.substring(0, i) + 590 cur.substring(i + innerTagValue.length()), quote); 591 592 return null; 593 594 case ConcatToStart: 595 if (cur != null) return tn.setAV(innerTag, innerTagValue + cur, quote); 596 return null; 597 598 case ConcatToStartOrSet: 599 if (cur != null) return tn.setAV(innerTag, innerTagValue + cur, quote); 600 return tn.setAV(innerTag, innerTagValue, quote); 601 602 case ConcatToStartAddSpace: 603 if (cur != null) return tn.setAV(innerTag, innerTagValue + ' ' + cur, quote); 604 return null; 605 606 case ConcatToStartOrSetAddSpace: 607 if (cur != null) return tn.setAV(innerTag, innerTagValue + ' ' + cur, quote); 608 return tn.setAV(innerTag, innerTagValue, quote); 609 610 case ConcatToEnd: 611 if (cur != null) return tn.setAV(innerTag, cur + innerTagValue, quote); 612 return null; 613 614 case ConcatToEndOrSet: 615 if (cur != null) return tn.setAV(innerTag, cur + innerTagValue, quote); 616 return tn.setAV(innerTag, innerTagValue, quote); 617 618 case ConcatToEndAddSpace: 619 if (cur != null) return tn.setAV(innerTag, cur + ' ' + innerTagValue, quote); 620 return null; 621 622 case ConcatToEndOrSetAddSpace: 623 if (cur != null) return tn.setAV(innerTag, cur + ' ' + innerTagValue, quote); 624 return tn.setAV(innerTag, innerTagValue, quote); 625 626 default: throw new UnreachableError(); 627 } 628 } 629}