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 &lt;label&gt; 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 &lt;label&gt; 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}&lt;String, {@link JsonObject},
807     * {@link Ret0}&gt;</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}&lt;String, {@link JsonObject},
839     * {@link Ret0}&gt;</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}&lt;String, {@link JsonObject},
883     * {@link Accessibility.AXNode}[]&gt;</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>&lt;JsonObject,
887     * {@link Accessibility.AXNode}[]&gt;</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}&lt;String, {@link JsonObject},
943     * {@link Accessibility.AXNode}[]&gt;</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>&lt;JsonObject,
947     * {@link Accessibility.AXNode}[]&gt;</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}&lt;String, {@link JsonObject},
996     * {@link Accessibility.AXNode}[]&gt;</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>&lt;JsonObject,
1000     * {@link Accessibility.AXNode}[]&gt;</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}&lt;String, {@link JsonObject},
1065     * {@link Accessibility.AXNode}[]&gt;</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>&lt;JsonObject,
1069     * {@link Accessibility.AXNode}[]&gt;</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}