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