001package Torello.Browser; 002 003import java.util.*; 004import javax.json.*; 005import javax.json.stream.*; 006import java.io.*; 007 008import java.lang.reflect.Method; 009import java.lang.reflect.Parameter; 010import java.util.function.Function; 011 012import Torello.Java.Additional.*; 013import Torello.Java.JSON.*; 014 015import static Torello.Java.JSON.JFlag.*; 016 017import Torello.Java.StrCmpr; 018import Torello.JavaDoc.StaticFunctional; 019import Torello.JavaDoc.JDHeaderBackgroundImg; 020import Torello.JavaDoc.Excuse; 021 022/** 023 * <SPAN CLASS=COPIEDJDK><B>This domain facilitates obtaining document snapshots with DOM, layout, and style information.</B></SPAN> 024 * 025 * <EMBED CLASS='external-html' DATA-FILE-ID=CODE_GEN_NOTE> 026 */ 027@StaticFunctional(Excused={"counter"}, Excuses={Excuse.CONFIGURATION}) 028@JDHeaderBackgroundImg(EmbedTagFileID="WOOD_PLANK_NOTE") 029public class DOMSnapshot 030{ 031 // ******************************************************************************************** 032 // ******************************************************************************************** 033 // Class Header Stuff 034 // ******************************************************************************************** 035 // ******************************************************************************************** 036 037 038 // No Pubic Constructors 039 private DOMSnapshot () { } 040 041 // These two Vector's are used by all the "Methods" exported by this class. java.lang.reflect 042 // is used to generate the JSON String's. It saves thousands of lines of Auto-Generated Code. 043 private static final Map<String, Vector<String>> parameterNames = new HashMap<>(); 044 private static final Map<String, Vector<Class<?>>> parameterTypes = new HashMap<>(); 045 046 // Some Methods do not take any parameters - for instance all the "enable()" and "disable()" 047 // I simply could not get ride of RAW-TYPES and UNCHECKED warnings... so there are now, 048 // offically, two empty-vectors. One for String's, and the other for Classes. 049 050 private static final Vector<String> EMPTY_VEC_STR = new Vector<>(); 051 private static final Vector<Class<?>> EMPTY_VEC_CLASS = new Vector<>(); 052 053 static 054 { 055 for (Method m : DOMSnapshot.class.getMethods()) 056 { 057 // This doesn't work! The parameter names are all "arg0" ... "argN" 058 // It works for java.lang.reflect.Field, BUT NOT java.lang.reflect.Parameter! 059 // 060 // Vector<String> parameterNamesList = new Vector<>(); -- NOPE! 061 062 Vector<Class<?>> parameterTypesList = new Vector<>(); 063 064 for (Parameter p : m.getParameters()) parameterTypesList.add(p.getType()); 065 066 parameterTypes.put( 067 m.getName(), 068 (parameterTypesList.size() > 0) ? parameterTypesList : EMPTY_VEC_CLASS 069 ); 070 } 071 } 072 073 static 074 { 075 Vector<String> v = null; 076 077 parameterNames.put("disable", EMPTY_VEC_STR); 078 079 parameterNames.put("enable", EMPTY_VEC_STR); 080 081 v = new Vector<String>(4); 082 parameterNames.put("getSnapshot", v); 083 Collections.addAll(v, new String[] 084 { "computedStyleWhitelist", "includeEventListeners", "includePaintOrder", "includeUserAgentShadowTree", }); 085 086 v = new Vector<String>(5); 087 parameterNames.put("captureSnapshot", v); 088 Collections.addAll(v, new String[] 089 { "computedStyles", "includePaintOrder", "includeDOMRects", "includeBlendedBackgroundColors", "includeTextColorOpacities", }); 090 } 091 092 093 // ******************************************************************************************** 094 // ******************************************************************************************** 095 // Types - Static Inner Classes 096 // ******************************************************************************************** 097 // ******************************************************************************************** 098 099 // public static class StringIndex => Integer 100 101 // public static class ArrayOfStrings => int[] 102 103 // public static class Rectangle => Number[] 104 105 /** A Node in the DOM tree. */ 106 public static class DOMNode 107 extends BaseType 108 implements java.io.Serializable 109 { 110 /** For Object Serialization. java.io.Serializable */ 111 protected static final long serialVersionUID = 1; 112 113 public boolean[] optionals() 114 { return new boolean[] { false, false, false, true, true, true, true, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, }; } 115 116 /** <CODE>Node</CODE>'s nodeType. */ 117 public final int nodeType; 118 119 /** <CODE>Node</CODE>'s nodeName. */ 120 public final String nodeName; 121 122 /** <CODE>Node</CODE>'s nodeValue. */ 123 public final String nodeValue; 124 125 /** 126 * Only set for textarea elements, contains the text value. 127 * <BR /> 128 * <BR /><B>OPTIONAL</B> 129 */ 130 public final String textValue; 131 132 /** 133 * Only set for input elements, contains the input's associated text value. 134 * <BR /> 135 * <BR /><B>OPTIONAL</B> 136 */ 137 public final String inputValue; 138 139 /** 140 * Only set for radio and checkbox input elements, indicates if the element has been checked 141 * <BR /> 142 * <BR /><B>OPTIONAL</B> 143 */ 144 public final Boolean inputChecked; 145 146 /** 147 * Only set for option elements, indicates if the element has been selected 148 * <BR /> 149 * <BR /><B>OPTIONAL</B> 150 */ 151 public final Boolean optionSelected; 152 153 /** <CODE>Node</CODE>'s id, corresponds to DOM.Node.backendNodeId. */ 154 public final int backendNodeId; 155 156 /** 157 * The indexes of the node's child nodes in the <CODE>domNodes</CODE> array returned by <CODE>getSnapshot</CODE>, if 158 * any. 159 * <BR /> 160 * <BR /><B>OPTIONAL</B> 161 */ 162 public final int[] childNodeIndexes; 163 164 /** 165 * Attributes of an <CODE>Element</CODE> node. 166 * <BR /> 167 * <BR /><B>OPTIONAL</B> 168 */ 169 public final DOMSnapshot.NameValue[] attributes; 170 171 /** 172 * Indexes of pseudo elements associated with this node in the <CODE>domNodes</CODE> array returned by 173 * <CODE>getSnapshot</CODE>, if any. 174 * <BR /> 175 * <BR /><B>OPTIONAL</B> 176 */ 177 public final int[] pseudoElementIndexes; 178 179 /** 180 * The index of the node's related layout tree node in the <CODE>layoutTreeNodes</CODE> array returned by 181 * <CODE>getSnapshot</CODE>, if any. 182 * <BR /> 183 * <BR /><B>OPTIONAL</B> 184 */ 185 public final Integer layoutNodeIndex; 186 187 /** 188 * Document URL that <CODE>Document</CODE> or <CODE>FrameOwner</CODE> node points to. 189 * <BR /> 190 * <BR /><B>OPTIONAL</B> 191 */ 192 public final String documentURL; 193 194 /** 195 * Base URL that <CODE>Document</CODE> or <CODE>FrameOwner</CODE> node uses for URL completion. 196 * <BR /> 197 * <BR /><B>OPTIONAL</B> 198 */ 199 public final String baseURL; 200 201 /** 202 * Only set for documents, contains the document's content language. 203 * <BR /> 204 * <BR /><B>OPTIONAL</B> 205 */ 206 public final String contentLanguage; 207 208 /** 209 * Only set for documents, contains the document's character set encoding. 210 * <BR /> 211 * <BR /><B>OPTIONAL</B> 212 */ 213 public final String documentEncoding; 214 215 /** 216 * <CODE>DocumentType</CODE> node's publicId. 217 * <BR /> 218 * <BR /><B>OPTIONAL</B> 219 */ 220 public final String publicId; 221 222 /** 223 * <CODE>DocumentType</CODE> node's systemId. 224 * <BR /> 225 * <BR /><B>OPTIONAL</B> 226 */ 227 public final String systemId; 228 229 /** 230 * Frame ID for frame owner elements and also for the document node. 231 * <BR /> 232 * <BR /><B>OPTIONAL</B> 233 */ 234 public final String frameId; 235 236 /** 237 * The index of a frame owner element's content document in the <CODE>domNodes</CODE> array returned by 238 * <CODE>getSnapshot</CODE>, if any. 239 * <BR /> 240 * <BR /><B>OPTIONAL</B> 241 */ 242 public final Integer contentDocumentIndex; 243 244 /** 245 * Type of a pseudo element node. 246 * <BR /> 247 * <BR /><B>OPTIONAL</B> 248 */ 249 public final String pseudoType; 250 251 /** 252 * Shadow root type. 253 * <BR /> 254 * <BR /><B>OPTIONAL</B> 255 */ 256 public final String shadowRootType; 257 258 /** 259 * Whether this DOM node responds to mouse clicks. This includes nodes that have had click 260 * event listeners attached via JavaScript as well as anchor tags that naturally navigate when 261 * clicked. 262 * <BR /> 263 * <BR /><B>OPTIONAL</B> 264 */ 265 public final Boolean isClickable; 266 267 /** 268 * Details of the node's event listeners, if any. 269 * <BR /> 270 * <BR /><B>OPTIONAL</B> 271 */ 272 public final DOMDebugger.EventListener[] eventListeners; 273 274 /** 275 * The selected url for nodes with a srcset attribute. 276 * <BR /> 277 * <BR /><B>OPTIONAL</B> 278 */ 279 public final String currentSourceURL; 280 281 /** 282 * The url of the script (if any) that generates this node. 283 * <BR /> 284 * <BR /><B>OPTIONAL</B> 285 */ 286 public final String originURL; 287 288 /** 289 * Scroll offsets, set when this node is a Document. 290 * <BR /> 291 * <BR /><B>OPTIONAL</B> 292 */ 293 public final Number scrollOffsetX; 294 295 /** 296 * <CODE>[No Description Provided by Google]</CODE> 297 * <BR /> 298 * <BR /><B>OPTIONAL</B> 299 */ 300 public final Number scrollOffsetY; 301 302 /** 303 * Constructor 304 * 305 * @param nodeType <CODE>Node</CODE>'s nodeType. 306 * 307 * @param nodeName <CODE>Node</CODE>'s nodeName. 308 * 309 * @param nodeValue <CODE>Node</CODE>'s nodeValue. 310 * 311 * @param textValue Only set for textarea elements, contains the text value. 312 * <BR /><B>OPTIONAL</B> 313 * 314 * @param inputValue Only set for input elements, contains the input's associated text value. 315 * <BR /><B>OPTIONAL</B> 316 * 317 * @param inputChecked Only set for radio and checkbox input elements, indicates if the element has been checked 318 * <BR /><B>OPTIONAL</B> 319 * 320 * @param optionSelected Only set for option elements, indicates if the element has been selected 321 * <BR /><B>OPTIONAL</B> 322 * 323 * @param backendNodeId <CODE>Node</CODE>'s id, corresponds to DOM.Node.backendNodeId. 324 * 325 * @param childNodeIndexes 326 * The indexes of the node's child nodes in the <CODE>domNodes</CODE> array returned by <CODE>getSnapshot</CODE>, if 327 * any. 328 * <BR /><B>OPTIONAL</B> 329 * 330 * @param attributes Attributes of an <CODE>Element</CODE> node. 331 * <BR /><B>OPTIONAL</B> 332 * 333 * @param pseudoElementIndexes 334 * Indexes of pseudo elements associated with this node in the <CODE>domNodes</CODE> array returned by 335 * <CODE>getSnapshot</CODE>, if any. 336 * <BR /><B>OPTIONAL</B> 337 * 338 * @param layoutNodeIndex 339 * The index of the node's related layout tree node in the <CODE>layoutTreeNodes</CODE> array returned by 340 * <CODE>getSnapshot</CODE>, if any. 341 * <BR /><B>OPTIONAL</B> 342 * 343 * @param documentURL Document URL that <CODE>Document</CODE> or <CODE>FrameOwner</CODE> node points to. 344 * <BR /><B>OPTIONAL</B> 345 * 346 * @param baseURL Base URL that <CODE>Document</CODE> or <CODE>FrameOwner</CODE> node uses for URL completion. 347 * <BR /><B>OPTIONAL</B> 348 * 349 * @param contentLanguage Only set for documents, contains the document's content language. 350 * <BR /><B>OPTIONAL</B> 351 * 352 * @param documentEncoding Only set for documents, contains the document's character set encoding. 353 * <BR /><B>OPTIONAL</B> 354 * 355 * @param publicId <CODE>DocumentType</CODE> node's publicId. 356 * <BR /><B>OPTIONAL</B> 357 * 358 * @param systemId <CODE>DocumentType</CODE> node's systemId. 359 * <BR /><B>OPTIONAL</B> 360 * 361 * @param frameId Frame ID for frame owner elements and also for the document node. 362 * <BR /><B>OPTIONAL</B> 363 * 364 * @param contentDocumentIndex 365 * The index of a frame owner element's content document in the <CODE>domNodes</CODE> array returned by 366 * <CODE>getSnapshot</CODE>, if any. 367 * <BR /><B>OPTIONAL</B> 368 * 369 * @param pseudoType Type of a pseudo element node. 370 * <BR /><B>OPTIONAL</B> 371 * 372 * @param shadowRootType Shadow root type. 373 * <BR /><B>OPTIONAL</B> 374 * 375 * @param isClickable 376 * Whether this DOM node responds to mouse clicks. This includes nodes that have had click 377 * event listeners attached via JavaScript as well as anchor tags that naturally navigate when 378 * clicked. 379 * <BR /><B>OPTIONAL</B> 380 * 381 * @param eventListeners Details of the node's event listeners, if any. 382 * <BR /><B>OPTIONAL</B> 383 * 384 * @param currentSourceURL The selected url for nodes with a srcset attribute. 385 * <BR /><B>OPTIONAL</B> 386 * 387 * @param originURL The url of the script (if any) that generates this node. 388 * <BR /><B>OPTIONAL</B> 389 * 390 * @param scrollOffsetX Scroll offsets, set when this node is a Document. 391 * <BR /><B>OPTIONAL</B> 392 * 393 * @param scrollOffsetY - 394 * <BR /><B>OPTIONAL</B> 395 */ 396 public DOMNode( 397 int nodeType, String nodeName, String nodeValue, String textValue, 398 String inputValue, Boolean inputChecked, Boolean optionSelected, int backendNodeId, 399 int[] childNodeIndexes, DOMSnapshot.NameValue[] attributes, 400 int[] pseudoElementIndexes, Integer layoutNodeIndex, String documentURL, 401 String baseURL, String contentLanguage, String documentEncoding, String publicId, 402 String systemId, String frameId, Integer contentDocumentIndex, String pseudoType, 403 String shadowRootType, Boolean isClickable, 404 DOMDebugger.EventListener[] eventListeners, String currentSourceURL, 405 String originURL, Number scrollOffsetX, Number scrollOffsetY 406 ) 407 { 408 // Exception-Check(s) to ensure that if any parameters which are not declared as 409 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 410 411 if (nodeName == null) THROWS.throwNPE("nodeName"); 412 if (nodeValue == null) THROWS.throwNPE("nodeValue"); 413 414 // Exception-Check(s) to ensure that if any parameters which must adhere to a 415 // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw. 416 417 THROWS.checkIAE("pseudoType", pseudoType, "DOM.PseudoType", DOM.PseudoType); 418 THROWS.checkIAE("shadowRootType", shadowRootType, "DOM.ShadowRootType", DOM.ShadowRootType); 419 420 this.nodeType = nodeType; 421 this.nodeName = nodeName; 422 this.nodeValue = nodeValue; 423 this.textValue = textValue; 424 this.inputValue = inputValue; 425 this.inputChecked = inputChecked; 426 this.optionSelected = optionSelected; 427 this.backendNodeId = backendNodeId; 428 this.childNodeIndexes = childNodeIndexes; 429 this.attributes = attributes; 430 this.pseudoElementIndexes = pseudoElementIndexes; 431 this.layoutNodeIndex = layoutNodeIndex; 432 this.documentURL = documentURL; 433 this.baseURL = baseURL; 434 this.contentLanguage = contentLanguage; 435 this.documentEncoding = documentEncoding; 436 this.publicId = publicId; 437 this.systemId = systemId; 438 this.frameId = frameId; 439 this.contentDocumentIndex = contentDocumentIndex; 440 this.pseudoType = pseudoType; 441 this.shadowRootType = shadowRootType; 442 this.isClickable = isClickable; 443 this.eventListeners = eventListeners; 444 this.currentSourceURL = currentSourceURL; 445 this.originURL = originURL; 446 this.scrollOffsetX = scrollOffsetX; 447 this.scrollOffsetY = scrollOffsetY; 448 } 449 450 /** 451 * JSON Object Constructor 452 * @param jo A Json-Object having data about an instance of {@code 'DOMNode'}. 453 */ 454 public DOMNode (JsonObject jo) 455 { 456 this.nodeType = ReadPrimJSON.getInt(jo, "nodeType"); 457 this.nodeName = ReadJSON.getString(jo, "nodeName", false, true); 458 this.nodeValue = ReadJSON.getString(jo, "nodeValue", false, true); 459 this.textValue = ReadJSON.getString(jo, "textValue", true, false); 460 this.inputValue = ReadJSON.getString(jo, "inputValue", true, false); 461 this.inputChecked = ReadBoxedJSON.getBoolean(jo, "inputChecked", true); 462 this.optionSelected = ReadBoxedJSON.getBoolean(jo, "optionSelected", true); 463 this.backendNodeId = ReadPrimJSON.getInt(jo, "backendNodeId"); 464 this.childNodeIndexes = (jo.getJsonArray("childNodeIndexes") == null) 465 ? null 466 : RJArrIntoPrimArray.intArr(jo.getJsonArray("childNodeIndexes"), -1, 0, null); 467 468 this.attributes = (jo.getJsonArray("attributes") == null) 469 ? null 470 : RJArrIntoStream.objArr(jo.getJsonArray("attributes"), null, 0, DOMSnapshot.NameValue.class).toArray(DOMSnapshot.NameValue[]::new); 471 472 this.pseudoElementIndexes = (jo.getJsonArray("pseudoElementIndexes") == null) 473 ? null 474 : RJArrIntoPrimArray.intArr(jo.getJsonArray("pseudoElementIndexes"), -1, 0, null); 475 476 this.layoutNodeIndex = ReadBoxedJSON.getInteger(jo, "layoutNodeIndex", true); 477 this.documentURL = ReadJSON.getString(jo, "documentURL", true, false); 478 this.baseURL = ReadJSON.getString(jo, "baseURL", true, false); 479 this.contentLanguage = ReadJSON.getString(jo, "contentLanguage", true, false); 480 this.documentEncoding = ReadJSON.getString(jo, "documentEncoding", true, false); 481 this.publicId = ReadJSON.getString(jo, "publicId", true, false); 482 this.systemId = ReadJSON.getString(jo, "systemId", true, false); 483 this.frameId = ReadJSON.getString(jo, "frameId", true, false); 484 this.contentDocumentIndex = ReadBoxedJSON.getInteger(jo, "contentDocumentIndex", true); 485 this.pseudoType = ReadJSON.getString(jo, "pseudoType", true, false); 486 this.shadowRootType = ReadJSON.getString(jo, "shadowRootType", true, false); 487 this.isClickable = ReadBoxedJSON.getBoolean(jo, "isClickable", true); 488 this.eventListeners = (jo.getJsonArray("eventListeners") == null) 489 ? null 490 : RJArrIntoStream.objArr(jo.getJsonArray("eventListeners"), null, 0, DOMDebugger.EventListener.class).toArray(DOMDebugger.EventListener[]::new); 491 492 this.currentSourceURL = ReadJSON.getString(jo, "currentSourceURL", true, false); 493 this.originURL = ReadJSON.getString(jo, "originURL", true, false); 494 this.scrollOffsetX = ReadNumberJSON.get(jo, "scrollOffsetX", true, false); 495 this.scrollOffsetY = ReadNumberJSON.get(jo, "scrollOffsetY", true, false); 496 } 497 498 499 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 500 public boolean equals(Object other) 501 { 502 if (this == other) return true; 503 if (other == null) return false; 504 if (other.getClass() != this.getClass()) return false; 505 506 DOMNode o = (DOMNode) other; 507 508 return 509 (this.nodeType == o.nodeType) 510 && Objects.equals(this.nodeName, o.nodeName) 511 && Objects.equals(this.nodeValue, o.nodeValue) 512 && Objects.equals(this.textValue, o.textValue) 513 && Objects.equals(this.inputValue, o.inputValue) 514 && Objects.equals(this.inputChecked, o.inputChecked) 515 && Objects.equals(this.optionSelected, o.optionSelected) 516 && Objects.equals(this.backendNodeId, o.backendNodeId) 517 && Arrays.equals(this.childNodeIndexes, o.childNodeIndexes) 518 && Arrays.deepEquals(this.attributes, o.attributes) 519 && Arrays.equals(this.pseudoElementIndexes, o.pseudoElementIndexes) 520 && Objects.equals(this.layoutNodeIndex, o.layoutNodeIndex) 521 && Objects.equals(this.documentURL, o.documentURL) 522 && Objects.equals(this.baseURL, o.baseURL) 523 && Objects.equals(this.contentLanguage, o.contentLanguage) 524 && Objects.equals(this.documentEncoding, o.documentEncoding) 525 && Objects.equals(this.publicId, o.publicId) 526 && Objects.equals(this.systemId, o.systemId) 527 && Objects.equals(this.frameId, o.frameId) 528 && Objects.equals(this.contentDocumentIndex, o.contentDocumentIndex) 529 && Objects.equals(this.pseudoType, o.pseudoType) 530 && Objects.equals(this.shadowRootType, o.shadowRootType) 531 && Objects.equals(this.isClickable, o.isClickable) 532 && Arrays.deepEquals(this.eventListeners, o.eventListeners) 533 && Objects.equals(this.currentSourceURL, o.currentSourceURL) 534 && Objects.equals(this.originURL, o.originURL) 535 && Objects.equals(this.scrollOffsetX, o.scrollOffsetX) 536 && Objects.equals(this.scrollOffsetY, o.scrollOffsetY); 537 } 538 539 /** Generates a Hash-Code for {@code 'this'} instance */ 540 public int hashCode() 541 { 542 return 543 this.nodeType 544 + Objects.hashCode(this.nodeName) 545 + Objects.hashCode(this.nodeValue) 546 + Objects.hashCode(this.textValue) 547 + Objects.hashCode(this.inputValue) 548 + Objects.hashCode(this.inputChecked) 549 + Objects.hashCode(this.optionSelected) 550 + this.backendNodeId 551 + Arrays.hashCode(this.childNodeIndexes) 552 + Arrays.deepHashCode(this.attributes) 553 + Arrays.hashCode(this.pseudoElementIndexes) 554 + Objects.hashCode(this.layoutNodeIndex) 555 + Objects.hashCode(this.documentURL) 556 + Objects.hashCode(this.baseURL) 557 + Objects.hashCode(this.contentLanguage) 558 + Objects.hashCode(this.documentEncoding) 559 + Objects.hashCode(this.publicId) 560 + Objects.hashCode(this.systemId) 561 + Objects.hashCode(this.frameId) 562 + Objects.hashCode(this.contentDocumentIndex) 563 + Objects.hashCode(this.pseudoType) 564 + Objects.hashCode(this.shadowRootType) 565 + Objects.hashCode(this.isClickable) 566 + Arrays.deepHashCode(this.eventListeners) 567 + Objects.hashCode(this.currentSourceURL) 568 + Objects.hashCode(this.originURL) 569 + Objects.hashCode(this.scrollOffsetX) 570 + Objects.hashCode(this.scrollOffsetY); 571 } 572 } 573 574 /** 575 * Details of post layout rendered text positions. The exact layout should not be regarded as 576 * stable and may change between versions. 577 */ 578 public static class InlineTextBox 579 extends BaseType 580 implements java.io.Serializable 581 { 582 /** For Object Serialization. java.io.Serializable */ 583 protected static final long serialVersionUID = 1; 584 585 public boolean[] optionals() 586 { return new boolean[] { false, false, false, }; } 587 588 /** The bounding box in document coordinates. Note that scroll offset of the document is ignored. */ 589 public final DOM.Rect boundingBox; 590 591 /** 592 * The starting index in characters, for this post layout textbox substring. Characters that 593 * would be represented as a surrogate pair in UTF-16 have length 2. 594 */ 595 public final int startCharacterIndex; 596 597 /** 598 * The number of characters in this post layout textbox substring. Characters that would be 599 * represented as a surrogate pair in UTF-16 have length 2. 600 */ 601 public final int numCharacters; 602 603 /** 604 * Constructor 605 * 606 * @param boundingBox The bounding box in document coordinates. Note that scroll offset of the document is ignored. 607 * 608 * @param startCharacterIndex 609 * The starting index in characters, for this post layout textbox substring. Characters that 610 * would be represented as a surrogate pair in UTF-16 have length 2. 611 * 612 * @param numCharacters 613 * The number of characters in this post layout textbox substring. Characters that would be 614 * represented as a surrogate pair in UTF-16 have length 2. 615 */ 616 public InlineTextBox(DOM.Rect boundingBox, int startCharacterIndex, int numCharacters) 617 { 618 // Exception-Check(s) to ensure that if any parameters which are not declared as 619 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 620 621 if (boundingBox == null) THROWS.throwNPE("boundingBox"); 622 623 this.boundingBox = boundingBox; 624 this.startCharacterIndex = startCharacterIndex; 625 this.numCharacters = numCharacters; 626 } 627 628 /** 629 * JSON Object Constructor 630 * @param jo A Json-Object having data about an instance of {@code 'InlineTextBox'}. 631 */ 632 public InlineTextBox (JsonObject jo) 633 { 634 this.boundingBox = ReadJSON.getObject(jo, "boundingBox", DOM.Rect.class, false, true); 635 this.startCharacterIndex = ReadPrimJSON.getInt(jo, "startCharacterIndex"); 636 this.numCharacters = ReadPrimJSON.getInt(jo, "numCharacters"); 637 } 638 639 640 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 641 public boolean equals(Object other) 642 { 643 if (this == other) return true; 644 if (other == null) return false; 645 if (other.getClass() != this.getClass()) return false; 646 647 InlineTextBox o = (InlineTextBox) other; 648 649 return 650 Objects.equals(this.boundingBox, o.boundingBox) 651 && (this.startCharacterIndex == o.startCharacterIndex) 652 && (this.numCharacters == o.numCharacters); 653 } 654 655 /** Generates a Hash-Code for {@code 'this'} instance */ 656 public int hashCode() 657 { 658 return 659 this.boundingBox.hashCode() 660 + this.startCharacterIndex 661 + this.numCharacters; 662 } 663 } 664 665 /** Details of an element in the DOM tree with a LayoutObject. */ 666 public static class LayoutTreeNode 667 extends BaseType 668 implements java.io.Serializable 669 { 670 /** For Object Serialization. java.io.Serializable */ 671 protected static final long serialVersionUID = 1; 672 673 public boolean[] optionals() 674 { return new boolean[] { false, false, true, true, true, true, true, }; } 675 676 /** The index of the related DOM node in the <CODE>domNodes</CODE> array returned by <CODE>getSnapshot</CODE>. */ 677 public final int domNodeIndex; 678 679 /** The bounding box in document coordinates. Note that scroll offset of the document is ignored. */ 680 public final DOM.Rect boundingBox; 681 682 /** 683 * Contents of the LayoutText, if any. 684 * <BR /> 685 * <BR /><B>OPTIONAL</B> 686 */ 687 public final String layoutText; 688 689 /** 690 * The post-layout inline text nodes, if any. 691 * <BR /> 692 * <BR /><B>OPTIONAL</B> 693 */ 694 public final DOMSnapshot.InlineTextBox[] inlineTextNodes; 695 696 /** 697 * Index into the <CODE>computedStyles</CODE> array returned by <CODE>getSnapshot</CODE>. 698 * <BR /> 699 * <BR /><B>OPTIONAL</B> 700 */ 701 public final Integer styleIndex; 702 703 /** 704 * Global paint order index, which is determined by the stacking order of the nodes. Nodes 705 * that are painted together will have the same index. Only provided if includePaintOrder in 706 * getSnapshot was true. 707 * <BR /> 708 * <BR /><B>OPTIONAL</B> 709 */ 710 public final Integer paintOrder; 711 712 /** 713 * Set to true to indicate the element begins a new stacking context. 714 * <BR /> 715 * <BR /><B>OPTIONAL</B> 716 */ 717 public final Boolean isStackingContext; 718 719 /** 720 * Constructor 721 * 722 * @param domNodeIndex The index of the related DOM node in the <CODE>domNodes</CODE> array returned by <CODE>getSnapshot</CODE>. 723 * 724 * @param boundingBox The bounding box in document coordinates. Note that scroll offset of the document is ignored. 725 * 726 * @param layoutText Contents of the LayoutText, if any. 727 * <BR /><B>OPTIONAL</B> 728 * 729 * @param inlineTextNodes The post-layout inline text nodes, if any. 730 * <BR /><B>OPTIONAL</B> 731 * 732 * @param styleIndex Index into the <CODE>computedStyles</CODE> array returned by <CODE>getSnapshot</CODE>. 733 * <BR /><B>OPTIONAL</B> 734 * 735 * @param paintOrder 736 * Global paint order index, which is determined by the stacking order of the nodes. Nodes 737 * that are painted together will have the same index. Only provided if includePaintOrder in 738 * getSnapshot was true. 739 * <BR /><B>OPTIONAL</B> 740 * 741 * @param isStackingContext Set to true to indicate the element begins a new stacking context. 742 * <BR /><B>OPTIONAL</B> 743 */ 744 public LayoutTreeNode( 745 int domNodeIndex, DOM.Rect boundingBox, String layoutText, 746 DOMSnapshot.InlineTextBox[] inlineTextNodes, Integer styleIndex, Integer paintOrder, 747 Boolean isStackingContext 748 ) 749 { 750 // Exception-Check(s) to ensure that if any parameters which are not declared as 751 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 752 753 if (boundingBox == null) THROWS.throwNPE("boundingBox"); 754 755 this.domNodeIndex = domNodeIndex; 756 this.boundingBox = boundingBox; 757 this.layoutText = layoutText; 758 this.inlineTextNodes = inlineTextNodes; 759 this.styleIndex = styleIndex; 760 this.paintOrder = paintOrder; 761 this.isStackingContext = isStackingContext; 762 } 763 764 /** 765 * JSON Object Constructor 766 * @param jo A Json-Object having data about an instance of {@code 'LayoutTreeNode'}. 767 */ 768 public LayoutTreeNode (JsonObject jo) 769 { 770 this.domNodeIndex = ReadPrimJSON.getInt(jo, "domNodeIndex"); 771 this.boundingBox = ReadJSON.getObject(jo, "boundingBox", DOM.Rect.class, false, true); 772 this.layoutText = ReadJSON.getString(jo, "layoutText", true, false); 773 this.inlineTextNodes = (jo.getJsonArray("inlineTextNodes") == null) 774 ? null 775 : RJArrIntoStream.objArr(jo.getJsonArray("inlineTextNodes"), null, 0, DOMSnapshot.InlineTextBox.class).toArray(DOMSnapshot.InlineTextBox[]::new); 776 777 this.styleIndex = ReadBoxedJSON.getInteger(jo, "styleIndex", true); 778 this.paintOrder = ReadBoxedJSON.getInteger(jo, "paintOrder", true); 779 this.isStackingContext = ReadBoxedJSON.getBoolean(jo, "isStackingContext", true); 780 } 781 782 783 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 784 public boolean equals(Object other) 785 { 786 if (this == other) return true; 787 if (other == null) return false; 788 if (other.getClass() != this.getClass()) return false; 789 790 LayoutTreeNode o = (LayoutTreeNode) other; 791 792 return 793 (this.domNodeIndex == o.domNodeIndex) 794 && Objects.equals(this.boundingBox, o.boundingBox) 795 && Objects.equals(this.layoutText, o.layoutText) 796 && Arrays.deepEquals(this.inlineTextNodes, o.inlineTextNodes) 797 && Objects.equals(this.styleIndex, o.styleIndex) 798 && Objects.equals(this.paintOrder, o.paintOrder) 799 && Objects.equals(this.isStackingContext, o.isStackingContext); 800 } 801 802 /** Generates a Hash-Code for {@code 'this'} instance */ 803 public int hashCode() 804 { 805 return 806 this.domNodeIndex 807 + this.boundingBox.hashCode() 808 + Objects.hashCode(this.layoutText) 809 + Arrays.deepHashCode(this.inlineTextNodes) 810 + Objects.hashCode(this.styleIndex) 811 + Objects.hashCode(this.paintOrder) 812 + Objects.hashCode(this.isStackingContext); 813 } 814 } 815 816 /** A subset of the full ComputedStyle as defined by the request whitelist. */ 817 public static class ComputedStyle 818 extends BaseType 819 implements java.io.Serializable 820 { 821 /** For Object Serialization. java.io.Serializable */ 822 protected static final long serialVersionUID = 1; 823 824 public boolean[] optionals() 825 { return new boolean[] { false, }; } 826 827 /** Name/value pairs of computed style properties. */ 828 public final DOMSnapshot.NameValue[] properties; 829 830 /** 831 * Constructor 832 * 833 * @param properties Name/value pairs of computed style properties. 834 */ 835 public ComputedStyle(DOMSnapshot.NameValue[] properties) 836 { 837 // Exception-Check(s) to ensure that if any parameters which are not declared as 838 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 839 840 if (properties == null) THROWS.throwNPE("properties"); 841 842 this.properties = properties; 843 } 844 845 /** 846 * JSON Object Constructor 847 * @param jo A Json-Object having data about an instance of {@code 'ComputedStyle'}. 848 */ 849 public ComputedStyle (JsonObject jo) 850 { 851 this.properties = (jo.getJsonArray("properties") == null) 852 ? null 853 : RJArrIntoStream.objArr(jo.getJsonArray("properties"), null, 0, DOMSnapshot.NameValue.class).toArray(DOMSnapshot.NameValue[]::new); 854 855 } 856 857 858 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 859 public boolean equals(Object other) 860 { 861 if (this == other) return true; 862 if (other == null) return false; 863 if (other.getClass() != this.getClass()) return false; 864 865 ComputedStyle o = (ComputedStyle) other; 866 867 return 868 Arrays.deepEquals(this.properties, o.properties); 869 } 870 871 /** Generates a Hash-Code for {@code 'this'} instance */ 872 public int hashCode() 873 { 874 return 875 Arrays.deepHashCode(this.properties); 876 } 877 } 878 879 /** A name/value pair. */ 880 public static class NameValue 881 extends BaseType 882 implements java.io.Serializable 883 { 884 /** For Object Serialization. java.io.Serializable */ 885 protected static final long serialVersionUID = 1; 886 887 public boolean[] optionals() 888 { return new boolean[] { false, false, }; } 889 890 /** Attribute/property name. */ 891 public final String name; 892 893 /** Attribute/property value. */ 894 public final String value; 895 896 /** 897 * Constructor 898 * 899 * @param name Attribute/property name. 900 * 901 * @param value Attribute/property value. 902 */ 903 public NameValue(String name, String value) 904 { 905 // Exception-Check(s) to ensure that if any parameters which are not declared as 906 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 907 908 if (name == null) THROWS.throwNPE("name"); 909 if (value == null) THROWS.throwNPE("value"); 910 911 this.name = name; 912 this.value = value; 913 } 914 915 /** 916 * JSON Object Constructor 917 * @param jo A Json-Object having data about an instance of {@code 'NameValue'}. 918 */ 919 public NameValue (JsonObject jo) 920 { 921 this.name = ReadJSON.getString(jo, "name", false, true); 922 this.value = ReadJSON.getString(jo, "value", false, true); 923 } 924 925 926 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 927 public boolean equals(Object other) 928 { 929 if (this == other) return true; 930 if (other == null) return false; 931 if (other.getClass() != this.getClass()) return false; 932 933 NameValue o = (NameValue) other; 934 935 return 936 Objects.equals(this.name, o.name) 937 && Objects.equals(this.value, o.value); 938 } 939 940 /** Generates a Hash-Code for {@code 'this'} instance */ 941 public int hashCode() 942 { 943 return 944 Objects.hashCode(this.name) 945 + Objects.hashCode(this.value); 946 } 947 } 948 949 /** Data that is only present on rare nodes. */ 950 public static class RareStringData 951 extends BaseType 952 implements java.io.Serializable 953 { 954 /** For Object Serialization. java.io.Serializable */ 955 protected static final long serialVersionUID = 1; 956 957 public boolean[] optionals() 958 { return new boolean[] { false, false, }; } 959 960 /** <CODE>[No Description Provided by Google]</CODE> */ 961 public final int[] index; 962 963 /** <CODE>[No Description Provided by Google]</CODE> */ 964 public final int[] value; 965 966 /** 967 * Constructor 968 * 969 * @param index - 970 * 971 * @param value - 972 */ 973 public RareStringData(int[] index, int[] value) 974 { 975 // Exception-Check(s) to ensure that if any parameters which are not declared as 976 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 977 978 if (index == null) THROWS.throwNPE("index"); 979 if (value == null) THROWS.throwNPE("value"); 980 981 this.index = index; 982 this.value = value; 983 } 984 985 /** 986 * JSON Object Constructor 987 * @param jo A Json-Object having data about an instance of {@code 'RareStringData'}. 988 */ 989 public RareStringData (JsonObject jo) 990 { 991 this.index = (jo.getJsonArray("index") == null) 992 ? null 993 : RJArrIntoPrimArray.intArr(jo.getJsonArray("index"), -1, 0, null); 994 995 this.value = (jo.getJsonArray("value") == null) 996 ? null 997 : RJArrIntoPrimArray.intArr(jo.getJsonArray("value"), -1, 0, null); 998 999 } 1000 1001 1002 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 1003 public boolean equals(Object other) 1004 { 1005 if (this == other) return true; 1006 if (other == null) return false; 1007 if (other.getClass() != this.getClass()) return false; 1008 1009 RareStringData o = (RareStringData) other; 1010 1011 return 1012 Arrays.equals(this.index, o.index) 1013 && Arrays.equals(this.value, o.value); 1014 } 1015 1016 /** Generates a Hash-Code for {@code 'this'} instance */ 1017 public int hashCode() 1018 { 1019 return 1020 Arrays.hashCode(this.index) 1021 + Arrays.hashCode(this.value); 1022 } 1023 } 1024 1025 /** <CODE>[No Description Provided by Google]</CODE> */ 1026 public static class RareBooleanData 1027 extends BaseType 1028 implements java.io.Serializable 1029 { 1030 /** For Object Serialization. java.io.Serializable */ 1031 protected static final long serialVersionUID = 1; 1032 1033 public boolean[] optionals() 1034 { return new boolean[] { false, }; } 1035 1036 /** <CODE>[No Description Provided by Google]</CODE> */ 1037 public final int[] index; 1038 1039 /** 1040 * Constructor 1041 * 1042 * @param index - 1043 */ 1044 public RareBooleanData(int[] index) 1045 { 1046 // Exception-Check(s) to ensure that if any parameters which are not declared as 1047 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 1048 1049 if (index == null) THROWS.throwNPE("index"); 1050 1051 this.index = index; 1052 } 1053 1054 /** 1055 * JSON Object Constructor 1056 * @param jo A Json-Object having data about an instance of {@code 'RareBooleanData'}. 1057 */ 1058 public RareBooleanData (JsonObject jo) 1059 { 1060 this.index = (jo.getJsonArray("index") == null) 1061 ? null 1062 : RJArrIntoPrimArray.intArr(jo.getJsonArray("index"), -1, 0, null); 1063 1064 } 1065 1066 1067 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 1068 public boolean equals(Object other) 1069 { 1070 if (this == other) return true; 1071 if (other == null) return false; 1072 if (other.getClass() != this.getClass()) return false; 1073 1074 RareBooleanData o = (RareBooleanData) other; 1075 1076 return 1077 Arrays.equals(this.index, o.index); 1078 } 1079 1080 /** Generates a Hash-Code for {@code 'this'} instance */ 1081 public int hashCode() 1082 { 1083 return 1084 Arrays.hashCode(this.index); 1085 } 1086 } 1087 1088 /** <CODE>[No Description Provided by Google]</CODE> */ 1089 public static class RareIntegerData 1090 extends BaseType 1091 implements java.io.Serializable 1092 { 1093 /** For Object Serialization. java.io.Serializable */ 1094 protected static final long serialVersionUID = 1; 1095 1096 public boolean[] optionals() 1097 { return new boolean[] { false, false, }; } 1098 1099 /** <CODE>[No Description Provided by Google]</CODE> */ 1100 public final int[] index; 1101 1102 /** <CODE>[No Description Provided by Google]</CODE> */ 1103 public final int[] value; 1104 1105 /** 1106 * Constructor 1107 * 1108 * @param index - 1109 * 1110 * @param value - 1111 */ 1112 public RareIntegerData(int[] index, int[] value) 1113 { 1114 // Exception-Check(s) to ensure that if any parameters which are not declared as 1115 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 1116 1117 if (index == null) THROWS.throwNPE("index"); 1118 if (value == null) THROWS.throwNPE("value"); 1119 1120 this.index = index; 1121 this.value = value; 1122 } 1123 1124 /** 1125 * JSON Object Constructor 1126 * @param jo A Json-Object having data about an instance of {@code 'RareIntegerData'}. 1127 */ 1128 public RareIntegerData (JsonObject jo) 1129 { 1130 this.index = (jo.getJsonArray("index") == null) 1131 ? null 1132 : RJArrIntoPrimArray.intArr(jo.getJsonArray("index"), -1, 0, null); 1133 1134 this.value = (jo.getJsonArray("value") == null) 1135 ? null 1136 : RJArrIntoPrimArray.intArr(jo.getJsonArray("value"), -1, 0, null); 1137 1138 } 1139 1140 1141 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 1142 public boolean equals(Object other) 1143 { 1144 if (this == other) return true; 1145 if (other == null) return false; 1146 if (other.getClass() != this.getClass()) return false; 1147 1148 RareIntegerData o = (RareIntegerData) other; 1149 1150 return 1151 Arrays.equals(this.index, o.index) 1152 && Arrays.equals(this.value, o.value); 1153 } 1154 1155 /** Generates a Hash-Code for {@code 'this'} instance */ 1156 public int hashCode() 1157 { 1158 return 1159 Arrays.hashCode(this.index) 1160 + Arrays.hashCode(this.value); 1161 } 1162 } 1163 1164 /** Document snapshot. */ 1165 public static class DocumentSnapshot 1166 extends BaseType 1167 implements java.io.Serializable 1168 { 1169 /** For Object Serialization. java.io.Serializable */ 1170 protected static final long serialVersionUID = 1; 1171 1172 public boolean[] optionals() 1173 { return new boolean[] { false, false, false, false, false, false, false, false, false, false, false, true, true, true, true, }; } 1174 1175 /** Document URL that <CODE>Document</CODE> or <CODE>FrameOwner</CODE> node points to. */ 1176 public final int documentURL; 1177 1178 /** Document title. */ 1179 public final int title; 1180 1181 /** Base URL that <CODE>Document</CODE> or <CODE>FrameOwner</CODE> node uses for URL completion. */ 1182 public final int baseURL; 1183 1184 /** Contains the document's content language. */ 1185 public final int contentLanguage; 1186 1187 /** Contains the document's character set encoding. */ 1188 public final int encodingName; 1189 1190 /** <CODE>DocumentType</CODE> node's publicId. */ 1191 public final int publicId; 1192 1193 /** <CODE>DocumentType</CODE> node's systemId. */ 1194 public final int systemId; 1195 1196 /** Frame ID for frame owner elements and also for the document node. */ 1197 public final int frameId; 1198 1199 /** A table with dom nodes. */ 1200 public final DOMSnapshot.NodeTreeSnapshot nodes; 1201 1202 /** The nodes in the layout tree. */ 1203 public final DOMSnapshot.LayoutTreeSnapshot layout; 1204 1205 /** The post-layout inline text nodes. */ 1206 public final DOMSnapshot.TextBoxSnapshot textBoxes; 1207 1208 /** 1209 * Horizontal scroll offset. 1210 * <BR /> 1211 * <BR /><B>OPTIONAL</B> 1212 */ 1213 public final Number scrollOffsetX; 1214 1215 /** 1216 * Vertical scroll offset. 1217 * <BR /> 1218 * <BR /><B>OPTIONAL</B> 1219 */ 1220 public final Number scrollOffsetY; 1221 1222 /** 1223 * Document content width. 1224 * <BR /> 1225 * <BR /><B>OPTIONAL</B> 1226 */ 1227 public final Number contentWidth; 1228 1229 /** 1230 * Document content height. 1231 * <BR /> 1232 * <BR /><B>OPTIONAL</B> 1233 */ 1234 public final Number contentHeight; 1235 1236 /** 1237 * Constructor 1238 * 1239 * @param documentURL Document URL that <CODE>Document</CODE> or <CODE>FrameOwner</CODE> node points to. 1240 * 1241 * @param title Document title. 1242 * 1243 * @param baseURL Base URL that <CODE>Document</CODE> or <CODE>FrameOwner</CODE> node uses for URL completion. 1244 * 1245 * @param contentLanguage Contains the document's content language. 1246 * 1247 * @param encodingName Contains the document's character set encoding. 1248 * 1249 * @param publicId <CODE>DocumentType</CODE> node's publicId. 1250 * 1251 * @param systemId <CODE>DocumentType</CODE> node's systemId. 1252 * 1253 * @param frameId Frame ID for frame owner elements and also for the document node. 1254 * 1255 * @param nodes A table with dom nodes. 1256 * 1257 * @param layout The nodes in the layout tree. 1258 * 1259 * @param textBoxes The post-layout inline text nodes. 1260 * 1261 * @param scrollOffsetX Horizontal scroll offset. 1262 * <BR /><B>OPTIONAL</B> 1263 * 1264 * @param scrollOffsetY Vertical scroll offset. 1265 * <BR /><B>OPTIONAL</B> 1266 * 1267 * @param contentWidth Document content width. 1268 * <BR /><B>OPTIONAL</B> 1269 * 1270 * @param contentHeight Document content height. 1271 * <BR /><B>OPTIONAL</B> 1272 */ 1273 public DocumentSnapshot( 1274 int documentURL, int title, int baseURL, int contentLanguage, int encodingName, 1275 int publicId, int systemId, int frameId, DOMSnapshot.NodeTreeSnapshot nodes, 1276 DOMSnapshot.LayoutTreeSnapshot layout, DOMSnapshot.TextBoxSnapshot textBoxes, 1277 Number scrollOffsetX, Number scrollOffsetY, Number contentWidth, Number contentHeight 1278 ) 1279 { 1280 // Exception-Check(s) to ensure that if any parameters which are not declared as 1281 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 1282 1283 if (nodes == null) THROWS.throwNPE("nodes"); 1284 if (layout == null) THROWS.throwNPE("layout"); 1285 if (textBoxes == null) THROWS.throwNPE("textBoxes"); 1286 1287 this.documentURL = documentURL; 1288 this.title = title; 1289 this.baseURL = baseURL; 1290 this.contentLanguage = contentLanguage; 1291 this.encodingName = encodingName; 1292 this.publicId = publicId; 1293 this.systemId = systemId; 1294 this.frameId = frameId; 1295 this.nodes = nodes; 1296 this.layout = layout; 1297 this.textBoxes = textBoxes; 1298 this.scrollOffsetX = scrollOffsetX; 1299 this.scrollOffsetY = scrollOffsetY; 1300 this.contentWidth = contentWidth; 1301 this.contentHeight = contentHeight; 1302 } 1303 1304 /** 1305 * JSON Object Constructor 1306 * @param jo A Json-Object having data about an instance of {@code 'DocumentSnapshot'}. 1307 */ 1308 public DocumentSnapshot (JsonObject jo) 1309 { 1310 this.documentURL = ReadPrimJSON.getInt(jo, "documentURL"); 1311 this.title = ReadPrimJSON.getInt(jo, "title"); 1312 this.baseURL = ReadPrimJSON.getInt(jo, "baseURL"); 1313 this.contentLanguage = ReadPrimJSON.getInt(jo, "contentLanguage"); 1314 this.encodingName = ReadPrimJSON.getInt(jo, "encodingName"); 1315 this.publicId = ReadPrimJSON.getInt(jo, "publicId"); 1316 this.systemId = ReadPrimJSON.getInt(jo, "systemId"); 1317 this.frameId = ReadPrimJSON.getInt(jo, "frameId"); 1318 this.nodes = ReadJSON.getObject(jo, "nodes", DOMSnapshot.NodeTreeSnapshot.class, false, true); 1319 this.layout = ReadJSON.getObject(jo, "layout", DOMSnapshot.LayoutTreeSnapshot.class, false, true); 1320 this.textBoxes = ReadJSON.getObject(jo, "textBoxes", DOMSnapshot.TextBoxSnapshot.class, false, true); 1321 this.scrollOffsetX = ReadNumberJSON.get(jo, "scrollOffsetX", true, false); 1322 this.scrollOffsetY = ReadNumberJSON.get(jo, "scrollOffsetY", true, false); 1323 this.contentWidth = ReadNumberJSON.get(jo, "contentWidth", true, false); 1324 this.contentHeight = ReadNumberJSON.get(jo, "contentHeight", true, false); 1325 } 1326 1327 1328 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 1329 public boolean equals(Object other) 1330 { 1331 if (this == other) return true; 1332 if (other == null) return false; 1333 if (other.getClass() != this.getClass()) return false; 1334 1335 DocumentSnapshot o = (DocumentSnapshot) other; 1336 1337 return 1338 Objects.equals(this.documentURL, o.documentURL) 1339 && Objects.equals(this.title, o.title) 1340 && Objects.equals(this.baseURL, o.baseURL) 1341 && Objects.equals(this.contentLanguage, o.contentLanguage) 1342 && Objects.equals(this.encodingName, o.encodingName) 1343 && Objects.equals(this.publicId, o.publicId) 1344 && Objects.equals(this.systemId, o.systemId) 1345 && Objects.equals(this.frameId, o.frameId) 1346 && Objects.equals(this.nodes, o.nodes) 1347 && Objects.equals(this.layout, o.layout) 1348 && Objects.equals(this.textBoxes, o.textBoxes) 1349 && Objects.equals(this.scrollOffsetX, o.scrollOffsetX) 1350 && Objects.equals(this.scrollOffsetY, o.scrollOffsetY) 1351 && Objects.equals(this.contentWidth, o.contentWidth) 1352 && Objects.equals(this.contentHeight, o.contentHeight); 1353 } 1354 1355 /** Generates a Hash-Code for {@code 'this'} instance */ 1356 public int hashCode() 1357 { 1358 return 1359 this.documentURL 1360 + this.title 1361 + this.baseURL 1362 + this.contentLanguage 1363 + this.encodingName 1364 + this.publicId 1365 + this.systemId 1366 + this.frameId 1367 + this.nodes.hashCode() 1368 + this.layout.hashCode() 1369 + this.textBoxes.hashCode() 1370 + Objects.hashCode(this.scrollOffsetX) 1371 + Objects.hashCode(this.scrollOffsetY) 1372 + Objects.hashCode(this.contentWidth) 1373 + Objects.hashCode(this.contentHeight); 1374 } 1375 } 1376 1377 /** Table containing nodes. */ 1378 public static class NodeTreeSnapshot 1379 extends BaseType 1380 implements java.io.Serializable 1381 { 1382 /** For Object Serialization. java.io.Serializable */ 1383 protected static final long serialVersionUID = 1; 1384 1385 public boolean[] optionals() 1386 { return new boolean[] { true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, }; } 1387 1388 /** 1389 * Parent node index. 1390 * <BR /> 1391 * <BR /><B>OPTIONAL</B> 1392 */ 1393 public final int[] parentIndex; 1394 1395 /** 1396 * <CODE>Node</CODE>'s nodeType. 1397 * <BR /> 1398 * <BR /><B>OPTIONAL</B> 1399 */ 1400 public final int[] nodeType; 1401 1402 /** 1403 * Type of the shadow root the <CODE>Node</CODE> is in. String values are equal to the <CODE>ShadowRootType</CODE> enum. 1404 * <BR /> 1405 * <BR /><B>OPTIONAL</B> 1406 */ 1407 public final DOMSnapshot.RareStringData shadowRootType; 1408 1409 /** 1410 * <CODE>Node</CODE>'s nodeName. 1411 * <BR /> 1412 * <BR /><B>OPTIONAL</B> 1413 */ 1414 public final int[] nodeName; 1415 1416 /** 1417 * <CODE>Node</CODE>'s nodeValue. 1418 * <BR /> 1419 * <BR /><B>OPTIONAL</B> 1420 */ 1421 public final int[] nodeValue; 1422 1423 /** 1424 * <CODE>Node</CODE>'s id, corresponds to DOM.Node.backendNodeId. 1425 * <BR /> 1426 * <BR /><B>OPTIONAL</B> 1427 */ 1428 public final int[] backendNodeId; 1429 1430 /** 1431 * Attributes of an <CODE>Element</CODE> node. Flatten name, value pairs. 1432 * <BR /> 1433 * <BR /><B>OPTIONAL</B> 1434 */ 1435 public final int[][] attributes; 1436 1437 /** 1438 * Only set for textarea elements, contains the text value. 1439 * <BR /> 1440 * <BR /><B>OPTIONAL</B> 1441 */ 1442 public final DOMSnapshot.RareStringData textValue; 1443 1444 /** 1445 * Only set for input elements, contains the input's associated text value. 1446 * <BR /> 1447 * <BR /><B>OPTIONAL</B> 1448 */ 1449 public final DOMSnapshot.RareStringData inputValue; 1450 1451 /** 1452 * Only set for radio and checkbox input elements, indicates if the element has been checked 1453 * <BR /> 1454 * <BR /><B>OPTIONAL</B> 1455 */ 1456 public final DOMSnapshot.RareBooleanData inputChecked; 1457 1458 /** 1459 * Only set for option elements, indicates if the element has been selected 1460 * <BR /> 1461 * <BR /><B>OPTIONAL</B> 1462 */ 1463 public final DOMSnapshot.RareBooleanData optionSelected; 1464 1465 /** 1466 * The index of the document in the list of the snapshot documents. 1467 * <BR /> 1468 * <BR /><B>OPTIONAL</B> 1469 */ 1470 public final DOMSnapshot.RareIntegerData contentDocumentIndex; 1471 1472 /** 1473 * Type of a pseudo element node. 1474 * <BR /> 1475 * <BR /><B>OPTIONAL</B> 1476 */ 1477 public final DOMSnapshot.RareStringData pseudoType; 1478 1479 /** 1480 * Whether this DOM node responds to mouse clicks. This includes nodes that have had click 1481 * event listeners attached via JavaScript as well as anchor tags that naturally navigate when 1482 * clicked. 1483 * <BR /> 1484 * <BR /><B>OPTIONAL</B> 1485 */ 1486 public final DOMSnapshot.RareBooleanData isClickable; 1487 1488 /** 1489 * The selected url for nodes with a srcset attribute. 1490 * <BR /> 1491 * <BR /><B>OPTIONAL</B> 1492 */ 1493 public final DOMSnapshot.RareStringData currentSourceURL; 1494 1495 /** 1496 * The url of the script (if any) that generates this node. 1497 * <BR /> 1498 * <BR /><B>OPTIONAL</B> 1499 */ 1500 public final DOMSnapshot.RareStringData originURL; 1501 1502 /** 1503 * Constructor 1504 * 1505 * @param parentIndex Parent node index. 1506 * <BR /><B>OPTIONAL</B> 1507 * 1508 * @param nodeType <CODE>Node</CODE>'s nodeType. 1509 * <BR /><B>OPTIONAL</B> 1510 * 1511 * @param shadowRootType Type of the shadow root the <CODE>Node</CODE> is in. String values are equal to the <CODE>ShadowRootType</CODE> enum. 1512 * <BR /><B>OPTIONAL</B> 1513 * 1514 * @param nodeName <CODE>Node</CODE>'s nodeName. 1515 * <BR /><B>OPTIONAL</B> 1516 * 1517 * @param nodeValue <CODE>Node</CODE>'s nodeValue. 1518 * <BR /><B>OPTIONAL</B> 1519 * 1520 * @param backendNodeId <CODE>Node</CODE>'s id, corresponds to DOM.Node.backendNodeId. 1521 * <BR /><B>OPTIONAL</B> 1522 * 1523 * @param attributes Attributes of an <CODE>Element</CODE> node. Flatten name, value pairs. 1524 * <BR /><B>OPTIONAL</B> 1525 * 1526 * @param textValue Only set for textarea elements, contains the text value. 1527 * <BR /><B>OPTIONAL</B> 1528 * 1529 * @param inputValue Only set for input elements, contains the input's associated text value. 1530 * <BR /><B>OPTIONAL</B> 1531 * 1532 * @param inputChecked Only set for radio and checkbox input elements, indicates if the element has been checked 1533 * <BR /><B>OPTIONAL</B> 1534 * 1535 * @param optionSelected Only set for option elements, indicates if the element has been selected 1536 * <BR /><B>OPTIONAL</B> 1537 * 1538 * @param contentDocumentIndex The index of the document in the list of the snapshot documents. 1539 * <BR /><B>OPTIONAL</B> 1540 * 1541 * @param pseudoType Type of a pseudo element node. 1542 * <BR /><B>OPTIONAL</B> 1543 * 1544 * @param isClickable 1545 * Whether this DOM node responds to mouse clicks. This includes nodes that have had click 1546 * event listeners attached via JavaScript as well as anchor tags that naturally navigate when 1547 * clicked. 1548 * <BR /><B>OPTIONAL</B> 1549 * 1550 * @param currentSourceURL The selected url for nodes with a srcset attribute. 1551 * <BR /><B>OPTIONAL</B> 1552 * 1553 * @param originURL The url of the script (if any) that generates this node. 1554 * <BR /><B>OPTIONAL</B> 1555 */ 1556 public NodeTreeSnapshot( 1557 int[] parentIndex, int[] nodeType, DOMSnapshot.RareStringData shadowRootType, 1558 int[] nodeName, int[] nodeValue, int[] backendNodeId, int[][] attributes, 1559 DOMSnapshot.RareStringData textValue, DOMSnapshot.RareStringData inputValue, 1560 DOMSnapshot.RareBooleanData inputChecked, 1561 DOMSnapshot.RareBooleanData optionSelected, 1562 DOMSnapshot.RareIntegerData contentDocumentIndex, 1563 DOMSnapshot.RareStringData pseudoType, DOMSnapshot.RareBooleanData isClickable, 1564 DOMSnapshot.RareStringData currentSourceURL, DOMSnapshot.RareStringData originURL 1565 ) 1566 { 1567 this.parentIndex = parentIndex; 1568 this.nodeType = nodeType; 1569 this.shadowRootType = shadowRootType; 1570 this.nodeName = nodeName; 1571 this.nodeValue = nodeValue; 1572 this.backendNodeId = backendNodeId; 1573 this.attributes = attributes; 1574 this.textValue = textValue; 1575 this.inputValue = inputValue; 1576 this.inputChecked = inputChecked; 1577 this.optionSelected = optionSelected; 1578 this.contentDocumentIndex = contentDocumentIndex; 1579 this.pseudoType = pseudoType; 1580 this.isClickable = isClickable; 1581 this.currentSourceURL = currentSourceURL; 1582 this.originURL = originURL; 1583 } 1584 1585 /** 1586 * JSON Object Constructor 1587 * @param jo A Json-Object having data about an instance of {@code 'NodeTreeSnapshot'}. 1588 */ 1589 public NodeTreeSnapshot (JsonObject jo) 1590 { 1591 this.parentIndex = (jo.getJsonArray("parentIndex") == null) 1592 ? null 1593 : RJArrIntoPrimArray.intArr(jo.getJsonArray("parentIndex"), -1, 0, null); 1594 1595 this.nodeType = (jo.getJsonArray("nodeType") == null) 1596 ? null 1597 : RJArrIntoPrimArray.intArr(jo.getJsonArray("nodeType"), -1, 0, null); 1598 1599 this.shadowRootType = ReadJSON.getObject(jo, "shadowRootType", DOMSnapshot.RareStringData.class, true, false); 1600 this.nodeName = (jo.getJsonArray("nodeName") == null) 1601 ? null 1602 : RJArrIntoPrimArray.intArr(jo.getJsonArray("nodeName"), -1, 0, null); 1603 1604 this.nodeValue = (jo.getJsonArray("nodeValue") == null) 1605 ? null 1606 : RJArrIntoPrimArray.intArr(jo.getJsonArray("nodeValue"), -1, 0, null); 1607 1608 this.backendNodeId = (jo.getJsonArray("backendNodeId") == null) 1609 ? null 1610 : RJArrIntoPrimArray.intArr(jo.getJsonArray("backendNodeId"), -1, 0, null); 1611 1612 this.attributes = (jo.getJsonArray("attributes") == null) 1613 ? null 1614 : RJArrDimN.intArr(jo.getJsonArray("attributes"), -1, 0, null, int[][].class); 1615 1616 this.textValue = ReadJSON.getObject(jo, "textValue", DOMSnapshot.RareStringData.class, true, false); 1617 this.inputValue = ReadJSON.getObject(jo, "inputValue", DOMSnapshot.RareStringData.class, true, false); 1618 this.inputChecked = ReadJSON.getObject(jo, "inputChecked", DOMSnapshot.RareBooleanData.class, true, false); 1619 this.optionSelected = ReadJSON.getObject(jo, "optionSelected", DOMSnapshot.RareBooleanData.class, true, false); 1620 this.contentDocumentIndex = ReadJSON.getObject(jo, "contentDocumentIndex", DOMSnapshot.RareIntegerData.class, true, false); 1621 this.pseudoType = ReadJSON.getObject(jo, "pseudoType", DOMSnapshot.RareStringData.class, true, false); 1622 this.isClickable = ReadJSON.getObject(jo, "isClickable", DOMSnapshot.RareBooleanData.class, true, false); 1623 this.currentSourceURL = ReadJSON.getObject(jo, "currentSourceURL", DOMSnapshot.RareStringData.class, true, false); 1624 this.originURL = ReadJSON.getObject(jo, "originURL", DOMSnapshot.RareStringData.class, true, false); 1625 } 1626 1627 1628 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 1629 public boolean equals(Object other) 1630 { 1631 if (this == other) return true; 1632 if (other == null) return false; 1633 if (other.getClass() != this.getClass()) return false; 1634 1635 NodeTreeSnapshot o = (NodeTreeSnapshot) other; 1636 1637 return 1638 Arrays.equals(this.parentIndex, o.parentIndex) 1639 && Arrays.equals(this.nodeType, o.nodeType) 1640 && Objects.equals(this.shadowRootType, o.shadowRootType) 1641 && Arrays.equals(this.nodeName, o.nodeName) 1642 && Arrays.equals(this.nodeValue, o.nodeValue) 1643 && Arrays.equals(this.backendNodeId, o.backendNodeId) 1644 && Arrays.equals(this.attributes, o.attributes) 1645 && Objects.equals(this.textValue, o.textValue) 1646 && Objects.equals(this.inputValue, o.inputValue) 1647 && Objects.equals(this.inputChecked, o.inputChecked) 1648 && Objects.equals(this.optionSelected, o.optionSelected) 1649 && Objects.equals(this.contentDocumentIndex, o.contentDocumentIndex) 1650 && Objects.equals(this.pseudoType, o.pseudoType) 1651 && Objects.equals(this.isClickable, o.isClickable) 1652 && Objects.equals(this.currentSourceURL, o.currentSourceURL) 1653 && Objects.equals(this.originURL, o.originURL); 1654 } 1655 1656 /** Generates a Hash-Code for {@code 'this'} instance */ 1657 public int hashCode() 1658 { 1659 return 1660 Arrays.hashCode(this.parentIndex) 1661 + Arrays.hashCode(this.nodeType) 1662 + this.shadowRootType.hashCode() 1663 + Arrays.hashCode(this.nodeName) 1664 + Arrays.hashCode(this.nodeValue) 1665 + Arrays.hashCode(this.backendNodeId) 1666 + Arrays.hashCode(this.attributes) 1667 + this.textValue.hashCode() 1668 + this.inputValue.hashCode() 1669 + this.inputChecked.hashCode() 1670 + this.optionSelected.hashCode() 1671 + this.contentDocumentIndex.hashCode() 1672 + this.pseudoType.hashCode() 1673 + this.isClickable.hashCode() 1674 + this.currentSourceURL.hashCode() 1675 + this.originURL.hashCode(); 1676 } 1677 } 1678 1679 /** Table of details of an element in the DOM tree with a LayoutObject. */ 1680 public static class LayoutTreeSnapshot 1681 extends BaseType 1682 implements java.io.Serializable 1683 { 1684 /** For Object Serialization. java.io.Serializable */ 1685 protected static final long serialVersionUID = 1; 1686 1687 public boolean[] optionals() 1688 { return new boolean[] { false, false, false, false, false, true, true, true, true, true, true, }; } 1689 1690 /** Index of the corresponding node in the <CODE>NodeTreeSnapshot</CODE> array returned by <CODE>captureSnapshot</CODE>. */ 1691 public final int[] nodeIndex; 1692 1693 /** Array of indexes specifying computed style strings, filtered according to the <CODE>computedStyles</CODE> parameter passed to <CODE>captureSnapshot</CODE>. */ 1694 public final int[][] styles; 1695 1696 /** The absolute position bounding box. */ 1697 public final Number[][] bounds; 1698 1699 /** Contents of the LayoutText, if any. */ 1700 public final int[] text; 1701 1702 /** Stacking context information. */ 1703 public final DOMSnapshot.RareBooleanData stackingContexts; 1704 1705 /** 1706 * Global paint order index, which is determined by the stacking order of the nodes. Nodes 1707 * that are painted together will have the same index. Only provided if includePaintOrder in 1708 * captureSnapshot was true. 1709 * <BR /> 1710 * <BR /><B>OPTIONAL</B> 1711 */ 1712 public final int[] paintOrders; 1713 1714 /** 1715 * The offset rect of nodes. Only available when includeDOMRects is set to true 1716 * <BR /> 1717 * <BR /><B>OPTIONAL</B> 1718 */ 1719 public final Number[][] offsetRects; 1720 1721 /** 1722 * The scroll rect of nodes. Only available when includeDOMRects is set to true 1723 * <BR /> 1724 * <BR /><B>OPTIONAL</B> 1725 */ 1726 public final Number[][] scrollRects; 1727 1728 /** 1729 * The client rect of nodes. Only available when includeDOMRects is set to true 1730 * <BR /> 1731 * <BR /><B>OPTIONAL</B> 1732 */ 1733 public final Number[][] clientRects; 1734 1735 /** 1736 * The list of background colors that are blended with colors of overlapping elements. 1737 * <BR /> 1738 * <BR /><B>OPTIONAL</B> 1739 * <BR /><B>EXPERIMENTAL</B> 1740 */ 1741 public final int[] blendedBackgroundColors; 1742 1743 /** 1744 * The list of computed text opacities. 1745 * <BR /> 1746 * <BR /><B>OPTIONAL</B> 1747 * <BR /><B>EXPERIMENTAL</B> 1748 */ 1749 public final Number[] textColorOpacities; 1750 1751 /** 1752 * Constructor 1753 * 1754 * @param nodeIndex Index of the corresponding node in the <CODE>NodeTreeSnapshot</CODE> array returned by <CODE>captureSnapshot</CODE>. 1755 * 1756 * @param styles Array of indexes specifying computed style strings, filtered according to the <CODE>computedStyles</CODE> parameter passed to <CODE>captureSnapshot</CODE>. 1757 * 1758 * @param bounds The absolute position bounding box. 1759 * 1760 * @param text Contents of the LayoutText, if any. 1761 * 1762 * @param stackingContexts Stacking context information. 1763 * 1764 * @param paintOrders 1765 * Global paint order index, which is determined by the stacking order of the nodes. Nodes 1766 * that are painted together will have the same index. Only provided if includePaintOrder in 1767 * captureSnapshot was true. 1768 * <BR /><B>OPTIONAL</B> 1769 * 1770 * @param offsetRects The offset rect of nodes. Only available when includeDOMRects is set to true 1771 * <BR /><B>OPTIONAL</B> 1772 * 1773 * @param scrollRects The scroll rect of nodes. Only available when includeDOMRects is set to true 1774 * <BR /><B>OPTIONAL</B> 1775 * 1776 * @param clientRects The client rect of nodes. Only available when includeDOMRects is set to true 1777 * <BR /><B>OPTIONAL</B> 1778 * 1779 * @param blendedBackgroundColors The list of background colors that are blended with colors of overlapping elements. 1780 * <BR /><B>OPTIONAL</B> 1781 * <BR /><B>EXPERIMENTAL</B> 1782 * 1783 * @param textColorOpacities The list of computed text opacities. 1784 * <BR /><B>OPTIONAL</B> 1785 * <BR /><B>EXPERIMENTAL</B> 1786 */ 1787 public LayoutTreeSnapshot( 1788 int[] nodeIndex, int[][] styles, Number[][] bounds, int[] text, 1789 DOMSnapshot.RareBooleanData stackingContexts, int[] paintOrders, 1790 Number[][] offsetRects, Number[][] scrollRects, Number[][] clientRects, 1791 int[] blendedBackgroundColors, Number[] textColorOpacities 1792 ) 1793 { 1794 // Exception-Check(s) to ensure that if any parameters which are not declared as 1795 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 1796 1797 if (nodeIndex == null) THROWS.throwNPE("nodeIndex"); 1798 if (styles == null) THROWS.throwNPE("styles"); 1799 if (bounds == null) THROWS.throwNPE("bounds"); 1800 if (text == null) THROWS.throwNPE("text"); 1801 if (stackingContexts == null) THROWS.throwNPE("stackingContexts"); 1802 1803 this.nodeIndex = nodeIndex; 1804 this.styles = styles; 1805 this.bounds = bounds; 1806 this.text = text; 1807 this.stackingContexts = stackingContexts; 1808 this.paintOrders = paintOrders; 1809 this.offsetRects = offsetRects; 1810 this.scrollRects = scrollRects; 1811 this.clientRects = clientRects; 1812 this.blendedBackgroundColors = blendedBackgroundColors; 1813 this.textColorOpacities = textColorOpacities; 1814 } 1815 1816 /** 1817 * JSON Object Constructor 1818 * @param jo A Json-Object having data about an instance of {@code 'LayoutTreeSnapshot'}. 1819 */ 1820 public LayoutTreeSnapshot (JsonObject jo) 1821 { 1822 this.nodeIndex = (jo.getJsonArray("nodeIndex") == null) 1823 ? null 1824 : RJArrIntoPrimArray.intArr(jo.getJsonArray("nodeIndex"), -1, 0, null); 1825 1826 this.styles = (jo.getJsonArray("styles") == null) 1827 ? null 1828 : RJArrDimN.intArr(jo.getJsonArray("styles"), -1, 0, null, int[][].class); 1829 1830 this.bounds = (jo.getJsonArray("bounds") == null) 1831 ? null 1832 : RJArrDimN.arrNumber(jo.getJsonArray("bounds"), -1, 0, null, Number[][].class); 1833 1834 this.text = (jo.getJsonArray("text") == null) 1835 ? null 1836 : RJArrIntoPrimArray.intArr(jo.getJsonArray("text"), -1, 0, null); 1837 1838 this.stackingContexts = ReadJSON.getObject(jo, "stackingContexts", DOMSnapshot.RareBooleanData.class, false, true); 1839 this.paintOrders = (jo.getJsonArray("paintOrders") == null) 1840 ? null 1841 : RJArrIntoPrimArray.intArr(jo.getJsonArray("paintOrders"), -1, 0, null); 1842 1843 this.offsetRects = (jo.getJsonArray("offsetRects") == null) 1844 ? null 1845 : RJArrDimN.arrNumber(jo.getJsonArray("offsetRects"), -1, 0, null, Number[][].class); 1846 1847 this.scrollRects = (jo.getJsonArray("scrollRects") == null) 1848 ? null 1849 : RJArrDimN.arrNumber(jo.getJsonArray("scrollRects"), -1, 0, null, Number[][].class); 1850 1851 this.clientRects = (jo.getJsonArray("clientRects") == null) 1852 ? null 1853 : RJArrDimN.arrNumber(jo.getJsonArray("clientRects"), -1, 0, null, Number[][].class); 1854 1855 this.blendedBackgroundColors = (jo.getJsonArray("blendedBackgroundColors") == null) 1856 ? null 1857 : RJArrIntoPrimArray.intArr(jo.getJsonArray("blendedBackgroundColors"), -1, 0, null); 1858 1859 this.textColorOpacities = (jo.getJsonArray("textColorOpacities") == null) 1860 ? null 1861 : RJArrIntoBoxedStream.numberArr(jo.getJsonArray("textColorOpacities"), -1, 0, null).toArray(Number[]::new); 1862 1863 } 1864 1865 1866 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 1867 public boolean equals(Object other) 1868 { 1869 if (this == other) return true; 1870 if (other == null) return false; 1871 if (other.getClass() != this.getClass()) return false; 1872 1873 LayoutTreeSnapshot o = (LayoutTreeSnapshot) other; 1874 1875 return 1876 Arrays.equals(this.nodeIndex, o.nodeIndex) 1877 && Arrays.equals(this.styles, o.styles) 1878 && Arrays.deepEquals(this.bounds, o.bounds) 1879 && Arrays.equals(this.text, o.text) 1880 && Objects.equals(this.stackingContexts, o.stackingContexts) 1881 && Arrays.equals(this.paintOrders, o.paintOrders) 1882 && Arrays.deepEquals(this.offsetRects, o.offsetRects) 1883 && Arrays.deepEquals(this.scrollRects, o.scrollRects) 1884 && Arrays.deepEquals(this.clientRects, o.clientRects) 1885 && Arrays.equals(this.blendedBackgroundColors, o.blendedBackgroundColors) 1886 && Arrays.deepEquals(this.textColorOpacities, o.textColorOpacities); 1887 } 1888 1889 /** Generates a Hash-Code for {@code 'this'} instance */ 1890 public int hashCode() 1891 { 1892 return 1893 Arrays.hashCode(this.nodeIndex) 1894 + Arrays.hashCode(this.styles) 1895 + Arrays.deepHashCode(this.bounds) 1896 + Arrays.hashCode(this.text) 1897 + this.stackingContexts.hashCode() 1898 + Arrays.hashCode(this.paintOrders) 1899 + Arrays.deepHashCode(this.offsetRects) 1900 + Arrays.deepHashCode(this.scrollRects) 1901 + Arrays.deepHashCode(this.clientRects) 1902 + Arrays.hashCode(this.blendedBackgroundColors) 1903 + Arrays.deepHashCode(this.textColorOpacities); 1904 } 1905 } 1906 1907 /** 1908 * Table of details of the post layout rendered text positions. The exact layout should not be regarded as 1909 * stable and may change between versions. 1910 */ 1911 public static class TextBoxSnapshot 1912 extends BaseType 1913 implements java.io.Serializable 1914 { 1915 /** For Object Serialization. java.io.Serializable */ 1916 protected static final long serialVersionUID = 1; 1917 1918 public boolean[] optionals() 1919 { return new boolean[] { false, false, false, false, }; } 1920 1921 /** Index of the layout tree node that owns this box collection. */ 1922 public final int[] layoutIndex; 1923 1924 /** The absolute position bounding box. */ 1925 public final Number[][] bounds; 1926 1927 /** 1928 * The starting index in characters, for this post layout textbox substring. Characters that 1929 * would be represented as a surrogate pair in UTF-16 have length 2. 1930 */ 1931 public final int[] start; 1932 1933 /** 1934 * The number of characters in this post layout textbox substring. Characters that would be 1935 * represented as a surrogate pair in UTF-16 have length 2. 1936 */ 1937 public final int[] length; 1938 1939 /** 1940 * Constructor 1941 * 1942 * @param layoutIndex Index of the layout tree node that owns this box collection. 1943 * 1944 * @param bounds The absolute position bounding box. 1945 * 1946 * @param start 1947 * The starting index in characters, for this post layout textbox substring. Characters that 1948 * would be represented as a surrogate pair in UTF-16 have length 2. 1949 * 1950 * @param length 1951 * The number of characters in this post layout textbox substring. Characters that would be 1952 * represented as a surrogate pair in UTF-16 have length 2. 1953 */ 1954 public TextBoxSnapshot(int[] layoutIndex, Number[][] bounds, int[] start, int[] length) 1955 { 1956 // Exception-Check(s) to ensure that if any parameters which are not declared as 1957 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 1958 1959 if (layoutIndex == null) THROWS.throwNPE("layoutIndex"); 1960 if (bounds == null) THROWS.throwNPE("bounds"); 1961 if (start == null) THROWS.throwNPE("start"); 1962 if (length == null) THROWS.throwNPE("length"); 1963 1964 this.layoutIndex = layoutIndex; 1965 this.bounds = bounds; 1966 this.start = start; 1967 this.length = length; 1968 } 1969 1970 /** 1971 * JSON Object Constructor 1972 * @param jo A Json-Object having data about an instance of {@code 'TextBoxSnapshot'}. 1973 */ 1974 public TextBoxSnapshot (JsonObject jo) 1975 { 1976 this.layoutIndex = (jo.getJsonArray("layoutIndex") == null) 1977 ? null 1978 : RJArrIntoPrimArray.intArr(jo.getJsonArray("layoutIndex"), -1, 0, null); 1979 1980 this.bounds = (jo.getJsonArray("bounds") == null) 1981 ? null 1982 : RJArrDimN.arrNumber(jo.getJsonArray("bounds"), -1, 0, null, Number[][].class); 1983 1984 this.start = (jo.getJsonArray("start") == null) 1985 ? null 1986 : RJArrIntoPrimArray.intArr(jo.getJsonArray("start"), -1, 0, null); 1987 1988 this.length = (jo.getJsonArray("length") == null) 1989 ? null 1990 : RJArrIntoPrimArray.intArr(jo.getJsonArray("length"), -1, 0, null); 1991 1992 } 1993 1994 1995 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 1996 public boolean equals(Object other) 1997 { 1998 if (this == other) return true; 1999 if (other == null) return false; 2000 if (other.getClass() != this.getClass()) return false; 2001 2002 TextBoxSnapshot o = (TextBoxSnapshot) other; 2003 2004 return 2005 Arrays.equals(this.layoutIndex, o.layoutIndex) 2006 && Arrays.deepEquals(this.bounds, o.bounds) 2007 && Arrays.equals(this.start, o.start) 2008 && Arrays.equals(this.length, o.length); 2009 } 2010 2011 /** Generates a Hash-Code for {@code 'this'} instance */ 2012 public int hashCode() 2013 { 2014 return 2015 Arrays.hashCode(this.layoutIndex) 2016 + Arrays.deepHashCode(this.bounds) 2017 + Arrays.hashCode(this.start) 2018 + Arrays.hashCode(this.length); 2019 } 2020 } 2021 2022 2023 // Counter for keeping the WebSocket Request ID's distinct. 2024 private static int counter = 1; 2025 2026 /** 2027 * Disables DOM snapshot agent for the given page. 2028 * 2029 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 2030 * {@link Ret0}></CODE> 2031 * 2032 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 2033 * browser receives the invocation-request. 2034 * 2035 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 2036 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 2037 * {@code >} to ensure the Browser Function has run to completion. 2038 */ 2039 public static Script<String, JsonObject, Ret0> disable() 2040 { 2041 final int webSocketID = 17000000 + counter++; 2042 final boolean[] optionals = new boolean[0]; 2043 2044 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 2045 String requestJSON = WriteJSON.get( 2046 parameterTypes.get("disable"), 2047 parameterNames.get("disable"), 2048 optionals, webSocketID, 2049 "DOMSnapshot.disable" 2050 ); 2051 2052 // This Remote Command does not have a Return-Value. 2053 return new Script<> 2054 (webSocketID, requestJSON, VOID_RETURN.NoReturnValues); 2055 } 2056 2057 /** 2058 * Enables DOM snapshot agent for the given page. 2059 * 2060 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 2061 * {@link Ret0}></CODE> 2062 * 2063 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 2064 * browser receives the invocation-request. 2065 * 2066 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 2067 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 2068 * {@code >} to ensure the Browser Function has run to completion. 2069 */ 2070 public static Script<String, JsonObject, Ret0> enable() 2071 { 2072 final int webSocketID = 17001000 + counter++; 2073 final boolean[] optionals = new boolean[0]; 2074 2075 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 2076 String requestJSON = WriteJSON.get( 2077 parameterTypes.get("enable"), 2078 parameterNames.get("enable"), 2079 optionals, webSocketID, 2080 "DOMSnapshot.enable" 2081 ); 2082 2083 // This Remote Command does not have a Return-Value. 2084 return new Script<> 2085 (webSocketID, requestJSON, VOID_RETURN.NoReturnValues); 2086 } 2087 2088 /** 2089 * Returns a document snapshot, including the full DOM tree of the root node (including iframes, 2090 * template contents, and imported documents) in a flattened array, as well as layout and 2091 * white-listed computed style information for the nodes. Shadow DOM in the returned DOM tree is 2092 * flattened. 2093 * <BR /><B>DEPRECATED</B> 2094 * 2095 * @param computedStyleWhitelist Whitelist of computed styles to return. 2096 * 2097 * @param includeEventListeners Whether or not to retrieve details of DOM listeners (default false). 2098 * <BR /><B>OPTIONAL</B> 2099 * 2100 * @param includePaintOrder Whether to determine and include the paint order index of LayoutTreeNodes (default false). 2101 * <BR /><B>OPTIONAL</B> 2102 * 2103 * @param includeUserAgentShadowTree Whether to include UA shadow tree in the snapshot (default false). 2104 * <BR /><B>OPTIONAL</B> 2105 * 2106 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 2107 * {@link Ret3}></CODE> 2108 * 2109 * <BR /><BR />This {@link Script} may be <B STYLE='color:red'>executed</B> (using 2110 * {@link Script#exec()}), and a {@link Promise} returned. 2111 * 2112 * <BR /><BR />When the {@code Promise} is <B STYLE='color: red'>awaited</B> 2113 * (using {@link Promise#await()}), the {@code Ret3} will subsequently 2114 * be returned from that call. 2115 * 2116 * <BR /><BR />The <B STYLE='color: red'>returned</B> values are encapsulated 2117 * in an instance of <B>{@link Ret3}</B> 2118 * 2119 * <BR /><BR /><UL CLASS=JDUL> 2120 * <LI><CODE><B>Ret3.a:</B> {@link DOMSnapshot.DOMNode}[] (<B>domNodes</B>)</CODE> 2121 * <BR />The nodes in the DOM tree. The DOMNode at index 0 corresponds to the root document. 2122 * <BR /><BR /></LI> 2123 * <LI><CODE><B>Ret3.b:</B> {@link DOMSnapshot.LayoutTreeNode}[] (<B>layoutTreeNodes</B>)</CODE> 2124 * <BR />The nodes in the layout tree. 2125 * <BR /><BR /></LI> 2126 * <LI><CODE><B>Ret3.c:</B> {@link DOMSnapshot.ComputedStyle}[] (<B>computedStyles</B>)</CODE> 2127 * <BR />Whitelisted ComputedStyle properties for each node in the layout tree. 2128 * </LI> 2129 * </UL> 2130 */ 2131 public static Script<String, JsonObject, Ret3<DOMSnapshot.DOMNode[], DOMSnapshot.LayoutTreeNode[], DOMSnapshot.ComputedStyle[]>> 2132 getSnapshot( 2133 String[] computedStyleWhitelist, Boolean includeEventListeners, 2134 Boolean includePaintOrder, Boolean includeUserAgentShadowTree 2135 ) 2136 { 2137 // Exception-Check(s) to ensure that if any parameters which are not declared as 2138 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 2139 2140 if (computedStyleWhitelist == null) THROWS.throwNPE("computedStyleWhitelist"); 2141 2142 final int webSocketID = 17002000 + counter++; 2143 final boolean[] optionals = { false, true, true, true, }; 2144 2145 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 2146 String requestJSON = WriteJSON.get( 2147 parameterTypes.get("getSnapshot"), 2148 parameterNames.get("getSnapshot"), 2149 optionals, webSocketID, 2150 "DOMSnapshot.getSnapshot", 2151 computedStyleWhitelist, includeEventListeners, includePaintOrder, 2152 includeUserAgentShadowTree 2153 ); 2154 2155 // 'JSON Binding' ... Converts Browser Response-JSON into Java-Type 'Ret3' 2156 Function<JsonObject, Ret3<DOMSnapshot.DOMNode[], DOMSnapshot.LayoutTreeNode[], DOMSnapshot.ComputedStyle[]>> 2157 responseProcessor = (JsonObject jo) -> new Ret3<>( 2158 (jo.getJsonArray("domNodes") == null) 2159 ? null 2160 : RJArrIntoStream.objArr(jo.getJsonArray("domNodes"), null, 0, DOMSnapshot.DOMNode.class).toArray(DOMSnapshot.DOMNode[]::new), 2161 (jo.getJsonArray("layoutTreeNodes") == null) 2162 ? null 2163 : RJArrIntoStream.objArr(jo.getJsonArray("layoutTreeNodes"), null, 0, DOMSnapshot.LayoutTreeNode.class).toArray(DOMSnapshot.LayoutTreeNode[]::new), 2164 (jo.getJsonArray("computedStyles") == null) 2165 ? null 2166 : RJArrIntoStream.objArr(jo.getJsonArray("computedStyles"), null, 0, DOMSnapshot.ComputedStyle.class).toArray(DOMSnapshot.ComputedStyle[]::new) 2167 ); 2168 2169 return new Script<>(webSocketID, requestJSON, responseProcessor); 2170 } 2171 2172 /** 2173 * Returns a document snapshot, including the full DOM tree of the root node (including iframes, 2174 * template contents, and imported documents) in a flattened array, as well as layout and 2175 * white-listed computed style information for the nodes. Shadow DOM in the returned DOM tree is 2176 * flattened. 2177 * 2178 * @param computedStyles Whitelist of computed styles to return. 2179 * 2180 * @param includePaintOrder Whether to include layout object paint orders into the snapshot. 2181 * <BR /><B>OPTIONAL</B> 2182 * 2183 * @param includeDOMRects Whether to include DOM rectangles (offsetRects, clientRects, scrollRects) into the snapshot 2184 * <BR /><B>OPTIONAL</B> 2185 * 2186 * @param includeBlendedBackgroundColors 2187 * Whether to include blended background colors in the snapshot (default: false). 2188 * Blended background color is achieved by blending background colors of all elements 2189 * that overlap with the current element. 2190 * <BR /><B>OPTIONAL</B> 2191 * <BR /><B>EXPERIMENTAL</B> 2192 * 2193 * @param includeTextColorOpacities 2194 * Whether to include text color opacity in the snapshot (default: false). 2195 * An element might have the opacity property set that affects the text color of the element. 2196 * The final text color opacity is computed based on the opacity of all overlapping elements. 2197 * <BR /><B>OPTIONAL</B> 2198 * <BR /><B>EXPERIMENTAL</B> 2199 * 2200 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 2201 * {@link Ret2}></CODE> 2202 * 2203 * <BR /><BR />This {@link Script} may be <B STYLE='color:red'>executed</B> (using 2204 * {@link Script#exec()}), and a {@link Promise} returned. 2205 * 2206 * <BR /><BR />When the {@code Promise} is <B STYLE='color: red'>awaited</B> 2207 * (using {@link Promise#await()}), the {@code Ret2} will subsequently 2208 * be returned from that call. 2209 * 2210 * <BR /><BR />The <B STYLE='color: red'>returned</B> values are encapsulated 2211 * in an instance of <B>{@link Ret2}</B> 2212 * 2213 * <BR /><BR /><UL CLASS=JDUL> 2214 * <LI><CODE><B>Ret2.a:</B> {@link DOMSnapshot.DocumentSnapshot}[] (<B>documents</B>)</CODE> 2215 * <BR />The nodes in the DOM tree. The DOMNode at index 0 corresponds to the root document. 2216 * <BR /><BR /></LI> 2217 * <LI><CODE><B>Ret2.b:</B> String[] (<B>strings</B>)</CODE> 2218 * <BR />Shared string table that all string properties refer to with indexes. 2219 * </LI> 2220 * </UL> 2221 */ 2222 public static Script<String, JsonObject, Ret2<DOMSnapshot.DocumentSnapshot[], String[]>> captureSnapshot( 2223 String[] computedStyles, Boolean includePaintOrder, Boolean includeDOMRects, 2224 Boolean includeBlendedBackgroundColors, Boolean includeTextColorOpacities 2225 ) 2226 { 2227 // Exception-Check(s) to ensure that if any parameters which are not declared as 2228 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 2229 2230 if (computedStyles == null) THROWS.throwNPE("computedStyles"); 2231 2232 final int webSocketID = 17003000 + counter++; 2233 final boolean[] optionals = { false, true, true, true, true, }; 2234 2235 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 2236 String requestJSON = WriteJSON.get( 2237 parameterTypes.get("captureSnapshot"), 2238 parameterNames.get("captureSnapshot"), 2239 optionals, webSocketID, 2240 "DOMSnapshot.captureSnapshot", 2241 computedStyles, includePaintOrder, includeDOMRects, includeBlendedBackgroundColors, 2242 includeTextColorOpacities 2243 ); 2244 2245 // 'JSON Binding' ... Converts Browser Response-JSON into Java-Type 'Ret2' 2246 Function<JsonObject, Ret2<DOMSnapshot.DocumentSnapshot[], String[]>> 2247 responseProcessor = (JsonObject jo) -> new Ret2<>( 2248 (jo.getJsonArray("documents") == null) 2249 ? null 2250 : RJArrIntoStream.objArr(jo.getJsonArray("documents"), null, 0, DOMSnapshot.DocumentSnapshot.class).toArray(DOMSnapshot.DocumentSnapshot[]::new), 2251 (jo.getJsonArray("strings") == null) 2252 ? null 2253 : RJArrIntoStream.strArr(jo.getJsonArray("strings"), null, 0).toArray(String[]::new) 2254 ); 2255 2256 return new Script<>(webSocketID, requestJSON, responseProcessor); 2257 } 2258 2259}