]>
git.wh0rd.org - chrome-ext/web-power-switch.git/blob - popup.js
1 // Written by Mike Frysinger <vapier@gmail.com>. Released into the public domain.
3 var url_base
, user
, pass
;
5 function fetchpage(url
, callback
) {
6 url
= url_base
+ '/' + url
;
8 var xhr
= new XMLHttpRequest();
11 xhr
.onreadystatechange = function(state
) {
12 if (xhr
.readyState
== 4) {
13 if (xhr
.status
== 200) {
18 'Could not connect;<br>check your ' +
19 '<a id="open-settings" href="">settings</a>'
21 document
.getElementById('open-settings').onclick
= open_settings_page
;
22 console
.log('connect error', state
);
26 xhr
.onerror = function(error
) {
28 setstatus('onerror; see console');
29 console
.log('xhr error:', error
);
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
));
40 setstatus('Exception; see console');
41 console
.log('exception:', e
);
45 function get_css_var(key
) { return getComputedStyle(document
.documentElement
).getPropertyValue(`--${key}`); }
48 const data
= o
.toUpperCase();
55 // For example, cycle uses CCL.
60 function toggleit(button
) {
61 const outlet_num
= button
.id
.split(':')[0];
62 var old_status
= button
.data
;
63 var new_status
= onoff(button
.data
);
64 var url
= 'outlet?' + outlet_num
+ '=' + new_status
;
66 if (!button
.id
.endsWith('cycle')) {
67 const cycler
= document
.getElementById(`${button.id}:cycle`);
68 cycler
.style
.display
= new_status
=== 'ON' ? 'block' : 'none';
71 fetchpage(url
, function(xhr
, state
) {
72 console
.log('switch ' + outlet_num
+ ': ' + old_status
+ ' -> ' + new_status
);
73 if (!button
.id
.endsWith('cycle')) {
74 button
.value
= 'Switch ' + old_status
;
75 button
.data
= new_status
;
83 function toggle_confirmed() {
84 clearTimeout(this.timeout
);
85 this.onclick
= toggle_confirm
;
89 function toggle_confirm() {
91 this.onclick
= toggle_confirmed
;
92 this.oldvalue
= this.value
;
93 this.value
= 'Confirm!?';
94 this.timeout
= setTimeout(function() {
95 button
.value
= button
.oldvalue
;
96 button
.onclick
= toggle_confirm
;
100 /* Toggle the selected theme. */
101 function toggle_theme() {
102 const theme
= get_css_var('theme') == 'light' ? 'dark' : 'light';
103 const css
= $('link#theme-override');
104 css
.href
= `css/${theme}.css`;
105 storage
.set({theme
});
109 function initpopup(xhr
, state
) {
110 var tbl
= document
.getElementById('buttons');
111 var row
, cell
, button
;
113 console
.log(xhr
, state
);
115 // There is no clean API for extracting the current state.
119 <th bgcolor="#DDDDFF" align=left>
120 Controller: !!!Web Power Switch 6
125 var th
, ths
= state
.currentTarget
.responseXML
.querySelectorAll('th');
126 for (var i
= 0; th
= ths
[i
]; ++i
) {
127 if (th
.bgColor
!= '#DDDDFF')
130 var controller_name
= th
.innerText
.trim();
131 if (controller_name
.slice(0, 12) != 'Controller: ')
134 row
= tbl
.insertRow(-1);
135 cell
= row
.insertCell(-1);
137 cell
.align
= 'center';
139 const a
= document
.createElement('a');
142 a
.text
= controller_name
.slice(12).trim();
145 const button
= document
.createElement('button');
146 button
.name
= 'theme';
147 button
.onclick
= toggle_theme
;
148 cell
.appendChild(button
);
151 var tr
, trs
= state
.currentTarget
.responseXML
.querySelectorAll('tr');
152 for (var i
= 0; tr
= trs
[i
]; ++i
) {
153 if (tr
.bgColor
!= '#F4F4F4')
156 var outlet_num
= tr
.children
[0].innerText
.trim();
157 var outlet_name
= tr
.children
[1].innerText
.trim();
158 var current_status
= tr
.children
[2].innerText
.trim();
159 var new_status
= tr
.children
[3].innerText
.trim();
160 var confirmable
= tr
.children
[3].children
[0].hasAttribute('onclick');
162 row
= tbl
.insertRow(-1);
163 cell
= row
.insertCell(-1);
164 if (outlet_name
=== '')
165 cell
.innerHTML
= '<i>unnamed</i>';
167 cell
.innerText
= outlet_name
+ ':';
168 cell
= row
.insertCell(-1);
169 button
= document
.createElement('input');
170 button
.type
= 'button';
171 button
.id
= outlet_num
;
172 button
.value
= new_status
;
173 button
.data
= current_status
;
174 button
.onclick
= confirmable
? toggle_confirm
: toggle
;
175 cell
.appendChild(button
);
177 // The switch only allows cycling when it's on.
178 cell
= row
.insertCell(-1);
179 button
= document
.createElement('input');
180 button
.type
= 'button';
181 button
.id
= `${outlet_num}:cycle`;
182 button
.value
= '🗘';
184 button
.title
= 'Power cycle';
185 button
.onclick
= confirmable
? toggle_confirm
: toggle
;
186 if (current_status
.toUpperCase() === 'OFF') {
187 button
.style
.display
= 'none';
189 button
.style
.fontSize
= 'smaller';
190 cell
.appendChild(button
);
196 function setstatus(msg
) {
197 var status
= document
.getElementById('status');
198 status
.innerHTML
= msg
;
199 status
.style
.visibility
= msg
? '' : 'hidden';
200 status
.style
.float = msg
? '' : 'left';
201 status
.style
.position
= msg
? '' : 'absolute';
204 function open_settings_page() {
205 chrome
.runtime
.openOptionsPage();
208 document
.addEventListener('DOMContentLoaded', function() {
209 storage
.get(settings_keys
, function(settings_storage
) {
210 const settings
= Object
.assign({}, settings_defaults
, settings_storage
);
211 url_base
= settings
['url'];
212 user
= settings
['user'];
213 pass
= settings
['pass'];
214 chrome
.permissions
.contains({
215 origins
: [url_base
+ '/*']
216 }, function(granted
) {
218 fetchpage('index.htm', initpopup
);
221 'Missing permissions;<br>please visit the ' +
222 '<a id="open-settings" href="">settings page</a>' +
223 '<br>to grant access.<br>' +
224 '<center><input id=retry type=submit value=Retry></center>'
226 document
.getElementById('open-settings').onclick
= open_settings_page
;
227 // Work around http://crbug.com/125706.
228 document
.getElementById('retry').onclick = function() {
229 chrome
.permissions
.request({origins
: [url_base
+ '/*']});
230 fetchpage('index.htm', initpopup
);