]> git.wh0rd.org - chrome-ext/web-power-switch.git/blame - popup.js
popup: use standard String.trim() now
[chrome-ext/web-power-switch.git] / popup.js
CommitLineData
dc7033a8 1// Written by Mike Frysinger <vapier@gmail.com>. Released into the public domain.
a98f3ef6
MF
2
3var url_base, user, pass;
4
5function fetchpage(url, callback) {
6 url = url_base + '/' + url;
7
8 var xhr = new XMLHttpRequest();
9 xhr.setstatus = false;
10 try {
11 xhr.onreadystatechange = function(state) {
12 if (xhr.readyState == 4) {
13 if (xhr.status == 200) {
14 callback(xhr, state);
15 } else {
16 xhr.setstatus = true;
d5664f4c
MF
17 setstatus(
18 'Could not connect;<br>check your ' +
19 '<a id="open-settings" href="">settings</a>'
20 );
21 document.getElementById('open-settings').onclick = open_settings_page;
a98f3ef6
MF
22 console.log('connect error', state);
23 }
24 }
25 }
26 xhr.onerror = function(error) {
27 if (!xhr.setstatus)
28 setstatus('onerror; see console');
29 console.log('xhr error:', error);
30 }
31
32 console.log('fetching', url)
33 xhr.withCredentials = true;
34 xhr.open('GET', url, true, user, pass);
35 xhr.responseType = 'document';
36 // The user/pass options above don't seem to work, so do it ourselves.
37 xhr.setRequestHeader('Authorization', 'Basic ' + btoa(user + ':' + pass));
38 xhr.send();
39 } catch(e) {
40 setstatus('Exception; see console');
41 console.log('exception:', e);
42 }
43}
44
45function onoff(o) {
ceb29ec9
MF
46 const data = o.toUpperCase();
47 switch (data) {
48 case 'OFF':
49 return 'ON';
50 case 'ON':
51 return 'OFF';
52 default:
53 // For example, cycle uses CCL.
54 return data;
55 }
a98f3ef6
MF
56}
57
58function toggleit(button) {
ceb29ec9 59 const outlet_num = button.id.split(':')[0];
a98f3ef6
MF
60 var old_status = button.data;
61 var new_status = onoff(button.data);
62 var url = 'outlet?' + outlet_num + '=' + new_status;
63
ceb29ec9
MF
64 if (!button.id.endsWith('cycle')) {
65 const cycler = document.getElementById(`${button.id}:cycle`);
66 cycler.style.display = new_status === 'ON' ? 'block' : 'none';
67 }
68
a98f3ef6
MF
69 fetchpage(url, function(xhr, state) {
70 console.log('switch ' + outlet_num + ': ' + old_status + ' -> ' + new_status);
ceb29ec9
MF
71 if (!button.id.endsWith('cycle')) {
72 button.value = 'Switch ' + old_status;
73 button.data = new_status;
74 }
a98f3ef6
MF
75 });
76}
77function toggle() {
78 toggleit(this);
79}
80
81function toggle_confirmed() {
82 clearTimeout(this.timeout);
83 this.onclick = toggle_confirm;
84 toggleit(this);
85}
86
87function toggle_confirm() {
88 var button = this;
89 this.onclick = toggle_confirmed;
90 this.oldvalue = this.value;
91 this.value = 'Confirm!?';
92 this.timeout = setTimeout(function() {
93 button.value = button.oldvalue;
94 button.onclick = toggle_confirm;
95 }, 5000);
96}
97
a98f3ef6
MF
98}
99
100function initpopup(xhr, state) {
101 var tbl = document.getElementById('buttons');
102 var row, cell, button;
103
104 console.log(xhr, state);
105
106 // There is no clean API for extracting the current state.
107 // Example result:
38573511
MF
108 /*
109 <tr>
110 <th bgcolor="#DDDDFF" align=left>
111 Controller: !!!Web Power Switch 6
112 </th>
113 </tr>
114 */
115
116 var th, ths = state.currentTarget.responseXML.querySelectorAll('th');
117 for (var i = 0; th = ths[i]; ++i) {
118 if (th.bgColor != '#DDDDFF')
119 continue;
120
dce75bc9 121 var controller_name = th.innerText.trim();
38573511
MF
122 if (controller_name.slice(0, 12) != 'Controller: ')
123 continue;
124
125 row = tbl.insertRow(-1);
126 cell = row.insertCell(-1);
ceb29ec9 127 cell.colSpan = 10;
38573511
MF
128 cell.align = 'center';
129 cell.innerText = controller_name.slice(12);
130 cell.innerHTML = '<a href="' + url_base + '" target="_blank">' + cell.innerHTML + '</a>'
131 }
132
a98f3ef6
MF
133 var tr, trs = state.currentTarget.responseXML.querySelectorAll('tr');
134 for (var i = 0; tr = trs[i]; ++i) {
135 if (tr.bgColor != '#F4F4F4')
136 continue;
137
dce75bc9
MF
138 var outlet_num = tr.children[0].innerText.trim();
139 var outlet_name = tr.children[1].innerText.trim();
140 var current_status = tr.children[2].innerText.trim();
141 var new_status = tr.children[3].innerText.trim();
a98f3ef6
MF
142 var confirmable = tr.children[3].children[0].hasAttribute('onclick');
143
144 row = tbl.insertRow(-1);
145 cell = row.insertCell(-1);
8191f7e7
MF
146 if (outlet_name === '')
147 cell.innerHTML = '<i>unnamed</i>';
148 else
149 cell.innerText = outlet_name + ':';
a98f3ef6
MF
150 cell = row.insertCell(-1);
151 button = document.createElement('input');
152 button.type = 'button';
153 button.id = outlet_num;
154 button.value = new_status;
155 button.data = current_status;
156 button.onclick = confirmable ? toggle_confirm : toggle;
157 cell.appendChild(button);
ceb29ec9
MF
158
159 // The switch only allows cycling when it's on.
160 cell = row.insertCell(-1);
161 button = document.createElement('input');
162 button.type = 'button';
163 button.id = `${outlet_num}:cycle`;
164 button.value = '🗘';
165 button.data = 'CCL';
166 button.title = 'Power cycle';
167 button.onclick = confirmable ? toggle_confirm : toggle;
168 if (current_status.toUpperCase() === 'OFF') {
169 button.style.display = 'none';
170 }
171 button.style.fontSize = 'smaller';
172 cell.appendChild(button);
a98f3ef6
MF
173 }
174
175 setstatus();
176}
177
178function setstatus(msg) {
179 var status = document.getElementById('status');
e981c837 180 status.innerHTML = msg;
a98f3ef6
MF
181 status.style.visibility = msg ? '' : 'hidden';
182 status.style.float = msg ? '' : 'left';
183 status.style.position = msg ? '' : 'absolute';
184}
185
d5664f4c
MF
186function open_settings_page() {
187 chrome.runtime.openOptionsPage();
188}
189
a98f3ef6
MF
190document.addEventListener('DOMContentLoaded', function() {
191 storage.get(settings_keys, function(settings) {
192 url_base = settings['url'] || settings_defaults['url'];
193 user = settings['user'] || settings_defaults['user'];
194 pass = settings['pass'] || settings_defaults['pass'];
ecc284d8
MF
195 chrome.permissions.contains({
196 origins: [url_base + '/*']
197 }, function(granted) {
d03b7e74 198 if (granted) {
ecc284d8 199 fetchpage('index.htm', initpopup);
d03b7e74
MF
200 } else {
201 setstatus(
202 'Missing permissions;<br>please visit the ' +
d5664f4c 203 '<a id="open-settings" href="">settings page</a>' +
d03b7e74
MF
204 '<br>to grant access.<br>' +
205 '<center><input id=retry type=submit value=Retry></center>'
206 );
d5664f4c 207 document.getElementById('open-settings').onclick = open_settings_page;
d03b7e74
MF
208 // Work around http://crbug.com/125706.
209 document.getElementById('retry').onclick = function() {
210 chrome.permissions.request({origins: [url_base + '/*']});
211 fetchpage('index.htm', initpopup);
212 };
213 }
ecc284d8 214 });
a98f3ef6
MF
215 });
216});