OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2013 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 |