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><CODE>[No Description Provided by Google]</CODE></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 Accessibility 030{ 031 // ******************************************************************************************** 032 // ******************************************************************************************** 033 // Class Header Stuff 034 // ******************************************************************************************** 035 // ******************************************************************************************** 036 037 038 // No Pubic Constructors 039 private Accessibility () { } 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 : Accessibility.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("getPartialAXTree", v); 083 Collections.addAll(v, new String[] 084 { "nodeId", "backendNodeId", "objectId", "fetchRelatives", }); 085 086 v = new Vector<String>(3); 087 parameterNames.put("getFullAXTree", v); 088 Collections.addAll(v, new String[] 089 { "depth", "max_depth", "frameId", }); 090 091 v = new Vector<String>(2); 092 parameterNames.put("getChildAXNodes", v); 093 Collections.addAll(v, new String[] 094 { "id", "frameId", }); 095 096 v = new Vector<String>(5); 097 parameterNames.put("queryAXTree", v); 098 Collections.addAll(v, new String[] 099 { "nodeId", "backendNodeId", "objectId", "accessibleName", "role", }); 100 } 101 102 103 // ******************************************************************************************** 104 // ******************************************************************************************** 105 // Types - Static Inner Classes 106 // ******************************************************************************************** 107 // ******************************************************************************************** 108 109 // public static class AXNodeId => String 110 111 /** Enum of possible property types. */ 112 public static final String[] AXValueType = 113 { 114 "boolean", "tristate", "booleanOrUndefined", "idref", "idrefList", "integer", "node", 115 "nodeList", "number", "string", "computedString", "token", "tokenList", "domRelation", 116 "role", "internalRole", "valueUndefined", 117 }; 118 119 /** Enum of possible property sources. */ 120 public static final String[] AXValueSourceType = 121 { "attribute", "implicit", "style", "contents", "placeholder", "relatedElement", }; 122 123 /** Enum of possible native property sources (as a subtype of a particular AXValueSourceType). */ 124 public static final String[] AXValueNativeSourceType = 125 { 126 "description", "figcaption", "label", "labelfor", "labelwrapped", "legend", 127 "rubyannotation", "tablecaption", "title", "other", 128 }; 129 130 /** 131 * Values of AXProperty name: 132 * - from 'busy' to 'roledescription': states which apply to every AX node 133 * - from 'live' to 'root': attributes which apply to nodes in live regions 134 * - from 'autocomplete' to 'valuetext': attributes which apply to widgets 135 * - from 'checked' to 'selected': states which apply to widgets 136 * - from 'activedescendant' to 'owns' - relationships between elements other than parent/child/sibling. 137 */ 138 public static final String[] AXPropertyName = 139 { 140 "busy", "disabled", "editable", "focusable", "focused", "hidden", "hiddenRoot", "invalid", 141 "keyshortcuts", "settable", "roledescription", "live", "atomic", "relevant", "root", 142 "autocomplete", "hasPopup", "level", "multiselectable", "orientation", "multiline", 143 "readonly", "required", "valuemin", "valuemax", "valuetext", "checked", "expanded", 144 "modal", "pressed", "selected", "activedescendant", "controls", "describedby", "details", 145 "errormessage", "flowto", "labelledby", "owns", 146 }; 147 148 /** A single source for a computed AX property. */ 149 public static class AXValueSource 150 extends BaseType 151 implements java.io.Serializable 152 { 153 /** For Object Serialization. java.io.Serializable */ 154 protected static final long serialVersionUID = 1; 155 156 public boolean[] optionals() 157 { return new boolean[] { false, true, true, true, true, true, true, true, true, }; } 158 159 /** What type of source this is. */ 160 public final String type; 161 162 /** 163 * The value of this property source. 164 * <BR /> 165 * <BR /><B>OPTIONAL</B> 166 */ 167 public final Accessibility.AXValue value; 168 169 /** 170 * The name of the relevant attribute, if any. 171 * <BR /> 172 * <BR /><B>OPTIONAL</B> 173 */ 174 public final String attribute; 175 176 /** 177 * The value of the relevant attribute, if any. 178 * <BR /> 179 * <BR /><B>OPTIONAL</B> 180 */ 181 public final Accessibility.AXValue attributeValue; 182 183 /** 184 * Whether this source is superseded by a higher priority source. 185 * <BR /> 186 * <BR /><B>OPTIONAL</B> 187 */ 188 public final Boolean superseded; 189 190 /** 191 * The native markup source for this value, e.g. a <label> element. 192 * <BR /> 193 * <BR /><B>OPTIONAL</B> 194 */ 195 public final String nativeSource; 196 197 /** 198 * The value, such as a node or node list, of the native source. 199 * <BR /> 200 * <BR /><B>OPTIONAL</B> 201 */ 202 public final Accessibility.AXValue nativeSourceValue; 203 204 /** 205 * Whether the value for this property is invalid. 206 * <BR /> 207 * <BR /><B>OPTIONAL</B> 208 */ 209 public final Boolean invalid; 210 211 /** 212 * Reason for the value being invalid, if it is. 213 * <BR /> 214 * <BR /><B>OPTIONAL</B> 215 */ 216 public final String invalidReason; 217 218 /** 219 * Constructor 220 * 221 * @param type What type of source this is. 222 * 223 * @param value The value of this property source. 224 * <BR /><B>OPTIONAL</B> 225 * 226 * @param attribute The name of the relevant attribute, if any. 227 * <BR /><B>OPTIONAL</B> 228 * 229 * @param attributeValue The value of the relevant attribute, if any. 230 * <BR /><B>OPTIONAL</B> 231 * 232 * @param superseded Whether this source is superseded by a higher priority source. 233 * <BR /><B>OPTIONAL</B> 234 * 235 * @param nativeSource The native markup source for this value, e.g. a <label> element. 236 * <BR /><B>OPTIONAL</B> 237 * 238 * @param nativeSourceValue The value, such as a node or node list, of the native source. 239 * <BR /><B>OPTIONAL</B> 240 * 241 * @param invalid Whether the value for this property is invalid. 242 * <BR /><B>OPTIONAL</B> 243 * 244 * @param invalidReason Reason for the value being invalid, if it is. 245 * <BR /><B>OPTIONAL</B> 246 */ 247 public AXValueSource( 248 String type, Accessibility.AXValue value, String attribute, 249 Accessibility.AXValue attributeValue, Boolean superseded, String nativeSource, 250 Accessibility.AXValue nativeSourceValue, Boolean invalid, String invalidReason 251 ) 252 { 253 // Exception-Check(s) to ensure that if any parameters which are not declared as 254 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 255 256 if (type == null) THROWS.throwNPE("type"); 257 258 // Exception-Check(s) to ensure that if any parameters which must adhere to a 259 // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw. 260 261 THROWS.checkIAE("type", type, "Accessibility.AXValueSourceType", Accessibility.AXValueSourceType); 262 THROWS.checkIAE("nativeSource", nativeSource, "Accessibility.AXValueNativeSourceType", Accessibility.AXValueNativeSourceType); 263 264 this.type = type; 265 this.value = value; 266 this.attribute = attribute; 267 this.attributeValue = attributeValue; 268 this.superseded = superseded; 269 this.nativeSource = nativeSource; 270 this.nativeSourceValue = nativeSourceValue; 271 this.invalid = invalid; 272 this.invalidReason = invalidReason; 273 } 274 275 /** 276 * JSON Object Constructor 277 * @param jo A Json-Object having data about an instance of {@code 'AXValueSource'}. 278 */ 279 public AXValueSource (JsonObject jo) 280 { 281 this.type = ReadJSON.getString(jo, "type", false, true); 282 this.value = ReadJSON.getObject(jo, "value", Accessibility.AXValue.class, true, false); 283 this.attribute = ReadJSON.getString(jo, "attribute", true, false); 284 this.attributeValue = ReadJSON.getObject(jo, "attributeValue", Accessibility.AXValue.class, true, false); 285 this.superseded = ReadBoxedJSON.getBoolean(jo, "superseded", true); 286 this.nativeSource = ReadJSON.getString(jo, "nativeSource", true, false); 287 this.nativeSourceValue = ReadJSON.getObject(jo, "nativeSourceValue", Accessibility.AXValue.class, true, false); 288 this.invalid = ReadBoxedJSON.getBoolean(jo, "invalid", true); 289 this.invalidReason = ReadJSON.getString(jo, "invalidReason", true, false); 290 } 291 292 293 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 294 public boolean equals(Object other) 295 { 296 if (this == other) return true; 297 if (other == null) return false; 298 if (other.getClass() != this.getClass()) return false; 299 300 AXValueSource o = (AXValueSource) other; 301 302 return 303 Objects.equals(this.type, o.type) 304 && Objects.equals(this.value, o.value) 305 && Objects.equals(this.attribute, o.attribute) 306 && Objects.equals(this.attributeValue, o.attributeValue) 307 && Objects.equals(this.superseded, o.superseded) 308 && Objects.equals(this.nativeSource, o.nativeSource) 309 && Objects.equals(this.nativeSourceValue, o.nativeSourceValue) 310 && Objects.equals(this.invalid, o.invalid) 311 && Objects.equals(this.invalidReason, o.invalidReason); 312 } 313 314 /** Generates a Hash-Code for {@code 'this'} instance */ 315 public int hashCode() 316 { 317 return 318 Objects.hashCode(this.type) 319 + this.value.hashCode() 320 + Objects.hashCode(this.attribute) 321 + this.attributeValue.hashCode() 322 + Objects.hashCode(this.superseded) 323 + Objects.hashCode(this.nativeSource) 324 + this.nativeSourceValue.hashCode() 325 + Objects.hashCode(this.invalid) 326 + Objects.hashCode(this.invalidReason); 327 } 328 } 329 330 /** <CODE>[No Description Provided by Google]</CODE> */ 331 public static class AXRelatedNode 332 extends BaseType 333 implements java.io.Serializable 334 { 335 /** For Object Serialization. java.io.Serializable */ 336 protected static final long serialVersionUID = 1; 337 338 public boolean[] optionals() 339 { return new boolean[] { false, true, true, }; } 340 341 /** The BackendNodeId of the related DOM node. */ 342 public final int backendDOMNodeId; 343 344 /** 345 * The IDRef value provided, if any. 346 * <BR /> 347 * <BR /><B>OPTIONAL</B> 348 */ 349 public final String idref; 350 351 /** 352 * The text alternative of this node in the current context. 353 * <BR /> 354 * <BR /><B>OPTIONAL</B> 355 */ 356 public final String text; 357 358 /** 359 * Constructor 360 * 361 * @param backendDOMNodeId The BackendNodeId of the related DOM node. 362 * 363 * @param idref The IDRef value provided, if any. 364 * <BR /><B>OPTIONAL</B> 365 * 366 * @param text The text alternative of this node in the current context. 367 * <BR /><B>OPTIONAL</B> 368 */ 369 public AXRelatedNode(int backendDOMNodeId, String idref, String text) 370 { 371 this.backendDOMNodeId = backendDOMNodeId; 372 this.idref = idref; 373 this.text = text; 374 } 375 376 /** 377 * JSON Object Constructor 378 * @param jo A Json-Object having data about an instance of {@code 'AXRelatedNode'}. 379 */ 380 public AXRelatedNode (JsonObject jo) 381 { 382 this.backendDOMNodeId = ReadPrimJSON.getInt(jo, "backendDOMNodeId"); 383 this.idref = ReadJSON.getString(jo, "idref", true, false); 384 this.text = ReadJSON.getString(jo, "text", true, false); 385 } 386 387 388 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 389 public boolean equals(Object other) 390 { 391 if (this == other) return true; 392 if (other == null) return false; 393 if (other.getClass() != this.getClass()) return false; 394 395 AXRelatedNode o = (AXRelatedNode) other; 396 397 return 398 Objects.equals(this.backendDOMNodeId, o.backendDOMNodeId) 399 && Objects.equals(this.idref, o.idref) 400 && Objects.equals(this.text, o.text); 401 } 402 403 /** Generates a Hash-Code for {@code 'this'} instance */ 404 public int hashCode() 405 { 406 return 407 this.backendDOMNodeId 408 + Objects.hashCode(this.idref) 409 + Objects.hashCode(this.text); 410 } 411 } 412 413 /** <CODE>[No Description Provided by Google]</CODE> */ 414 public static class AXProperty 415 extends BaseType 416 implements java.io.Serializable 417 { 418 /** For Object Serialization. java.io.Serializable */ 419 protected static final long serialVersionUID = 1; 420 421 public boolean[] optionals() 422 { return new boolean[] { false, false, }; } 423 424 /** The name of this property. */ 425 public final String name; 426 427 /** The value of this property. */ 428 public final Accessibility.AXValue value; 429 430 /** 431 * Constructor 432 * 433 * @param name The name of this property. 434 * 435 * @param value The value of this property. 436 */ 437 public AXProperty(String name, Accessibility.AXValue value) 438 { 439 // Exception-Check(s) to ensure that if any parameters which are not declared as 440 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 441 442 if (name == null) THROWS.throwNPE("name"); 443 if (value == null) THROWS.throwNPE("value"); 444 445 // Exception-Check(s) to ensure that if any parameters which must adhere to a 446 // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw. 447 448 THROWS.checkIAE("name", name, "Accessibility.AXPropertyName", Accessibility.AXPropertyName); 449 450 this.name = name; 451 this.value = value; 452 } 453 454 /** 455 * JSON Object Constructor 456 * @param jo A Json-Object having data about an instance of {@code 'AXProperty'}. 457 */ 458 public AXProperty (JsonObject jo) 459 { 460 this.name = ReadJSON.getString(jo, "name", false, true); 461 this.value = ReadJSON.getObject(jo, "value", Accessibility.AXValue.class, false, true); 462 } 463 464 465 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 466 public boolean equals(Object other) 467 { 468 if (this == other) return true; 469 if (other == null) return false; 470 if (other.getClass() != this.getClass()) return false; 471 472 AXProperty o = (AXProperty) other; 473 474 return 475 Objects.equals(this.name, o.name) 476 && Objects.equals(this.value, o.value); 477 } 478 479 /** Generates a Hash-Code for {@code 'this'} instance */ 480 public int hashCode() 481 { 482 return 483 Objects.hashCode(this.name) 484 + this.value.hashCode(); 485 } 486 } 487 488 /** A single computed AX property. */ 489 public static class AXValue 490 extends BaseType 491 implements java.io.Serializable 492 { 493 /** For Object Serialization. java.io.Serializable */ 494 protected static final long serialVersionUID = 1; 495 496 public boolean[] optionals() 497 { return new boolean[] { false, true, true, true, }; } 498 499 /** The type of this value. */ 500 public final String type; 501 502 /** 503 * The computed value of this property. 504 * <BR /> 505 * <BR /><B>OPTIONAL</B> 506 */ 507 public final JsonValue value; 508 509 /** 510 * One or more related nodes, if applicable. 511 * <BR /> 512 * <BR /><B>OPTIONAL</B> 513 */ 514 public final Accessibility.AXRelatedNode[] relatedNodes; 515 516 /** 517 * The sources which contributed to the computation of this property. 518 * <BR /> 519 * <BR /><B>OPTIONAL</B> 520 */ 521 public final Accessibility.AXValueSource[] sources; 522 523 /** 524 * Constructor 525 * 526 * @param type The type of this value. 527 * 528 * @param value The computed value of this property. 529 * <BR /><B>OPTIONAL</B> 530 * 531 * @param relatedNodes One or more related nodes, if applicable. 532 * <BR /><B>OPTIONAL</B> 533 * 534 * @param sources The sources which contributed to the computation of this property. 535 * <BR /><B>OPTIONAL</B> 536 */ 537 public AXValue( 538 String type, JsonValue value, Accessibility.AXRelatedNode[] relatedNodes, 539 Accessibility.AXValueSource[] sources 540 ) 541 { 542 // Exception-Check(s) to ensure that if any parameters which are not declared as 543 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 544 545 if (type == null) THROWS.throwNPE("type"); 546 547 // Exception-Check(s) to ensure that if any parameters which must adhere to a 548 // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw. 549 550 THROWS.checkIAE("type", type, "Accessibility.AXValueType", Accessibility.AXValueType); 551 552 this.type = type; 553 this.value = value; 554 this.relatedNodes = relatedNodes; 555 this.sources = sources; 556 } 557 558 /** 559 * JSON Object Constructor 560 * @param jo A Json-Object having data about an instance of {@code 'AXValue'}. 561 */ 562 public AXValue (JsonObject jo) 563 { 564 this.type = ReadJSON.getString(jo, "type", false, true); 565 this.value = jo.get("value"); 566 this.relatedNodes = (jo.getJsonArray("relatedNodes") == null) 567 ? null 568 : RJArrIntoStream.objArr(jo.getJsonArray("relatedNodes"), null, 0, Accessibility.AXRelatedNode.class).toArray(Accessibility.AXRelatedNode[]::new); 569 570 this.sources = (jo.getJsonArray("sources") == null) 571 ? null 572 : RJArrIntoStream.objArr(jo.getJsonArray("sources"), null, 0, Accessibility.AXValueSource.class).toArray(Accessibility.AXValueSource[]::new); 573 574 } 575 576 577 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 578 public boolean equals(Object other) 579 { 580 if (this == other) return true; 581 if (other == null) return false; 582 if (other.getClass() != this.getClass()) return false; 583 584 AXValue o = (AXValue) other; 585 586 return 587 Objects.equals(this.type, o.type) 588 && Objects.equals(this.value, o.value) 589 && Arrays.deepEquals(this.relatedNodes, o.relatedNodes) 590 && Arrays.deepEquals(this.sources, o.sources); 591 } 592 593 /** Generates a Hash-Code for {@code 'this'} instance */ 594 public int hashCode() 595 { 596 return 597 Objects.hashCode(this.type) 598 + Objects.hashCode(this.value) 599 + Arrays.deepHashCode(this.relatedNodes) 600 + Arrays.deepHashCode(this.sources); 601 } 602 } 603 604 /** A node in the accessibility tree. */ 605 public static class AXNode 606 extends BaseType 607 implements java.io.Serializable 608 { 609 /** For Object Serialization. java.io.Serializable */ 610 protected static final long serialVersionUID = 1; 611 612 public boolean[] optionals() 613 { return new boolean[] { false, false, true, true, true, true, true, true, true, true, }; } 614 615 /** Unique identifier for this node. */ 616 public final String nodeId; 617 618 /** Whether this node is ignored for accessibility */ 619 public final boolean ignored; 620 621 /** 622 * Collection of reasons why this node is hidden. 623 * <BR /> 624 * <BR /><B>OPTIONAL</B> 625 */ 626 public final Accessibility.AXProperty[] ignoredReasons; 627 628 /** 629 * This <CODE>Node</CODE>'s role, whether explicit or implicit. 630 * <BR /> 631 * <BR /><B>OPTIONAL</B> 632 */ 633 public final Accessibility.AXValue role; 634 635 /** 636 * The accessible name for this <CODE>Node</CODE>. 637 * <BR /> 638 * <BR /><B>OPTIONAL</B> 639 */ 640 public final Accessibility.AXValue name; 641 642 /** 643 * The accessible description for this <CODE>Node</CODE>. 644 * <BR /> 645 * <BR /><B>OPTIONAL</B> 646 */ 647 public final Accessibility.AXValue description; 648 649 /** 650 * The value for this <CODE>Node</CODE>. 651 * <BR /> 652 * <BR /><B>OPTIONAL</B> 653 */ 654 public final Accessibility.AXValue value; 655 656 /** 657 * All other properties 658 * <BR /> 659 * <BR /><B>OPTIONAL</B> 660 */ 661 public final Accessibility.AXProperty[] properties; 662 663 /** 664 * IDs for each of this node's child nodes. 665 * <BR /> 666 * <BR /><B>OPTIONAL</B> 667 */ 668 public final String[] childIds; 669 670 /** 671 * The backend ID for the associated DOM node, if any. 672 * <BR /> 673 * <BR /><B>OPTIONAL</B> 674 */ 675 public final Integer backendDOMNodeId; 676 677 /** 678 * Constructor 679 * 680 * @param nodeId Unique identifier for this node. 681 * 682 * @param ignored Whether this node is ignored for accessibility 683 * 684 * @param ignoredReasons Collection of reasons why this node is hidden. 685 * <BR /><B>OPTIONAL</B> 686 * 687 * @param role This <CODE>Node</CODE>'s role, whether explicit or implicit. 688 * <BR /><B>OPTIONAL</B> 689 * 690 * @param name The accessible name for this <CODE>Node</CODE>. 691 * <BR /><B>OPTIONAL</B> 692 * 693 * @param description The accessible description for this <CODE>Node</CODE>. 694 * <BR /><B>OPTIONAL</B> 695 * 696 * @param value The value for this <CODE>Node</CODE>. 697 * <BR /><B>OPTIONAL</B> 698 * 699 * @param properties All other properties 700 * <BR /><B>OPTIONAL</B> 701 * 702 * @param childIds IDs for each of this node's child nodes. 703 * <BR /><B>OPTIONAL</B> 704 * 705 * @param backendDOMNodeId The backend ID for the associated DOM node, if any. 706 * <BR /><B>OPTIONAL</B> 707 */ 708 public AXNode( 709 String nodeId, boolean ignored, Accessibility.AXProperty[] ignoredReasons, 710 Accessibility.AXValue role, Accessibility.AXValue name, 711 Accessibility.AXValue description, Accessibility.AXValue value, 712 Accessibility.AXProperty[] properties, String[] childIds, Integer backendDOMNodeId 713 ) 714 { 715 // Exception-Check(s) to ensure that if any parameters which are not declared as 716 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 717 718 if (nodeId == null) THROWS.throwNPE("nodeId"); 719 720 this.nodeId = nodeId; 721 this.ignored = ignored; 722 this.ignoredReasons = ignoredReasons; 723 this.role = role; 724 this.name = name; 725 this.description = description; 726 this.value = value; 727 this.properties = properties; 728 this.childIds = childIds; 729 this.backendDOMNodeId = backendDOMNodeId; 730 } 731 732 /** 733 * JSON Object Constructor 734 * @param jo A Json-Object having data about an instance of {@code 'AXNode'}. 735 */ 736 public AXNode (JsonObject jo) 737 { 738 this.nodeId = ReadJSON.getString(jo, "nodeId", false, true); 739 this.ignored = ReadPrimJSON.getBoolean(jo, "ignored"); 740 this.ignoredReasons = (jo.getJsonArray("ignoredReasons") == null) 741 ? null 742 : RJArrIntoStream.objArr(jo.getJsonArray("ignoredReasons"), null, 0, Accessibility.AXProperty.class).toArray(Accessibility.AXProperty[]::new); 743 744 this.role = ReadJSON.getObject(jo, "role", Accessibility.AXValue.class, true, false); 745 this.name = ReadJSON.getObject(jo, "name", Accessibility.AXValue.class, true, false); 746 this.description = ReadJSON.getObject(jo, "description", Accessibility.AXValue.class, true, false); 747 this.value = ReadJSON.getObject(jo, "value", Accessibility.AXValue.class, true, false); 748 this.properties = (jo.getJsonArray("properties") == null) 749 ? null 750 : RJArrIntoStream.objArr(jo.getJsonArray("properties"), null, 0, Accessibility.AXProperty.class).toArray(Accessibility.AXProperty[]::new); 751 752 this.childIds = (jo.getJsonArray("childIds") == null) 753 ? null 754 : RJArrIntoStream.strArr(jo.getJsonArray("childIds"), null, 0).toArray(String[]::new); 755 756 this.backendDOMNodeId = ReadBoxedJSON.getInteger(jo, "backendDOMNodeId", true); 757 } 758 759 760 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 761 public boolean equals(Object other) 762 { 763 if (this == other) return true; 764 if (other == null) return false; 765 if (other.getClass() != this.getClass()) return false; 766 767 AXNode o = (AXNode) other; 768 769 return 770 Objects.equals(this.nodeId, o.nodeId) 771 && (this.ignored == o.ignored) 772 && Arrays.deepEquals(this.ignoredReasons, o.ignoredReasons) 773 && Objects.equals(this.role, o.role) 774 && Objects.equals(this.name, o.name) 775 && Objects.equals(this.description, o.description) 776 && Objects.equals(this.value, o.value) 777 && Arrays.deepEquals(this.properties, o.properties) 778 && Arrays.deepEquals(this.childIds, o.childIds) 779 && Objects.equals(this.backendDOMNodeId, o.backendDOMNodeId); 780 } 781 782 /** Generates a Hash-Code for {@code 'this'} instance */ 783 public int hashCode() 784 { 785 return 786 Objects.hashCode(this.nodeId) 787 + (this.ignored ? 1 : 0) 788 + Arrays.deepHashCode(this.ignoredReasons) 789 + this.role.hashCode() 790 + this.name.hashCode() 791 + this.description.hashCode() 792 + this.value.hashCode() 793 + Arrays.deepHashCode(this.properties) 794 + Arrays.deepHashCode(this.childIds) 795 + Objects.hashCode(this.backendDOMNodeId); 796 } 797 } 798 799 800 // Counter for keeping the WebSocket Request ID's distinct. 801 private static int counter = 1; 802 803 /** 804 * Disables the accessibility domain. 805 * 806 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 807 * {@link Ret0}></CODE> 808 * 809 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 810 * browser receives the invocation-request. 811 * 812 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 813 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 814 * {@code >} to ensure the Browser Function has run to completion. 815 */ 816 public static Script<String, JsonObject, Ret0> disable() 817 { 818 final int webSocketID = 7000000 + counter++; 819 final boolean[] optionals = new boolean[0]; 820 821 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 822 String requestJSON = WriteJSON.get( 823 parameterTypes.get("disable"), 824 parameterNames.get("disable"), 825 optionals, webSocketID, 826 "Accessibility.disable" 827 ); 828 829 // This Remote Command does not have a Return-Value. 830 return new Script<> 831 (webSocketID, requestJSON, VOID_RETURN.NoReturnValues); 832 } 833 834 /** 835 * Enables the accessibility domain which causes <CODE>AXNodeId</CODE>s to remain consistent between method calls. 836 * This turns on accessibility for the page, which can impact performance until accessibility is disabled. 837 * 838 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 839 * {@link Ret0}></CODE> 840 * 841 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 842 * browser receives the invocation-request. 843 * 844 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 845 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 846 * {@code >} to ensure the Browser Function has run to completion. 847 */ 848 public static Script<String, JsonObject, Ret0> enable() 849 { 850 final int webSocketID = 7001000 + counter++; 851 final boolean[] optionals = new boolean[0]; 852 853 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 854 String requestJSON = WriteJSON.get( 855 parameterTypes.get("enable"), 856 parameterNames.get("enable"), 857 optionals, webSocketID, 858 "Accessibility.enable" 859 ); 860 861 // This Remote Command does not have a Return-Value. 862 return new Script<> 863 (webSocketID, requestJSON, VOID_RETURN.NoReturnValues); 864 } 865 866 /** 867 * Fetches the accessibility node and partial accessibility tree for this DOM node, if it exists. 868 * <BR /><B>EXPERIMENTAL</B> 869 * 870 * @param nodeId Identifier of the node to get the partial accessibility tree for. 871 * <BR /><B>OPTIONAL</B> 872 * 873 * @param backendNodeId Identifier of the backend node to get the partial accessibility tree for. 874 * <BR /><B>OPTIONAL</B> 875 * 876 * @param objectId JavaScript object id of the node wrapper to get the partial accessibility tree for. 877 * <BR /><B>OPTIONAL</B> 878 * 879 * @param fetchRelatives Whether to fetch this nodes ancestors, siblings and children. Defaults to true. 880 * <BR /><B>OPTIONAL</B> 881 * 882 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 883 * {@link Accessibility.AXNode}[]></CODE> 884 * 885 * <BR /><BR />This <B>script</B> may be <B STYLE='color: red'>executed</B>, using 886 * {@link Script#exec()}, and afterwards, a {@link Promise}<CODE><JsonObject, 887 * {@link Accessibility.AXNode}[]></CODE> will be returned. 888 * 889 * <BR /><BR />Finally, the <B>{@code Promise}</B> may be <B STYLE='color: red'>awaited</B>, 890 * using {@link Promise#await()}, <I>and the returned result of this Browser Function may 891 * may be retrieved.</I> 892 * 893 * <BR /><BR />This Browser Function <B STYLE='color: red'>returns</B> 894 * <BR /><BR /><UL CLASS=JDUL> 895 * <LI><CODE>{@link Accessibility.AXNode}[] (<B>nodes</B></CODE>) 896 * <BR />The <CODE>Accessibility.AXNode</CODE> for this DOM node, if it exists, plus its ancestors, siblings and 897 * children, if requested. 898 * </LI> 899 * </UL> */ 900 public static Script<String, JsonObject, Accessibility.AXNode[]> getPartialAXTree 901 (Integer nodeId, Integer backendNodeId, String objectId, Boolean fetchRelatives) 902 { 903 final int webSocketID = 7002000 + counter++; 904 final boolean[] optionals = { true, true, true, true, }; 905 906 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 907 String requestJSON = WriteJSON.get( 908 parameterTypes.get("getPartialAXTree"), 909 parameterNames.get("getPartialAXTree"), 910 optionals, webSocketID, 911 "Accessibility.getPartialAXTree", 912 nodeId, backendNodeId, objectId, fetchRelatives 913 ); 914 915 // 'JSON Binding' ... Converts Browser Response-JSON to 'Accessibility.AXNode[]' 916 Function<JsonObject, Accessibility.AXNode[]> responseProcessor = (JsonObject jo) -> 917 (jo.getJsonArray("nodes") == null) 918 ? null 919 : RJArrIntoStream.objArr(jo.getJsonArray("nodes"), null, 0, Accessibility.AXNode.class).toArray(Accessibility.AXNode[]::new); 920 921 return new Script<>(webSocketID, requestJSON, responseProcessor); 922 } 923 924 /** 925 * Fetches the entire accessibility tree for the root Document 926 * <BR /><B>EXPERIMENTAL</B> 927 * 928 * @param depth 929 * The maximum depth at which descendants of the root node should be retrieved. 930 * If omitted, the full tree is returned. 931 * <BR /><B>OPTIONAL</B> 932 * 933 * @param max_depth Deprecated. This parameter has been renamed to <CODE>depth</CODE>. If depth is not provided, max_depth will be used. 934 * <BR /><B>OPTIONAL</B> 935 * <BR /><B>DEPRECATED</B> 936 * 937 * @param frameId 938 * The frame for whose document the AX tree should be retrieved. 939 * If omited, the root frame is used. 940 * <BR /><B>OPTIONAL</B> 941 * 942 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 943 * {@link Accessibility.AXNode}[]></CODE> 944 * 945 * <BR /><BR />This <B>script</B> may be <B STYLE='color: red'>executed</B>, using 946 * {@link Script#exec()}, and afterwards, a {@link Promise}<CODE><JsonObject, 947 * {@link Accessibility.AXNode}[]></CODE> will be returned. 948 * 949 * <BR /><BR />Finally, the <B>{@code Promise}</B> may be <B STYLE='color: red'>awaited</B>, 950 * using {@link Promise#await()}, <I>and the returned result of this Browser Function may 951 * may be retrieved.</I> 952 * 953 * <BR /><BR />This Browser Function <B STYLE='color: red'>returns</B> 954 * <BR /><BR /><UL CLASS=JDUL> 955 * <LI><CODE>{@link Accessibility.AXNode}[] (<B>nodes</B></CODE>) 956 * <BR />- 957 * </LI> 958 * </UL> */ 959 public static Script<String, JsonObject, Accessibility.AXNode[]> getFullAXTree 960 (Integer depth, Integer max_depth, String frameId) 961 { 962 final int webSocketID = 7003000 + counter++; 963 final boolean[] optionals = { true, true, true, }; 964 965 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 966 String requestJSON = WriteJSON.get( 967 parameterTypes.get("getFullAXTree"), 968 parameterNames.get("getFullAXTree"), 969 optionals, webSocketID, 970 "Accessibility.getFullAXTree", 971 depth, max_depth, frameId 972 ); 973 974 // 'JSON Binding' ... Converts Browser Response-JSON to 'Accessibility.AXNode[]' 975 Function<JsonObject, Accessibility.AXNode[]> responseProcessor = (JsonObject jo) -> 976 (jo.getJsonArray("nodes") == null) 977 ? null 978 : RJArrIntoStream.objArr(jo.getJsonArray("nodes"), null, 0, Accessibility.AXNode.class).toArray(Accessibility.AXNode[]::new); 979 980 return new Script<>(webSocketID, requestJSON, responseProcessor); 981 } 982 983 /** 984 * Fetches a particular accessibility node by AXNodeId. 985 * Requires <CODE>enable()</CODE> to have been called previously. 986 * <BR /><B>EXPERIMENTAL</B> 987 * 988 * @param id - 989 * 990 * @param frameId 991 * The frame in whose document the node resides. 992 * If omitted, the root frame is used. 993 * <BR /><B>OPTIONAL</B> 994 * 995 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 996 * {@link Accessibility.AXNode}[]></CODE> 997 * 998 * <BR /><BR />This <B>script</B> may be <B STYLE='color: red'>executed</B>, using 999 * {@link Script#exec()}, and afterwards, a {@link Promise}<CODE><JsonObject, 1000 * {@link Accessibility.AXNode}[]></CODE> will be returned. 1001 * 1002 * <BR /><BR />Finally, the <B>{@code Promise}</B> may be <B STYLE='color: red'>awaited</B>, 1003 * using {@link Promise#await()}, <I>and the returned result of this Browser Function may 1004 * may be retrieved.</I> 1005 * 1006 * <BR /><BR />This Browser Function <B STYLE='color: red'>returns</B> 1007 * <BR /><BR /><UL CLASS=JDUL> 1008 * <LI><CODE>{@link Accessibility.AXNode}[] (<B>nodes</B></CODE>) 1009 * <BR />- 1010 * </LI> 1011 * </UL> */ 1012 public static Script<String, JsonObject, Accessibility.AXNode[]> getChildAXNodes 1013 (String id, String frameId) 1014 { 1015 // Exception-Check(s) to ensure that if any parameters which are not declared as 1016 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 1017 1018 if (id == null) THROWS.throwNPE("id"); 1019 1020 final int webSocketID = 7004000 + counter++; 1021 final boolean[] optionals = { false, true, }; 1022 1023 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 1024 String requestJSON = WriteJSON.get( 1025 parameterTypes.get("getChildAXNodes"), 1026 parameterNames.get("getChildAXNodes"), 1027 optionals, webSocketID, 1028 "Accessibility.getChildAXNodes", 1029 id, frameId 1030 ); 1031 1032 // 'JSON Binding' ... Converts Browser Response-JSON to 'Accessibility.AXNode[]' 1033 Function<JsonObject, Accessibility.AXNode[]> responseProcessor = (JsonObject jo) -> 1034 (jo.getJsonArray("nodes") == null) 1035 ? null 1036 : RJArrIntoStream.objArr(jo.getJsonArray("nodes"), null, 0, Accessibility.AXNode.class).toArray(Accessibility.AXNode[]::new); 1037 1038 return new Script<>(webSocketID, requestJSON, responseProcessor); 1039 } 1040 1041 /** 1042 * Query a DOM node's accessibility subtree for accessible name and role. 1043 * This command computes the name and role for all nodes in the subtree, including those that are 1044 * ignored for accessibility, and returns those that mactch the specified name and role. If no DOM 1045 * node is specified, or the DOM node does not exist, the command returns an error. If neither 1046 * <CODE>accessibleName</CODE> or <CODE>role</CODE> is specified, it returns all the accessibility nodes in the subtree. 1047 * <BR /><B>EXPERIMENTAL</B> 1048 * 1049 * @param nodeId Identifier of the node for the root to query. 1050 * <BR /><B>OPTIONAL</B> 1051 * 1052 * @param backendNodeId Identifier of the backend node for the root to query. 1053 * <BR /><B>OPTIONAL</B> 1054 * 1055 * @param objectId JavaScript object id of the node wrapper for the root to query. 1056 * <BR /><B>OPTIONAL</B> 1057 * 1058 * @param accessibleName Find nodes with this computed name. 1059 * <BR /><B>OPTIONAL</B> 1060 * 1061 * @param role Find nodes with this computed role. 1062 * <BR /><B>OPTIONAL</B> 1063 * 1064 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 1065 * {@link Accessibility.AXNode}[]></CODE> 1066 * 1067 * <BR /><BR />This <B>script</B> may be <B STYLE='color: red'>executed</B>, using 1068 * {@link Script#exec()}, and afterwards, a {@link Promise}<CODE><JsonObject, 1069 * {@link Accessibility.AXNode}[]></CODE> will be returned. 1070 * 1071 * <BR /><BR />Finally, the <B>{@code Promise}</B> may be <B STYLE='color: red'>awaited</B>, 1072 * using {@link Promise#await()}, <I>and the returned result of this Browser Function may 1073 * may be retrieved.</I> 1074 * 1075 * <BR /><BR />This Browser Function <B STYLE='color: red'>returns</B> 1076 * <BR /><BR /><UL CLASS=JDUL> 1077 * <LI><CODE>{@link Accessibility.AXNode}[] (<B>nodes</B></CODE>) 1078 * <BR />A list of <CODE>Accessibility.AXNode</CODE> matching the specified attributes, 1079 * including nodes that are ignored for accessibility. 1080 * </LI> 1081 * </UL> */ 1082 public static Script<String, JsonObject, Accessibility.AXNode[]> queryAXTree 1083 (Integer nodeId, Integer backendNodeId, String objectId, String accessibleName, String role) 1084 { 1085 final int webSocketID = 7005000 + counter++; 1086 final boolean[] optionals = { true, true, true, true, true, }; 1087 1088 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 1089 String requestJSON = WriteJSON.get( 1090 parameterTypes.get("queryAXTree"), 1091 parameterNames.get("queryAXTree"), 1092 optionals, webSocketID, 1093 "Accessibility.queryAXTree", 1094 nodeId, backendNodeId, objectId, accessibleName, role 1095 ); 1096 1097 // 'JSON Binding' ... Converts Browser Response-JSON to 'Accessibility.AXNode[]' 1098 Function<JsonObject, Accessibility.AXNode[]> responseProcessor = (JsonObject jo) -> 1099 (jo.getJsonArray("nodes") == null) 1100 ? null 1101 : RJArrIntoStream.objArr(jo.getJsonArray("nodes"), null, 0, Accessibility.AXNode.class).toArray(Accessibility.AXNode[]::new); 1102 1103 return new Script<>(webSocketID, requestJSON, responseProcessor); 1104 } 1105 1106}