Home | History | Annotate | Download | only in chromeos
      1 // Copyright (c) 2012 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('options.internet', function() {
      6   var OptionsPage = options.OptionsPage;
      7   /** @const */ var ArrayDataModel = cr.ui.ArrayDataModel;
      8   /** @const */ var IPAddressField = options.internet.IPAddressField;
      9 
     10   /**
     11    * Network settings constants. These enums must match their C++
     12    * counterparts.
     13    */
     14   function Constants() {}
     15 
     16   // Network types:
     17   Constants.TYPE_UNKNOWN = 'UNKNOWN';
     18   Constants.TYPE_ETHERNET = 'ethernet';
     19   Constants.TYPE_WIFI = 'wifi';
     20   Constants.TYPE_WIMAX = 'wimax';
     21   Constants.TYPE_BLUETOOTH = 'bluetooth';
     22   Constants.TYPE_CELLULAR = 'cellular';
     23   Constants.TYPE_VPN = 'vpn';
     24 
     25   /*
     26    * Helper function to set hidden attribute for elements matching a selector.
     27    * @param {string} selector CSS selector for extracting a list of elements.
     28    * @param {bool} hidden New hidden value.
     29    */
     30   function updateHidden(selector, hidden) {
     31     var elements = cr.doc.querySelectorAll(selector);
     32     for (var i = 0, el; el = elements[i]; i++) {
     33       el.hidden = hidden;
     34     }
     35   }
     36 
     37   /*
     38    * Helper function to update the properties of the data object from the
     39    * properties in the update object.
     40    * @param {object} data object to update.
     41    * @param {object} object containing the updated properties.
     42    */
     43   function updateDataObject(data, update) {
     44     for (prop in update) {
     45       if (prop in data)
     46         data[prop] = update[prop];
     47     }
     48   }
     49 
     50   /**
     51    * Monitor pref change of given element.
     52    * @param {Element} el Target element.
     53    */
     54   function observePrefsUI(el) {
     55     Preferences.getInstance().addEventListener(el.pref, handlePrefUpdate);
     56   }
     57 
     58   /**
     59    * UI pref change handler.
     60    * @param {Event} e The update event.
     61    */
     62   function handlePrefUpdate(e) {
     63     DetailsInternetPage.getInstance().updateControls();
     64   }
     65 
     66   /////////////////////////////////////////////////////////////////////////////
     67   // DetailsInternetPage class:
     68 
     69   /**
     70    * Encapsulated handling of ChromeOS internet details overlay page.
     71    * @constructor
     72    */
     73   function DetailsInternetPage() {
     74     OptionsPage.call(this,
     75                      'detailsInternetPage',
     76                      null,
     77                      'details-internet-page');
     78   }
     79 
     80   cr.addSingletonGetter(DetailsInternetPage);
     81 
     82   DetailsInternetPage.prototype = {
     83     __proto__: OptionsPage.prototype,
     84 
     85     /**
     86      * Initializes DetailsInternetPage page.
     87      * Calls base class implementation to starts preference initialization.
     88      */
     89     initializePage: function() {
     90       OptionsPage.prototype.initializePage.call(this);
     91       var params = parseQueryParams(window.location);
     92       this.initializePageContents_(params);
     93       this.showNetworkDetails_(params);
     94     },
     95 
     96     /**
     97      * Auto-activates the network details dialog if network information
     98      * is included in the URL.
     99      */
    100     showNetworkDetails_: function(params) {
    101       var servicePath = params.servicePath;
    102       var networkType = params.networkType;
    103       if (!servicePath || !servicePath.length ||
    104           !networkType || !networkType.length)
    105         return;
    106       chrome.send('networkCommand',
    107           [networkType, servicePath, 'options']);
    108     },
    109 
    110 
    111     /**
    112      * Initializes the contents of the page.
    113      */
    114     initializePageContents_: function(params) {
    115       $('details-internet-dismiss').addEventListener('click', function(event) {
    116         DetailsInternetPage.setDetails();
    117       });
    118 
    119       $('details-internet-login').addEventListener('click', function(event) {
    120         DetailsInternetPage.setDetails();
    121         DetailsInternetPage.loginFromDetails();
    122       });
    123 
    124       $('details-internet-disconnect').addEventListener('click',
    125                                                         function(event) {
    126         DetailsInternetPage.setDetails();
    127         DetailsInternetPage.disconnectNetwork();
    128       });
    129 
    130       $('details-internet-configure').addEventListener('click',
    131                                                        function(event) {
    132         DetailsInternetPage.setDetails();
    133         DetailsInternetPage.configureNetwork();
    134       });
    135 
    136       $('activate-details').addEventListener('click', function(event) {
    137         DetailsInternetPage.activateFromDetails();
    138       });
    139 
    140       $('buyplan-details').addEventListener('click', function(event) {
    141         var data = $('connection-state').data;
    142         chrome.send('buyDataPlan', [data.servicePath]);
    143         OptionsPage.closeOverlay();
    144       });
    145 
    146       $('view-account-details').addEventListener('click', function(event) {
    147         var data = $('connection-state').data;
    148         chrome.send('showMorePlanInfo', [data.servicePath]);
    149         OptionsPage.closeOverlay();
    150       });
    151 
    152       $('cellular-apn-use-default').addEventListener('click', function(event) {
    153         var data = $('connection-state').data;
    154         var apnSelector = $('select-apn');
    155 
    156         if (data.userApnIndex != -1) {
    157           apnSelector.remove(data.userApnIndex);
    158           data.userApnIndex = -1;
    159         }
    160 
    161         if (data.providerApnList.value.length > 0) {
    162           var iApn = 0;
    163           data.apn.apn = data.providerApnList.value[iApn].apn;
    164           var username = data.providerApnList.value[iApn].username;
    165           var password = data.providerApnList.value[iApn].password;
    166           data.apn.username = username ? username : '';
    167           data.apn.password = password ? password : '';
    168           chrome.send('setApn', [data.servicePath,
    169                                  String(data.apn.apn),
    170                                  String(data.apn.username),
    171                                  String(data.apn.password)]);
    172           apnSelector.selectedIndex = iApn;
    173           data.selectedApn = iApn;
    174         } else {
    175           data.apn.apn = '';
    176           data.apn.username = '';
    177           data.apn.password = '';
    178           apnSelector.selectedIndex = -1;
    179           data.selectedApn = -1;
    180         }
    181         updateHidden('.apn-list-view', false);
    182         updateHidden('.apn-details-view', true);
    183       });
    184 
    185       $('cellular-apn-set').addEventListener('click', function(event) {
    186         if ($('cellular-apn').value == '')
    187           return;
    188 
    189         var data = $('connection-state').data;
    190         var apnSelector = $('select-apn');
    191 
    192         data.apn.apn = String($('cellular-apn').value);
    193         data.apn.username = String($('cellular-apn-username').value);
    194         data.apn.password = String($('cellular-apn-password').value);
    195         chrome.send('setApn', [data.servicePath,
    196                                String(data.apn.apn),
    197                                String(data.apn.username),
    198                                String(data.apn.password)]);
    199 
    200         if (data.userApnIndex != -1) {
    201           apnSelector.remove(data.userApnIndex);
    202           data.userApnIndex = -1;
    203         }
    204 
    205         var option = document.createElement('option');
    206         option.textContent = data.apn.apn;
    207         option.value = -1;
    208         option.selected = true;
    209         apnSelector.add(option, apnSelector[apnSelector.length - 1]);
    210         data.userApnIndex = apnSelector.length - 2;
    211         data.selectedApn = data.userApnIndex;
    212 
    213         updateHidden('.apn-list-view', false);
    214         updateHidden('.apn-details-view', true);
    215       });
    216 
    217       $('cellular-apn-cancel').addEventListener('click', function(event) {
    218         $('select-apn').selectedIndex = $('connection-state').data.selectedApn;
    219         updateHidden('.apn-list-view', false);
    220         updateHidden('.apn-details-view', true);
    221       });
    222 
    223       $('select-apn').addEventListener('change', function(event) {
    224         var data = $('connection-state').data;
    225         var apnSelector = $('select-apn');
    226         if (apnSelector[apnSelector.selectedIndex].value != -1) {
    227           var apnList = data.providerApnList.value;
    228           chrome.send('setApn', [data.servicePath,
    229               String(apnList[apnSelector.selectedIndex].apn),
    230               String(apnList[apnSelector.selectedIndex].username),
    231               String(apnList[apnSelector.selectedIndex].password)
    232           ]);
    233           data.selectedApn = apnSelector.selectedIndex;
    234         } else if (apnSelector.selectedIndex == data.userApnIndex) {
    235           chrome.send('setApn', [data.servicePath,
    236                                  String(data.apn.apn),
    237                                  String(data.apn.username),
    238                                  String(data.apn.password)]);
    239           data.selectedApn = apnSelector.selectedIndex;
    240         } else {
    241           $('cellular-apn').value = data.apn.apn;
    242           var username = data.apn.username;
    243           var password = data.apn.password;
    244           $('cellular-apn-username').value = username ? username : '';
    245           $('cellular-apn-password').value = password ? password : '';
    246 
    247           updateHidden('.apn-list-view', true);
    248           updateHidden('.apn-details-view', false);
    249         }
    250       });
    251 
    252       $('sim-card-lock-enabled').addEventListener('click', function(event) {
    253         var newValue = $('sim-card-lock-enabled').checked;
    254         // Leave value as is because user needs to enter PIN code first.
    255         // When PIN will be entered and value changed,
    256         // we'll update UI to reflect that change.
    257         $('sim-card-lock-enabled').checked = !newValue;
    258         chrome.send('setSimCardLock', [newValue]);
    259       });
    260       $('change-pin').addEventListener('click', function(event) {
    261         chrome.send('changePin');
    262       });
    263 
    264       // Proxy
    265       ['proxy-host-single-port',
    266        'secure-proxy-port',
    267        'socks-port',
    268        'ftp-proxy-port',
    269        'proxy-host-port'
    270       ].forEach(function(id) {
    271         options.PrefPortNumber.decorate($(id));
    272       });
    273 
    274       options.proxyexceptions.ProxyExceptions.decorate($('ignored-host-list'));
    275       $('remove-host').addEventListener('click',
    276                                         this.handleRemoveProxyExceptions_);
    277       $('add-host').addEventListener('click', this.handleAddProxyException_);
    278       $('direct-proxy').addEventListener('click', this.disableManualProxy_);
    279       $('manual-proxy').addEventListener('click', this.enableManualProxy_);
    280       $('auto-proxy').addEventListener('click', this.disableManualProxy_);
    281       $('proxy-all-protocols').addEventListener('click',
    282                                                 this.toggleSingleProxy_);
    283       $('proxy-use-pac-url').addEventListener('change',
    284                                               this.handleAutoConfigProxy_);
    285 
    286       observePrefsUI($('direct-proxy'));
    287       observePrefsUI($('manual-proxy'));
    288       observePrefsUI($('auto-proxy'));
    289       observePrefsUI($('proxy-all-protocols'));
    290       observePrefsUI($('proxy-use-pac-url'));
    291 
    292       $('ip-automatic-configuration-checkbox').addEventListener('click',
    293         this.handleIpAutoConfig_);
    294       $('automatic-dns-radio').addEventListener('click',
    295         this.handleNameServerTypeChange_);
    296       $('google-dns-radio').addEventListener('click',
    297         this.handleNameServerTypeChange_);
    298       $('user-dns-radio').addEventListener('click',
    299         this.handleNameServerTypeChange_);
    300 
    301       // We only load this string if we have the string data available
    302       // because the proxy settings page on the login screen re-uses the
    303       // proxy sub-page from the internet options, and it doesn't ever
    304       // show the DNS settings, so we don't need this string there.
    305       // The string isn't available because
    306       // chrome://settings-frame/strings.js (where the string is
    307       // stored) is not accessible from the login screen.
    308       // TODO(pneubeck): Remove this once i18n of the proxy dialog on the login
    309       // page is fixed. http://crbug.com/242865
    310       if (loadTimeData.data_) {
    311         $('google-dns-label').innerHTML =
    312           loadTimeData.getString('googleNameServers');
    313       }
    314     },
    315 
    316     /**
    317      * Handler for "add" event fired from userNameEdit.
    318      * @param {Event} e Add event fired from userNameEdit.
    319      * @private
    320      */
    321     handleAddProxyException_: function(e) {
    322       var exception = $('new-host').value;
    323       $('new-host').value = '';
    324 
    325       exception = exception.trim();
    326       if (exception)
    327         $('ignored-host-list').addException(exception);
    328     },
    329 
    330     /**
    331      * Handler for when the remove button is clicked
    332      * @param {Event} e The click event.
    333      * @private
    334      */
    335     handleRemoveProxyExceptions_: function(e) {
    336       var selectedItems = $('ignored-host-list').selectedItems;
    337       for (var x = 0; x < selectedItems.length; x++) {
    338         $('ignored-host-list').removeException(selectedItems[x]);
    339       }
    340     },
    341 
    342     /**
    343      * Handler for when the IP automatic configuration checkbox is clicked.
    344      * @param {Event} e The click event.
    345      * @private
    346      */
    347     handleIpAutoConfig_: function(e) {
    348       var checked = $('ip-automatic-configuration-checkbox').checked;
    349       var fields = [$('ip-address'), $('ip-netmask'), $('ip-gateway')];
    350       for (var i = 0; i < fields.length; ++i) {
    351         fields[i].editable = !checked;
    352         if (checked) {
    353           var model = fields[i].model;
    354           model.value = model.automatic;
    355           fields[i].model = model;
    356         }
    357       }
    358       if (!checked)
    359         $('ip-address').focus();
    360     },
    361 
    362     /**
    363      * Handler for when the name server selection changes.
    364      * @param {Event} e The click event.
    365      * @private
    366      */
    367     handleNameServerTypeChange_: function(event) {
    368       var type = event.target.value;
    369       DetailsInternetPage.updateNameServerDisplay(type);
    370     },
    371 
    372     /**
    373      * Update details page controls.
    374      * @private
    375      */
    376     updateControls: function() {
    377       // Only show ipconfig section if network is connected OR if nothing on
    378       // this device is connected. This is so that you can fix the ip configs
    379       // if you can't connect to any network.
    380       // TODO(chocobo): Once ipconfig is moved to flimflam service objects,
    381       //   we need to redo this logic to allow configuration of all networks.
    382       $('ipconfig-section').hidden = !this.connected && this.deviceConnected;
    383       $('ipconfig-dns-section').hidden =
    384         !this.connected && this.deviceConnected;
    385 
    386       // Network type related.
    387       updateHidden('#details-internet-page .cellular-details', !this.cellular);
    388       updateHidden('#details-internet-page .wifi-details', !this.wireless);
    389       updateHidden('#details-internet-page .wimax-details', !this.wimax);
    390       updateHidden('#details-internet-page .vpn-details', !this.vpn);
    391       updateHidden('#details-internet-page .proxy-details', !this.showProxy);
    392       /* Network information merged into the Wifi tab for wireless networks
    393          unless the option is set for enabling a static IP configuration. */
    394       updateHidden('#details-internet-page .network-details',
    395                    (this.wireless && !this.showStaticIPConfig) || this.vpn);
    396       updateHidden('#details-internet-page .wifi-network-setting',
    397                    this.showStaticIPConfig);
    398 
    399       // Wifi - Password and shared.
    400       updateHidden('#details-internet-page #password-details',
    401                    !this.wireless || !this.password);
    402       updateHidden('#details-internet-page #wifi-shared-network',
    403           !this.shared);
    404       updateHidden('#details-internet-page #prefer-network',
    405                    !this.showPreferred);
    406 
    407       // WiMAX.
    408       updateHidden('#details-internet-page #wimax-shared-network',
    409         !this.shared);
    410 
    411       // Proxy
    412       this.updateProxyBannerVisibility_();
    413       this.toggleSingleProxy_();
    414       if ($('manual-proxy').checked)
    415         this.enableManualProxy_();
    416       else
    417         this.disableManualProxy_();
    418     },
    419 
    420     /**
    421      * Updates info banner visibility state. This function shows the banner
    422      * if proxy is managed or shared-proxies is off for shared network.
    423      * @private
    424      */
    425     updateProxyBannerVisibility_: function() {
    426       var bannerDiv = $('network-proxy-info-banner');
    427       if (!loadTimeData.data_) {
    428         // TODO(pneubeck): This temporarily prevents an exception below until
    429         // i18n of the proxy dialog on the login page is
    430         // fixed. http://crbug.com/242865
    431         bannerDiv.hidden = true;
    432         return;
    433       }
    434 
    435       // Show banner and determine its message if necessary.
    436       var controlledBy = $('direct-proxy').controlledBy;
    437       if (!controlledBy || controlledBy == '') {
    438         bannerDiv.hidden = true;
    439       } else {
    440         bannerDiv.hidden = false;
    441         // The possible banner texts are loaded in proxy_handler.cc.
    442         var bannerText = 'proxyBanner' + controlledBy.charAt(0).toUpperCase() +
    443                          controlledBy.slice(1);
    444         $('banner-text').textContent = loadTimeData.getString(bannerText);
    445       }
    446     },
    447 
    448     /**
    449      * Handler for when the user clicks on the checkbox to allow a
    450      * single proxy usage.
    451      * @private
    452      * @param {Event} e Click Event.
    453      */
    454     toggleSingleProxy_: function(e) {
    455       if ($('proxy-all-protocols').checked) {
    456         $('multi-proxy').hidden = true;
    457         $('single-proxy').hidden = false;
    458       } else {
    459         $('multi-proxy').hidden = false;
    460         $('single-proxy').hidden = true;
    461       }
    462     },
    463 
    464     /**
    465      * Handler for when the user clicks on the checkbox to enter
    466      * auto configuration URL.
    467      * @private
    468      * @param {Event} e Click Event.
    469      */
    470     handleAutoConfigProxy_: function(e) {
    471       $('proxy-pac-url').disabled = !$('proxy-use-pac-url').checked;
    472     },
    473 
    474     /**
    475      * Handler for selecting a radio button that will disable the manual
    476      * controls.
    477      * @private
    478      * @param {Event} e Click event.
    479      */
    480     disableManualProxy_: function(e) {
    481       $('ignored-host-list').disabled = true;
    482       $('new-host').disabled = true;
    483       $('remove-host').disabled = true;
    484       $('add-host').disabled = true;
    485       $('proxy-all-protocols').disabled = true;
    486       $('proxy-host-name').disabled = true;
    487       $('proxy-host-port').disabled = true;
    488       $('proxy-host-single-name').disabled = true;
    489       $('proxy-host-single-port').disabled = true;
    490       $('secure-proxy-host-name').disabled = true;
    491       $('secure-proxy-port').disabled = true;
    492       $('ftp-proxy').disabled = true;
    493       $('ftp-proxy-port').disabled = true;
    494       $('socks-host').disabled = true;
    495       $('socks-port').disabled = true;
    496       $('proxy-use-pac-url').disabled = $('auto-proxy').disabled ||
    497                                         !$('auto-proxy').checked;
    498       $('proxy-pac-url').disabled = $('proxy-use-pac-url').disabled ||
    499                                     !$('proxy-use-pac-url').checked;
    500       $('auto-proxy-parms').hidden = !$('auto-proxy').checked;
    501       $('manual-proxy-parms').hidden = !$('manual-proxy').checked;
    502     },
    503 
    504     /**
    505      * Handler for selecting a radio button that will enable the manual
    506      * controls.
    507      * @private
    508      * @param {Event} e Click event.
    509      */
    510     enableManualProxy_: function(e) {
    511       $('ignored-host-list').redraw();
    512       var allDisabled = $('manual-proxy').disabled;
    513       $('ignored-host-list').disabled = allDisabled;
    514       $('new-host').disabled = allDisabled;
    515       $('remove-host').disabled = allDisabled;
    516       $('add-host').disabled = allDisabled;
    517       $('proxy-all-protocols').disabled = allDisabled;
    518       $('proxy-host-name').disabled = allDisabled;
    519       $('proxy-host-port').disabled = allDisabled;
    520       $('proxy-host-single-name').disabled = allDisabled;
    521       $('proxy-host-single-port').disabled = allDisabled;
    522       $('secure-proxy-host-name').disabled = allDisabled;
    523       $('secure-proxy-port').disabled = allDisabled;
    524       $('ftp-proxy').disabled = allDisabled;
    525       $('ftp-proxy-port').disabled = allDisabled;
    526       $('socks-host').disabled = allDisabled;
    527       $('socks-port').disabled = allDisabled;
    528       $('proxy-use-pac-url').disabled = true;
    529       $('proxy-pac-url').disabled = true;
    530       $('auto-proxy-parms').hidden = !$('auto-proxy').checked;
    531       $('manual-proxy-parms').hidden = !$('manual-proxy').checked;
    532     },
    533   };
    534 
    535   /**
    536    * Enables or Disables all buttons that provide operations on the cellular
    537    * network.
    538    */
    539   DetailsInternetPage.changeCellularButtonsState = function(disable) {
    540     var buttonsToDisableList =
    541         new Array('details-internet-login',
    542                   'details-internet-disconnect',
    543                   'details-internet-configure',
    544                   'activate-details',
    545                   'buyplan-details',
    546                   'view-account-details');
    547 
    548     for (var i = 0; i < buttonsToDisableList.length; ++i) {
    549       button = $(buttonsToDisableList[i]);
    550       button.disabled = disable;
    551     }
    552   };
    553 
    554   /**
    555    * Shows a spinner while the carrier is changed.
    556    */
    557   DetailsInternetPage.showCarrierChangeSpinner = function(visible) {
    558     $('switch-carrier-spinner').hidden = !visible;
    559     // Disable any buttons that allow us to operate on cellular networks.
    560     DetailsInternetPage.changeCellularButtonsState(visible);
    561   };
    562 
    563   /**
    564    * Changes the network carrier.
    565    */
    566   DetailsInternetPage.handleCarrierChanged = function() {
    567     var carrierSelector = $('select-carrier');
    568     var carrier = carrierSelector[carrierSelector.selectedIndex].textContent;
    569     DetailsInternetPage.showCarrierChangeSpinner(true);
    570     var data = $('connection-state').data;
    571     chrome.send('setCarrier', [data.servicePath, carrier]);
    572   };
    573 
    574   /**
    575    * Performs minimal initialization of the InternetDetails dialog in
    576    * preparation for showing proxy-setttings.
    577    */
    578   DetailsInternetPage.initializeProxySettings = function() {
    579     var detailsPage = DetailsInternetPage.getInstance();
    580     detailsPage.initializePageContents_();
    581   };
    582 
    583   /**
    584    * Displays the InternetDetails dialog with only the proxy settings visible.
    585    */
    586   DetailsInternetPage.showProxySettings = function() {
    587     var detailsPage = DetailsInternetPage.getInstance();
    588     $('network-details-header').hidden = true;
    589     $('buyplan-details').hidden = true;
    590     $('activate-details').hidden = true;
    591     $('view-account-details').hidden = true;
    592     $('web-proxy-auto-discovery').hidden = true;
    593     detailsPage.cellular = false;
    594     detailsPage.wireless = false;
    595     detailsPage.vpn = false;
    596     detailsPage.showProxy = true;
    597     updateHidden('#internet-tab', true);
    598     updateHidden('#details-tab-strip', true);
    599     updateHidden('#details-internet-page .action-area', true);
    600     detailsPage.updateControls();
    601     detailsPage.visible = true;
    602   };
    603 
    604   /**
    605    * Initializes even handling for keyboard driven flow.
    606    */
    607   DetailsInternetPage.initializeKeyboardFlow = function() {
    608     keyboard.initializeKeyboardFlow();
    609   };
    610 
    611   DetailsInternetPage.updateProxySettings = function(type) {
    612       var proxyHost = null,
    613           proxyPort = null;
    614 
    615       if (type == 'cros.session.proxy.singlehttp') {
    616         proxyHost = 'proxy-host-single-name';
    617         proxyPort = 'proxy-host-single-port';
    618       }else if (type == 'cros.session.proxy.httpurl') {
    619         proxyHost = 'proxy-host-name';
    620         proxyPort = 'proxy-host-port';
    621       }else if (type == 'cros.session.proxy.httpsurl') {
    622         proxyHost = 'secure-proxy-host-name';
    623         proxyPort = 'secure-proxy-port';
    624       }else if (type == 'cros.session.proxy.ftpurl') {
    625         proxyHost = 'ftp-proxy';
    626         proxyPort = 'ftp-proxy-port';
    627       }else if (type == 'cros.session.proxy.socks') {
    628         proxyHost = 'socks-host';
    629         proxyPort = 'socks-port';
    630       }else {
    631         return;
    632       }
    633 
    634       var hostValue = $(proxyHost).value;
    635       if (hostValue.indexOf(':') !== -1) {
    636         if (hostValue.match(/:/g).length == 1) {
    637           hostValue = hostValue.split(':');
    638           $(proxyHost).value = hostValue[0];
    639           $(proxyPort).value = hostValue[1];
    640         }
    641       }
    642   };
    643 
    644   DetailsInternetPage.updateCarrier = function() {
    645     DetailsInternetPage.showCarrierChangeSpinner(false);
    646   };
    647 
    648   DetailsInternetPage.updateSecurityTab = function(requirePin) {
    649     $('sim-card-lock-enabled').checked = requirePin;
    650     $('change-pin').hidden = !requirePin;
    651   };
    652 
    653   DetailsInternetPage.loginFromDetails = function() {
    654     var data = $('connection-state').data;
    655     var servicePath = data.servicePath;
    656     chrome.send('networkCommand', [String(data.type),
    657                                           servicePath,
    658                                           'connect']);
    659     OptionsPage.closeOverlay();
    660   };
    661 
    662   DetailsInternetPage.disconnectNetwork = function() {
    663     var data = $('connection-state').data;
    664     var servicePath = data.servicePath;
    665     chrome.send('networkCommand', [String(data.type),
    666                                           servicePath,
    667                                           'disconnect']);
    668     OptionsPage.closeOverlay();
    669   };
    670 
    671   DetailsInternetPage.configureNetwork = function() {
    672     var data = $('connection-state').data;
    673     var servicePath = data.servicePath;
    674     chrome.send('networkCommand', [String(data.type),
    675                                           servicePath,
    676                                           'configure']);
    677     OptionsPage.closeOverlay();
    678   };
    679 
    680   DetailsInternetPage.activateFromDetails = function() {
    681     var data = $('connection-state').data;
    682     var servicePath = data.servicePath;
    683     if (data.type == Constants.TYPE_CELLULAR) {
    684       chrome.send('networkCommand', [String(data.type),
    685                                             servicePath,
    686                                             'activate']);
    687     }
    688     OptionsPage.closeOverlay();
    689   };
    690 
    691   DetailsInternetPage.setDetails = function() {
    692     var data = $('connection-state').data;
    693     var servicePath = data.servicePath;
    694     if (data.type == Constants.TYPE_WIFI) {
    695       chrome.send('setPreferNetwork',
    696                    [servicePath,
    697                     $('prefer-network-wifi').checked ? 'true' : 'false']);
    698       chrome.send('setAutoConnect',
    699                   [servicePath,
    700                    $('auto-connect-network-wifi').checked ? 'true' : 'false']);
    701     } else if (data.type == Constants.TYPE_WIMAX) {
    702       chrome.send('setAutoConnect',
    703                   [servicePath,
    704                    $('auto-connect-network-wimax').checked ? 'true' : 'false']);
    705     } else if (data.type == Constants.TYPE_CELLULAR) {
    706       chrome.send('setAutoConnect',
    707                   [servicePath,
    708                    $('auto-connect-network-cellular').checked ? 'true' :
    709                        'false']);
    710     } else if (data.type == Constants.TYPE_VPN) {
    711       chrome.send('setServerHostname',
    712                   [servicePath,
    713                    $('inet-server-hostname').value]);
    714       chrome.send('setAutoConnect',
    715                   [servicePath,
    716                    $('auto-connect-network-vpn').checked ? 'true' : 'false']);
    717     }
    718 
    719     var nameServerTypes = ['automatic', 'google', 'user'];
    720     var nameServerType = 'automatic';
    721     for (var i = 0; i < nameServerTypes.length; ++i) {
    722       if ($(nameServerTypes[i] + '-dns-radio').checked) {
    723         nameServerType = nameServerTypes[i];
    724         break;
    725       }
    726     }
    727 
    728     // Skip any empty values.
    729     var userNameServers = [];
    730     for (var i = 1; i <= 4; ++i) {
    731       var nameServerField = $('ipconfig-dns' + i);
    732       if (nameServerField && nameServerField.model &&
    733           nameServerField.model.value) {
    734         userNameServers.push(nameServerField.model.value);
    735       }
    736     }
    737 
    738     userNameServers = userNameServers.join(',');
    739 
    740     chrome.send('setIPConfig',
    741                 [servicePath,
    742                  Boolean($('ip-automatic-configuration-checkbox').checked),
    743                  $('ip-address').model.value || '',
    744                  $('ip-netmask').model.value || '',
    745                  $('ip-gateway').model.value || '',
    746                  nameServerType,
    747                  userNameServers]);
    748     OptionsPage.closeOverlay();
    749   };
    750 
    751   DetailsInternetPage.updateNameServerDisplay = function(type) {
    752     var editable = type == 'user';
    753     var fields = [$('ipconfig-dns1'), $('ipconfig-dns2'),
    754                   $('ipconfig-dns3'), $('ipconfig-dns4')];
    755     for (var i = 0; i < fields.length; ++i) {
    756       fields[i].editable = editable;
    757     }
    758     if (editable)
    759       $('ipconfig-dns1').focus();
    760 
    761     var automaticDns = $('automatic-dns-display');
    762     var googleDns = $('google-dns-display');
    763     var userDns = $('user-dns-settings');
    764     switch (type) {
    765       case 'automatic':
    766         automaticDns.setAttribute('selected', '');
    767         googleDns.removeAttribute('selected');
    768         userDns.removeAttribute('selected');
    769         break;
    770       case 'google':
    771         automaticDns.removeAttribute('selected');
    772         googleDns.setAttribute('selected', '');
    773         userDns.removeAttribute('selected');
    774         break;
    775       case 'user':
    776         automaticDns.removeAttribute('selected');
    777         googleDns.removeAttribute('selected');
    778         userDns.setAttribute('selected', '');
    779         break;
    780     }
    781   };
    782 
    783   DetailsInternetPage.updateConnectionButtonVisibilty = function(data) {
    784     $('details-internet-login').hidden = data.connected;
    785     $('details-internet-login').disabled = data.disableConnectButton;
    786 
    787     if (!data.connected &&
    788         ((data.type == Constants.TYPE_WIFI && data.encryption) ||
    789           data.type == Constants.TYPE_WIMAX ||
    790           data.type == Constants.TYPE_VPN)) {
    791       $('details-internet-configure').hidden = false;
    792     } else {
    793       $('details-internet-configure').hidden = true;
    794     }
    795 
    796     if (data.type == Constants.TYPE_ETHERNET)
    797       $('details-internet-disconnect').hidden = true;
    798     else
    799       $('details-internet-disconnect').hidden = !data.connected;
    800   };
    801 
    802   DetailsInternetPage.updateConnectionData = function(update) {
    803     var detailsPage = DetailsInternetPage.getInstance();
    804     if (!detailsPage.visible)
    805       return;
    806 
    807     var data = $('connection-state').data;
    808     if (!data)
    809       return;
    810 
    811     if (update.servicePath != data.servicePath)
    812       return;
    813 
    814     // Update our cached data object.
    815     updateDataObject(data, update);
    816 
    817     detailsPage.deviceConnected = data.deviceConnected;
    818     detailsPage.connecting = data.connecting;
    819     detailsPage.connected = data.connected;
    820     $('connection-state').textContent = data.connectionState;
    821 
    822     this.updateConnectionButtonVisibilty(data);
    823 
    824     if (data.type == Constants.TYPE_WIFI) {
    825       $('wifi-connection-state').textContent = data.connectionState;
    826     } else if (data.type == Constants.TYPE_WIMAX) {
    827       $('wimax-connection-state').textContent = data.connectionState;
    828     } else if (data.type == Constants.TYPE_CELLULAR) {
    829       $('activation-state').textContent = data.activationState;
    830 
    831       $('buyplan-details').hidden = !data.showBuyButton;
    832       $('view-account-details').hidden = !data.showViewAccountButton;
    833 
    834       $('activate-details').hidden = !data.showActivateButton;
    835       if (data.showActivateButton)
    836         $('details-internet-login').hidden = true;
    837     }
    838 
    839     $('connection-state').data = data;
    840   };
    841 
    842   DetailsInternetPage.showDetailedInfo = function(data) {
    843     var detailsPage = DetailsInternetPage.getInstance();
    844 
    845     // Populate header
    846     $('network-details-title').textContent = data.networkName;
    847     var statusKey = data.connected ? 'networkConnected' :
    848                                      'networkNotConnected';
    849     $('network-details-subtitle-status').textContent =
    850         loadTimeData.getString(statusKey);
    851     var typeKey = null;
    852     switch (data.type) {
    853     case Constants.TYPE_ETHERNET:
    854       typeKey = 'ethernetTitle';
    855       break;
    856     case Constants.TYPE_WIFI:
    857       typeKey = 'wifiTitle';
    858       break;
    859     case Constants.TYPE_WIMAX:
    860       typeKey = 'wimaxTitle';
    861       break;
    862     case Constants.TYPE_CELLULAR:
    863       typeKey = 'cellularTitle';
    864       break;
    865     case Constants.TYPE_VPN:
    866       typeKey = 'vpnTitle';
    867       break;
    868     }
    869     var typeLabel = $('network-details-subtitle-type');
    870     var typeSeparator = $('network-details-subtitle-separator');
    871     if (typeKey) {
    872       typeLabel.textContent = loadTimeData.getString(typeKey);
    873       typeLabel.hidden = false;
    874       typeSeparator.hidden = false;
    875     } else {
    876       typeLabel.hidden = true;
    877       typeSeparator.hidden = true;
    878     }
    879 
    880     // TODO(chocobo): Is this hack to cache the data here reasonable?
    881     // TODO(kevers): Find more appropriate place to cache data.
    882     $('connection-state').data = data;
    883 
    884     $('buyplan-details').hidden = true;
    885     $('activate-details').hidden = true;
    886     $('view-account-details').hidden = true;
    887 
    888     this.updateConnectionButtonVisibilty(data);
    889 
    890     $('web-proxy-auto-discovery').hidden = true;
    891 
    892     detailsPage.deviceConnected = data.deviceConnected;
    893     detailsPage.connecting = data.connecting;
    894     detailsPage.connected = data.connected;
    895     detailsPage.showProxy = data.showProxy;
    896     if (detailsPage.showProxy)
    897       chrome.send('selectNetwork', [data.servicePath]);
    898 
    899     detailsPage.showStaticIPConfig = data.showStaticIPConfig;
    900     $('connection-state').textContent = data.connectionState;
    901 
    902     var ipAutoConfig = data.ipAutoConfig ? 'automatic' : 'user';
    903     $('ip-automatic-configuration-checkbox').checked = data.ipAutoConfig;
    904     var inetAddress = {autoConfig: ipAutoConfig};
    905     var inetNetmask = {autoConfig: ipAutoConfig};
    906     var inetGateway = {autoConfig: ipAutoConfig};
    907 
    908     if (data.ipconfig.value) {
    909       inetAddress.automatic = data.ipconfig.value.address;
    910       inetAddress.value = data.ipconfig.value.address;
    911       inetNetmask.automatic = data.ipconfig.value.netmask;
    912       inetNetmask.value = data.ipconfig.value.netmask;
    913       inetGateway.automatic = data.ipconfig.value.gateway;
    914       inetGateway.value = data.ipconfig.value.gateway;
    915       if (data.ipconfig.value.webProxyAutoDiscoveryUrl) {
    916         $('web-proxy-auto-discovery').hidden = false;
    917         $('web-proxy-auto-discovery-url').value =
    918             data.ipconfig.value.webProxyAutoDiscoveryUrl;
    919       }
    920     }
    921 
    922     // Override the "automatic" values with the real saved DHCP values,
    923     // if they are set.
    924     if (data.savedIP.address) {
    925       inetAddress.automatic = data.savedIP.address;
    926       inetAddress.value = data.savedIP.address;
    927     }
    928     if (data.savedIP.netmask) {
    929       inetNetmask.automatic = data.savedIP.netmask;
    930       inetNetmask.value = data.savedIP.netmask;
    931     }
    932     if (data.savedIP.gateway) {
    933       inetGateway.automatic = data.savedIP.gateway;
    934       inetGateway.value = data.savedIP.gateway;
    935     }
    936 
    937     if (ipAutoConfig == 'user') {
    938       if (data.staticIP.value.address) {
    939         inetAddress.value = data.staticIP.value.address;
    940         inetAddress.user = data.staticIP.value.address;
    941       }
    942       if (data.staticIP.value.netmask) {
    943         inetNetmask.value = data.staticIP.value.netmask;
    944         inetNetmask.user = data.staticIP.value.netmask;
    945       }
    946       if (data.staticIP.value.gateway) {
    947         inetGateway.value = data.staticIP.value.gateway;
    948         inetGateway.user = data.staticIP.value.gateway;
    949       }
    950     }
    951 
    952     var configureAddressField = function(field, model) {
    953       IPAddressField.decorate(field);
    954       field.model = model;
    955       field.editable = model.autoConfig == 'user';
    956     };
    957 
    958     configureAddressField($('ip-address'), inetAddress);
    959     configureAddressField($('ip-netmask'), inetNetmask);
    960     configureAddressField($('ip-gateway'), inetGateway);
    961 
    962     var inetNameServers = '';
    963     if (data.ipconfig.value && data.ipconfig.value.nameServers) {
    964       inetNameServers = data.ipconfig.value.nameServers;
    965       $('automatic-dns-display').textContent = inetNameServers;
    966     }
    967 
    968     if (data.savedIP && data.savedIP.nameServers)
    969       $('automatic-dns-display').textContent = data.savedIP.nameServers;
    970 
    971     if (data.nameServersGoogle)
    972       $('google-dns-display').textContent = data.nameServersGoogle;
    973 
    974     var nameServersUser = [];
    975     if (data.staticIP.value.nameServers)
    976       nameServersUser = data.staticIP.value.nameServers.split(',');
    977 
    978     var nameServerModels = [];
    979     for (var i = 0; i < 4; ++i)
    980       nameServerModels.push({value: nameServersUser[i] || ''});
    981 
    982     $(data.nameServerType + '-dns-radio').checked = true;
    983     configureAddressField($('ipconfig-dns1'), nameServerModels[0]);
    984     configureAddressField($('ipconfig-dns2'), nameServerModels[1]);
    985     configureAddressField($('ipconfig-dns3'), nameServerModels[2]);
    986     configureAddressField($('ipconfig-dns4'), nameServerModels[3]);
    987 
    988     DetailsInternetPage.updateNameServerDisplay(data.nameServerType);
    989 
    990     if (data.hardwareAddress) {
    991       $('hardware-address').textContent = data.hardwareAddress;
    992       $('hardware-address-row').style.display = 'table-row';
    993     } else {
    994       // This is most likely a device without a hardware address.
    995       $('hardware-address-row').style.display = 'none';
    996     }
    997     if (data.type == Constants.TYPE_WIFI) {
    998       OptionsPage.showTab($('wifi-network-nav-tab'));
    999       detailsPage.wireless = true;
   1000       detailsPage.vpn = false;
   1001       detailsPage.ethernet = false;
   1002       detailsPage.cellular = false;
   1003       detailsPage.gsm = false;
   1004       detailsPage.wimax = false;
   1005       detailsPage.shared = data.shared;
   1006       $('wifi-connection-state').textContent = data.connectionState;
   1007       $('wifi-ssid').textContent = data.ssid;
   1008       if (data.bssid && data.bssid.length > 0) {
   1009         $('wifi-bssid').textContent = data.bssid;
   1010         $('wifi-bssid-entry').hidden = false;
   1011       } else {
   1012         $('wifi-bssid-entry').hidden = true;
   1013       }
   1014       $('wifi-ip-address').textContent = inetAddress.value;
   1015       $('wifi-netmask').textContent = inetNetmask.value;
   1016       $('wifi-gateway').textContent = inetGateway.value;
   1017       $('wifi-name-servers').textContent = inetNameServers;
   1018       if (data.encryption && data.encryption.length > 0) {
   1019         $('wifi-security').textContent = data.encryption;
   1020         $('wifi-security-entry').hidden = false;
   1021       } else {
   1022         $('wifi-security-entry').hidden = true;
   1023       }
   1024       // Frequency is in MHz.
   1025       var frequency = loadTimeData.getString('inetFrequencyFormat');
   1026       frequency = frequency.replace('$1', data.frequency);
   1027       $('wifi-frequency').textContent = frequency;
   1028       // Signal strength as percentage.
   1029       var signalStrength = loadTimeData.getString('inetSignalStrengthFormat');
   1030       signalStrength = signalStrength.replace('$1', data.strength);
   1031       $('wifi-signal-strength').textContent = signalStrength;
   1032       if (data.hardwareAddress) {
   1033         $('wifi-hardware-address').textContent = data.hardwareAddress;
   1034         $('wifi-hardware-address-entry').hidden = false;
   1035       } else {
   1036         $('wifi-hardware-address-entry').hidden = true;
   1037       }
   1038       detailsPage.showPreferred = data.showPreferred;
   1039       $('prefer-network-wifi').checked = data.preferred.value;
   1040       $('prefer-network-wifi').disabled = !data.remembered;
   1041       $('auto-connect-network-wifi').checked = data.autoConnect.value;
   1042       $('auto-connect-network-wifi').disabled = !data.remembered;
   1043       detailsPage.password = data.encrypted;
   1044     } else if (data.type == Constants.TYPE_WIMAX) {
   1045       OptionsPage.showTab($('wimax-network-nav-tab'));
   1046       detailsPage.wimax = true;
   1047       detailsPage.wireless = false;
   1048       detailsPage.vpn = false;
   1049       detailsPage.ethernet = false;
   1050       detailsPage.cellular = false;
   1051       detailsPage.gsm = false;
   1052       detailsPage.shared = data.shared;
   1053       detailsPage.showPreferred = data.showPreferred;
   1054       $('wimax-connection-state').textContent = data.connectionState;
   1055       $('auto-connect-network-wimax').checked = data.autoConnect.value;
   1056       $('auto-connect-network-wimax').disabled = !data.remembered;
   1057       if (data.identity) {
   1058         $('wimax-eap-identity').textContent = data.identity;
   1059         $('wimax-eap-identity-entry').hidden = false;
   1060       } else {
   1061         $('wimax-eap-identity-entry').hidden = true;
   1062       }
   1063       // Signal strength as percentage.
   1064       var signalStrength = loadTimeData.getString('inetSignalStrengthFormat');
   1065       signalStrength = signalStrength.replace('$1', data.strength);
   1066       $('wimax-signal-strength').textContent = signalStrength;
   1067     } else if (data.type == Constants.TYPE_CELLULAR) {
   1068       OptionsPage.showTab($('cellular-conn-nav-tab'));
   1069       detailsPage.ethernet = false;
   1070       detailsPage.wireless = false;
   1071       detailsPage.wimax = false;
   1072       detailsPage.vpn = false;
   1073       detailsPage.cellular = true;
   1074       if (data.showCarrierSelect && data.currentCarrierIndex != -1) {
   1075         var carrierSelector = $('select-carrier');
   1076         carrierSelector.onchange = DetailsInternetPage.handleCarrierChanged;
   1077         carrierSelector.options.length = 0;
   1078         for (var i = 0; i < data.carriers.length; ++i) {
   1079           var option = document.createElement('option');
   1080           option.textContent = data.carriers[i];
   1081           carrierSelector.add(option);
   1082         }
   1083         carrierSelector.selectedIndex = data.currentCarrierIndex;
   1084       } else {
   1085         $('service-name').textContent = data.serviceName;
   1086       }
   1087 
   1088       $('network-technology').textContent = data.networkTechnology;
   1089       $('activation-state').textContent = data.activationState;
   1090       $('roaming-state').textContent = data.roamingState;
   1091       $('restricted-pool').textContent = data.restrictedPool;
   1092       $('error-state').textContent = data.errorState;
   1093       $('manufacturer').textContent = data.manufacturer;
   1094       $('model-id').textContent = data.modelId;
   1095       $('firmware-revision').textContent = data.firmwareRevision;
   1096       $('hardware-revision').textContent = data.hardwareRevision;
   1097       $('prl-version').textContent = data.prlVersion;
   1098       $('meid').textContent = data.meid;
   1099       $('iccid').textContent = data.iccid;
   1100       $('imei').textContent = data.imei;
   1101       $('mdn').textContent = data.mdn;
   1102       $('esn').textContent = data.esn;
   1103       $('min').textContent = data.min;
   1104       detailsPage.gsm = data.gsm;
   1105       if (data.gsm) {
   1106         $('operator-name').textContent = data.operatorName;
   1107         $('operator-code').textContent = data.operatorCode;
   1108         $('imsi').textContent = data.imsi;
   1109 
   1110         var apnSelector = $('select-apn');
   1111         // Clear APN lists, keep only last element that "other".
   1112         while (apnSelector.length != 1)
   1113           apnSelector.remove(0);
   1114         var otherOption = apnSelector[0];
   1115         data.selectedApn = -1;
   1116         data.userApnIndex = -1;
   1117         var apnList = data.providerApnList.value;
   1118         for (var i = 0; i < apnList.length; i++) {
   1119           var option = document.createElement('option');
   1120           var localizedName = apnList[i].localizedName;
   1121           var name = localizedName ? localizedName : apnList[i].name;
   1122           var apn = apnList[i].apn;
   1123           option.textContent = name ? (name + ' (' + apn + ')') : apn;
   1124           option.value = i;
   1125           // data.apn and data.lastGoodApn will always be defined, however
   1126           // data.apn.apn and data.lastGoodApn.apn may not be. This is not a
   1127           // problem, as apnList[i].apn will always be defined and the
   1128           // comparisons below will work as expected.
   1129           if ((data.apn.apn == apn &&
   1130                data.apn.username == apnList[i].username &&
   1131                data.apn.password == apnList[i].password) ||
   1132               (!data.apn.apn &&
   1133                data.lastGoodApn.apn == apn &&
   1134                data.lastGoodApn.username == apnList[i].username &&
   1135                data.lastGoodApn.password == apnList[i].password)) {
   1136             data.selectedApn = i;
   1137           }
   1138           // Insert new option before "other" option.
   1139           apnSelector.add(option, otherOption);
   1140         }
   1141         if (data.selectedApn == -1 && data.apn.apn) {
   1142           var option = document.createElement('option');
   1143           option.textContent = data.apn.apn;
   1144           option.value = -1;
   1145           apnSelector.add(option, otherOption);
   1146           data.selectedApn = apnSelector.length - 2;
   1147           data.userApnIndex = data.selectedApn;
   1148         }
   1149         apnSelector.selectedIndex = data.selectedApn;
   1150         updateHidden('.apn-list-view', false);
   1151         updateHidden('.apn-details-view', true);
   1152         DetailsInternetPage.updateSecurityTab(data.simCardLockEnabled.value);
   1153       }
   1154       $('auto-connect-network-cellular').checked = data.autoConnect.value;
   1155       $('auto-connect-network-cellular').disabled = false;
   1156 
   1157       $('buyplan-details').hidden = !data.showBuyButton;
   1158       $('view-account-details').hidden = !data.showViewAccountButton;
   1159       $('activate-details').hidden = !data.showActivateButton;
   1160       if (data.showActivateButton) {
   1161         $('details-internet-login').hidden = true;
   1162       }
   1163     } else if (data.type == Constants.TYPE_VPN) {
   1164       OptionsPage.showTab($('vpn-nav-tab'));
   1165       detailsPage.wireless = false;
   1166       detailsPage.wimax = false;
   1167       detailsPage.vpn = true;
   1168       detailsPage.ethernet = false;
   1169       detailsPage.cellular = false;
   1170       detailsPage.gsm = false;
   1171       $('inet-service-name').textContent = data.serviceName;
   1172       $('inet-provider-type').textContent = data.providerType;
   1173       $('inet-username').textContent = data.username;
   1174       var inetServerHostname = $('inet-server-hostname');
   1175       inetServerHostname.value = data.serverHostname.value;
   1176       inetServerHostname.resetHandler = function() {
   1177         OptionsPage.hideBubble();
   1178         inetServerHostname.value = data.serverHostname.recommendedValue;
   1179       };
   1180       $('auto-connect-network-vpn').checked = data.autoConnect.value;
   1181       $('auto-connect-network-vpn').disabled = false;
   1182     } else {
   1183       OptionsPage.showTab($('internet-nav-tab'));
   1184       detailsPage.ethernet = true;
   1185       detailsPage.wireless = false;
   1186       detailsPage.wimax = false;
   1187       detailsPage.vpn = false;
   1188       detailsPage.cellular = false;
   1189       detailsPage.gsm = false;
   1190     }
   1191 
   1192     // Update controlled option indicators.
   1193     indicators = cr.doc.querySelectorAll(
   1194         '#details-internet-page .controlled-setting-indicator');
   1195     for (var i = 0; i < indicators.length; i++) {
   1196       var propName = indicators[i].getAttribute('data');
   1197       if (!propName || !data[propName])
   1198         continue;
   1199       var propData = data[propName];
   1200       // Create a synthetic pref change event decorated as
   1201       // CoreOptionsHandler::CreateValueForPref() does.
   1202       var event = new cr.Event(name);
   1203       event.value = {
   1204         value: propData.value,
   1205         controlledBy: propData.controlledBy,
   1206         recommendedValue: propData.recommendedValue,
   1207       };
   1208       indicators[i].handlePrefChange(event);
   1209       var forElement = $(indicators[i].getAttribute('for'));
   1210       if (forElement) {
   1211         forElement.disabled = propData.controlledBy == 'policy';
   1212         if (forElement.resetHandler)
   1213           indicators[i].resetHandler = forElement.resetHandler;
   1214       }
   1215     }
   1216 
   1217     detailsPage.updateControls();
   1218 
   1219     // Don't show page name in address bar and in history to prevent people
   1220     // navigate here by hand and solve issue with page session restore.
   1221     OptionsPage.showPageByName('detailsInternetPage', false);
   1222   };
   1223 
   1224   return {
   1225     DetailsInternetPage: DetailsInternetPage
   1226   };
   1227 });
   1228