OLD | NEW |
| (Empty) |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 cr.define('nfcDebug', function() { | |
6 'use strict'; | |
7 | |
8 function NfcDebugUI() { | |
9 this.adapterData_ = {}; | |
10 this.peerData_ = {}; | |
11 this.tagData_ = {}; | |
12 } | |
13 | |
14 NfcDebugUI.prototype = { | |
15 setAdapterData: function(data) { | |
16 this.adapterData_ = data; | |
17 }, | |
18 | |
19 setPeerData: function(data) { | |
20 this.peerData_ = data; | |
21 }, | |
22 | |
23 setTagData: function(data) { | |
24 this.tagData_ = data; | |
25 }, | |
26 | |
27 /** | |
28 * Powers the NFC adapter ON or OFF. | |
29 */ | |
30 toggleAdapterPower: function() { | |
31 chrome.send('setAdapterPower', [!this.adapterData_.powered]); | |
32 }, | |
33 | |
34 /** | |
35 * Tells the NFC adapter to start or stop polling. | |
36 */ | |
37 toggleAdapterPolling: function() { | |
38 chrome.send('setAdapterPolling', [!this.adapterData_.polling]); | |
39 }, | |
40 | |
41 /** | |
42 * Notifies the UI that the user made an NDEF type selection and the | |
43 * appropriate form should be displayed. | |
44 */ | |
45 recordTypeChanged: function() { | |
46 this.updateRecordFormContents(); | |
47 }, | |
48 | |
49 /** | |
50 * Creates a table element and populates it for each record contained | |
51 * in the given list of records and adds them as a child of the given | |
52 * DOMElement. This method will replace the contents of the given element | |
53 * with the tables. | |
54 * | |
55 * @param {DOMElement} div The container that the records should be rendered | |
56 * to. | |
57 * @param {Array} records List of NDEF record data. | |
58 */ | |
59 renderRecords: function(div, records) { | |
60 div.textContent = ''; | |
61 if (records.length == 0) { | |
62 return; | |
63 } | |
64 var self = this; | |
65 records.forEach(function(record) { | |
66 var recordDiv = document.createElement('div'); | |
67 recordDiv.setAttribute('class', 'record-div'); | |
68 for (var key in record) { | |
69 if (!record.hasOwnProperty(key)) | |
70 continue; | |
71 | |
72 var rowDiv = document.createElement('div'); | |
73 rowDiv.setAttribute('class', 'record-key-value-div'); | |
74 | |
75 var keyElement, valueElement; | |
76 if (key == 'titles') { | |
77 keyElement = document.createElement('div'); | |
78 keyElement.setAttribute('class', 'record-key-div'); | |
79 keyElement.appendChild(document.createTextNode(key)); | |
80 valueElement = document.createElement('div'); | |
81 valueElement.setAttribute('class', 'record-value-div'); | |
82 self.renderRecords(valueElement, record[key]); | |
83 } else { | |
84 keyElement = document.createElement('span'); | |
85 keyElement.setAttribute('class', 'record-key-span'); | |
86 keyElement.appendChild(document.createTextNode(key)); | |
87 valueElement = document.createElement('span'); | |
88 valueElement.setAttribute('class', 'record-value-span'); | |
89 valueElement.appendChild(document.createTextNode(record[key])); | |
90 } | |
91 rowDiv.appendChild(keyElement); | |
92 rowDiv.appendChild(valueElement); | |
93 recordDiv.appendChild(rowDiv); | |
94 } | |
95 div.appendChild(recordDiv); | |
96 if (records[records.length - 1] !== record) | |
97 div.appendChild(document.createElement('hr')); | |
98 }); | |
99 }, | |
100 | |
101 /** | |
102 * Updates which record type form is displayed based on the currently | |
103 * selected type. | |
104 */ | |
105 updateRecordFormContents: function() { | |
106 var recordTypeMenu = $('record-type-menu'); | |
107 var selectedType = | |
108 recordTypeMenu.options[recordTypeMenu.selectedIndex].value; | |
109 this.updateRecordFormContentsFromType(selectedType); | |
110 }, | |
111 | |
112 /** | |
113 * Updates which record type form is displayed based on the passed in | |
114 * type string. | |
115 * | |
116 * @param {string} type The record type. | |
117 */ | |
118 updateRecordFormContentsFromType: function(type) { | |
119 $('text-form').hidden = (type != 'text'); | |
120 $('uri-form').hidden = (type != 'uri'); | |
121 $('smart-poster-form').hidden = (type != 'smart-poster'); | |
122 }, | |
123 | |
124 /** | |
125 * Tries to push or write the record to the remote tag or device based on | |
126 * the contents of the record form fields. | |
127 */ | |
128 submitRecordForm: function() { | |
129 var recordTypeMenu = $('record-type-menu'); | |
130 var selectedType = | |
131 recordTypeMenu.options[recordTypeMenu.selectedIndex].value; | |
132 var recordData = {}; | |
133 if (selectedType == 'text') { | |
134 recordData.type = 'TEXT'; | |
135 if ($('text-form-text').value) | |
136 recordData.text = $('text-form-text').value; | |
137 if ($('text-form-encoding').value) | |
138 recordData.encoding = $('text-form-encoding').value; | |
139 if ($('text-form-language-code').value) | |
140 recordData.languageCode = $('text-form-language-code').value; | |
141 } else if (selectedType == 'uri') { | |
142 recordData.type = 'URI'; | |
143 if ($('uri-form-uri').value) | |
144 recordData.uri = $('uri-form-uri').value; | |
145 if ($('uri-form-mime-type').value) | |
146 recordData.mimeType = $('uri-form-mime-type').value; | |
147 if ($('uri-form-target-size').value) { | |
148 var targetSize = $('uri-form-target-size').value; | |
149 targetSize = parseFloat(targetSize); | |
150 recordData.targetSize = isNaN(targetSize) ? 0.0 : targetSize; | |
151 } | |
152 } else if (selectedType == 'smart-poster') { | |
153 recordData.type = 'SMART_POSTER'; | |
154 if ($('smart-poster-form-uri').value) | |
155 recordData.uri = $('smart-poster-form-uri').value; | |
156 if ($('smart-poster-form-mime-type').value) | |
157 recordData.mimeType = $('smart-poster-form-mime-type').value; | |
158 if ($('smart-poster-form-target-size').value) { | |
159 var targetSize = $('smart-poster-form-target-size').value; | |
160 targetSize = parseFloat(targetSize); | |
161 recordData.targetSize = isNaN(targetSize) ? 0.0 : targetSize; | |
162 } | |
163 var title = {}; | |
164 if ($('smart-poster-form-title-text').value) | |
165 title.text = $('smart-poster-form-title-text').value; | |
166 if ($('smart-poster-form-title-encoding').value) | |
167 title.encoding = $('smart-poster-form-title-encoding').value; | |
168 if ($('smart-poster-form-title-language-code').value) | |
169 title.languageCode = | |
170 $('smart-poster-form-title-language-code').value; | |
171 if (Object.keys(title).length != 0) | |
172 recordData.titles = [title]; | |
173 } | |
174 chrome.send('submitRecordForm', [recordData]); | |
175 }, | |
176 | |
177 /** | |
178 * Given a dictionary |data|, builds a table where each row contains the | |
179 * a key and its value. The resulting table is then added as the sole child | |
180 * of |div|. |data| contains information about an adapter, tag, or peer and | |
181 * this method creates a table for display, thus the value of some keys | |
182 * will be processed. | |
183 * | |
184 * @param {DOMElement} div The container that the table should be rendered | |
185 * to. | |
186 * @param {dictionary} data Data to generate the table from. | |
187 */ | |
188 createTableFromData: function(div, data) { | |
189 div.textContent = ''; | |
190 var table = document.createElement('table'); | |
191 table.classList.add('parameters-table'); | |
192 for (var key in data) { | |
193 var row = document.createElement('tr'); | |
194 var col = document.createElement('td'); | |
195 col.textContent = key; | |
196 row.appendChild(col); | |
197 | |
198 col = document.createElement('td'); | |
199 var value = data[key]; | |
200 if (key == 'records') | |
201 value = value.length; | |
202 else if (key == 'supportedTechnologies') | |
203 value = value.join(', '); | |
204 col.textContent = value; | |
205 row.appendChild(col); | |
206 table.appendChild(row); | |
207 } | |
208 div.appendChild(table); | |
209 }, | |
210 }; | |
211 | |
212 cr.addSingletonGetter(NfcDebugUI); | |
213 | |
214 /** | |
215 * Initializes the page after the content has loaded. | |
216 */ | |
217 NfcDebugUI.initialize = function() { | |
218 $('nfc-adapter-info').hidden = true; | |
219 $('adapter-toggles').hidden = true; | |
220 $('nfc-adapter-info').classList.add('transition-out'); | |
221 $('ndef-record-form').classList.add('transition-out'); | |
222 $('nfc-peer-info').classList.add('transition-out'); | |
223 $('nfc-tag-info').classList.add('transition-out'); | |
224 $('power-toggle').onclick = function() { | |
225 NfcDebugUI.getInstance().toggleAdapterPower(); | |
226 }; | |
227 $('poll-toggle').onclick = function() { | |
228 NfcDebugUI.getInstance().toggleAdapterPolling(); | |
229 }; | |
230 $('record-type-menu').onchange = function() { | |
231 NfcDebugUI.getInstance().recordTypeChanged(); | |
232 }; | |
233 $('record-form-submit-button').onclick = function() { | |
234 NfcDebugUI.getInstance().submitRecordForm(); | |
235 }; | |
236 $('record-form-submit-button').hidden = true; | |
237 NfcDebugUI.getInstance().updateRecordFormContents(); | |
238 chrome.send('initialize'); | |
239 }; | |
240 | |
241 /** | |
242 * Updates the UI based on the NFC availability on the current platform. | |
243 * | |
244 * @param {bool} available If true, NFC is supported on the current platform. | |
245 */ | |
246 NfcDebugUI.onNfcAvailabilityDetermined = function(available) { | |
247 $('nfc-not-supported').hidden = available; | |
248 }; | |
249 | |
250 /** | |
251 * Notifies the UI that information about the NFC adapter has been received. | |
252 * | |
253 * @param {dictionary} data Properties of the NFC adapter. | |
254 */ | |
255 NfcDebugUI.onNfcAdapterInfoChanged = function(data) { | |
256 NfcDebugUI.getInstance().setAdapterData(data); | |
257 | |
258 $('nfc-adapter-info').hidden = false; | |
259 NfcDebugUI.getInstance().createTableFromData($('adapter-parameters'), data); | |
260 | |
261 $('nfc-adapter-info').classList.toggle('transition-out', !data.present); | |
262 $('nfc-adapter-info').classList.toggle('transition-in', data.present); | |
263 $('ndef-record-form').classList.toggle('transition-out', !data.present); | |
264 $('ndef-record-form').classList.toggle('transition-in', data.present); | |
265 | |
266 $('adapter-toggles').hidden = !data.present; | |
267 $('ndef-record-form').hidden = !data.present; | |
268 | |
269 $('power-toggle').textContent = loadTimeData.getString( | |
270 data.powered ? 'adapterPowerOffText' : 'adapterPowerOnText'); | |
271 $('poll-toggle').textContent = loadTimeData.getString( | |
272 data.polling ? 'adapterStopPollText' : 'adapterStartPollText'); | |
273 }; | |
274 | |
275 /** | |
276 * Notifies the UI that information about an NFC peer has been received. | |
277 * | |
278 * @param {dictionary} data Properties of the NFC peer device. | |
279 */ | |
280 NfcDebugUI.onNfcPeerDeviceInfoChanged = function(data) { | |
281 NfcDebugUI.getInstance().setPeerData(data); | |
282 | |
283 if (Object.keys(data).length == 0) { | |
284 $('nfc-peer-info').classList.add('transition-out'); | |
285 $('nfc-peer-info').classList.remove('transition-in'); | |
286 $('record-form-submit-button').hidden = true; | |
287 return; | |
288 } | |
289 | |
290 $('nfc-peer-info').classList.remove('transition-out'); | |
291 $('nfc-peer-info').classList.add('transition-in'); | |
292 | |
293 NfcDebugUI.getInstance().createTableFromData($('peer-parameters'), data); | |
294 | |
295 $('record-form-submit-button').hidden = false; | |
296 $('record-form-submit-button').textContent = | |
297 loadTimeData.getString('ndefFormPushButtonText'); | |
298 | |
299 if (data.records.length == 0) { | |
300 $('peer-records-entry').hidden = true; | |
301 return; | |
302 } | |
303 | |
304 $('peer-records-entry').hidden = false; | |
305 NfcDebugUI.getInstance().renderRecords($('peer-records-container'), | |
306 data.records); | |
307 }; | |
308 | |
309 /** | |
310 * Notifies the UI that information about an NFC tag has been received. | |
311 * | |
312 * @param {dictionary} data Properties of the NFC tag. | |
313 */ | |
314 NfcDebugUI.onNfcTagInfoChanged = function(data) { | |
315 NfcDebugUI.getInstance().setTagData(data); | |
316 | |
317 if (Object.keys(data).length == 0) { | |
318 $('nfc-tag-info').classList.add('transition-out'); | |
319 $('nfc-tag-info').classList.remove('transition-in'); | |
320 $('record-form-submit-button').hidden = true; | |
321 return; | |
322 } | |
323 | |
324 $('nfc-tag-info').classList.remove('transition-out'); | |
325 $('nfc-tag-info').classList.add('transition-in'); | |
326 | |
327 NfcDebugUI.getInstance().createTableFromData($('tag-parameters'), data); | |
328 | |
329 $('record-form-submit-button').hidden = false; | |
330 $('record-form-submit-button').textContent = | |
331 loadTimeData.getString('ndefFormWriteButtonText'); | |
332 | |
333 if (data.records.length == 0) { | |
334 $('tag-records-entry').hidden = true; | |
335 return; | |
336 } | |
337 | |
338 $('tag-records-entry').hidden = false; | |
339 NfcDebugUI.getInstance().renderRecords($('tag-records-container'), | |
340 data.records); | |
341 }; | |
342 | |
343 /** | |
344 * Notifies the UI that a call to "setAdapterPower" failed. Displays an | |
345 * alert. | |
346 */ | |
347 NfcDebugUI.onSetAdapterPowerFailed = function() { | |
348 alert(loadTimeData.getString('errorFailedToSetPowerText')); | |
349 }; | |
350 | |
351 /** | |
352 * Notifies the UI that a call to "setAdapterPolling" failed. Displays an | |
353 * alert. | |
354 */ | |
355 NfcDebugUI.onSetAdapterPollingFailed = function() { | |
356 alert(loadTimeData.getString('errorFailedToSetPollingText')); | |
357 }; | |
358 | |
359 /** | |
360 * Notifies the UI that an error occurred while submitting an NDEF record | |
361 * form. | |
362 * @param {string} errorMessage An error message, describing the failure. | |
363 */ | |
364 NfcDebugUI.onSubmitRecordFormFailed = function(errorMessage) { | |
365 alert(loadTimeData.getString('errorFailedToSubmitPrefixText') + | |
366 ' ' + errorMessage); | |
367 }; | |
368 | |
369 // Export | |
370 return { | |
371 NfcDebugUI: NfcDebugUI | |
372 }; | |
373 }); | |
374 | |
375 document.addEventListener('DOMContentLoaded', nfcDebug.NfcDebugUI.initialize); | |
OLD | NEW |