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