1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
package Torello.Browser;

import static Torello.Java.C.BYELLOW;
import static Torello.Java.C.RESET;

import Torello.Java.JSON.ReadJSON;
import Torello.JavaDoc.LinkJavaSource;
import Torello.Browser.BrowserEvent;
import Torello.Browser.WebSocketSender;
import NeoVisionaries.WebSockets.WebSocketException;

import java.util.stream.Stream;
import java.io.IOException;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.Objects;
import javax.json.JsonObject;


// @AutoFindFieldDocs(location="BRDPC/PageConn/fields/")
/**
 * A Connection to a specific page within a browser.
 * <EMBED CLASS='external-html' DATA-FILE-ID=PAGE_CONN>
 */
@Torello.JavaDoc.CSSLinks(FileNames="BrowserAndPageConn.css")
public class PageConn
{
    // ********************************************************************************************
    // ********************************************************************************************
    // Public Fields
    // ********************************************************************************************
    // ********************************************************************************************


    /** <EMBED CLASS='external-html' DATA-FILE-ID=PC_ID> */
    public final String id;

    /** <EMBED CLASS='external-html' DATA-FILE-ID=PC_TYPE> */
    public final String type;

    /** <EMBED CLASS='external-html' DATA-FILE-ID=PC_TITLE> */
    public final String title;

    /** <EMBED CLASS='external-html' DATA-FILE-ID=PC_URL> */
    public final String url;

    /** <EMBED CLASS='external-html' DATA-FILE-ID=PC_DESCRIPTION> */
    public final String description;

    /** <EMBED CLASS='external-html' DATA-FILE-ID=PC_WS_DEBUG_URL> */
    public final String webSocketDebuggerUrl;

    /** <EMBED CLASS='external-html' DATA-FILE-ID=PC_DEVTOOLS_URL> */
    public final String devtoolsFrontendUrl;

    /** <EMBED CLASS='external-html' DATA-FILE-ID=PC_FAVICON_URL> */
    public final String faviconUrl;


    // ********************************************************************************************
    // ********************************************************************************************
    // Package Private Constructors
    // ********************************************************************************************
    // ********************************************************************************************


    public PageConn(
            final String id,
            final String type,
            final String title,
            final String url,
            final String description,
            final String webSocketDebuggerUrl,
            final String devtoolsFrontendUrl,
            final String faviconUrl
        )
    {
        Objects.requireNonNull(webSocketDebuggerUrl, "webSocketDebuggerUrl is null");

        this.id                     = id;
        this.type                   = type;
        this.title                  = title;
        this.url                    = url;
        this.description            = description;
        this.webSocketDebuggerUrl   = webSocketDebuggerUrl;
        this.devtoolsFrontendUrl    = devtoolsFrontendUrl;
        this.faviconUrl             = faviconUrl;
    }

    public PageConn(JsonObject jo)
    {
        // Boolean #1: 'isOptional'
        //      FALSE   ==> throws if Missing
        //      TRUE    ==> Assigns Null if Missing
        // 
        // Boolean #2: 'throwOnNull'
        //      FALSE   ==> returns null if Json-Null has been passed
        //      TRUE    ==> throws if Json-Null has been passed

        this.id     = ReadJSON.getString(jo, "id",      false, true);
        this.type   = ReadJSON.getString(jo, "type",    false, true);
        this.title  = ReadJSON.getString(jo, "title",   true, false);
        this.url    = ReadJSON.getString(jo, "url",     false, true);
    
        this.description =
            ReadJSON.getString(jo, "description", true, false);
    
        this.webSocketDebuggerUrl =
            ReadJSON.getString(jo, "webSocketDebuggerUrl", false, true);
    
        this.devtoolsFrontendUrl =
            ReadJSON.getString(jo, "devtoolsFrontendUrl", true, false);
    
        this.faviconUrl =
            ReadJSON.getString(jo, "faviconUrl", true, false);
    }


    // ********************************************************************************************
    // ********************************************************************************************
    // Builder Methods
    // ********************************************************************************************
    // ********************************************************************************************


    /**
     * Creates a {@link WebSocketSender} connected to the {@link #webSocketDebuggerUrl} for this
     * tab.  This URL is the endpoint that speaks the Chrome DevTools Protocol (CDP).
     * 
     * @param eventHandler          <EMBED CLASS='external-html' DATA-FILE-ID=PCBC_EVENT_H>
     * @param rdpErrorHandler       <EMBED CLASS='external-html' DATA-FILE-ID=PCBC_RDP_ERR_H>
     * @param browserErrorHandler   <EMBED CLASS='external-html' DATA-FILE-ID=PCBC_BROWSER_ERR_H>
     */
    public WebSocketSender createSender(
            final Consumer<BrowserEvent>    eventHandler,
            final Consumer<RDPError>        rdpErrorHandler,
            final Consumer<BrowserError>    browserErrorHandler
        )
        throws IOException, WebSocketException
    {
        return new WebSocketSender
            (this.webSocketDebuggerUrl, eventHandler, rdpErrorHandler, browserErrorHandler);
    }

    /**
     * Retrieves all pages from the CDP-RDP endpoint currently open on the named port.
     * This queries {@code /json/list} and returns a Java-{@code Stream} of the instnces of this 
     * class.
     *
     * @param port  The DevTools port Chrome is listening on (default is 9222 if {@code null}).
     * @param quiet If {@code TRUE}, output is shunted.
     * @return A list of all Open-Pages, as instances of {@code PageConn}
     */
    @LinkJavaSource(handle="PCBuilder")
    public static Stream<PageConn> getAllPageConn(Integer port, final boolean quiet)
    { return PCBuilder.getAllPageConn(port, quiet); }


    // ********************************************************************************************
    // ********************************************************************************************
    // java.lang.Object Methods
    // ********************************************************************************************
    // ********************************************************************************************


    @LinkJavaSource(handle="PCHelper", name="toString")
    public String toString() { return PCHelper.toString(this); }

    @LinkJavaSource(handle="PCHelper", name="hashCode")
    public int hashCode() { return PCHelper.hashCode(this); }

    @LinkJavaSource(handle="PCHelper", name="equals")
    public boolean equals(Object o) { return PCHelper.equals(this, o); }

    @LinkJavaSource(handle="PCHelper", name="clone")
    public PageConn clone() { return PCHelper.clone(this); }
}