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.
5 cr.define('nfcDebug', function() {
8 function NfcDebugUI() {
9 this.adapterData_ = {};
14 NfcDebugUI.prototype = {
15 setAdapterData: function(data) {
16 this.adapterData_ = data;
19 setPeerData: function(data) {
20 this.peerData_ = data;
23 setTagData: function(data) {
28 * Powers the NFC adapter ON or OFF.
30 toggleAdapterPower: function() {
31 chrome.send('setAdapterPower', [!this.adapterData_.powered]);
35 * Tells the NFC adapter to start or stop polling.
37 toggleAdapterPolling: function() {
38 chrome.send('setAdapterPolling', [!this.adapterData_.polling]);
42 * Notifies the UI that the user made an NDEF type selection and the
43 * appropriate form should be displayed.
45 recordTypeChanged: function() {
46 this.updateRecordFormContents();
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
55 * @param {DOMElement} div The container that the records should be rendered
57 * @param {Array} records List of NDEF record data.
59 renderRecords: function(div, records) {
61 if (records.length == 0) {
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))
72 var rowDiv = document.createElement('div');
73 rowDiv.setAttribute('class', 'record-key-value-div');
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]);
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]));
91 rowDiv.appendChild(keyElement);
92 rowDiv.appendChild(valueElement);
93 recordDiv.appendChild(rowDiv);
95 div.appendChild(recordDiv);
96 if (records[records.length - 1] !== record)
97 div.appendChild(document.createElement('hr'));
102 * Updates which record type form is displayed based on the currently
105 updateRecordFormContents: function() {
106 var recordTypeMenu = $('record-type-menu');
108 recordTypeMenu.options[recordTypeMenu.selectedIndex].value;
109 this.updateRecordFormContentsFromType(selectedType);
113 * Updates which record type form is displayed based on the passed in
116 * @param {string} type The record type.
118 updateRecordFormContentsFromType: function(type) {
119 $('text-form').hidden = (type != 'text');
120 $('uri-form').hidden = (type != 'uri');
121 $('smart-poster-form').hidden = (type != 'smart-poster');
125 * Tries to push or write the record to the remote tag or device based on
126 * the contents of the record form fields.
128 submitRecordForm: function() {
129 var recordTypeMenu = $('record-type-menu');
131 recordTypeMenu.options[recordTypeMenu.selectedIndex].value;
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;
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;
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)
170 $('smart-poster-form-title-language-code').value;
171 if (Object.keys(title).length != 0)
172 recordData.titles = [title];
174 chrome.send('submitRecordForm', [recordData]);
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
184 * @param {DOMElement} div The container that the table should be rendered
186 * @param {dictionary} data Data to generate the table from.
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);
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);
208 div.appendChild(table);
212 cr.addSingletonGetter(NfcDebugUI);
215 * Initializes the page after the content has loaded.
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();
227 $('poll-toggle').onclick = function() {
228 NfcDebugUI.getInstance().toggleAdapterPolling();
230 $('record-type-menu').onchange = function() {
231 NfcDebugUI.getInstance().recordTypeChanged();
233 $('record-form-submit-button').onclick = function() {
234 NfcDebugUI.getInstance().submitRecordForm();
236 $('record-form-submit-button').hidden = true;
237 NfcDebugUI.getInstance().updateRecordFormContents();
238 chrome.send('initialize');
242 * Updates the UI based on the NFC availability on the current platform.
244 * @param {bool} available If true, NFC is supported on the current platform.
246 NfcDebugUI.onNfcAvailabilityDetermined = function(available) {
247 $('nfc-not-supported').hidden = available;
251 * Notifies the UI that information about the NFC adapter has been received.
253 * @param {dictionary} data Properties of the NFC adapter.
255 NfcDebugUI.onNfcAdapterInfoChanged = function(data) {
256 NfcDebugUI.getInstance().setAdapterData(data);
258 $('nfc-adapter-info').hidden = false;
259 NfcDebugUI.getInstance().createTableFromData($('adapter-parameters'), data);
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);
266 $('adapter-toggles').hidden = !data.present;
267 $('ndef-record-form').hidden = !data.present;
269 $('power-toggle').textContent = loadTimeData.getString(
270 data.powered ? 'adapterPowerOffText' : 'adapterPowerOnText');
271 $('poll-toggle').textContent = loadTimeData.getString(
272 data.polling ? 'adapterStopPollText' : 'adapterStartPollText');
276 * Notifies the UI that information about an NFC peer has been received.
278 * @param {dictionary} data Properties of the NFC peer device.
280 NfcDebugUI.onNfcPeerDeviceInfoChanged = function(data) {
281 NfcDebugUI.getInstance().setPeerData(data);
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;
290 $('nfc-peer-info').classList.remove('transition-out');
291 $('nfc-peer-info').classList.add('transition-in');
293 NfcDebugUI.getInstance().createTableFromData($('peer-parameters'), data);
295 $('record-form-submit-button').hidden = false;
296 $('record-form-submit-button').textContent =
297 loadTimeData.getString('ndefFormPushButtonText');
299 if (data.records.length == 0) {
300 $('peer-records-entry').hidden = true;
304 $('peer-records-entry').hidden = false;
305 NfcDebugUI.getInstance().renderRecords($('peer-records-container'),
310 * Notifies the UI that information about an NFC tag has been received.
312 * @param {dictionary} data Properties of the NFC tag.
314 NfcDebugUI.onNfcTagInfoChanged = function(data) {
315 NfcDebugUI.getInstance().setTagData(data);
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;
324 $('nfc-tag-info').classList.remove('transition-out');
325 $('nfc-tag-info').classList.add('transition-in');
327 NfcDebugUI.getInstance().createTableFromData($('tag-parameters'), data);
329 $('record-form-submit-button').hidden = false;
330 $('record-form-submit-button').textContent =
331 loadTimeData.getString('ndefFormWriteButtonText');
333 if (data.records.length == 0) {
334 $('tag-records-entry').hidden = true;
338 $('tag-records-entry').hidden = false;
339 NfcDebugUI.getInstance().renderRecords($('tag-records-container'),
344 * Notifies the UI that a call to "setAdapterPower" failed. Displays an
347 NfcDebugUI.onSetAdapterPowerFailed = function() {
348 alert(loadTimeData.getString('errorFailedToSetPowerText'));
352 * Notifies the UI that a call to "setAdapterPolling" failed. Displays an
355 NfcDebugUI.onSetAdapterPollingFailed = function() {
356 alert(loadTimeData.getString('errorFailedToSetPollingText'));
360 * Notifies the UI that an error occurred while submitting an NDEF record
362 * @param {string} errorMessage An error message, describing the failure.
364 NfcDebugUI.onSubmitRecordFormFailed = function(errorMessage) {
365 alert(loadTimeData.getString('errorFailedToSubmitPrefixText') +
371 NfcDebugUI: NfcDebugUI
375 document.addEventListener('DOMContentLoaded', nfcDebug.NfcDebugUI.initialize);