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
);