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) BRDPC.throwNPE("nodeName"); 412 if (nodeValue == null) BRDPC.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 BRDPC.checkIAE("pseudoType", pseudoType, "DOM.PseudoType", DOM.PseudoType); 418 BRDPC.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 : ReadArrJSON.DimN.intArr(jo.getJsonArray("childNodeIndexes"), -1, 0, null, int[].class); 467 468 this.attributes = (jo.getJsonArray("attributes") == null) 469 ? null 470 : ReadArrJSON.DimN.objArr(jo.getJsonArray("attributes"), null, 0, DOMSnapshot.NameValue[].class); 471 472 this.pseudoElementIndexes = (jo.getJsonArray("pseudoElementIndexes") == null) 473 ? null 474 : ReadArrJSON.DimN.intArr(jo.getJsonArray("pseudoElementIndexes"), -1, 0, null, int[].class); 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 : ReadArrJSON.DimN.objArr(jo.getJsonArray("eventListeners"), null, 0, DOMDebugger.EventListener[].class); 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 (other == null) return false; 503 if (other.getClass() != this.getClass()) return false; 504 505 DOMNode o = (DOMNode) other; 506 507 return 508 (this.nodeType == o.nodeType) 509 && Objects.equals(this.nodeName, o.nodeName) 510 && Objects.equals(this.nodeValue, o.nodeValue) 511 && Objects.equals(this.textValue, o.textValue) 512 && Objects.equals(this.inputValue, o.inputValue) 513 && Objects.equals(this.inputChecked, o.inputChecked) 514 && Objects.equals(this.optionSelected, o.optionSelected) 515 && Objects.equals(this.backendNodeId, o.backendNodeId) 516 && Arrays.equals(this.childNodeIndexes, o.childNodeIndexes) 517 && Arrays.deepEquals(this.attributes, o.attributes) 518 && Arrays.equals(this.pseudoElementIndexes, o.pseudoElementIndexes) 519 && Objects.equals(this.layoutNodeIndex, o.layoutNodeIndex) 520 && Objects.equals(this.documentURL, o.documentURL) 521 && Objects.equals(this.baseURL, o.baseURL) 522 && Objects.equals(this.contentLanguage, o.contentLanguage) 523 && Objects.equals(this.documentEncoding, o.documentEncoding) 524 && Objects.equals(this.publicId, o.publicId) 525 && Objects.equals(this.systemId, o.systemId) 526 && Objects.equals(this.frameId, o.frameId) 527 && Objects.equals(this.contentDocumentIndex, o.contentDocumentIndex) 528 && Objects.equals(this.pseudoType, o.pseudoType) 529 && Objects.equals(this.shadowRootType, o.shadowRootType) 530 && Objects.equals(this.isClickable, o.isClickable) 531 && Arrays.deepEquals(this.eventListeners, o.eventListeners) 532 && Objects.equals(this.currentSourceURL, o.currentSourceURL) 533 && Objects.equals(this.originURL, o.originURL) 534 && Objects.equals(this.scrollOffsetX, o.scrollOffsetX) 535 && Objects.equals(this.scrollOffsetY, o.scrollOffsetY); 536 } 537 538 /** Generates a Hash-Code for {@code 'this'} instance */ 539 public int hashCode() 540 { 541 return 542 this.nodeType 543 + Objects.hashCode(this.nodeName) 544 + Objects.hashCode(this.nodeValue) 545 + Objects.hashCode(this.textValue) 546 + Objects.hashCode(this.inputValue) 547 + Objects.hashCode(this.inputChecked) 548 + Objects.hashCode(this.optionSelected) 549 + this.backendNodeId 550 + Arrays.hashCode(this.childNodeIndexes) 551 + Arrays.deepHashCode(this.attributes) 552 + Arrays.hashCode(this.pseudoElementIndexes) 553 + Objects.hashCode(this.layoutNodeIndex) 554 + Objects.hashCode(this.documentURL) 555 + Objects.hashCode(this.baseURL) 556 + Objects.hashCode(this.contentLanguage) 557 + Objects.hashCode(this.documentEncoding) 558 + Objects.hashCode(this.publicId) 559 + Objects.hashCode(this.systemId) 560 + Objects.hashCode(this.frameId) 561 + Objects.hashCode(this.contentDocumentIndex) 562 + Objects.hashCode(this.pseudoType) 563 + Objects.hashCode(this.shadowRootType) 564 + Objects.hashCode(this.isClickable) 565 + Arrays.deepHashCode(this.eventListeners) 566 + Objects.hashCode(this.currentSourceURL) 567 + Objects.hashCode(this.originURL) 568 + Objects.hashCode(this.scrollOffsetX) 569 + Objects.hashCode(this.scrollOffsetY); 570 } 571 } 572 573 /** 574 * Details of post layout rendered text positions. The exact layout should not be regarded as 575 * stable and may change between versions. 576 */ 577 public static class InlineTextBox 578 extends BaseType 579 implements java.io.Serializable 580 { 581 /** For Object Serialization. java.io.Serializable */ 582 protected static final long serialVersionUID = 1; 583 584 public boolean[] optionals() 585 { return new boolean[] { false, false, false, }; } 586 587 /** The bounding box in document coordinates. Note that scroll offset of the document is ignored. */ 588 public final DOM.Rect boundingBox; 589 590 /** 591 * The starting index in characters, for this post layout textbox substring. Characters that 592 * would be represented as a surrogate pair in UTF-16 have length 2. 593 */ 594 public final int startCharacterIndex; 595 596 /** 597 * The number of characters in this post layout textbox substring. Characters that would be 598 * represented as a surrogate pair in UTF-16 have length 2. 599 */ 600 public final int numCharacters; 601 602 /** 603 * Constructor 604 * 605 * @param boundingBox The bounding box in document coordinates. Note that scroll offset of the document is ignored. 606 * 607 * @param startCharacterIndex 608 * The starting index in characters, for this post layout textbox substring. Characters that 609 * would be represented as a surrogate pair in UTF-16 have length 2. 610 * 611 * @param numCharacters 612 * The number of characters in this post layout textbox substring. Characters that would be 613 * represented as a surrogate pair in UTF-16 have length 2. 614 */ 615 public InlineTextBox(DOM.Rect boundingBox, int startCharacterIndex, int numCharacters) 616 { 617 // Exception-Check(s) to ensure that if any parameters which are not declared as 618 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 619 620 if (boundingBox == null) BRDPC.throwNPE("boundingBox"); 621 622 this.boundingBox = boundingBox; 623 this.startCharacterIndex = startCharacterIndex; 624 this.numCharacters = numCharacters; 625 } 626 627 /** 628 * JSON Object Constructor 629 * @param jo A Json-Object having data about an instance of {@code 'InlineTextBox'}. 630 */ 631 public InlineTextBox (JsonObject jo) 632 { 633 this.boundingBox = ReadJSON.getObject(jo, "boundingBox", DOM.Rect.class, false, true); 634 this.startCharacterIndex = ReadPrimJSON.getInt(jo, "startCharacterIndex"); 635 this.numCharacters = ReadPrimJSON.getInt(jo, "numCharacters"); 636 } 637 638 639 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 640 public boolean equals(Object other) 641 { 642 if (other == null) return false; 643 if (other.getClass() != this.getClass()) return false; 644 645 InlineTextBox o = (InlineTextBox) other; 646 647 return 648 Objects.equals(this.boundingBox, o.boundingBox) 649 && (this.startCharacterIndex == o.startCharacterIndex) 650 && (this.numCharacters == o.numCharacters); 651 } 652 653 /** Generates a Hash-Code for {@code 'this'} instance */ 654 public int hashCode() 655 { 656 return 657 this.boundingBox.hashCode() 658 + this.startCharacterIndex 659 + this.numCharacters; 660 } 661 } 662 663 /** Details of an element in the DOM tree with a LayoutObject. */ 664 public static class LayoutTreeNode 665 extends BaseType 666 implements java.io.Serializable 667 { 668 /** For Object Serialization. java.io.Serializable */ 669 protected static final long serialVersionUID = 1; 670 671 public boolean[] optionals() 672 { return new boolean[] { false, false, true, true, true, true, true, }; } 673 674 /** The index of the related DOM node in the <CODE>domNodes</CODE> array returned by <CODE>getSnapshot</CODE>. */ 675 public final int domNodeIndex; 676 677 /** The bounding box in document coordinates. Note that scroll offset of the document is ignored. */ 678 public final DOM.Rect boundingBox; 679 680 /** 681 * Contents of the LayoutText, if any. 682 * <BR /> 683 * <BR /><B>OPTIONAL</B> 684 */ 685 public final String layoutText; 686 687 /** 688 * The post-layout inline text nodes, if any. 689 * <BR /> 690 * <BR /><B>OPTIONAL</B> 691 */ 692 public final DOMSnapshot.InlineTextBox[] inlineTextNodes; 693 694 /** 695 * Index into the <CODE>computedStyles</CODE> array returned by <CODE>getSnapshot</CODE>. 696 * <BR /> 697 * <BR /><B>OPTIONAL</B> 698 */ 699 public final Integer styleIndex; 700 701 /** 702 * Global paint order index, which is determined by the stacking order of the nodes. Nodes 703 * that are painted together will have the same index. Only provided if includePaintOrder in 704 * getSnapshot was true. 705 * <BR /> 706 * <BR /><B>OPTIONAL</B> 707 */ 708 public final Integer paintOrder; 709 710 /** 711 * Set to true to indicate the element begins a new stacking context. 712 * <BR /> 713 * <BR /><B>OPTIONAL</B> 714 */ 715 public final Boolean isStackingContext; 716 717 /** 718 * Constructor 719 * 720 * @param domNodeIndex The index of the related DOM node in the <CODE>domNodes</CODE> array returned by <CODE>getSnapshot</CODE>. 721 * 722 * @param boundingBox The bounding box in document coordinates. Note that scroll offset of the document is ignored. 723 * 724 * @param layoutText Contents of the LayoutText, if any. 725 * <BR /><B>OPTIONAL</B> 726 * 727 * @param inlineTextNodes The post-layout inline text nodes, if any. 728 * <BR /><B>OPTIONAL</B> 729 * 730 * @param styleIndex Index into the <CODE>computedStyles</CODE> array returned by <CODE>getSnapshot</CODE>. 731 * <BR /><B>OPTIONAL</B> 732 * 733 * @param paintOrder 734 * Global paint order index, which is determined by the stacking order of the nodes. Nodes 735 * that are painted together will have the same index. Only provided if includePaintOrder in 736 * getSnapshot was true. 737 * <BR /><B>OPTIONAL</B> 738 * 739 * @param isStackingContext Set to true to indicate the element begins a new stacking context. 740 * <BR /><B>OPTIONAL</B> 741 */ 742 public LayoutTreeNode( 743 int domNodeIndex, DOM.Rect boundingBox, String layoutText, 744 DOMSnapshot.InlineTextBox[] inlineTextNodes, Integer styleIndex, Integer paintOrder, 745 Boolean isStackingContext 746 ) 747 { 748 // Exception-Check(s) to ensure that if any parameters which are not declared as 749 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 750 751 if (boundingBox == null) BRDPC.throwNPE("boundingBox"); 752 753 this.domNodeIndex = domNodeIndex; 754 this.boundingBox = boundingBox; 755 this.layoutText = layoutText; 756 this.inlineTextNodes = inlineTextNodes; 757 this.styleIndex = styleIndex; 758 this.paintOrder = paintOrder; 759 this.isStackingContext = isStackingContext; 760 } 761 762 /** 763 * JSON Object Constructor 764 * @param jo A Json-Object having data about an instance of {@code 'LayoutTreeNode'}. 765 */ 766 public LayoutTreeNode (JsonObject jo) 767 { 768 this.domNodeIndex = ReadPrimJSON.getInt(jo, "domNodeIndex"); 769 this.boundingBox = ReadJSON.getObject(jo, "boundingBox", DOM.Rect.class, false, true); 770 this.layoutText = ReadJSON.getString(jo, "layoutText", true, false); 771 this.inlineTextNodes = (jo.getJsonArray("inlineTextNodes") == null) 772 ? null 773 : ReadArrJSON.DimN.objArr(jo.getJsonArray("inlineTextNodes"), null, 0, DOMSnapshot.InlineTextBox[].class); 774 775 this.styleIndex = ReadBoxedJSON.getInteger(jo, "styleIndex", true); 776 this.paintOrder = ReadBoxedJSON.getInteger(jo, "paintOrder", true); 777 this.isStackingContext = ReadBoxedJSON.getBoolean(jo, "isStackingContext", true); 778 } 779 780 781 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 782 public boolean equals(Object other) 783 { 784 if (other == null) return false; 785 if (other.getClass() != this.getClass()) return false; 786 787 LayoutTreeNode o = (LayoutTreeNode) other; 788 789 return 790 (this.domNodeIndex == o.domNodeIndex) 791 && Objects.equals(this.boundingBox, o.boundingBox) 792 && Objects.equals(this.layoutText, o.layoutText) 793 && Arrays.deepEquals(this.inlineTextNodes, o.inlineTextNodes) 794 && Objects.equals(this.styleIndex, o.styleIndex) 795 && Objects.equals(this.paintOrder, o.paintOrder) 796 && Objects.equals(this.isStackingContext, o.isStackingContext); 797 } 798 799 /** Generates a Hash-Code for {@code 'this'} instance */ 800 public int hashCode() 801 { 802 return 803 this.domNodeIndex 804 + this.boundingBox.hashCode() 805 + Objects.hashCode(this.layoutText) 806 + Arrays.deepHashCode(this.inlineTextNodes) 807 + Objects.hashCode(this.styleIndex) 808 + Objects.hashCode(this.paintOrder) 809 + Objects.hashCode(this.isStackingContext); 810 } 811 } 812 813 /** A subset of the full ComputedStyle as defined by the request whitelist. */ 814 public static class ComputedStyle 815 extends BaseType 816 implements java.io.Serializable 817 { 818 /** For Object Serialization. java.io.Serializable */ 819 protected static final long serialVersionUID = 1; 820 821 public boolean[] optionals() 822 { return new boolean[] { false, }; } 823 824 /** Name/value pairs of computed style properties. */ 825 public final DOMSnapshot.NameValue[] properties; 826 827 /** 828 * Constructor 829 * 830 * @param properties Name/value pairs of computed style properties. 831 */ 832 public ComputedStyle(DOMSnapshot.NameValue[] properties) 833 { 834 // Exception-Check(s) to ensure that if any parameters which are not declared as 835 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 836 837 if (properties == null) BRDPC.throwNPE("properties"); 838 839 this.properties = properties; 840 } 841 842 /** 843 * JSON Object Constructor 844 * @param jo A Json-Object having data about an instance of {@code 'ComputedStyle'}. 845 */ 846 public ComputedStyle (JsonObject jo) 847 { 848 this.properties = (jo.getJsonArray("properties") == null) 849 ? null 850 : ReadArrJSON.DimN.objArr(jo.getJsonArray("properties"), null, 0, DOMSnapshot.NameValue[].class); 851 852 } 853 854 855 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 856 public boolean equals(Object other) 857 { 858 if (other == null) return false; 859 if (other.getClass() != this.getClass()) return false; 860 861 ComputedStyle o = (ComputedStyle) other; 862 863 return 864 Arrays.deepEquals(this.properties, o.properties); 865 } 866 867 /** Generates a Hash-Code for {@code 'this'} instance */ 868 public int hashCode() 869 { 870 return 871 Arrays.deepHashCode(this.properties); 872 } 873 } 874 875 /** A name/value pair. */ 876 public static class NameValue 877 extends BaseType 878 implements java.io.Serializable 879 { 880 /** For Object Serialization. java.io.Serializable */ 881 protected static final long serialVersionUID = 1; 882 883 public boolean[] optionals() 884 { return new boolean[] { false, false, }; } 885 886 /** Attribute/property name. */ 887 public final String name; 888 889 /** Attribute/property value. */ 890 public final String value; 891 892 /** 893 * Constructor 894 * 895 * @param name Attribute/property name. 896 * 897 * @param value Attribute/property value. 898 */ 899 public NameValue(String name, String value) 900 { 901 // Exception-Check(s) to ensure that if any parameters which are not declared as 902 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 903 904 if (name == null) BRDPC.throwNPE("name"); 905 if (value == null) BRDPC.throwNPE("value"); 906 907 this.name = name; 908 this.value = value; 909 } 910 911 /** 912 * JSON Object Constructor 913 * @param jo A Json-Object having data about an instance of {@code 'NameValue'}. 914 */ 915 public NameValue (JsonObject jo) 916 { 917 this.name = ReadJSON.getString(jo, "name", false, true); 918 this.value = ReadJSON.getString(jo, "value", false, true); 919 } 920 921 922 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 923 public boolean equals(Object other) 924 { 925 if (other == null) return false; 926 if (other.getClass() != this.getClass()) return false; 927 928 NameValue o = (NameValue) other; 929 930 return 931 Objects.equals(this.name, o.name) 932 && Objects.equals(this.value, o.value); 933 } 934 935 /** Generates a Hash-Code for {@code 'this'} instance */ 936 public int hashCode() 937 { 938 return 939 Objects.hashCode(this.name) 940 + Objects.hashCode(this.value); 941 } 942 } 943 944 /** Data that is only present on rare nodes. */ 945 public static class RareStringData 946 extends BaseType 947 implements java.io.Serializable 948 { 949 /** For Object Serialization. java.io.Serializable */ 950 protected static final long serialVersionUID = 1; 951 952 public boolean[] optionals() 953 { return new boolean[] { false, false, }; } 954 955 /** <CODE>[No Description Provided by Google]</CODE> */ 956 public final int[] index; 957 958 /** <CODE>[No Description Provided by Google]</CODE> */ 959 public final int[] value; 960 961 /** 962 * Constructor 963 * 964 * @param index - 965 * 966 * @param value - 967 */ 968 public RareStringData(int[] index, int[] value) 969 { 970 // Exception-Check(s) to ensure that if any parameters which are not declared as 971 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 972 973 if (index == null) BRDPC.throwNPE("index"); 974 if (value == null) BRDPC.throwNPE("value"); 975 976 this.index = index; 977 this.value = value; 978 } 979 980 /** 981 * JSON Object Constructor 982 * @param jo A Json-Object having data about an instance of {@code 'RareStringData'}. 983 */ 984 public RareStringData (JsonObject jo) 985 { 986 this.index = (jo.getJsonArray("index") == null) 987 ? null 988 : ReadArrJSON.DimN.intArr(jo.getJsonArray("index"), -1, 0, null, int[].class); 989 990 this.value = (jo.getJsonArray("value") == null) 991 ? null 992 : ReadArrJSON.DimN.intArr(jo.getJsonArray("value"), -1, 0, null, int[].class); 993 994 } 995 996 997 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 998 public boolean equals(Object other) 999 { 1000 if (other == null) return false; 1001 if (other.getClass() != this.getClass()) return false; 1002 1003 RareStringData o = (RareStringData) other; 1004 1005 return 1006 Arrays.equals(this.index, o.index) 1007 && Arrays.equals(this.value, o.value); 1008 } 1009 1010 /** Generates a Hash-Code for {@code 'this'} instance */ 1011 public int hashCode() 1012 { 1013 return 1014 Arrays.hashCode(this.index) 1015 + Arrays.hashCode(this.value); 1016 } 1017 } 1018 1019 /** <CODE>[No Description Provided by Google]</CODE> */ 1020 public static class RareBooleanData 1021 extends BaseType 1022 implements java.io.Serializable 1023 { 1024 /** For Object Serialization. java.io.Serializable */ 1025 protected static final long serialVersionUID = 1; 1026 1027 public boolean[] optionals() 1028 { return new boolean[] { false, }; } 1029 1030 /** <CODE>[No Description Provided by Google]</CODE> */ 1031 public final int[] index; 1032 1033 /** 1034 * Constructor 1035 * 1036 * @param index - 1037 */ 1038 public RareBooleanData(int[] index) 1039 { 1040 // Exception-Check(s) to ensure that if any parameters which are not declared as 1041 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 1042 1043 if (index == null) BRDPC.throwNPE("index"); 1044 1045 this.index = index; 1046 } 1047 1048 /** 1049 * JSON Object Constructor 1050 * @param jo A Json-Object having data about an instance of {@code 'RareBooleanData'}. 1051 */ 1052 public RareBooleanData (JsonObject jo) 1053 { 1054 this.index = (jo.getJsonArray("index") == null) 1055 ? null 1056 : ReadArrJSON.DimN.intArr(jo.getJsonArray("index"), -1, 0, null, int[].class); 1057 1058 } 1059 1060 1061 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 1062 public boolean equals(Object other) 1063 { 1064 if (other == null) return false; 1065 if (other.getClass() != this.getClass()) return false; 1066 1067 RareBooleanData o = (RareBooleanData) other; 1068 1069 return 1070 Arrays.equals(this.index, o.index); 1071 } 1072 1073 /** Generates a Hash-Code for {@code 'this'} instance */ 1074 public int hashCode() 1075 { 1076 return 1077 Arrays.hashCode(this.index); 1078 } 1079 } 1080 1081 /** <CODE>[No Description Provided by Google]</CODE> */ 1082 public static class RareIntegerData 1083 extends BaseType 1084 implements java.io.Serializable 1085 { 1086 /** For Object Serialization. java.io.Serializable */ 1087 protected static final long serialVersionUID = 1; 1088 1089 public boolean[] optionals() 1090 { return new boolean[] { false, false, }; } 1091 1092 /** <CODE>[No Description Provided by Google]</CODE> */ 1093 public final int[] index; 1094 1095 /** <CODE>[No Description Provided by Google]</CODE> */ 1096 public final int[] value; 1097 1098 /** 1099 * Constructor 1100 * 1101 * @param index - 1102 * 1103 * @param value - 1104 */ 1105 public RareIntegerData(int[] index, int[] value) 1106 { 1107 // Exception-Check(s) to ensure that if any parameters which are not declared as 1108 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 1109 1110 if (index == null) BRDPC.throwNPE("index"); 1111 if (value == null) BRDPC.throwNPE("value"); 1112 1113 this.index = index; 1114 this.value = value; 1115 } 1116 1117 /** 1118 * JSON Object Constructor 1119 * @param jo A Json-Object having data about an instance of {@code 'RareIntegerData'}. 1120 */ 1121 public RareIntegerData (JsonObject jo) 1122 { 1123 this.index = (jo.getJsonArray("index") == null) 1124 ? null 1125 : ReadArrJSON.DimN.intArr(jo.getJsonArray("index"), -1, 0, null, int[].class); 1126 1127 this.value = (jo.getJsonArray("value") == null) 1128 ? null 1129 : ReadArrJSON.DimN.intArr(jo.getJsonArray("value"), -1, 0, null, int[].class); 1130 1131 } 1132 1133 1134 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 1135 public boolean equals(Object other) 1136 { 1137 if (other == null) return false; 1138 if (other.getClass() != this.getClass()) return false; 1139 1140 RareIntegerData o = (RareIntegerData) other; 1141 1142 return 1143 Arrays.equals(this.index, o.index) 1144 && Arrays.equals(this.value, o.value); 1145 } 1146 1147 /** Generates a Hash-Code for {@code 'this'} instance */ 1148 public int hashCode() 1149 { 1150 return 1151 Arrays.hashCode(this.index) 1152 + Arrays.hashCode(this.value); 1153 } 1154 } 1155 1156 /** Document snapshot. */ 1157 public static class DocumentSnapshot 1158 extends BaseType 1159 implements java.io.Serializable 1160 { 1161 /** For Object Serialization. java.io.Serializable */ 1162 protected static final long serialVersionUID = 1; 1163 1164 public boolean[] optionals() 1165 { return new boolean[] { false, false, false, false, false, false, false, false, false, false, false, true, true, true, true, }; } 1166 1167 /** Document URL that <CODE>Document</CODE> or <CODE>FrameOwner</CODE> node points to. */ 1168 public final int documentURL; 1169 1170 /** Document title. */ 1171 public final int title; 1172 1173 /** Base URL that <CODE>Document</CODE> or <CODE>FrameOwner</CODE> node uses for URL completion. */ 1174 public final int baseURL; 1175 1176 /** Contains the document's content language. */ 1177 public final int contentLanguage; 1178 1179 /** Contains the document's character set encoding. */ 1180 public final int encodingName; 1181 1182 /** <CODE>DocumentType</CODE> node's publicId. */ 1183 public final int publicId; 1184 1185 /** <CODE>DocumentType</CODE> node's systemId. */ 1186 public final int systemId; 1187 1188 /** Frame ID for frame owner elements and also for the document node. */ 1189 public final int frameId; 1190 1191 /** A table with dom nodes. */ 1192 public final DOMSnapshot.NodeTreeSnapshot nodes; 1193 1194 /** The nodes in the layout tree. */ 1195 public final DOMSnapshot.LayoutTreeSnapshot layout; 1196 1197 /** The post-layout inline text nodes. */ 1198 public final DOMSnapshot.TextBoxSnapshot textBoxes; 1199 1200 /** 1201 * Horizontal scroll offset. 1202 * <BR /> 1203 * <BR /><B>OPTIONAL</B> 1204 */ 1205 public final Number scrollOffsetX; 1206 1207 /** 1208 * Vertical scroll offset. 1209 * <BR /> 1210 * <BR /><B>OPTIONAL</B> 1211 */ 1212 public final Number scrollOffsetY; 1213 1214 /** 1215 * Document content width. 1216 * <BR /> 1217 * <BR /><B>OPTIONAL</B> 1218 */ 1219 public final Number contentWidth; 1220 1221 /** 1222 * Document content height. 1223 * <BR /> 1224 * <BR /><B>OPTIONAL</B> 1225 */ 1226 public final Number contentHeight; 1227 1228 /** 1229 * Constructor 1230 * 1231 * @param documentURL Document URL that <CODE>Document</CODE> or <CODE>FrameOwner</CODE> node points to. 1232 * 1233 * @param title Document title. 1234 * 1235 * @param baseURL Base URL that <CODE>Document</CODE> or <CODE>FrameOwner</CODE> node uses for URL completion. 1236 * 1237 * @param contentLanguage Contains the document's content language. 1238 * 1239 * @param encodingName Contains the document's character set encoding. 1240 * 1241 * @param publicId <CODE>DocumentType</CODE> node's publicId. 1242 * 1243 * @param systemId <CODE>DocumentType</CODE> node's systemId. 1244 * 1245 * @param frameId Frame ID for frame owner elements and also for the document node. 1246 * 1247 * @param nodes A table with dom nodes. 1248 * 1249 * @param layout The nodes in the layout tree. 1250 * 1251 * @param textBoxes The post-layout inline text nodes. 1252 * 1253 * @param scrollOffsetX Horizontal scroll offset. 1254 * <BR /><B>OPTIONAL</B> 1255 * 1256 * @param scrollOffsetY Vertical scroll offset. 1257 * <BR /><B>OPTIONAL</B> 1258 * 1259 * @param contentWidth Document content width. 1260 * <BR /><B>OPTIONAL</B> 1261 * 1262 * @param contentHeight Document content height. 1263 * <BR /><B>OPTIONAL</B> 1264 */ 1265 public DocumentSnapshot( 1266 int documentURL, int title, int baseURL, int contentLanguage, int encodingName, 1267 int publicId, int systemId, int frameId, DOMSnapshot.NodeTreeSnapshot nodes, 1268 DOMSnapshot.LayoutTreeSnapshot layout, DOMSnapshot.TextBoxSnapshot textBoxes, 1269 Number scrollOffsetX, Number scrollOffsetY, Number contentWidth, Number contentHeight 1270 ) 1271 { 1272 // Exception-Check(s) to ensure that if any parameters which are not declared as 1273 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 1274 1275 if (nodes == null) BRDPC.throwNPE("nodes"); 1276 if (layout == null) BRDPC.throwNPE("layout"); 1277 if (textBoxes == null) BRDPC.throwNPE("textBoxes"); 1278 1279 this.documentURL = documentURL; 1280 this.title = title; 1281 this.baseURL = baseURL; 1282 this.contentLanguage = contentLanguage; 1283 this.encodingName = encodingName; 1284 this.publicId = publicId; 1285 this.systemId = systemId; 1286 this.frameId = frameId; 1287 this.nodes = nodes; 1288 this.layout = layout; 1289 this.textBoxes = textBoxes; 1290 this.scrollOffsetX = scrollOffsetX; 1291 this.scrollOffsetY = scrollOffsetY; 1292 this.contentWidth = contentWidth; 1293 this.contentHeight = contentHeight; 1294 } 1295 1296 /** 1297 * JSON Object Constructor 1298 * @param jo A Json-Object having data about an instance of {@code 'DocumentSnapshot'}. 1299 */ 1300 public DocumentSnapshot (JsonObject jo) 1301 { 1302 this.documentURL = ReadPrimJSON.getInt(jo, "documentURL"); 1303 this.title = ReadPrimJSON.getInt(jo, "title"); 1304 this.baseURL = ReadPrimJSON.getInt(jo, "baseURL"); 1305 this.contentLanguage = ReadPrimJSON.getInt(jo, "contentLanguage"); 1306 this.encodingName = ReadPrimJSON.getInt(jo, "encodingName"); 1307 this.publicId = ReadPrimJSON.getInt(jo, "publicId"); 1308 this.systemId = ReadPrimJSON.getInt(jo, "systemId"); 1309 this.frameId = ReadPrimJSON.getInt(jo, "frameId"); 1310 this.nodes = ReadJSON.getObject(jo, "nodes", DOMSnapshot.NodeTreeSnapshot.class, false, true); 1311 this.layout = ReadJSON.getObject(jo, "layout", DOMSnapshot.LayoutTreeSnapshot.class, false, true); 1312 this.textBoxes = ReadJSON.getObject(jo, "textBoxes", DOMSnapshot.TextBoxSnapshot.class, false, true); 1313 this.scrollOffsetX = ReadNumberJSON.get(jo, "scrollOffsetX", true, false); 1314 this.scrollOffsetY = ReadNumberJSON.get(jo, "scrollOffsetY", true, false); 1315 this.contentWidth = ReadNumberJSON.get(jo, "contentWidth", true, false); 1316 this.contentHeight = ReadNumberJSON.get(jo, "contentHeight", true, false); 1317 } 1318 1319 1320 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 1321 public boolean equals(Object other) 1322 { 1323 if (other == null) return false; 1324 if (other.getClass() != this.getClass()) return false; 1325 1326 DocumentSnapshot o = (DocumentSnapshot) other; 1327 1328 return 1329 Objects.equals(this.documentURL, o.documentURL) 1330 && Objects.equals(this.title, o.title) 1331 && Objects.equals(this.baseURL, o.baseURL) 1332 && Objects.equals(this.contentLanguage, o.contentLanguage) 1333 && Objects.equals(this.encodingName, o.encodingName) 1334 && Objects.equals(this.publicId, o.publicId) 1335 && Objects.equals(this.systemId, o.systemId) 1336 && Objects.equals(this.frameId, o.frameId) 1337 && Objects.equals(this.nodes, o.nodes) 1338 && Objects.equals(this.layout, o.layout) 1339 && Objects.equals(this.textBoxes, o.textBoxes) 1340 && Objects.equals(this.scrollOffsetX, o.scrollOffsetX) 1341 && Objects.equals(this.scrollOffsetY, o.scrollOffsetY) 1342 && Objects.equals(this.contentWidth, o.contentWidth) 1343 && Objects.equals(this.contentHeight, o.contentHeight); 1344 } 1345 1346 /** Generates a Hash-Code for {@code 'this'} instance */ 1347 public int hashCode() 1348 { 1349 return 1350 this.documentURL 1351 + this.title 1352 + this.baseURL 1353 + this.contentLanguage 1354 + this.encodingName 1355 + this.publicId 1356 + this.systemId 1357 + this.frameId 1358 + this.nodes.hashCode() 1359 + this.layout.hashCode() 1360 + this.textBoxes.hashCode() 1361 + Objects.hashCode(this.scrollOffsetX) 1362 + Objects.hashCode(this.scrollOffsetY) 1363 + Objects.hashCode(this.contentWidth) 1364 + Objects.hashCode(this.contentHeight); 1365 } 1366 } 1367 1368 /** Table containing nodes. */ 1369 public static class NodeTreeSnapshot 1370 extends BaseType 1371 implements java.io.Serializable 1372 { 1373 /** For Object Serialization. java.io.Serializable */ 1374 protected static final long serialVersionUID = 1; 1375 1376 public boolean[] optionals() 1377 { return new boolean[] { true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, }; } 1378 1379 /** 1380 * Parent node index. 1381 * <BR /> 1382 * <BR /><B>OPTIONAL</B> 1383 */ 1384 public final int[] parentIndex; 1385 1386 /** 1387 * <CODE>Node</CODE>'s nodeType. 1388 * <BR /> 1389 * <BR /><B>OPTIONAL</B> 1390 */ 1391 public final int[] nodeType; 1392 1393 /** 1394 * Type of the shadow root the <CODE>Node</CODE> is in. String values are equal to the <CODE>ShadowRootType</CODE> enum. 1395 * <BR /> 1396 * <BR /><B>OPTIONAL</B> 1397 */ 1398 public final DOMSnapshot.RareStringData shadowRootType; 1399 1400 /** 1401 * <CODE>Node</CODE>'s nodeName. 1402 * <BR /> 1403 * <BR /><B>OPTIONAL</B> 1404 */ 1405 public final int[] nodeName; 1406 1407 /** 1408 * <CODE>Node</CODE>'s nodeValue. 1409 * <BR /> 1410 * <BR /><B>OPTIONAL</B> 1411 */ 1412 public final int[] nodeValue; 1413 1414 /** 1415 * <CODE>Node</CODE>'s id, corresponds to DOM.Node.backendNodeId. 1416 * <BR /> 1417 * <BR /><B>OPTIONAL</B> 1418 */ 1419 public final int[] backendNodeId; 1420 1421 /** 1422 * Attributes of an <CODE>Element</CODE> node. Flatten name, value pairs. 1423 * <BR /> 1424 * <BR /><B>OPTIONAL</B> 1425 */ 1426 public final int[][] attributes; 1427 1428 /** 1429 * Only set for textarea elements, contains the text value. 1430 * <BR /> 1431 * <BR /><B>OPTIONAL</B> 1432 */ 1433 public final DOMSnapshot.RareStringData textValue; 1434 1435 /** 1436 * Only set for input elements, contains the input's associated text value. 1437 * <BR /> 1438 * <BR /><B>OPTIONAL</B> 1439 */ 1440 public final DOMSnapshot.RareStringData inputValue; 1441 1442 /** 1443 * Only set for radio and checkbox input elements, indicates if the element has been checked 1444 * <BR /> 1445 * <BR /><B>OPTIONAL</B> 1446 */ 1447 public final DOMSnapshot.RareBooleanData inputChecked; 1448 1449 /** 1450 * Only set for option elements, indicates if the element has been selected 1451 * <BR /> 1452 * <BR /><B>OPTIONAL</B> 1453 */ 1454 public final DOMSnapshot.RareBooleanData optionSelected; 1455 1456 /** 1457 * The index of the document in the list of the snapshot documents. 1458 * <BR /> 1459 * <BR /><B>OPTIONAL</B> 1460 */ 1461 public final DOMSnapshot.RareIntegerData contentDocumentIndex; 1462 1463 /** 1464 * Type of a pseudo element node. 1465 * <BR /> 1466 * <BR /><B>OPTIONAL</B> 1467 */ 1468 public final DOMSnapshot.RareStringData pseudoType; 1469 1470 /** 1471 * Whether this DOM node responds to mouse clicks. This includes nodes that have had click 1472 * event listeners attached via JavaScript as well as anchor tags that naturally navigate when 1473 * clicked. 1474 * <BR /> 1475 * <BR /><B>OPTIONAL</B> 1476 */ 1477 public final DOMSnapshot.RareBooleanData isClickable; 1478 1479 /** 1480 * The selected url for nodes with a srcset attribute. 1481 * <BR /> 1482 * <BR /><B>OPTIONAL</B> 1483 */ 1484 public final DOMSnapshot.RareStringData currentSourceURL; 1485 1486 /** 1487 * The url of the script (if any) that generates this node. 1488 * <BR /> 1489 * <BR /><B>OPTIONAL</B> 1490 */ 1491 public final DOMSnapshot.RareStringData originURL; 1492 1493 /** 1494 * Constructor 1495 * 1496 * @param parentIndex Parent node index. 1497 * <BR /><B>OPTIONAL</B> 1498 * 1499 * @param nodeType <CODE>Node</CODE>'s nodeType. 1500 * <BR /><B>OPTIONAL</B> 1501 * 1502 * @param shadowRootType Type of the shadow root the <CODE>Node</CODE> is in. String values are equal to the <CODE>ShadowRootType</CODE> enum. 1503 * <BR /><B>OPTIONAL</B> 1504 * 1505 * @param nodeName <CODE>Node</CODE>'s nodeName. 1506 * <BR /><B>OPTIONAL</B> 1507 * 1508 * @param nodeValue <CODE>Node</CODE>'s nodeValue. 1509 * <BR /><B>OPTIONAL</B> 1510 * 1511 * @param backendNodeId <CODE>Node</CODE>'s id, corresponds to DOM.Node.backendNodeId. 1512 * <BR /><B>OPTIONAL</B> 1513 * 1514 * @param attributes Attributes of an <CODE>Element</CODE> node. Flatten name, value pairs. 1515 * <BR /><B>OPTIONAL</B> 1516 * 1517 * @param textValue Only set for textarea elements, contains the text value. 1518 * <BR /><B>OPTIONAL</B> 1519 * 1520 * @param inputValue Only set for input elements, contains the input's associated text value. 1521 * <BR /><B>OPTIONAL</B> 1522 * 1523 * @param inputChecked Only set for radio and checkbox input elements, indicates if the element has been checked 1524 * <BR /><B>OPTIONAL</B> 1525 * 1526 * @param optionSelected Only set for option elements, indicates if the element has been selected 1527 * <BR /><B>OPTIONAL</B> 1528 * 1529 * @param contentDocumentIndex The index of the document in the list of the snapshot documents. 1530 * <BR /><B>OPTIONAL</B> 1531 * 1532 * @param pseudoType Type of a pseudo element node. 1533 * <BR /><B>OPTIONAL</B> 1534 * 1535 * @param isClickable 1536 * Whether this DOM node responds to mouse clicks. This includes nodes that have had click 1537 * event listeners attached via JavaScript as well as anchor tags that naturally navigate when 1538 * clicked. 1539 * <BR /><B>OPTIONAL</B> 1540 * 1541 * @param currentSourceURL The selected url for nodes with a srcset attribute. 1542 * <BR /><B>OPTIONAL</B> 1543 * 1544 * @param originURL The url of the script (if any) that generates this node. 1545 * <BR /><B>OPTIONAL</B> 1546 */ 1547 public NodeTreeSnapshot( 1548 int[] parentIndex, int[] nodeType, DOMSnapshot.RareStringData shadowRootType, 1549 int[] nodeName, int[] nodeValue, int[] backendNodeId, int[][] attributes, 1550 DOMSnapshot.RareStringData textValue, DOMSnapshot.RareStringData inputValue, 1551 DOMSnapshot.RareBooleanData inputChecked, 1552 DOMSnapshot.RareBooleanData optionSelected, 1553 DOMSnapshot.RareIntegerData contentDocumentIndex, 1554 DOMSnapshot.RareStringData pseudoType, DOMSnapshot.RareBooleanData isClickable, 1555 DOMSnapshot.RareStringData currentSourceURL, DOMSnapshot.RareStringData originURL 1556 ) 1557 { 1558 this.parentIndex = parentIndex; 1559 this.nodeType = nodeType; 1560 this.shadowRootType = shadowRootType; 1561 this.nodeName = nodeName; 1562 this.nodeValue = nodeValue; 1563 this.backendNodeId = backendNodeId; 1564 this.attributes = attributes; 1565 this.textValue = textValue; 1566 this.inputValue = inputValue; 1567 this.inputChecked = inputChecked; 1568 this.optionSelected = optionSelected; 1569 this.contentDocumentIndex = contentDocumentIndex; 1570 this.pseudoType = pseudoType; 1571 this.isClickable = isClickable; 1572 this.currentSourceURL = currentSourceURL; 1573 this.originURL = originURL; 1574 } 1575 1576 /** 1577 * JSON Object Constructor 1578 * @param jo A Json-Object having data about an instance of {@code 'NodeTreeSnapshot'}. 1579 */ 1580 public NodeTreeSnapshot (JsonObject jo) 1581 { 1582 this.parentIndex = (jo.getJsonArray("parentIndex") == null) 1583 ? null 1584 : ReadArrJSON.DimN.intArr(jo.getJsonArray("parentIndex"), -1, 0, null, int[].class); 1585 1586 this.nodeType = (jo.getJsonArray("nodeType") == null) 1587 ? null 1588 : ReadArrJSON.DimN.intArr(jo.getJsonArray("nodeType"), -1, 0, null, int[].class); 1589 1590 this.shadowRootType = ReadJSON.getObject(jo, "shadowRootType", DOMSnapshot.RareStringData.class, true, false); 1591 this.nodeName = (jo.getJsonArray("nodeName") == null) 1592 ? null 1593 : ReadArrJSON.DimN.intArr(jo.getJsonArray("nodeName"), -1, 0, null, int[].class); 1594 1595 this.nodeValue = (jo.getJsonArray("nodeValue") == null) 1596 ? null 1597 : ReadArrJSON.DimN.intArr(jo.getJsonArray("nodeValue"), -1, 0, null, int[].class); 1598 1599 this.backendNodeId = (jo.getJsonArray("backendNodeId") == null) 1600 ? null 1601 : ReadArrJSON.DimN.intArr(jo.getJsonArray("backendNodeId"), -1, 0, null, int[].class); 1602 1603 this.attributes = (jo.getJsonArray("attributes") == null) 1604 ? null 1605 : ReadArrJSON.DimN.intArr(jo.getJsonArray("attributes"), -1, 0, null, int[][].class); 1606 1607 this.textValue = ReadJSON.getObject(jo, "textValue", DOMSnapshot.RareStringData.class, true, false); 1608 this.inputValue = ReadJSON.getObject(jo, "inputValue", DOMSnapshot.RareStringData.class, true, false); 1609 this.inputChecked = ReadJSON.getObject(jo, "inputChecked", DOMSnapshot.RareBooleanData.class, true, false); 1610 this.optionSelected = ReadJSON.getObject(jo, "optionSelected", DOMSnapshot.RareBooleanData.class, true, false); 1611 this.contentDocumentIndex = ReadJSON.getObject(jo, "contentDocumentIndex", DOMSnapshot.RareIntegerData.class, true, false); 1612 this.pseudoType = ReadJSON.getObject(jo, "pseudoType", DOMSnapshot.RareStringData.class, true, false); 1613 this.isClickable = ReadJSON.getObject(jo, "isClickable", DOMSnapshot.RareBooleanData.class, true, false); 1614 this.currentSourceURL = ReadJSON.getObject(jo, "currentSourceURL", DOMSnapshot.RareStringData.class, true, false); 1615 this.originURL = ReadJSON.getObject(jo, "originURL", DOMSnapshot.RareStringData.class, true, false); 1616 } 1617 1618 1619 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 1620 public boolean equals(Object other) 1621 { 1622 if (other == null) return false; 1623 if (other.getClass() != this.getClass()) return false; 1624 1625 NodeTreeSnapshot o = (NodeTreeSnapshot) other; 1626 1627 return 1628 Arrays.equals(this.parentIndex, o.parentIndex) 1629 && Arrays.equals(this.nodeType, o.nodeType) 1630 && Objects.equals(this.shadowRootType, o.shadowRootType) 1631 && Arrays.equals(this.nodeName, o.nodeName) 1632 && Arrays.equals(this.nodeValue, o.nodeValue) 1633 && Arrays.equals(this.backendNodeId, o.backendNodeId) 1634 && Arrays.equals(this.attributes, o.attributes) 1635 && Objects.equals(this.textValue, o.textValue) 1636 && Objects.equals(this.inputValue, o.inputValue) 1637 && Objects.equals(this.inputChecked, o.inputChecked) 1638 && Objects.equals(this.optionSelected, o.optionSelected) 1639 && Objects.equals(this.contentDocumentIndex, o.contentDocumentIndex) 1640 && Objects.equals(this.pseudoType, o.pseudoType) 1641 && Objects.equals(this.isClickable, o.isClickable) 1642 && Objects.equals(this.currentSourceURL, o.currentSourceURL) 1643 && Objects.equals(this.originURL, o.originURL); 1644 } 1645 1646 /** Generates a Hash-Code for {@code 'this'} instance */ 1647 public int hashCode() 1648 { 1649 return 1650 Arrays.hashCode(this.parentIndex) 1651 + Arrays.hashCode(this.nodeType) 1652 + this.shadowRootType.hashCode() 1653 + Arrays.hashCode(this.nodeName) 1654 + Arrays.hashCode(this.nodeValue) 1655 + Arrays.hashCode(this.backendNodeId) 1656 + Arrays.hashCode(this.attributes) 1657 + this.textValue.hashCode() 1658 + this.inputValue.hashCode() 1659 + this.inputChecked.hashCode() 1660 + this.optionSelected.hashCode() 1661 + this.contentDocumentIndex.hashCode() 1662 + this.pseudoType.hashCode() 1663 + this.isClickable.hashCode() 1664 + this.currentSourceURL.hashCode() 1665 + this.originURL.hashCode(); 1666 } 1667 } 1668 1669 /** Table of details of an element in the DOM tree with a LayoutObject. */ 1670 public static class LayoutTreeSnapshot 1671 extends BaseType 1672 implements java.io.Serializable 1673 { 1674 /** For Object Serialization. java.io.Serializable */ 1675 protected static final long serialVersionUID = 1; 1676 1677 public boolean[] optionals() 1678 { return new boolean[] { false, false, false, false, false, true, true, true, true, true, true, }; } 1679 1680 /** Index of the corresponding node in the <CODE>NodeTreeSnapshot</CODE> array returned by <CODE>captureSnapshot</CODE>. */ 1681 public final int[] nodeIndex; 1682 1683 /** Array of indexes specifying computed style strings, filtered according to the <CODE>computedStyles</CODE> parameter passed to <CODE>captureSnapshot</CODE>. */ 1684 public final int[][] styles; 1685 1686 /** The absolute position bounding box. */ 1687 public final Number[][] bounds; 1688 1689 /** Contents of the LayoutText, if any. */ 1690 public final int[] text; 1691 1692 /** Stacking context information. */ 1693 public final DOMSnapshot.RareBooleanData stackingContexts; 1694 1695 /** 1696 * Global paint order index, which is determined by the stacking order of the nodes. Nodes 1697 * that are painted together will have the same index. Only provided if includePaintOrder in 1698 * captureSnapshot was true. 1699 * <BR /> 1700 * <BR /><B>OPTIONAL</B> 1701 */ 1702 public final int[] paintOrders; 1703 1704 /** 1705 * The offset rect of nodes. Only available when includeDOMRects is set to true 1706 * <BR /> 1707 * <BR /><B>OPTIONAL</B> 1708 */ 1709 public final Number[][] offsetRects; 1710 1711 /** 1712 * The scroll rect of nodes. Only available when includeDOMRects is set to true 1713 * <BR /> 1714 * <BR /><B>OPTIONAL</B> 1715 */ 1716 public final Number[][] scrollRects; 1717 1718 /** 1719 * The client rect of nodes. Only available when includeDOMRects is set to true 1720 * <BR /> 1721 * <BR /><B>OPTIONAL</B> 1722 */ 1723 public final Number[][] clientRects; 1724 1725 /** 1726 * The list of background colors that are blended with colors of overlapping elements. 1727 * <BR /> 1728 * <BR /><B>OPTIONAL</B> 1729 * <BR /><B>EXPERIMENTAL</B> 1730 */ 1731 public final int[] blendedBackgroundColors; 1732 1733 /** 1734 * The list of computed text opacities. 1735 * <BR /> 1736 * <BR /><B>OPTIONAL</B> 1737 * <BR /><B>EXPERIMENTAL</B> 1738 */ 1739 public final Number[] textColorOpacities; 1740 1741 /** 1742 * Constructor 1743 * 1744 * @param nodeIndex Index of the corresponding node in the <CODE>NodeTreeSnapshot</CODE> array returned by <CODE>captureSnapshot</CODE>. 1745 * 1746 * @param styles Array of indexes specifying computed style strings, filtered according to the <CODE>computedStyles</CODE> parameter passed to <CODE>captureSnapshot</CODE>. 1747 * 1748 * @param bounds The absolute position bounding box. 1749 * 1750 * @param text Contents of the LayoutText, if any. 1751 * 1752 * @param stackingContexts Stacking context information. 1753 * 1754 * @param paintOrders 1755 * Global paint order index, which is determined by the stacking order of the nodes. Nodes 1756 * that are painted together will have the same index. Only provided if includePaintOrder in 1757 * captureSnapshot was true. 1758 * <BR /><B>OPTIONAL</B> 1759 * 1760 * @param offsetRects The offset rect of nodes. Only available when includeDOMRects is set to true 1761 * <BR /><B>OPTIONAL</B> 1762 * 1763 * @param scrollRects The scroll rect of nodes. Only available when includeDOMRects is set to true 1764 * <BR /><B>OPTIONAL</B> 1765 * 1766 * @param clientRects The client rect of nodes. Only available when includeDOMRects is set to true 1767 * <BR /><B>OPTIONAL</B> 1768 * 1769 * @param blendedBackgroundColors The list of background colors that are blended with colors of overlapping elements. 1770 * <BR /><B>OPTIONAL</B> 1771 * <BR /><B>EXPERIMENTAL</B> 1772 * 1773 * @param textColorOpacities The list of computed text opacities. 1774 * <BR /><B>OPTIONAL</B> 1775 * <BR /><B>EXPERIMENTAL</B> 1776 */ 1777 public LayoutTreeSnapshot( 1778 int[] nodeIndex, int[][] styles, Number[][] bounds, int[] text, 1779 DOMSnapshot.RareBooleanData stackingContexts, int[] paintOrders, 1780 Number[][] offsetRects, Number[][] scrollRects, Number[][] clientRects, 1781 int[] blendedBackgroundColors, Number[] textColorOpacities 1782 ) 1783 { 1784 // Exception-Check(s) to ensure that if any parameters which are not declared as 1785 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 1786 1787 if (nodeIndex == null) BRDPC.throwNPE("nodeIndex"); 1788 if (styles == null) BRDPC.throwNPE("styles"); 1789 if (bounds == null) BRDPC.throwNPE("bounds"); 1790 if (text == null) BRDPC.throwNPE("text"); 1791 if (stackingContexts == null) BRDPC.throwNPE("stackingContexts"); 1792 1793 this.nodeIndex = nodeIndex; 1794 this.styles = styles; 1795 this.bounds = bounds; 1796 this.text = text; 1797 this.stackingContexts = stackingContexts; 1798 this.paintOrders = paintOrders; 1799 this.offsetRects = offsetRects; 1800 this.scrollRects = scrollRects; 1801 this.clientRects = clientRects; 1802 this.blendedBackgroundColors = blendedBackgroundColors; 1803 this.textColorOpacities = textColorOpacities; 1804 } 1805 1806 /** 1807 * JSON Object Constructor 1808 * @param jo A Json-Object having data about an instance of {@code 'LayoutTreeSnapshot'}. 1809 */ 1810 public LayoutTreeSnapshot (JsonObject jo) 1811 { 1812 this.nodeIndex = (jo.getJsonArray("nodeIndex") == null) 1813 ? null 1814 : ReadArrJSON.DimN.intArr(jo.getJsonArray("nodeIndex"), -1, 0, null, int[].class); 1815 1816 this.styles = (jo.getJsonArray("styles") == null) 1817 ? null 1818 : ReadArrJSON.DimN.intArr(jo.getJsonArray("styles"), -1, 0, null, int[][].class); 1819 1820 this.bounds = (jo.getJsonArray("bounds") == null) 1821 ? null 1822 : ReadArrJSON.DimN.arrNumber(jo.getJsonArray("bounds"), -1, 0, null, Number[][].class); 1823 1824 this.text = (jo.getJsonArray("text") == null) 1825 ? null 1826 : ReadArrJSON.DimN.intArr(jo.getJsonArray("text"), -1, 0, null, int[].class); 1827 1828 this.stackingContexts = ReadJSON.getObject(jo, "stackingContexts", DOMSnapshot.RareBooleanData.class, false, true); 1829 this.paintOrders = (jo.getJsonArray("paintOrders") == null) 1830 ? null 1831 : ReadArrJSON.DimN.intArr(jo.getJsonArray("paintOrders"), -1, 0, null, int[].class); 1832 1833 this.offsetRects = (jo.getJsonArray("offsetRects") == null) 1834 ? null 1835 : ReadArrJSON.DimN.arrNumber(jo.getJsonArray("offsetRects"), -1, 0, null, Number[][].class); 1836 1837 this.scrollRects = (jo.getJsonArray("scrollRects") == null) 1838 ? null 1839 : ReadArrJSON.DimN.arrNumber(jo.getJsonArray("scrollRects"), -1, 0, null, Number[][].class); 1840 1841 this.clientRects = (jo.getJsonArray("clientRects") == null) 1842 ? null 1843 : ReadArrJSON.DimN.arrNumber(jo.getJsonArray("clientRects"), -1, 0, null, Number[][].class); 1844 1845 this.blendedBackgroundColors = (jo.getJsonArray("blendedBackgroundColors") == null) 1846 ? null 1847 : ReadArrJSON.DimN.intArr(jo.getJsonArray("blendedBackgroundColors"), -1, 0, null, int[].class); 1848 1849 this.textColorOpacities = (jo.getJsonArray("textColorOpacities") == null) 1850 ? null 1851 : ReadArrJSON.DimN.arrNumber(jo.getJsonArray("textColorOpacities"), -1, 0, null, Number[].class); 1852 1853 } 1854 1855 1856 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 1857 public boolean equals(Object other) 1858 { 1859 if (other == null) return false; 1860 if (other.getClass() != this.getClass()) return false; 1861 1862 LayoutTreeSnapshot o = (LayoutTreeSnapshot) other; 1863 1864 return 1865 Arrays.equals(this.nodeIndex, o.nodeIndex) 1866 && Arrays.equals(this.styles, o.styles) 1867 && Arrays.deepEquals(this.bounds, o.bounds) 1868 && Arrays.equals(this.text, o.text) 1869 && Objects.equals(this.stackingContexts, o.stackingContexts) 1870 && Arrays.equals(this.paintOrders, o.paintOrders) 1871 && Arrays.deepEquals(this.offsetRects, o.offsetRects) 1872 && Arrays.deepEquals(this.scrollRects, o.scrollRects) 1873 && Arrays.deepEquals(this.clientRects, o.clientRects) 1874 && Arrays.equals(this.blendedBackgroundColors, o.blendedBackgroundColors) 1875 && Arrays.deepEquals(this.textColorOpacities, o.textColorOpacities); 1876 } 1877 1878 /** Generates a Hash-Code for {@code 'this'} instance */ 1879 public int hashCode() 1880 { 1881 return 1882 Arrays.hashCode(this.nodeIndex) 1883 + Arrays.hashCode(this.styles) 1884 + Arrays.deepHashCode(this.bounds) 1885 + Arrays.hashCode(this.text) 1886 + this.stackingContexts.hashCode() 1887 + Arrays.hashCode(this.paintOrders) 1888 + Arrays.deepHashCode(this.offsetRects) 1889 + Arrays.deepHashCode(this.scrollRects) 1890 + Arrays.deepHashCode(this.clientRects) 1891 + Arrays.hashCode(this.blendedBackgroundColors) 1892 + Arrays.deepHashCode(this.textColorOpacities); 1893 } 1894 } 1895 1896 /** 1897 * Table of details of the post layout rendered text positions. The exact layout should not be regarded as 1898 * stable and may change between versions. 1899 */ 1900 public static class TextBoxSnapshot 1901 extends BaseType 1902 implements java.io.Serializable 1903 { 1904 /** For Object Serialization. java.io.Serializable */ 1905 protected static final long serialVersionUID = 1; 1906 1907 public boolean[] optionals() 1908 { return new boolean[] { false, false, false, false, }; } 1909 1910 /** Index of the layout tree node that owns this box collection. */ 1911 public final int[] layoutIndex; 1912 1913 /** The absolute position bounding box. */ 1914 public final Number[][] bounds; 1915 1916 /** 1917 * The starting index in characters, for this post layout textbox substring. Characters that 1918 * would be represented as a surrogate pair in UTF-16 have length 2. 1919 */ 1920 public final int[] start; 1921 1922 /** 1923 * The number of characters in this post layout textbox substring. Characters that would be 1924 * represented as a surrogate pair in UTF-16 have length 2. 1925 */ 1926 public final int[] length; 1927 1928 /** 1929 * Constructor 1930 * 1931 * @param layoutIndex Index of the layout tree node that owns this box collection. 1932 * 1933 * @param bounds The absolute position bounding box. 1934 * 1935 * @param start 1936 * The starting index in characters, for this post layout textbox substring. Characters that 1937 * would be represented as a surrogate pair in UTF-16 have length 2. 1938 * 1939 * @param length 1940 * The number of characters in this post layout textbox substring. Characters that would be 1941 * represented as a surrogate pair in UTF-16 have length 2. 1942 */ 1943 public TextBoxSnapshot(int[] layoutIndex, Number[][] bounds, int[] start, int[] length) 1944 { 1945 // Exception-Check(s) to ensure that if any parameters which are not declared as 1946 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 1947 1948 if (layoutIndex == null) BRDPC.throwNPE("layoutIndex"); 1949 if (bounds == null) BRDPC.throwNPE("bounds"); 1950 if (start == null) BRDPC.throwNPE("start"); 1951 if (length == null) BRDPC.throwNPE("length"); 1952 1953 this.layoutIndex = layoutIndex; 1954 this.bounds = bounds; 1955 this.start = start; 1956 this.length = length; 1957 } 1958 1959 /** 1960 * JSON Object Constructor 1961 * @param jo A Json-Object having data about an instance of {@code 'TextBoxSnapshot'}. 1962 */ 1963 public TextBoxSnapshot (JsonObject jo) 1964 { 1965 this.layoutIndex = (jo.getJsonArray("layoutIndex") == null) 1966 ? null 1967 : ReadArrJSON.DimN.intArr(jo.getJsonArray("layoutIndex"), -1, 0, null, int[].class); 1968 1969 this.bounds = (jo.getJsonArray("bounds") == null) 1970 ? null 1971 : ReadArrJSON.DimN.arrNumber(jo.getJsonArray("bounds"), -1, 0, null, Number[][].class); 1972 1973 this.start = (jo.getJsonArray("start") == null) 1974 ? null 1975 : ReadArrJSON.DimN.intArr(jo.getJsonArray("start"), -1, 0, null, int[].class); 1976 1977 this.length = (jo.getJsonArray("length") == null) 1978 ? null 1979 : ReadArrJSON.DimN.intArr(jo.getJsonArray("length"), -1, 0, null, int[].class); 1980 1981 } 1982 1983 1984 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 1985 public boolean equals(Object other) 1986 { 1987 if (other == null) return false; 1988 if (other.getClass() != this.getClass()) return false; 1989 1990 TextBoxSnapshot o = (TextBoxSnapshot) other; 1991 1992 return 1993 Arrays.equals(this.layoutIndex, o.layoutIndex) 1994 && Arrays.deepEquals(this.bounds, o.bounds) 1995 && Arrays.equals(this.start, o.start) 1996 && Arrays.equals(this.length, o.length); 1997 } 1998 1999 /** Generates a Hash-Code for {@code 'this'} instance */ 2000 public int hashCode() 2001 { 2002 return 2003 Arrays.hashCode(this.layoutIndex) 2004 + Arrays.deepHashCode(this.bounds) 2005 + Arrays.hashCode(this.start) 2006 + Arrays.hashCode(this.length); 2007 } 2008 } 2009 2010 2011 // Counter for keeping the WebSocket Request ID's distinct. 2012 private static int counter = 1; 2013 2014 /** 2015 * Disables DOM snapshot agent for the given page. 2016 * 2017 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 2018 * {@link Ret0}></CODE> 2019 * 2020 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 2021 * browser receives the invocation-request. 2022 * 2023 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 2024 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 2025 * {@code >} to ensure the Browser Function has run to completion. 2026 */ 2027 public static Script<String, JsonObject, Ret0> disable() 2028 { 2029 final int webSocketID = 17000000 + counter++; 2030 final boolean[] optionals = new boolean[0]; 2031 2032 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 2033 String requestJSON = WriteJSON.get( 2034 parameterTypes.get("disable"), 2035 parameterNames.get("disable"), 2036 optionals, webSocketID, 2037 "DOMSnapshot.disable" 2038 ); 2039 2040 // This Remote Command does not have a Return-Value. 2041 return new Script<> 2042 (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.NoReturnValues); 2043 } 2044 2045 /** 2046 * Enables DOM snapshot agent for the given page. 2047 * 2048 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 2049 * {@link Ret0}></CODE> 2050 * 2051 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 2052 * browser receives the invocation-request. 2053 * 2054 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 2055 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 2056 * {@code >} to ensure the Browser Function has run to completion. 2057 */ 2058 public static Script<String, JsonObject, Ret0> enable() 2059 { 2060 final int webSocketID = 17001000 + counter++; 2061 final boolean[] optionals = new boolean[0]; 2062 2063 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 2064 String requestJSON = WriteJSON.get( 2065 parameterTypes.get("enable"), 2066 parameterNames.get("enable"), 2067 optionals, webSocketID, 2068 "DOMSnapshot.enable" 2069 ); 2070 2071 // This Remote Command does not have a Return-Value. 2072 return new Script<> 2073 (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.NoReturnValues); 2074 } 2075 2076 /** 2077 * Returns a document snapshot, including the full DOM tree of the root node (including iframes, 2078 * template contents, and imported documents) in a flattened array, as well as layout and 2079 * white-listed computed style information for the nodes. Shadow DOM in the returned DOM tree is 2080 * flattened. 2081 * <BR /><B>DEPRECATED</B> 2082 * 2083 * @param computedStyleWhitelist Whitelist of computed styles to return. 2084 * 2085 * @param includeEventListeners Whether or not to retrieve details of DOM listeners (default false). 2086 * <BR /><B>OPTIONAL</B> 2087 * 2088 * @param includePaintOrder Whether to determine and include the paint order index of LayoutTreeNodes (default false). 2089 * <BR /><B>OPTIONAL</B> 2090 * 2091 * @param includeUserAgentShadowTree Whether to include UA shadow tree in the snapshot (default false). 2092 * <BR /><B>OPTIONAL</B> 2093 * 2094 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 2095 * {@link Ret3}></CODE> 2096 * 2097 * <BR /><BR />This {@link Script} may be <B STYLE='color:red'>executed</B> (using 2098 * {@link Script#exec()}), and a {@link Promise} returned. 2099 * 2100 * <BR /><BR />When the {@code Promise} is <B STYLE='color: red'>awaited</B> 2101 * (using {@link Promise#await()}), the {@code Ret3} will subsequently 2102 * be returned from that call. 2103 * 2104 * <BR /><BR />The <B STYLE='color: red'>returned</B> values are encapsulated 2105 * in an instance of <B>{@link Ret3}</B> 2106 * 2107 * <BR /><BR /><UL CLASS=JDUL> 2108 * <LI><CODE><B>Ret3.a:</B> {@link DOMSnapshot.DOMNode}[] (<B>domNodes</B>)</CODE> 2109 * <BR />The nodes in the DOM tree. The DOMNode at index 0 corresponds to the root document. 2110 * <BR /><BR /></LI> 2111 * <LI><CODE><B>Ret3.b:</B> {@link DOMSnapshot.LayoutTreeNode}[] (<B>layoutTreeNodes</B>)</CODE> 2112 * <BR />The nodes in the layout tree. 2113 * <BR /><BR /></LI> 2114 * <LI><CODE><B>Ret3.c:</B> {@link DOMSnapshot.ComputedStyle}[] (<B>computedStyles</B>)</CODE> 2115 * <BR />Whitelisted ComputedStyle properties for each node in the layout tree. 2116 * </LI> 2117 * </UL> 2118 */ 2119 public static Script<String, JsonObject, Ret3<DOMSnapshot.DOMNode[], DOMSnapshot.LayoutTreeNode[], DOMSnapshot.ComputedStyle[]>> 2120 getSnapshot( 2121 String[] computedStyleWhitelist, Boolean includeEventListeners, 2122 Boolean includePaintOrder, Boolean includeUserAgentShadowTree 2123 ) 2124 { 2125 // Exception-Check(s) to ensure that if any parameters which are not declared as 2126 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 2127 2128 if (computedStyleWhitelist == null) BRDPC.throwNPE("computedStyleWhitelist"); 2129 2130 final int webSocketID = 17002000 + counter++; 2131 final boolean[] optionals = { false, true, true, true, }; 2132 2133 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 2134 String requestJSON = WriteJSON.get( 2135 parameterTypes.get("getSnapshot"), 2136 parameterNames.get("getSnapshot"), 2137 optionals, webSocketID, 2138 "DOMSnapshot.getSnapshot", 2139 computedStyleWhitelist, includeEventListeners, includePaintOrder, 2140 includeUserAgentShadowTree 2141 ); 2142 2143 // 'JSON Binding' ... Converts Browser Response-JSON into Java-Type 'Ret3' 2144 Function<JsonObject, Ret3<DOMSnapshot.DOMNode[], DOMSnapshot.LayoutTreeNode[], DOMSnapshot.ComputedStyle[]>> 2145 responseProcessor = (JsonObject jo) -> new Ret3<>( 2146 (jo.getJsonArray("domNodes") == null) 2147 ? null 2148 : ReadArrJSON.DimN.objArr(jo.getJsonArray("domNodes"), null, 0, DOMSnapshot.DOMNode[].class), 2149 (jo.getJsonArray("layoutTreeNodes") == null) 2150 ? null 2151 : ReadArrJSON.DimN.objArr(jo.getJsonArray("layoutTreeNodes"), null, 0, DOMSnapshot.LayoutTreeNode[].class), 2152 (jo.getJsonArray("computedStyles") == null) 2153 ? null 2154 : ReadArrJSON.DimN.objArr(jo.getJsonArray("computedStyles"), null, 0, DOMSnapshot.ComputedStyle[].class) 2155 ); 2156 2157 // Pass the 'defaultSender' to Script-Constructor 2158 // The sender that is used can be changed before executing script. 2159 return new Script<>(BRDPC.defaultSender, webSocketID, requestJSON, responseProcessor); 2160 } 2161 2162 /** 2163 * Returns a document snapshot, including the full DOM tree of the root node (including iframes, 2164 * template contents, and imported documents) in a flattened array, as well as layout and 2165 * white-listed computed style information for the nodes. Shadow DOM in the returned DOM tree is 2166 * flattened. 2167 * 2168 * @param computedStyles Whitelist of computed styles to return. 2169 * 2170 * @param includePaintOrder Whether to include layout object paint orders into the snapshot. 2171 * <BR /><B>OPTIONAL</B> 2172 * 2173 * @param includeDOMRects Whether to include DOM rectangles (offsetRects, clientRects, scrollRects) into the snapshot 2174 * <BR /><B>OPTIONAL</B> 2175 * 2176 * @param includeBlendedBackgroundColors 2177 * Whether to include blended background colors in the snapshot (default: false). 2178 * Blended background color is achieved by blending background colors of all elements 2179 * that overlap with the current element. 2180 * <BR /><B>OPTIONAL</B> 2181 * <BR /><B>EXPERIMENTAL</B> 2182 * 2183 * @param includeTextColorOpacities 2184 * Whether to include text color opacity in the snapshot (default: false). 2185 * An element might have the opacity property set that affects the text color of the element. 2186 * The final text color opacity is computed based on the opacity of all overlapping elements. 2187 * <BR /><B>OPTIONAL</B> 2188 * <BR /><B>EXPERIMENTAL</B> 2189 * 2190 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 2191 * {@link Ret2}></CODE> 2192 * 2193 * <BR /><BR />This {@link Script} may be <B STYLE='color:red'>executed</B> (using 2194 * {@link Script#exec()}), and a {@link Promise} returned. 2195 * 2196 * <BR /><BR />When the {@code Promise} is <B STYLE='color: red'>awaited</B> 2197 * (using {@link Promise#await()}), the {@code Ret2} will subsequently 2198 * be returned from that call. 2199 * 2200 * <BR /><BR />The <B STYLE='color: red'>returned</B> values are encapsulated 2201 * in an instance of <B>{@link Ret2}</B> 2202 * 2203 * <BR /><BR /><UL CLASS=JDUL> 2204 * <LI><CODE><B>Ret2.a:</B> {@link DOMSnapshot.DocumentSnapshot}[] (<B>documents</B>)</CODE> 2205 * <BR />The nodes in the DOM tree. The DOMNode at index 0 corresponds to the root document. 2206 * <BR /><BR /></LI> 2207 * <LI><CODE><B>Ret2.b:</B> String[] (<B>strings</B>)</CODE> 2208 * <BR />Shared string table that all string properties refer to with indexes. 2209 * </LI> 2210 * </UL> 2211 */ 2212 public static Script<String, JsonObject, Ret2<DOMSnapshot.DocumentSnapshot[], String[]>> captureSnapshot( 2213 String[] computedStyles, Boolean includePaintOrder, Boolean includeDOMRects, 2214 Boolean includeBlendedBackgroundColors, Boolean includeTextColorOpacities 2215 ) 2216 { 2217 // Exception-Check(s) to ensure that if any parameters which are not declared as 2218 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 2219 2220 if (computedStyles == null) BRDPC.throwNPE("computedStyles"); 2221 2222 final int webSocketID = 17003000 + counter++; 2223 final boolean[] optionals = { false, true, true, true, true, }; 2224 2225 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 2226 String requestJSON = WriteJSON.get( 2227 parameterTypes.get("captureSnapshot"), 2228 parameterNames.get("captureSnapshot"), 2229 optionals, webSocketID, 2230 "DOMSnapshot.captureSnapshot", 2231 computedStyles, includePaintOrder, includeDOMRects, includeBlendedBackgroundColors, 2232 includeTextColorOpacities 2233 ); 2234 2235 // 'JSON Binding' ... Converts Browser Response-JSON into Java-Type 'Ret2' 2236 Function<JsonObject, Ret2<DOMSnapshot.DocumentSnapshot[], String[]>> 2237 responseProcessor = (JsonObject jo) -> new Ret2<>( 2238 (jo.getJsonArray("documents") == null) 2239 ? null 2240 : ReadArrJSON.DimN.objArr(jo.getJsonArray("documents"), null, 0, DOMSnapshot.DocumentSnapshot[].class), 2241 (jo.getJsonArray("strings") == null) 2242 ? null 2243 : ReadArrJSON.DimN.strArr(jo.getJsonArray("strings"), null, 0, String[].class) 2244 ); 2245 2246 // Pass the 'defaultSender' to Script-Constructor 2247 // The sender that is used can be changed before executing script. 2248 return new Script<>(BRDPC.defaultSender, webSocketID, requestJSON, responseProcessor); 2249 } 2250 2251}