diff options
Diffstat (limited to 'chromium/ui/webui')
62 files changed, 1382 insertions, 245 deletions
diff --git a/chromium/ui/webui/resources/cr_components/certificate_manager/certificate_subentry.html b/chromium/ui/webui/resources/cr_components/certificate_manager/certificate_subentry.html index 691625fb095..423a18a8e50 100644 --- a/chromium/ui/webui/resources/cr_components/certificate_manager/certificate_subentry.html +++ b/chromium/ui/webui/resources/cr_components/certificate_manager/certificate_subentry.html @@ -36,21 +36,21 @@ title="[[i18n('moreActions')]]" on-tap="onDotsTap_"></button> <template is="cr-lazy-render" id="menu"> <dialog is="cr-action-menu"> - <button class="dropdown-item" id="view" + <button slot="item" class="dropdown-item" id="view" on-tap="onViewTap_"> [[i18n('certificateManagerView')]] </button> - <button class="dropdown-item" id="edit" + <button slot="item" class="dropdown-item" id="edit" hidden$="[[!canEdit_(certificateType, model)]]" on-tap="onEditTap_"> [[i18n('edit')]] </button> - <button class="dropdown-item" id="export" + <button slot="item" class="dropdown-item" id="export" hidden$="[[!canExport_(certificateType, model)]]" on-tap="onExportTap_"> [[i18n('certificateManagerExport')]] </button> - <button class="dropdown-item" id="delete" + <button slot="item" class="dropdown-item" id="delete" hidden$="[[!canDelete_(model)]]" on-tap="onDeleteTap_"> [[i18n('certificateManagerDelete')]] diff --git a/chromium/ui/webui/resources/cr_components/chromeos/bluetooth_dialog.html b/chromium/ui/webui/resources/cr_components/chromeos/bluetooth_dialog.html index dc8592fc98c..a71d029f68a 100644 --- a/chromium/ui/webui/resources/cr_components/chromeos/bluetooth_dialog.html +++ b/chromium/ui/webui/resources/cr_components/chromeos/bluetooth_dialog.html @@ -13,7 +13,7 @@ <template> <style include="cr-hidden-style iron-flex"> dialog { - @apply(--bluetooth-dialog-style); + @apply --bluetooth-dialog-style; } #pairing { diff --git a/chromium/ui/webui/resources/cr_components/chromeos/compiled_resources2.gyp b/chromium/ui/webui/resources/cr_components/chromeos/compiled_resources2.gyp index 1e6afe0491a..02bc35a7bbe 100644 --- a/chromium/ui/webui/resources/cr_components/chromeos/compiled_resources2.gyp +++ b/chromium/ui/webui/resources/cr_components/chromeos/compiled_resources2.gyp @@ -11,6 +11,13 @@ ], }, { + 'target_name': 'quick_unlock_resources', + 'type': 'none', + 'dependencies': [ + 'quick_unlock/compiled_resources2.gyp:*', + ], + }, + { 'target_name': 'bluetooth_dialog', 'dependencies': [ '<(DEPTH)/ui/webui/resources/cr_elements/cr_dialog/compiled_resources2.gyp:cr_dialog', diff --git a/chromium/ui/webui/resources/cr_components/chromeos/network/network_config.html b/chromium/ui/webui/resources/cr_components/chromeos/network/network_config.html index a2ba57be7c2..32c5b74d9e7 100644 --- a/chromium/ui/webui/resources/cr_components/chromeos/network/network_config.html +++ b/chromium/ui/webui/resources/cr_components/chromeos/network/network_config.html @@ -15,14 +15,14 @@ </style> <!-- SSID (WiFi) --> - <template is="dom-if" if="[[isType_(NetworkType_.WI_FI, type)]]"> + <template is="dom-if" if="[[isType_(NetworkType_.WI_FI, type)]]" restamp> <network-config-input id="ssid" label="[[i18n('OncWiFi-SSID')]]" value="{{configProperties_.WiFi.SSID}}" disabled="[[hasGuid_(guid)]]"> </network-config-input> </template> <!-- Security (WiFi and Ethernet) --> - <template is="dom-if" if="[[securityIsVisible_(type)]]"> + <template is="dom-if" if="[[securityIsVisible_(type)]]" restamp> <network-config-select id="security" label="[[i18n('OncWiFi-Security')]]" value="{{security_}}" disabled="[[!securityIsEnabled_(guid, type)]]" @@ -32,7 +32,8 @@ </template> <!-- Passphrase (WiFi) --> - <template is="dom-if" if="[[configRequiresPassphrase_(type, security_)]]"> + <template is="dom-if" if="[[configRequiresPassphrase_(type, security_)]]" + restamp> <network-config-input label="[[i18n('OncWiFi-Passphrase')]]" value="{{configProperties_.WiFi.Passphrase}}" password> <iron-a11y-keys keys="enter" on-keys-pressed="connectIfConfigured_"> @@ -41,7 +42,7 @@ </template> <!-- VPN --> - <template is="dom-if" if="[[showVpn_]]"> + <template is="dom-if" if="[[showVpn_]]" restamp> <network-config-input label="[[i18n('OncVPN-Host')]]" value="{{configProperties_.VPN.Host}}"> </network-config-input> @@ -102,7 +103,7 @@ </template> <!-- EAP (WiFi, WiMAX, Ethernet) --> - <template is="dom-if" if="[[showEap_]]"> + <template is="dom-if" if="[[showEap_]]" restamp> <network-config-select id="outer" label="[[i18n('OncEAP-Outer')]]" value="{{eapProperties_.Outer}}" items="[[eapOuterItems_]]" onc-prefix="EAP.Outer" hidden="[[!showEap_.Outer]]"> @@ -147,7 +148,7 @@ <!-- Share (WiFi and WiMAX) --> <template is="dom-if" - if="[[shareIsVisible_(guid, type, networkProperties)]]"> + if="[[shareIsVisible_(guid, type, networkProperties)]]" restamp> <div class="property-box"> <div id="shareLabel" class="start">[[i18n('networkConfigShare')]]</div> <paper-toggle-button id="share" checked="{{shareNetwork_}}" diff --git a/chromium/ui/webui/resources/cr_components/chromeos/network/network_config.js b/chromium/ui/webui/resources/cr_components/chromeos/network/network_config.js index 74cdc9b049f..0b6ada22d5a 100644 --- a/chromium/ui/webui/resources/cr_components/chromeos/network/network_config.js +++ b/chromium/ui/webui/resources/cr_components/chromeos/network/network_config.js @@ -9,7 +9,7 @@ */ /** - * Combinaiton of CrOnc.VPNType + AuthenticationType for IPsec. + * Combination of CrOnc.VPNType + AuthenticationType for IPsec. * Note: closure does not always recognize this if inside function() {}. * @enum {string} */ @@ -24,6 +24,7 @@ var VPNConfigType = { /** @const */ var DEFAULT_HASH = 'default'; /** @const */ var DO_NOT_CHECK_HASH = 'do-not-check'; +/** @const */ var NO_CERTS_HASH = 'no-certs'; Polymer({ is: 'network-config', @@ -53,9 +54,6 @@ Polymer({ */ type: String, - /** Set by embedder if saveOrConnect should always connect. */ - connectOnSave: Boolean, - /** True if the user configuring the network can toggle the shared state. */ shareAllowEnable: Boolean, @@ -129,7 +127,7 @@ Polymer({ }, }, - /** @private */ + /** @private {string|undefined} */ selectedServerCaHash_: String, /** @@ -143,7 +141,7 @@ Polymer({ }, }, - /** @private */ + /** @private {string|undefined} */ selectedUserCertHash_: String, /** @@ -280,7 +278,7 @@ Polymer({ /** * Array of values for the VPN Type dropdown. For L2TP-IPSec, the - * IPsec AuthenticationType ('PSK' or 'Cert') is incuded in the type. + * IPsec AuthenticationType ('PSK' or 'Cert') is included in the type. * Note: closure does not recognize Array<VPNConfigType> here. * @private {!Array<string>} * @const @@ -313,6 +311,7 @@ Polymer({ 'updateIsConfigured_(configProperties_, eapProperties_.*)', 'updateIsConfigured_(configProperties_.WiFi.*)', 'updateIsConfigured_(configProperties_.VPN.*, vpnType_)', + 'updateIsConfigured_(selectedUserCertHash_)', ], /** @const */ @@ -343,6 +342,8 @@ Polymer({ init: function() { this.propertiesSent_ = false; + this.selectedServerCaHash_ = undefined; + this.selectedUserCertHash_ = undefined; this.guid = this.networkProperties.GUID; this.type = this.networkProperties.Type; if (this.guid) { @@ -360,7 +361,19 @@ Polymer({ this.setShareNetwork_(); }, - saveOrConnect: function() { + save: function() { + this.saveAndConnect_(false /* connect */); + }, + + connect: function() { + this.saveAndConnect_(true /* connect */); + }, + + /** + * @param {boolean} connect If true, connect after save. + * @private + */ + saveAndConnect_: function(connect) { if (this.propertiesSent_) return; this.propertiesSent_ = true; @@ -376,14 +389,14 @@ Polymer({ this.globalPolicy.AllowOnlyPolicyNetworksToConnect)) { CrOnc.setTypeProperty(propertiesToSet, 'AutoConnect', false); } - // Create the configuration, then connect to it in the callback. this.networkingPrivate.createNetwork( - this.shareNetwork_, propertiesToSet, - this.createNetworkCallback_.bind(this)); + this.shareNetwork_, propertiesToSet, (guid) => { + this.createNetworkCallback_(connect, guid); + }); } else { - propertiesToSet.GUID = this.guid; - this.networkingPrivate.setProperties( - this.guid, propertiesToSet, this.setPropertiesCallback_.bind(this)); + this.networkingPrivate.setProperties(this.guid, propertiesToSet, () => { + this.setPropertiesCallback_(connect); + }); } }, @@ -401,7 +414,7 @@ Polymer({ connectIfConfigured_: function() { if (!this.isConfigured_) return; - this.saveOrConnect(); + this.connect(); }, /** @private */ @@ -438,13 +451,30 @@ Polymer({ caCerts.push(this.getDefaultCert_( this.i18n('networkCADoNotCheck'), DO_NOT_CHECK_HASH)); this.set('serverCaCerts_', caCerts); + if (this.selectedServerCaHash_ && !caCerts.find((cert) => { + return cert.hash == this.selectedServerCaHash_; + })) { + this.selectedServerCaHash_ = undefined; + } var userCerts = certificateLists.userCertificates.slice(); if (!userCerts.length) { userCerts = [this.getDefaultCert_( - this.i18n('networkCertificateNoneInstalled'), '')]; + this.i18n('networkCertificateNoneInstalled'), NO_CERTS_HASH)]; + } else { + // Only hardware backed user certs are supported. + userCerts.forEach(function(cert) { + if (!cert.hardwareBacked) + cert.hash = ''; // Clear the hash to invalidate the certificate. + }); } this.set('userCerts_', userCerts); + if (this.selectedUserCertHash_ && !userCerts.find((cert) => { + return cert.hash == this.selectedUserCertHash_; + })) { + this.selectedUserCertHash_ = undefined; + } + this.updateCertError_(); }.bind(this)); }, @@ -501,8 +531,9 @@ Polymer({ this.propertiesReceived_ = true; this.networkProperties = properties; this.setError_(properties.ErrorState); + this.updateCertError_(); - // Set the current shareNetwork_ value when porperties are received. + // Set the current shareNetwork_ value when properties are received. this.setShareNetwork_(); }, @@ -727,7 +758,7 @@ Polymer({ } else { this.set('eapProperties_.Inner', undefined); } - // Set the share vaule to its default when the EAP.Outer value changes. + // Set the share value to its default when the EAP.Outer value changes. this.setShareNetwork_(); }, @@ -904,16 +935,39 @@ Polymer({ /** @private */ updateCertError_: function() { - /** @const */ var certError = 'networkErrorNoUserCertificate'; - if (this.error && this.error != certError) + // If |this.error| was set to something other than a cert error, do not + // change it. + /** @const */ var noCertsError = 'networkErrorNoUserCertificate'; + /** @const */ var noValidCertsError = 'networkErrorNotHardwareBacked'; + if (this.error && this.error != noCertsError && + this.error != noValidCertsError) { return; + } var requireCerts = (this.showEap_ && this.showEap_.UserCert) || (this.showVpn_ && this.showVpn_.UserCert); - this.setError_(requireCerts && !this.userCerts_.length ? certError : ''); + if (!requireCerts) { + this.setError_(''); + return; + } + if (!this.userCerts_.length || this.userCerts_[0].hash == NO_CERTS_HASH) { + this.setError_(noCertsError); + return; + } + var validUserCert = this.userCerts_.find(function(cert) { + return !!cert.hash; + }); + if (!validUserCert) { + this.setError_(noValidCertsError); + return; + } + this.setError_(''); + return; }, /** + * Sets the selected cert if |pem| (serverCa) or |certId| (user) is specified. + * Otherwise sets a default value if no certificate is selected. * @param {string|undefined} pem * @param {string|undefined} certId * @private @@ -936,8 +990,15 @@ Polymer({ if (userCert) this.selectedUserCertHash_ = userCert.hash; } - if (!this.selectedUserCertHash_ && this.userCerts_[0]) - this.selectedUserCertHash_ = this.userCerts_[0].hash; + if (!this.selectedUserCertHash_) { + // Find either the first valid entry or the 'no-certs' entry. + var selectUserCert = this.userCerts_.find(function(cert) { + return !!cert.hash; + }); + if (selectUserCert) + this.selectedUserCertHash_ = selectUserCert.hash; + } + this.updateIsConfigured_(); }, /** @@ -945,6 +1006,9 @@ Polymer({ * @private */ getIsConfigured_: function() { + if (!this.configProperties_) + return false; + if (this.configProperties_.Type == CrOnc.Type.VPN) return this.vpnIsConfigured_(); @@ -1063,13 +1127,22 @@ Polymer({ * @return {boolean} * @private */ + selectedUserCertHashIsValid_: function() { + return !!this.selectedUserCertHash_ && + this.selectedUserCertHash_ != NO_CERTS_HASH; + }, + + /** + * @return {boolean} + * @private + */ eapIsConfigured_: function() { var eap = this.getEap_(this.configProperties_); if (!eap) return false; if (eap.Outer != CrOnc.EAPType.EAP_TLS) return true; - return !!this.selectedUserCertHash_; + return this.selectedUserCertHashIsValid_(); }, /** @@ -1085,10 +1158,11 @@ Polymer({ case VPNConfigType.L2TP_IPSEC_PSK: return !!this.get('L2TP.Username', vpn) && !!this.get('IPsec.PSK', vpn); case VPNConfigType.L2TP_IPSEC_CERT: - return !!this.get('L2TP.Username', vpn) && !!this.selectedUserCertHash_; + return !!this.get('L2TP.Username', vpn) && + this.selectedUserCertHashIsValid_(); case VPNConfigType.OPEN_VPN: return !!this.get('OpenVPN.Username', vpn) && - !!this.selectedUserCertHash_; + this.selectedUserCertHashIsValid_(); } return false; }, @@ -1096,6 +1170,11 @@ Polymer({ /** @private */ getPropertiesToSet_: function() { var propertiesToSet = Object.assign({}, this.configProperties_); + // Do not set AutoConnect by default, the connection manager will set + // it to true on a successful connection. + CrOnc.setTypeProperty(propertiesToSet, 'AutoConnect', undefined); + if (this.guid) + propertiesToSet.GUID = this.guid; var eap = this.getEap_(propertiesToSet); if (eap) this.setEapProperties_(eap); @@ -1127,11 +1206,10 @@ Polymer({ * @private */ getUserCertPkcs11Id_: function() { - var userHash = this.selectedUserCertHash_; - if (!userHash) + if (!this.selectedUserCertHashIsValid_()) return ''; - var userCert = this.userCerts_.find(function(cert) { - return cert.hash == userHash; + var userCert = this.userCerts_.find((cert) => { + return cert.hash == this.selectedUserCertHash_; }); return (userCert && userCert.PKCS11Id) || ''; }, @@ -1203,8 +1281,11 @@ Polymer({ return (chrome.runtime.lastError && chrome.runtime.lastError.message) || ''; }, - /** @private */ - setPropertiesCallback_: function() { + /** + * @param {boolean} connect If true, connect after save. + * @private + */ + setPropertiesCallback_: function(connect) { this.setError_(this.getRuntimeError_()); if (this.error) { console.error('setProperties error: ' + this.guid + ': ' + this.error); @@ -1212,7 +1293,7 @@ Polymer({ return; } var connectState = this.networkProperties.ConnectionState; - if (this.connectOnSave && + if (connect && (!connectState || connectState == CrOnc.ConnectionState.NOT_CONNECTED)) { this.startConnect_(this.guid); @@ -1222,10 +1303,11 @@ Polymer({ }, /** + * @param {boolean} connect If true, connect after save. * @param {string} guid * @private */ - createNetworkCallback_: function(guid) { + createNetworkCallback_: function(connect, guid) { this.setError_(this.getRuntimeError_()); if (this.error) { console.error( @@ -1234,7 +1316,8 @@ Polymer({ this.propertiesSent_ = false; return; } - this.startConnect_(guid); + if (connect) + this.startConnect_(guid); }, /** diff --git a/chromium/ui/webui/resources/cr_components/chromeos/network/network_config_input.html b/chromium/ui/webui/resources/cr_components/chromeos/network/network_config_input.html index 12784fd7a51..d23f9ec5c4b 100644 --- a/chromium/ui/webui/resources/cr_components/chromeos/network/network_config_input.html +++ b/chromium/ui/webui/resources/cr_components/chromeos/network/network_config_input.html @@ -29,8 +29,8 @@ <div class="control-box"> <paper-input-container always-float-label> - <label id="label">[[label]]</label> - <input is="iron-input" value="{{value::input}}" + <label id="label" slot="label">[[label]]</label> + <input is="iron-input" value="{{value::input}}" slot="input" tabindex="1" disabled="[[disabled]]" aria-label$="[[label]]" type="[[getInputType_(password, showPassword)]]"> </paper-input-container> diff --git a/chromium/ui/webui/resources/cr_components/chromeos/network/network_ip_config.html b/chromium/ui/webui/resources/cr_components/chromeos/network/network_ip_config.html index 31ccb502f47..66dcf2537e8 100644 --- a/chromium/ui/webui/resources/cr_components/chromeos/network/network_ip_config.html +++ b/chromium/ui/webui/resources/cr_components/chromeos/network/network_ip_config.html @@ -14,6 +14,7 @@ [[i18n('networkIPConfigAuto')]] </div> <paper-toggle-button checked="{{automatic_}}" disabled="[[!editable]]" + on-change="onAutomaticChange_" aria-labelledby="autoIPConfigLabel"> </paper-toggle-button> </div> diff --git a/chromium/ui/webui/resources/cr_components/chromeos/network/network_ip_config.js b/chromium/ui/webui/resources/cr_components/chromeos/network/network_ip_config.js index de442adbaf3..4260815ca7f 100644 --- a/chromium/ui/webui/resources/cr_components/chromeos/network/network_ip_config.js +++ b/chromium/ui/webui/resources/cr_components/chromeos/network/network_ip_config.js @@ -38,7 +38,6 @@ Polymer({ automatic_: { type: Boolean, value: true, - observer: 'automaticChanged_', }, /** @@ -113,7 +112,7 @@ Polymer({ }, /** @private */ - automaticChanged_: function() { + onAutomaticChange_: function() { if (!this.automatic_) { var defaultIpv4 = { Gateway: '192.168.1.1', diff --git a/chromium/ui/webui/resources/cr_components/chromeos/network/network_nameservers.html b/chromium/ui/webui/resources/cr_components/chromeos/network/network_nameservers.html index 0f8bc18aa14..4caf352d6bc 100644 --- a/chromium/ui/webui/resources/cr_components/chromeos/network/network_nameservers.html +++ b/chromium/ui/webui/resources/cr_components/chromeos/network/network_nameservers.html @@ -90,7 +90,7 @@ <paper-input-container no-label-float> <input id="nameserver[[index]]" is="iron-input" value="[[item]]" disabled="[[!canEdit_(editable, nameserversType_)]]" - on-change="onValueChange_"> + on-change="onValueChange_" slot="input"> </paper-input-container> </template> </div> diff --git a/chromium/ui/webui/resources/cr_components/chromeos/network/network_property_list.html b/chromium/ui/webui/resources/cr_components/chromeos/network/network_property_list.html index 3ea4c64f27e..534ce962de2 100644 --- a/chromium/ui/webui/resources/cr_components/chromeos/network/network_property_list.html +++ b/chromium/ui/webui/resources/cr_components/chromeos/network/network_property_list.html @@ -44,7 +44,7 @@ <template is="dom-if" if="[[isEditable_( item, 'String', propertyDict, editFieldTypes)]]"> <paper-input-container no-label-float> - <input id="[[item]]" is="iron-input" + <input id="[[item]]" is="iron-input" slot="input" value="[[getPropertyValue_(item, prefix, propertyDict)]]" on-change="onValueChange_"> </paper-input-container> @@ -53,7 +53,7 @@ <template is="dom-if" if="[[isEditable_( item, 'Password', propertyDict, editFieldTypes)]]"> <paper-input-container no-label-float> - <input id="[[item]]" is="iron-input" type="password" + <input id="[[item]]" is="iron-input" type="password" slot="input" value="[[getPropertyValue_(item, prefix, propertyDict)]]" on-change="onValueChange_"> </paper-input-container> diff --git a/chromium/ui/webui/resources/cr_components/chromeos/network/network_proxy.html b/chromium/ui/webui/resources/cr_components/chromeos/network/network_proxy.html index 4b328f9145b..1834e1db0f0 100644 --- a/chromium/ui/webui/resources/cr_components/chromeos/network/network_proxy.html +++ b/chromium/ui/webui/resources/cr_components/chromeos/network/network_proxy.html @@ -53,10 +53,10 @@ <div class="property-box indented" hidden$="[[!matches_(proxy_.Type, ProxySettingsType_.PAC)]]"> <div>[[i18n('networkProxyAutoConfig')]]</div> - <paper-input no-label-float class="middle" value="{{proxy_.PAC}}" + <paper-input id="pacInput" no-label-float class="middle" + value="{{proxy_.PAC}}" on-change="onPACChange_" disabled="[[!isEditable_('PAC', networkProperties, editable, - useSharedProxies)]]" - on-change="onPACChange_"> + useSharedProxies)]]"> </paper-input> </div> @@ -130,8 +130,8 @@ </network-proxy-exclusions> <div class="layout horizontal"> <paper-input-container no-label-float class="flex"> - <input id="proxyExclusion" is="iron-input"> - <iron-a11y-keys keys="enter" + <input id="proxyExclusion" is="iron-input" slot="input"> + <iron-a11y-keys keys="enter" slot="add-on" on-keys-pressed="onAddProxyExclusionTap_"> </iron-a11y-keys> </paper-input-container> @@ -144,7 +144,7 @@ <paper-button id="saveManualProxy" on-tap="onSaveProxyTap_" class="action-button" disabled="[[!isSaveManualProxyEnabled_(networkProperties, - proxyModified_, proxy_.*)]]"> + proxyIsUserModified_, proxy_.*)]]"> [[i18n('save')]] </paper-button> </div> diff --git a/chromium/ui/webui/resources/cr_components/chromeos/network/network_proxy.js b/chromium/ui/webui/resources/cr_components/chromeos/network/network_proxy.js index a1f2056eba8..7dd7aeb8fe8 100644 --- a/chromium/ui/webui/resources/cr_components/chromeos/network/network_proxy.js +++ b/chromium/ui/webui/resources/cr_components/chromeos/network/network_proxy.js @@ -120,7 +120,7 @@ Polymer({ * override the edited values. * @private {boolean} */ - proxyModified_: false, + proxyIsUserModified_: false, /** @override */ attached: function() { @@ -132,14 +132,14 @@ Polymer({ * is updated correctly. */ reset: function() { - this.proxyModified_ = false; + this.proxyIsUserModified_ = false; this.proxy_ = this.createDefaultProxySettings_(); this.updateProxy_(); }, /** @private */ networkPropertiesChanged_: function() { - if (this.proxyModified_) + if (this.proxyIsUserModified_) return; // Ignore update. this.updateProxy_(); }, @@ -221,13 +221,13 @@ Polymer({ // Set this.proxy_ after dom-repeat has been stamped. this.async(() => { this.proxy_ = proxy; - this.proxyModified_ = false; + this.proxyIsUserModified_ = false; }); }, /** @private */ useSameProxyChanged_: function() { - this.proxyModified_ = true; + this.proxyIsUserModified_ = true; }, /** @@ -283,7 +283,7 @@ Polymer({ return; } this.fire('proxy-change', {field: 'ProxySettings', value: proxy}); - this.proxyModified_ = false; + this.proxyIsUserModified_ = false; }, /** @@ -296,10 +296,41 @@ Polymer({ var type = /** @type {chrome.networkingPrivate.ProxySettingsType} */ ( target.value); this.set('proxy_.Type', type); - if (type == CrOnc.ProxySettingsType.MANUAL) - this.proxyModified_ = true; - else + var proxyTypeChangeIsReady; + var elementToFocus; + switch (type) { + case CrOnc.ProxySettingsType.DIRECT: + case CrOnc.ProxySettingsType.WPAD: + // No addtional values are required, send the type change. + proxyTypeChangeIsReady = true; + break; + case CrOnc.ProxySettingsType.PAC: + elementToFocus = this.$$('#pacInput'); + // If a PAC is already defined, send the type change now, otherwise wait + // until the user provides a PAC value. + proxyTypeChangeIsReady = !!this.proxy_.PAC; + break; + case CrOnc.ProxySettingsType.MANUAL: + // Manual proxy configuration includes multiple input fields, so wait + // until the 'send' button is clicked. + proxyTypeChangeIsReady = false; + elementToFocus = this.$$('#manualProxy network-proxy-input'); + break; + } + + // If the new proxy type is fully configured, send it, otherwise set + // |proxyIsUserModified_| to true so that property updates do not + // overwrite user changes. + if (proxyTypeChangeIsReady) this.sendProxyChange_(); + else + this.proxyIsUserModified_ = true; + + if (elementToFocus) { + this.async(() => { + elementToFocus.focus(); + }); + } }, /** @private */ @@ -309,7 +340,7 @@ Polymer({ /** @private */ onProxyInputChange_: function() { - this.proxyModified_ = true; + this.proxyIsUserModified_ = true; }, /** @@ -324,7 +355,7 @@ Polymer({ this.push('proxy_.ExcludeDomains', value); // Clear input. this.$.proxyExclusion.value = ''; - this.proxyModified_ = true; + this.proxyIsUserModified_ = true; }, /** @@ -333,7 +364,7 @@ Polymer({ * @private */ onProxyExclusionsChange_: function(event) { - this.proxyModified_ = true; + this.proxyIsUserModified_ = true; }, /** @private */ @@ -406,7 +437,7 @@ Polymer({ * @private */ isSaveManualProxyEnabled_: function() { - if (!this.proxyModified_) + if (!this.proxyIsUserModified_) return false; var manual = this.proxy_.Manual; var httpHost = this.get('HTTPProxy.Host', manual); diff --git a/chromium/ui/webui/resources/cr_components/chromeos/network/network_proxy_exclusions.html b/chromium/ui/webui/resources/cr_components/chromeos/network/network_proxy_exclusions.html index f574252c285..4438899755c 100644 --- a/chromium/ui/webui/resources/cr_components/chromeos/network/network_proxy_exclusions.html +++ b/chromium/ui/webui/resources/cr_components/chromeos/network/network_proxy_exclusions.html @@ -9,7 +9,7 @@ <template> <style include="network-shared cr-hidden-style iron-flex"> iron-icon { - @apply(--cr-actionable); + @apply --cr-actionable; margin: 5px; } diff --git a/chromium/ui/webui/resources/cr_components/chromeos/network/network_proxy_input.html b/chromium/ui/webui/resources/cr_components/chromeos/network/network_proxy_input.html index a1104bde59f..940a9433450 100644 --- a/chromium/ui/webui/resources/cr_components/chromeos/network/network_proxy_input.html +++ b/chromium/ui/webui/resources/cr_components/chromeos/network/network_proxy_input.html @@ -36,12 +36,12 @@ <div id="container"> <div id="label">[[label]]</div> <paper-input-container id="host" no-label-float> - <input is="iron-input" bind-value="{{value.Host}}" + <input is="iron-input" bind-value="{{value.Host}}" slot="input" disabled="[[!editable]]" on-change="onValueChange_"> </paper-input-container> <div>[[i18n('networkProxyPort')]]</div> <paper-input-container id="port" no-label-float> - <input is="iron-input" bind-value="{{value.Port}}" + <input is="iron-input" bind-value="{{value.Port}}" slot="input" disabled="[[!editable]]" on-change="onValueChange_"> </paper-input-container> </div> diff --git a/chromium/ui/webui/resources/cr_components/chromeos/network/network_proxy_input.js b/chromium/ui/webui/resources/cr_components/chromeos/network/network_proxy_input.js index 63609b074ce..cb22d24ed38 100644 --- a/chromium/ui/webui/resources/cr_components/chromeos/network/network_proxy_input.js +++ b/chromium/ui/webui/resources/cr_components/chromeos/network/network_proxy_input.js @@ -43,6 +43,10 @@ Polymer({ }, }, + focus: function() { + this.$$('input').focus(); + }, + /** * Event triggered when an input value changes. * @private diff --git a/chromium/ui/webui/resources/cr_components/chromeos/network/network_shared_css.html b/chromium/ui/webui/resources/cr_components/chromeos/network/network_shared_css.html index 3d6b9eee8d8..7c2deb92100 100644 --- a/chromium/ui/webui/resources/cr_components/chromeos/network/network_shared_css.html +++ b/chromium/ui/webui/resources/cr_components/chromeos/network/network_shared_css.html @@ -19,7 +19,7 @@ } .property-box { - @apply(--cr-section); + @apply --cr-section; border-top: none; min-height: var(--cr-section-min-height); padding: 0; @@ -59,7 +59,7 @@ } .secondary { - @apply(--cr-secondary-text); + @apply --cr-secondary-text; } paper-input-container { diff --git a/chromium/ui/webui/resources/cr_components/chromeos/quick_unlock/compiled_resources2.gyp b/chromium/ui/webui/resources/cr_components/chromeos/quick_unlock/compiled_resources2.gyp new file mode 100644 index 00000000000..eff59d15d7c --- /dev/null +++ b/chromium/ui/webui/resources/cr_components/chromeos/quick_unlock/compiled_resources2.gyp @@ -0,0 +1,16 @@ +# Copyright 2018 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +{ + 'targets': [ + { + 'target_name': 'pin_keyboard', + 'dependencies': [ + '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior', + '<(DEPTH)/third_party/polymer/v1_0/components-chromium/paper-button/compiled_resources2.gyp:paper-button-extracted', + '<(DEPTH)/third_party/polymer/v1_0/components-chromium/paper-input/compiled_resources2.gyp:paper-input-extracted', + ], + 'includes': ['../../../../../../third_party/closure_compiler/compile_js2.gypi'], + }, + ], +} diff --git a/chromium/ui/webui/resources/cr_components/chromeos/quick_unlock/pin_keyboard.html b/chromium/ui/webui/resources/cr_components/chromeos/quick_unlock/pin_keyboard.html new file mode 100644 index 00000000000..ad554340880 --- /dev/null +++ b/chromium/ui/webui/resources/cr_components/chromeos/quick_unlock/pin_keyboard.html @@ -0,0 +1,266 @@ +<!-- TODO(crbug.com/603217): Use i18n instead of string literals. Figure out + what i18n to use for keypad, ie, does 1 ABC make + sense in every scenario? --> + +<link rel="import" href="chrome://resources/html/polymer.html"> + +<link rel="import" href="chrome://resources/cr_elements/icons.html"> +<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> +<link rel="import" href="chrome://resources/html/i18n_behavior.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/iron-iconset-svg/iron-iconset-svg.html"> + +<iron-iconset-svg name="pin-keyboard" size="24"> + <svg> + <defs> + <!-- + Inlined from Polymer's iron-icons to avoid importing everything. + See http://goo.gl/Y1OdAq for instructions on adding additional icons. + --> + <g id="arrow-forward"> + <path d="M12 4l-1.41 1.41L16.17 11H4v2h12.17l-5.58 5.59L12 20l8-8z"> + </path> + </g> + <g id="backspace"> + <path d="M22 3H7c-.69 0-1.23.35-1.59.88L0 12l5.41 8.11c.36.53.9.89 1.59.89h15c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-3 12.59L17.59 17 14 13.41 10.41 17 9 15.59 12.59 12 9 8.41 10.41 7 14 10.59 17.59 7 19 8.41 15.41 12 19 15.59z"> + </g> + </defs> + </svg> +</iron-iconset-svg> + +<dom-module id="pin-keyboard"> + <template> + <style include="cr-shared-style"> + :host { + outline: none; + } + + #root { + direction: ltr; + display: block; + } + + .row { + display: flex; + } + + :host([enable-password]) #pinInputDiv { + display: none; + } + + .bottom-row { + margin-bottom: 6px; + } + + .backspace-button-container { + position: relative; + } + + .backspace-button-container paper-ripple { + left: var(--pin-keyboard-backspace-paper-ripple-offset, 0); + top: var(--pin-keyboard-backspace-paper-ripple-offset, 0); + } + + .digit-button { + align-items: center; + background: none; + border-radius: 0; + box-sizing: border-box; + color: #000; + display: flex; + flex-direction: column; + height: 48px; + justify-content: center; + margin: 0; + min-height: 48px; + min-width: 48px; + opacity: 0.87px; + width: 60px; + + @apply --pin-keyboard-digit-button; + } + + .digit-button.backspace-button { + color: var(--pin-keyboard-backspace-color, #000); + left: 0; + opacity: var(--pin-keyboard-backspace-opacity, --dark-primary-opacity); + padding: 14px; + position: absolute; + top: 0; + } + + .digit-button.backspace-button:not([has-content]) { + opacity: 0.34; + } + + .digit-button inner-text { + display: flex; + flex-direction: column; + font-family: 'Roboto'; + } + + .letter { + color: var(--pin-keyboard-letter-color, --paper-blue-grey-700); + font-size: 9px; + margin-top: 4px; + } + + .number { + color: var(--pin-keyboard-number-color, --paper-blue-grey-700); + font-size: 20px; + height: 52px; + } + + paper-ripple { + border-radius: 100px; + color: #000; + height: 48px; + left: 6px; + width: 48px; + + @apply --pin-keyboard-paper-ripple; + } + + #pinInput { + background-color: white; + border: 0; + box-sizing: border-box; + font-face: Roboto-Regular; + font-size: 13px; + height: 43px; + left: 0; + opacity: var(--dark-secondary-opacity); + outline: 0; + position: relative; + text-align: center; + width: 180px; + + --paper-input-container-input: { + caret-color: var(--paper-input-container-focus-color); + } + } + + #pinInput[has-content] { + opacity: var(--dark-primary-opacity); + } + + #pinInput[is-input-rtl] { + direction: rtl; + } + + #pinInput[type=number]::-webkit-inner-spin-button, + #pinInput[type=number]::-webkit-outer-spin-button { + -webkit-appearance: none; + margin: 0; + } + + :host([has-error]) #pinInput { + --paper-input-container-focus-color: var(--paper-red-500); + } + + /* Ensure that all children of paper-button do not consume events. This + * simplifies the event handler code. */ + paper-button * { + pointer-events: none; + } + </style> + + <div id="root" on-contextmenu="onContextMenu_"> + <div id="pinInputDiv" class="row"> + <paper-input id="pinInput" type="password" no-label-float + value="[[value]]" + is-input-rtl$="[[isInputRtl_(value)]]" + has-content$="[[hasInput_(value)]]" + label="[[getInputPlaceholder_(enablePassword)]]" + on-keydown="onInputKeyDown_"> + </paper-input> + </div> + <slot select="[problem]"></slot> + <div class="row"> + <paper-button class="digit-button" on-tap="onNumberTap_" value="1" + noink> + <inner-text class="number">[[i18n('pinKeyboard1')]]</inner-text> + <paper-ripple> + </paper-button> + <paper-button class="digit-button" on-tap="onNumberTap_" value="2" + noink> + <inner-text class="number">[[i18n('pinKeyboard2')]]</inner-text> + <inner-text class="letter">ABC</inner-text> + <paper-ripple> + </paper-button> + <paper-button class="digit-button" on-tap="onNumberTap_" value="3" + noink> + <inner-text class="number">[[i18n('pinKeyboard3')]]</inner-text> + <inner-text class="letter">DEF</inner-text> + <paper-ripple> + </paper-button> + </div> + <div class="row"> + <paper-button class="digit-button" on-tap="onNumberTap_" value="4" + noink> + <inner-text class="number">[[i18n('pinKeyboard4')]]</inner-text> + <inner-text class="letter">GHI</inner-text> + <paper-ripple> + </paper-button> + <paper-button class="digit-button" on-tap="onNumberTap_" value="5" + noink> + <inner-text class="number">[[i18n('pinKeyboard5')]]</inner-text> + <inner-text class="letter">JKL</inner-text> + <paper-ripple> + </paper-button> + <paper-button class="digit-button" on-tap="onNumberTap_" value="6" + noink> + <inner-text class="number">[[i18n('pinKeyboard6')]]</inner-text> + <inner-text class="letter">MNO</inner-text> + <paper-ripple> + </paper-button> + </div> + <div class="row"> + <paper-button class="digit-button" on-tap="onNumberTap_" value="7" + noink> + <inner-text class="number">[[i18n('pinKeyboard7')]]</inner-text> + <inner-text class="letter">PQRS</inner-text> + <paper-ripple> + </paper-button> + <paper-button class="digit-button" on-tap="onNumberTap_" value="8" + noink> + <inner-text class="number">[[i18n('pinKeyboard8')]]</inner-text> + <inner-text class="letter">TUV</inner-text> + <paper-ripple> + </paper-button> + <paper-button class="digit-button" on-tap="onNumberTap_" value="9" + noink> + <inner-text class="number">[[i18n('pinKeyboard9')]]</inner-text> + <inner-text class="letter">WXYZ</inner-text> + <paper-ripple> + </paper-button> + </div> + <div class="row bottom-row"> + <div class="digit-button"></div> + <paper-button class="digit-button" on-tap="onNumberTap_" value="0" + noink> + <inner-text class="number">[[i18n('pinKeyboard0')]]</inner-text> + <inner-text class="letter">+</inner-text> + <paper-ripple> + </paper-button> + <div class="backspace-button-container"> + <paper-icon-button class="digit-button backspace-button" + has-content$="[[hasInput_(value)]]" + icon="pin-keyboard:backspace" + on-pointerdown="onBackspacePointerDown_" + on-pointerout="clearAndReset_" + on-pointerup="onBackspacePointerUp_" + aria-label="[[i18n('pinKeyboardDeleteAccessibleName')]]" + noink> + </paper-icon-button> + <paper-ripple> + </div> + </div> + </div> + </template> + <script src="pin_keyboard.js"></script> +</dom-module> diff --git a/chromium/ui/webui/resources/cr_components/chromeos/quick_unlock/pin_keyboard.js b/chromium/ui/webui/resources/cr_components/chromeos/quick_unlock/pin_keyboard.js new file mode 100644 index 00000000000..2ebcaaf4724 --- /dev/null +++ b/chromium/ui/webui/resources/cr_components/chromeos/quick_unlock/pin_keyboard.js @@ -0,0 +1,416 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview + * 'pin-keyboard' is a keyboard that can be used to enter PINs or more generally + * numeric values. + * + * Properties: + * value: The value of the PIN keyboard. Writing to this property will adjust + * the PIN keyboard's value. + * + * Events: + * pin-change: Fired when the PIN value has changed. The PIN is available at + * event.detail.pin. + * submit: Fired when the PIN is submitted. The PIN is available at + * event.detail.pin. + * + * Example: + * <pin-keyboard on-pin-change="onPinChange" on-submit="onPinSubmit"> + * </pin-keyboard> + */ + +(function() { + +/** + * Once auto backspace starts, the time between individual backspaces. + * @type {number} + * @const + */ +var REPEAT_BACKSPACE_DELAY_MS = 150; + +/** + * How long the backspace button must be held down before auto backspace + * starts. + * @type {number} + * @const + */ +var INITIAL_BACKSPACE_DELAY_MS = 500; + +/** + * The key codes of the keys allowed to be used on the pin input, in addition to + * number keys. Currently we allow backspace(8), tab(9), left(37) and right(39). + * @type {Array<number>} + * @const + */ +var PIN_INPUT_ALLOWED_NON_NUMBER_KEY_CODES = [8, 9, 37, 39]; + +Polymer({ + is: 'pin-keyboard', + + behaviors: [ + I18nBehavior, + ], + + properties: { + /** + * Whether or not the keyboard's input element should be numerical + * or password. + * @private + */ + enablePassword: { + type: Boolean, + value: false, + }, + + /** + * The password element the pin keyboard is associated with. If this is not + * set, then a default input element is shown and used. + * @type {?Element} + * @private + */ + passwordElement: { + type: Object, + value: function() { + return this.$.pinInput.inputElement; + }, + observer: 'onPasswordElementAttached_', + }, + + /** + * The intervalID used for the backspace button set/clear interval. + * @private + */ + repeatBackspaceIntervalId_: { + type: Number, + value: 0, + }, + + /** + * The timeoutID used for the auto backspace. + * @private + */ + startAutoBackspaceId_: { + type: Number, + value: 0, + }, + + /** + * Whether or not to show the default pin input. + * @private + */ + showPinInput_: { + type: Boolean, + value: false, + }, + + /** + * The value stored in the keyboard's input element. + * @private + */ + value: { + type: String, + notify: true, + value: '', + observer: 'onPinValueChange_', + }, + }, + + /** + * Called when a password element is attached to the pin keyboard. + * @param {HTMLInputElement} inputElement The PIN keyboard's input element. + * @private + */ + onPasswordElementAttached_: function(inputElement) { + this.showPinInput_ = inputElement == this.$.pinInput.inputElement; + inputElement.addEventListener('input', this.handleInputChanged_.bind(this)); + }, + + /** + * Called when the user uses the keyboard to enter a value into the input + * element. + * @param {Event} event The event object. + * @private + */ + handleInputChanged_: function(event) { + this.value = event.target.value; + }, + + /** + * Gets the selection start of the input field. + * @type {number} + * @private + */ + get selectionStart_() { + return this.passwordElement.selectionStart; + }, + + /** + * Gets the selection end of the input field. + * @type {number} + * @private + */ + get selectionEnd_() { + return this.passwordElement.selectionEnd; + }, + + /** + * Sets the selection start of the input field. + * @param {number} start The new selection start of the input element. + * @private + */ + set selectionStart_(start) { + this.passwordElement.selectionStart = start; + }, + + /** + * Sets the selection end of the input field. + * @param {number} end The new selection end of the input element. + * @private + */ + set selectionEnd_(end) { + this.passwordElement.selectionEnd = end; + }, + + /** + * Transfers blur to the input element. + */ + blur: function() { + this.passwordElement.blur(); + }, + + /** + * Transfers focus to the input element. This should not bring up the virtual + * keyboard, if it is enabled. After focus, moves the caret to the correct + * location if specified. + * @param {number=} opt_selectionStart + * @param {number=} opt_selectionEnd + */ + focus: function(opt_selectionStart, opt_selectionEnd) { + setTimeout(function() { + this.passwordElement.focus(); + this.selectionStart_ = opt_selectionStart || 0; + this.selectionEnd_ = opt_selectionEnd || 0; + }.bind(this), 0); + }, + + /** + * Called when a keypad number has been tapped. + * @param {Event} event The event object. + * @private + */ + onNumberTap_: function(event) { + var numberValue = event.target.getAttribute('value'); + + // Add the number where the caret is, then update the selection range of the + // input element. + var selectionStart = this.selectionStart_; + this.value = this.value.substring(0, this.selectionStart_) + numberValue + + this.value.substring(this.selectionEnd_); + + // If a number button is clicked, we do not want to switch focus to the + // button, therefore we transfer focus back to the input, but if a number + // button is tabbed into, it should keep focus, so users can use tab and + // spacebar/return to enter their PIN. + if (!event.target.receivedFocusFromKeyboard) + this.focus(selectionStart + 1, selectionStart + 1); + event.stopImmediatePropagation(); + }, + + /** Fires a submit event with the current PIN value. */ + firePinSubmitEvent_: function() { + this.fire('submit', {pin: this.value}); + }, + + /** + * Fires an update event with the current PIN value. The event will only be + * fired if the PIN value has actually changed. + * @param {string} value + * @param {string} previous + */ + onPinValueChange_: function(value, previous) { + if (value != previous) { + this.passwordElement.value = this.value; + this.fire('pin-change', {pin: value}); + } + }, + + /** + * Called when the user wants to erase the last character of the entered + * PIN value. + * @private + */ + onPinClear_: function() { + // If the input is shown, clear the text based on the caret location or + // selected region of the input element. If it is just a caret, remove the + // character in front of the caret. + var selectionStart = this.selectionStart_; + var selectionEnd = this.selectionEnd_; + if (selectionStart == selectionEnd && selectionStart) + selectionStart--; + + this.value = this.value.substring(0, selectionStart) + + this.value.substring(selectionEnd); + + // Move the caret or selected region to the correct new place. + this.selectionStart_ = selectionStart; + this.selectionEnd_ = selectionStart; + }, + + /** + * Called when the user presses or touches the backspace button. Starts a + * timer which starts an interval to repeatedly backspace the pin value until + * the interval is cleared. + * @param {Event} event The event object. + * @private + */ + onBackspacePointerDown_: function(event) { + this.startAutoBackspaceId_ = setTimeout(function() { + this.repeatBackspaceIntervalId_ = + setInterval(this.onPinClear_.bind(this), REPEAT_BACKSPACE_DELAY_MS); + }.bind(this), INITIAL_BACKSPACE_DELAY_MS); + + if (!event.target.receivedFocusFromKeyboard) + this.focus(this.selectionStart_, this.selectionEnd_); + event.stopImmediatePropagation(); + }, + + /** + * Helper function which clears the timer / interval ids and resets them. + * @private + */ + clearAndReset_: function() { + clearInterval(this.repeatBackspaceIntervalId_); + this.repeatBackspaceIntervalId_ = 0; + clearTimeout(this.startAutoBackspaceId_); + this.startAutoBackspaceId_ = 0; + }, + + /** + * Called when the user unpresses or untouches the backspace button. Stops the + * interval callback and fires a backspace event if there is no interval + * running. + * @param {Event} event The event object. + * @private + */ + onBackspacePointerUp_: function(event) { + // If an interval has started, do not fire event on pointer up. + if (!this.repeatBackspaceIntervalId_) + this.onPinClear_(); + this.clearAndReset_(); + + // Since on-down gives the input element focus, the input element will + // already have focus when on-up is called. This will actually bring up the + // virtual keyboard, even if focus() is wrapped in a setTimeout. Blur the + // input element first to workaround this. + this.blur(); + if (!event.target.receivedFocusFromKeyboard) + this.focus(this.selectionStart_, this.selectionEnd_); + event.stopImmediatePropagation(); + }, + + /** + * Helper function to check whether a given |event| should be processed by + * the numeric only input. + * @param {Event} event The event object. + * @private + */ + isValidEventForInput_: function(event) { + // Valid if the key is a number, and shift is not pressed. + if ((event.keyCode >= 48 && event.keyCode <= 57) && !event.shiftKey) + return true; + + // Valid if the key is one of the selected special keys defined in + // |PIN_INPUT_ALLOWED_NON_NUMBER_KEY_CODES|. + if (PIN_INPUT_ALLOWED_NON_NUMBER_KEY_CODES.indexOf(event.keyCode) > -1) + return true; + + // Valid if the key is CTRL+A to allow users to quickly select the entire + // PIN. + if (event.keyCode == 65 && event.ctrlKey) + return true; + + // The rest of the keys are invalid. + return false; + }, + + /** + * Called when a key event is pressed while the input element has focus. + * @param {Event} event The event object. + * @private + */ + onInputKeyDown_: function(event) { + // Up/down pressed, swallow the event to prevent the input value from + // being incremented or decremented. + if (event.keyCode == 38 || event.keyCode == 40) { + event.preventDefault(); + return; + } + + // Enter pressed. + if (event.keyCode == 13) { + this.firePinSubmitEvent_(); + event.preventDefault(); + return; + } + + // Do not pass events that are not numbers or special keys we care about. We + // use this instead of input type number because there are several issues + // with input type number, such as no selectionStart/selectionEnd and + // entered non numbers causes the caret to jump to the left. + if (!this.isValidEventForInput_(event)) { + event.preventDefault(); + return; + } + }, + + /** + * Disables the backspace button if nothing is entered. + * @param {string} value + * @private + */ + hasInput_: function(value) { + return value.length > 0; + }, + + /** + * Computes the value of the pin input placeholder. + * @param {boolean} enablePassword + * @private + */ + getInputPlaceholder_: function(enablePassword) { + return enablePassword ? this.i18n('pinKeyboardPlaceholderPinPassword') : + this.i18n('pinKeyboardPlaceholderPin'); + }, + + /** + * Computes the direction of the pin input. + * @param {string} password + * @private + */ + isInputRtl_: function(password) { + // +password will convert a string to a number or to NaN if that's not + // possible. Number.isInteger will verify the value is not a NaN and that it + // does not contain decimals. + // This heuristic will fail for inputs like '1.0'. + // + // Since we still support users entering their passwords through the PIN + // keyboard, we swap the input box to rtl when we think it is a password + // (just numbers), if the document direction is rtl. + return (document.dir == 'rtl') && !Number.isInteger(+password); + }, + + /** + * Catch and stop propagation of context menu events since we the backspace + * button can be held down on touch. + * @param {!Event} e + * @private + */ + onContextMenu_: function(e) { + e.preventDefault(); + e.stopPropagation(); + }, +}); +})(); diff --git a/chromium/ui/webui/resources/cr_components/cr_components_resources.grdp b/chromium/ui/webui/resources/cr_components/cr_components_resources.grdp index 1e198676684..46a47e79eac 100644 --- a/chromium/ui/webui/resources/cr_components/cr_components_resources.grdp +++ b/chromium/ui/webui/resources/cr_components/cr_components_resources.grdp @@ -208,4 +208,15 @@ type="chrome_html" compress="gzip" /> </if> + <if expr="chromeos"> + <!-- Shared between settings and OOBE, which is not vulcanized. --> + <structure name="IDR_WEBUI_CHROMEOS_QUICK_UNLOCK_PIN_KEYBOARD_HTML" + file="cr_components/chromeos/quick_unlock/pin_keyboard.html" + type="chrome_html" + compress="gzip" /> + <structure name="IDR_WEBUI_CHROMEOS_QUICK_UNLOCK_PIN_KEYBOARD_JS" + file="cr_components/chromeos/quick_unlock/pin_keyboard.js" + type="chrome_html" + compress="gzip" /> + </if> </grit-part> diff --git a/chromium/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_camera.js b/chromium/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_camera.js index 67e7b727be0..3e6255cccb1 100644 --- a/chromium/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_camera.js +++ b/chromium/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_camera.js @@ -77,6 +77,7 @@ Polymer({ this.$.cameraVideo.addEventListener('canplay', function() { this.$.userImageStreamCrop.classList.add('preview'); this.cameraOnline_ = true; + this.focusTakePhotoButton(); }.bind(this)); this.startCamera(); }, diff --git a/chromium/ui/webui/resources/cr_elements/chromeos/network/cr_network_list_item.js b/chromium/ui/webui/resources/cr_elements/chromeos/network/cr_network_list_item.js index e604c76d55e..2b878fd620d 100644 --- a/chromium/ui/webui/resources/cr_elements/chromeos/network/cr_network_list_item.js +++ b/chromium/ui/webui/resources/cr_elements/chromeos/network/cr_network_list_item.js @@ -78,8 +78,7 @@ Polymer({ if (connectionState == this.connectionState_) return; this.connectionState_ = connectionState; - if (connectionState == CrOnc.ConnectionState.CONNECTED) - this.fire('network-connected', this.networkState); + this.fire('network-connect-changed', this.networkState); }, /** @@ -104,9 +103,7 @@ Polymer({ * @private */ isStateTextVisible_: function() { - return !!this.networkState && - (this.networkState.ConnectionState != - CrOnc.ConnectionState.NOT_CONNECTED); + return !!this.networkState && !!this.getNetworkStateText_(); }, /** @@ -115,16 +112,20 @@ Polymer({ * @private */ getNetworkStateText_: function() { - if (!this.isStateTextVisible_()) + if (!this.networkState) return ''; - var state = this.networkState.ConnectionState; - // For Cellular, an empty ConnectionState indicates that the device is - // still initializing. - if (!state && this.networkState.Type == CrOnc.Type.CELLULAR) - return CrOncStrings.networkListItemInitializing; - if (state == CrOnc.ConnectionState.CONNECTED) + var connectionState = this.networkState.ConnectionState; + if (this.networkState.Type == CrOnc.Type.CELLULAR) { + // For Cellular, an empty ConnectionState indicates that the device is + // still initializing. + if (!connectionState) + return CrOncStrings.networkListItemInitializing; + if (this.networkState.Cellular && this.networkState.Cellular.Scanning) + return CrOncStrings.networkListItemScanning; + } + if (connectionState == CrOnc.ConnectionState.CONNECTED) return CrOncStrings.networkListItemConnected; - if (state == CrOnc.ConnectionState.CONNECTING) + if (connectionState == CrOnc.ConnectionState.CONNECTING) return CrOncStrings.networkListItemConnecting; return ''; }, diff --git a/chromium/ui/webui/resources/cr_elements/chromeos/network/cr_network_select.html b/chromium/ui/webui/resources/cr_elements/chromeos/network/cr_network_select.html index 8fea14ce971..def03d72acb 100644 --- a/chromium/ui/webui/resources/cr_elements/chromeos/network/cr_network_select.html +++ b/chromium/ui/webui/resources/cr_elements/chromeos/network/cr_network_select.html @@ -15,7 +15,6 @@ </style> <cr-network-list id="networkList" on-selected="onNetworkListItemSelected_" - on-network-connected="onNetworkConnected_" networks="[[networkStateList_]]" custom-items="[[customItems]]" show-buttons="[[showButtons]]" no-bottom-scroll-border="[[noBottomScrollBorder]]"> diff --git a/chromium/ui/webui/resources/cr_elements/chromeos/network/cr_network_select.js b/chromium/ui/webui/resources/cr_elements/chromeos/network/cr_network_select.js index 2a3afa75347..26a37dc478f 100644 --- a/chromium/ui/webui/resources/cr_elements/chromeos/network/cr_network_select.js +++ b/chromium/ui/webui/resources/cr_elements/chromeos/network/cr_network_select.js @@ -54,10 +54,16 @@ Polymer({ return []; }, }, + + /** + * Cached Cellular Device state or undefined if there is no Cellular device. + * @private {!CrOnc.DeviceStateProperties|undefined} deviceState + */ + cellularDeviceState_: Object, }, - /** @type {string} */ - defaultStateGuid_: '', + /** @type {!CrOnc.NetworkStateProperties|undefined} */ + defaultNetworkState_: undefined, focus: function() { this.$.networkList.focus(); @@ -124,60 +130,76 @@ Polymer({ * @private */ getDeviceStatesCallback_: function(deviceStates) { - var uninitializedCellular = deviceStates.find(function(device) { - return device.Type == CrOnc.Type.CELLULAR && - device.State == CrOnc.DeviceState.UNINITIALIZED; - }); - this.getNetworkStates_(uninitializedCellular); - }, - - /** - * @param {!CrOnc.DeviceStateProperties|undefined} uninitializedCellular - * A cellular device state to pass to |getNetworksCallback_| or undefined. - */ - getNetworkStates_: function(uninitializedCellular) { var filter = { networkType: chrome.networkingPrivate.NetworkType.ALL, visible: true, configured: false }; - chrome.networkingPrivate.getNetworks(filter, function(states) { - this.getNetworksCallback_(uninitializedCellular, states); + chrome.networkingPrivate.getNetworks(filter, function(networkStates) { + this.getNetworksCallback_(deviceStates, networkStates); }.bind(this)); }, /** - * @param {!CrOnc.DeviceStateProperties|undefined} uninitializedCellular - * If defined, prepends a Cellular state with no ConnectionState to - * represent an uninitialized Cellular device. - * @param {!Array<!CrOnc.NetworkStateProperties>} states + * @param {!Array<!CrOnc.DeviceStateProperties>} deviceStates + * @param {!Array<!CrOnc.NetworkStateProperties>} networkStates * @private */ - getNetworksCallback_: function(uninitializedCellular, states) { - if (uninitializedCellular) { - states.unshift({ - GUID: '', - Type: uninitializedCellular.Type, - }); + getNetworksCallback_: function(deviceStates, networkStates) { + this.cellularDeviceState_ = deviceStates.find(function(device) { + return device.Type == CrOnc.Type.CELLULAR; + }); + if (this.cellularDeviceState_) + this.ensureCellularNetwork_(networkStates); + this.networkStateList_ = networkStates; + var defaultNetwork; + if (networkStates.length > 0) { + // Handle an edge case where Ethernet is connecting. + if (networkStates.length > 1 && + networkStates[0].ConnectionState == + CrOnc.ConnectionState.CONNECTING && + networkStates[1].ConnectionState == CrOnc.ConnectionState.CONNECTED) { + defaultNetwork = networkStates[1]; + } else { + defaultNetwork = networkStates[0]; + } + } else if (!this.defaultNetworkState_) { + return; // No change } - this.networkStateList_ = states; - var defaultState = (this.networkStateList_.length > 0 && - this.networkStateList_[0].ConnectionState == - CrOnc.ConnectionState.CONNECTED) ? - this.networkStateList_[0] : - null; - - if (!defaultState && !this.defaultStateGuid_) - return; - - // defaultState.GUID must never be empty. - assert(!defaultState || defaultState.GUID); + if (defaultNetwork && this.defaultNetworkState_ && + defaultNetwork.GUID == this.defaultNetworkState_.GUID && + defaultNetwork.ConnectionState == + this.defaultNetworkState_.ConnectionState) { + return; // No change to network or ConnectionState + } + this.defaultNetworkState_ = + /** @type {!CrOnc.NetworkStateProperties|undefined} */ ( + Object.assign({}, defaultNetwork)); + this.fire('default-network-changed', defaultNetwork); + }, - if (defaultState && defaultState.GUID == this.defaultStateGuid_) + /** + * Modifies |networkStates| to include a cellular network if none exists. + * @param {!Array<!CrOnc.NetworkStateProperties>} networkStates + * @private + */ + ensureCellularNetwork_: function(networkStates) { + if (networkStates.find(function(network) { + return network.Type == CrOnc.Type.CELLULAR; + })) { return; - - this.defaultStateGuid_ = defaultState ? defaultState.GUID : ''; - this.fire('default-network-changed', defaultState); + } + // Add a Cellular network after the Ethernet network if it exists. + var idx = networkStates.length > 0 && + networkStates[0].Type == CrOnc.Type.ETHERNET ? + 1 : + 0; + var cellular = { + GUID: '', + Type: CrOnc.Type.CELLULAR, + Cellular: {Scanning: this.cellularDeviceState_.Scanning} + }; + networkStates.splice(idx, 0, cellular); }, /** @@ -194,6 +216,18 @@ Polymer({ return; } + // NOTE: This isn't used by OOBE (no handle-network-item-selected). + // TODO(stevenjb): Remove custom OOBE handling. + if (state.Type == CrOnc.Type.CELLULAR && this.cellularDeviceState_) { + var cellularDevice = this.cellularDeviceState_; + // If Cellular is not enabled and not SIM locked, enable Cellular. + if (cellularDevice.State != CrOnc.DeviceState.ENABLED && + (!cellularDevice.SIMLockStatus || + !cellularDevice.SIMLockStatus.LockType)) { + chrome.networkingPrivate.enableNetworkType(CrOnc.Type.CELLULAR); + } + } + if (state.ConnectionState != CrOnc.ConnectionState.NOT_CONNECTED) return; @@ -203,14 +237,4 @@ Polymer({ console.error('networkingPrivate.startConnect error: ' + lastError); }); }, - - /** - * Event triggered when a cr-network-list-item becomes connected. - * @param {!{target: HTMLElement, detail: !CrOnc.NetworkStateProperties}} e - * @private - */ - onNetworkConnected_: function(e) { - if (e.detail && e.detail.GUID != this.defaultStateGuid_) - this.refreshNetworks(); - }, }); diff --git a/chromium/ui/webui/resources/cr_elements/chromeos/network/cr_onc_types.js b/chromium/ui/webui/resources/cr_elements/chromeos/network/cr_onc_types.js index 5a7ed921c7b..b6671b12291 100644 --- a/chromium/ui/webui/resources/cr_elements/chromeos/network/cr_onc_types.js +++ b/chromium/ui/webui/resources/cr_elements/chromeos/network/cr_onc_types.js @@ -30,6 +30,7 @@ * networkListItemConnecting: string, * networkListItemConnectingTo: string, * networkListItemInitializing: string, + * networkListItemScanning: string, * networkListItemNotConnected: string, * networkListItemNoNetwork: string, * vpnNameTemplate: string, @@ -498,7 +499,8 @@ CrOnc.setValidStaticIPConfig = function(config, properties) { * @param {!chrome.networkingPrivate.NetworkConfigProperties} properties * The ONC property dictionary to modify. * @param {string} key The property key which may be nested, e.g. 'Foo.Bar'. - * @param {!CrOnc.NetworkPropertyType} value The property value to set. + * @param {!CrOnc.NetworkPropertyType|undefined} value The property value to + * set. If undefined the property will be removed. */ CrOnc.setProperty = function(properties, key, value) { while (true) { @@ -511,7 +513,10 @@ CrOnc.setProperty = function(properties, key, value) { properties = properties[keyComponent]; key = key.substr(index + 1); } - properties[key] = value; + if (value === undefined) + delete properties[key]; + else + properties[key] = value; }; /** @@ -519,7 +524,8 @@ CrOnc.setProperty = function(properties, key, value) { * @param {!chrome.networkingPrivate.NetworkConfigProperties} properties The * ONC properties to set. properties.Type must be set already. * @param {string} key The type property key, e.g. 'AutoConnect'. - * @param {!CrOnc.NetworkPropertyType} value The property value to set. + * @param {!CrOnc.NetworkPropertyType|undefined} value The property value to + * set. If undefined the property will be removed. */ CrOnc.setTypeProperty = function(properties, key, value) { if (properties.Type == undefined) { diff --git a/chromium/ui/webui/resources/cr_elements/cr_action_menu/compiled_resources2.gyp b/chromium/ui/webui/resources/cr_elements/cr_action_menu/compiled_resources2.gyp index c3698cf0147..5b542f023a5 100644 --- a/chromium/ui/webui/resources/cr_elements/cr_action_menu/compiled_resources2.gyp +++ b/chromium/ui/webui/resources/cr_elements/cr_action_menu/compiled_resources2.gyp @@ -9,6 +9,7 @@ '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:assert', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:util', '<(DEPTH)/ui/webui/resources/js/cr/ui/compiled_resources2.gyp:focus_without_ink', + '<(EXTERNS_GYP):pending', ], 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], }, diff --git a/chromium/ui/webui/resources/cr_elements/cr_action_menu/cr_action_menu.html b/chromium/ui/webui/resources/cr_elements/cr_action_menu/cr_action_menu.html index 05ca3cc16ce..70acc097ff2 100644 --- a/chromium/ui/webui/resources/cr_elements/cr_action_menu/cr_action_menu.html +++ b/chromium/ui/webui/resources/cr_elements/cr_action_menu/cr_action_menu.html @@ -21,7 +21,7 @@ background-color: transparent; } - :host ::content .dropdown-item { + :host ::slotted(.dropdown-item) { background: none; border: none; border-radius: 0; @@ -35,20 +35,20 @@ width: 100%; } - :host ::content .dropdown-item:not([hidden]) { + :host ::slotted(.dropdown-item:not([hidden])) { align-items: center; display: flex; } - :host ::content .dropdown-item[disabled] { + :host ::slotted(.dropdown-item[disabled]) { opacity: 0.65; } - :host ::content .dropdown-item:not([disabled]) { - @apply(--cr-actionable); + :host ::slotted(.dropdown-item:not([disabled])) { + @apply --cr-actionable; } - :host ::content .dropdown-item:focus { + :host ::slotted(.dropdown-item:focus) { background-color: var(--paper-grey-300); outline: none; } @@ -58,7 +58,7 @@ } </style> <div class="item-wrapper" tabindex="-1" role="menu"> - <content select=".dropdown-item,hr" id="contentNode"></content> + <slot name="item" id="contentNode"></slot> </div> </template> <script src="cr_action_menu.js"></script> diff --git a/chromium/ui/webui/resources/cr_elements/cr_action_menu/cr_action_menu.js b/chromium/ui/webui/resources/cr_elements/cr_action_menu/cr_action_menu.js index d524c5433cf..31613726bcc 100644 --- a/chromium/ui/webui/resources/cr_elements/cr_action_menu/cr_action_menu.js +++ b/chromium/ui/webui/resources/cr_elements/cr_action_menu/cr_action_menu.js @@ -4,6 +4,22 @@ /** * @typedef {{ + * top: (number|undefined), + * left: (number|undefined), + * width: (number|undefined), + * height: (number|undefined), + * anchorAlignmentX: (number|undefined), + * anchorAlignmentY: (number|undefined), + * minX: (number|undefined), + * minY: (number|undefined), + * maxX: (number|undefined), + * maxY: (number|undefined), + * }} + */ +var ShowAtConfig; + +/** + * @typedef {{ * top: number, * left: number, * width: (number|undefined), @@ -16,7 +32,7 @@ * maxY: (number|undefined), * }} */ -var ShowConfig; +var ShowAtPositionConfig; /** * @enum {number} @@ -81,7 +97,7 @@ function getStartPointWithAnchor( /** * @private - * @return {!ShowConfig} + * @return {!ShowAtPositionConfig} */ function getDefaultShowConfig() { var doc = document.scrollingElement; @@ -124,10 +140,25 @@ Polymer({ /** @private {?PolymerDomApi.ObserveHandle} */ contentObserver_: null, + /** @private {?ResizeObserver} */ + resizeObserver_: null, + + /** @private {?ShowAtPositionConfig} */ + lastConfig_: null, + hostAttributes: { tabindex: 0, }, + properties: { + // Setting this flag will make the menu listen for content size changes and + // reposition to its anchor accordingly. + autoReposition: { + type: Boolean, + value: false, + }, + }, + listeners: { 'keydown': 'onKeyDown_', 'mouseover': 'onMouseover_', @@ -147,6 +178,11 @@ Polymer({ Polymer.dom(this.$.contentNode).unobserveNodes(this.contentObserver_); this.contentObserver_ = null; } + + if (this.resizeObserver_) { + this.resizeObserver_.disconnect(); + this.resizeObserver_ = null; + } }, /** @@ -251,12 +287,15 @@ Polymer({ cr.ui.focusWithoutInk(assert(this.anchorElement_)); this.anchorElement_ = null; } + if (this.lastConfig_) { + this.lastConfig_ = null; + } }, /** * Shows the menu anchored to the given element. * @param {!Element} anchorElement - * @param {ShowConfig=} opt_config + * @param {ShowAtConfig=} opt_config */ showAt: function(anchorElement, opt_config) { this.anchorElement_ = anchorElement; @@ -265,7 +304,7 @@ Polymer({ this.anchorElement_.scrollIntoViewIfNeeded(); var rect = this.anchorElement_.getBoundingClientRect(); - this.showAtPosition(/** @type {ShowConfig} */ (Object.assign( + this.showAtPosition(/** @type {ShowAtPositionConfig} */ (Object.assign( { top: rect.top, left: rect.left, @@ -302,7 +341,7 @@ Polymer({ * (BEFORE_END, AFTER_START), whereas centering the menu below the bottom * edge of the anchor would use (CENTER, AFTER_END). * - * @param {!ShowConfig} config + * @param {!ShowAtPositionConfig} config */ showAtPosition: function(config) { // Save the scroll position of the viewport. @@ -319,7 +358,7 @@ Polymer({ config.top += scrollTop; config.left += scrollLeft; - this.positionDialog_(/** @type {ShowConfig} */ (Object.assign( + this.positionDialog_(/** @type {ShowAtPositionConfig} */ (Object.assign( { minX: scrollLeft, minY: scrollTop, @@ -344,10 +383,11 @@ Polymer({ /** * Position the dialog using the coordinates in config. Coordinates are * relative to the top-left of the viewport when scrolled to (0, 0). - * @param {!ShowConfig} config + * @param {!ShowAtPositionConfig} config * @private */ positionDialog_: function(config) { + this.lastConfig_ = config; var c = Object.assign(getDefaultShowConfig(), config); var top = c.top; @@ -397,6 +437,17 @@ Polymer({ } }); }); + + if (this.autoReposition) { + this.resizeObserver_ = new ResizeObserver(() => { + if (this.lastConfig_) { + this.positionDialog_(this.lastConfig_); + this.fire('cr-action-menu-repositioned'); // For easier testing. + } + }); + + this.resizeObserver_.observe(this); + } }, }); })(); diff --git a/chromium/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.html b/chromium/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.html index 759fcf8b6de..68cb78ff83f 100644 --- a/chromium/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.html +++ b/chromium/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.html @@ -29,6 +29,7 @@ flex-direction: column; max-height: 100vh; overflow: auto; + @apply --cr-dialog-wrapper; } /* When needing to flex, force .body-container alone to shrink. */ @@ -49,7 +50,7 @@ :host ::slotted([slot=body]) { padding: 12px 16px; - @apply(--cr-dialog-body); + @apply --cr-dialog-body; } :host ::slotted([slot=title]) { @@ -57,7 +58,7 @@ font-size: calc(15 / 13 * 100%); line-height: 1; padding: 16px 16px; - @apply(--cr-dialog-title); + @apply --cr-dialog-title; } :host ::slotted([slot=button-container]) { @@ -84,7 +85,7 @@ min-height: 60px; /* Minimum reasonably usable height. */ overflow: auto; - @apply(--cr-dialog-body-container); + @apply --cr-dialog-body-container; } .body-container.bottom-scrollable { @@ -116,6 +117,16 @@ align-self: flex-start; margin-top: 4px; padding: 10px; /* Makes the actual icon 16x16. */ + + @apply --cr-dialog-close-image; + } + + #close:hover { + @apply --cr-dialog-close-image-hover; + } + + #close:active { + @apply --cr-dialog-close-image-active; } </style> <!-- This wrapper is necessary, such that the "pulse" animation is not diff --git a/chromium/ui/webui/resources/cr_elements/cr_expand_button/cr_expand_button.html b/chromium/ui/webui/resources/cr_elements/cr_expand_button/cr_expand_button.html index 2753d98bb65..e31345821ed 100644 --- a/chromium/ui/webui/resources/cr_elements/cr_expand_button/cr_expand_button.html +++ b/chromium/ui/webui/resources/cr_elements/cr_expand_button/cr_expand_button.html @@ -11,7 +11,7 @@ } button[is=paper-icon-button-light] { - @apply(--cr-paper-icon-button-margin); + @apply --cr-paper-icon-button-margin; } #outer { @@ -26,8 +26,8 @@ <div id="outer" on-tap="toggleExpand_"> <div id="label" on-tap="toggleExpand_"><slot></slot></div> <button is="paper-icon-button-light" class$="[[iconName_(expanded)]]" - toggles active="{{expanded}}" disabled="[[disabled]]" alt="[[alt]]" - aria-active-attribute="aria-expanded" + toggles active="{{expanded}}" disabled="[[disabled]]" + aria-label$="[[alt]]" aria-pressed$="[[getAriaPressed_(expanded)]]" tabindex$="[[tabIndex]]"> </button> </div> diff --git a/chromium/ui/webui/resources/cr_elements/cr_expand_button/cr_expand_button.js b/chromium/ui/webui/resources/cr_elements/cr_expand_button/cr_expand_button.js index 6cc2d178740..65a019c9e11 100644 --- a/chromium/ui/webui/resources/cr_elements/cr_expand_button/cr_expand_button.js +++ b/chromium/ui/webui/resources/cr_elements/cr_expand_button/cr_expand_button.js @@ -44,4 +44,9 @@ Polymer({ this.expanded = !this.expanded; event.stopPropagation(); }, + + /** @private */ + getAriaPressed_: function(expanded) { + return expanded ? 'true' : 'false'; + }, }); diff --git a/chromium/ui/webui/resources/cr_elements/cr_icons_css.html b/chromium/ui/webui/resources/cr_elements/cr_icons_css.html index f207914c7da..f8dc56c8a7f 100644 --- a/chromium/ui/webui/resources/cr_elements/cr_icons_css.html +++ b/chromium/ui/webui/resources/cr_elements/cr_icons_css.html @@ -11,7 +11,7 @@ button[is='paper-icon-button-light'], .cr-icon { - @apply(--cr-paper-icon-button-margin); + @apply --cr-paper-icon-button-margin; background-position: center; background-repeat: no-repeat; background-size: var(--cr-icon-size); diff --git a/chromium/ui/webui/resources/cr_elements/cr_link_row/cr_link_row.html b/chromium/ui/webui/resources/cr_elements/cr_link_row/cr_link_row.html index 4f6115b4b82..97bb3cc66a7 100644 --- a/chromium/ui/webui/resources/cr_elements/cr_link_row/cr_link_row.html +++ b/chromium/ui/webui/resources/cr_elements/cr_link_row/cr_link_row.html @@ -65,7 +65,7 @@ } #subLabel { - /* TODO(dschuyler): replace with: @apply(--cr-secondary-text); */ + /* TODO(dschuyler): replace with: @apply --cr-secondary-text; */ color: var(--paper-grey-600); font-weight: 400; } diff --git a/chromium/ui/webui/resources/cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector.html b/chromium/ui/webui/resources/cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector.html index 29b9923b515..bc13ad1d5d6 100644 --- a/chromium/ui/webui/resources/cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector.html +++ b/chromium/ui/webui/resources/cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector.html @@ -12,7 +12,7 @@ --avatar-spacing: 24px; display: inline-flex; - @apply(--avatar-selector); + @apply --avatar-selector; } #avatar-grid .avatar { @@ -33,7 +33,7 @@ padding: 0; width: var(--avatar-size); - @apply(--avatar-selector-avatar); + @apply --avatar-selector-avatar; } #avatar-grid .avatar.iron-selected { diff --git a/chromium/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar_search_field.html b/chromium/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar_search_field.html index 24ca91153a1..063e1fd2902 100644 --- a/chromium/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar_search_field.html +++ b/chromium/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar_search_field.html @@ -40,7 +40,7 @@ } paper-spinner-lite { - @apply(--cr-icon-height-width); + @apply --cr-icon-height-width; --paper-spinner-color: white; margin: 0 6px; opacity: 0; diff --git a/chromium/ui/webui/resources/cr_elements/paper_toggle_style_css.html b/chromium/ui/webui/resources/cr_elements/paper_toggle_style_css.html index 95581fd1707..44260f5541d 100644 --- a/chromium/ui/webui/resources/cr_elements/paper_toggle_style_css.html +++ b/chromium/ui/webui/resources/cr_elements/paper_toggle_style_css.html @@ -28,7 +28,7 @@ --paper-toggle-button-checked-bar: var(--cr-toggle-bar-size); --paper-toggle-button-checked-bar-color: var(--cr-toggle-color); --paper-toggle-button-checked-button: { - @apply(--cr-toggle-button-size); + @apply --cr-toggle-button-size; transform: translate(18px, 0); }; --paper-toggle-button-checked-button-color: var(--cr-toggle-color); diff --git a/chromium/ui/webui/resources/cr_elements/policy/cr_policy_indicator_behavior.js b/chromium/ui/webui/resources/cr_elements/policy/cr_policy_indicator_behavior.js index 2ad60591ab2..e8b2bba0d98 100644 --- a/chromium/ui/webui/resources/cr_elements/policy/cr_policy_indicator_behavior.js +++ b/chromium/ui/webui/resources/cr_elements/policy/cr_policy_indicator_behavior.js @@ -120,7 +120,7 @@ var CrPolicyIndicatorBehavior = { return ''; // Tooltips may not be defined, e.g. in OOBE. switch (type) { case CrPolicyIndicatorType.EXTENSION: - return CrPolicyStrings.controlledSettingExtension; + return CrPolicyStrings.controlledSettingExtension.replace('$1', name); case CrPolicyIndicatorType.PRIMARY_USER: return CrPolicyStrings.controlledSettingShared.replace('$1', name); case CrPolicyIndicatorType.OWNER: diff --git a/chromium/ui/webui/resources/cr_elements/search_highlight_style_css.html b/chromium/ui/webui/resources/cr_elements/search_highlight_style_css.html new file mode 100644 index 00000000000..451f86dd950 --- /dev/null +++ b/chromium/ui/webui/resources/cr_elements/search_highlight_style_css.html @@ -0,0 +1,48 @@ +<link rel="import" href="chrome://resources/html/polymer.html"> + +<link rel="import" href="shared_vars_css.html"> + +<dom-module id="search-highlight-style"> + <template> + <style> + .search-bubble { + /* RGB value matches var(--paper-yellow-500). */ + --search-bubble-color: rgba(255, 235, 59, 0.9); + position: absolute; + z-index: 1; + } + + .search-bubble-innards { + align-items: center; + background-color: var(--search-bubble-color); + border-radius: 2px; + max-width: 100px; + min-width: 64px; + padding: 4px 10px; + text-align: center; + @apply --cr-text-elide; + } + + /* Provides the arrow which points at the anchor element. */ + .search-bubble-innards::after { + background-color: var(--search-bubble-color); + content: ''; + height: 10px; + left: calc(50% - 5px); + position: absolute; + top: -5px; + transform: rotate(-45deg); + width: 10px; + z-index: -1; + } + + /* Turns the arrow direction downwards, when the bubble is placed above + * the anchor element */ + .search-bubble-innards.above::after { + bottom: -5px; + top: auto; + transform: rotate(-135deg); + } + </style> + </template> +</dom-module> diff --git a/chromium/ui/webui/resources/cr_elements/shared_style_css.html b/chromium/ui/webui/resources/cr_elements/shared_style_css.html index f3bcb9eb1ff..090a611be97 100644 --- a/chromium/ui/webui/resources/cr_elements/shared_style_css.html +++ b/chromium/ui/webui/resources/cr_elements/shared_style_css.html @@ -36,7 +36,7 @@ } [actionable] { - @apply(--cr-actionable); + @apply --cr-actionable; } .subpage-arrow, @@ -71,8 +71,8 @@ border-bottom-color: var(--google-grey-300); } [scrollable] iron-list > :not(.no-outline):focus { - @apply(--cr-list-item-focus); - @apply(--cr-selectable-focus); + @apply --cr-list-item-focus; + @apply --cr-selectable-focus; } .scroll-container { @@ -83,15 +83,15 @@ [selectable]:focus, [selectable] > :focus { - @apply(--cr-selectable-focus); + @apply --cr-selectable-focus; } [selectable] > * { - @apply(--cr-actionable); + @apply --cr-actionable; } /** Styles for elements that implement the CrContainerShadowBehavior */ #cr-container-shadow { - @apply(--cr-container-shadow); + @apply --cr-container-shadow; } #cr-container-shadow.has-shadow { diff --git a/chromium/ui/webui/resources/cr_elements/shared_vars_css.html b/chromium/ui/webui/resources/cr_elements/shared_vars_css.html index 83d28f66dfd..f7eeb885181 100644 --- a/chromium/ui/webui/resources/cr_elements/shared_vars_css.html +++ b/chromium/ui/webui/resources/cr_elements/shared_vars_css.html @@ -67,6 +67,12 @@ padding: 0 var(--cr-section-padding); }; + --cr-text-elide: { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + }; + --cr-title-text: { color: rgb(90, 90, 90); font-size: 107.6923%; /* Go to 14px from 13px. */ diff --git a/chromium/ui/webui/resources/cr_elements_resources.grdp b/chromium/ui/webui/resources/cr_elements_resources.grdp index c5c61226a49..c348d34f2f6 100644 --- a/chromium/ui/webui/resources/cr_elements_resources.grdp +++ b/chromium/ui/webui/resources/cr_elements_resources.grdp @@ -284,6 +284,10 @@ file="../../webui/resources/cr_elements/paper_toggle_style_css.html" type="chrome_html" compress="gzip" /> + <structure name="IDR_CR_ELEMENTS_SEARCH_HIGHLIGHT_STYLE_CSS_HTML" + file="../../webui/resources/cr_elements/search_highlight_style_css.html" + type="chrome_html" + compress="gzip" /> <structure name="IDR_CR_ELEMENTS_CR_SHARED_VARS_CSS_HTML" file="../../webui/resources/cr_elements/shared_vars_css.html" type="chrome_html" diff --git a/chromium/ui/webui/resources/cr_polymer_resources.grdp b/chromium/ui/webui/resources/cr_polymer_resources.grdp new file mode 100644 index 00000000000..96e7fecc19f --- /dev/null +++ b/chromium/ui/webui/resources/cr_polymer_resources.grdp @@ -0,0 +1,47 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Holds various resources under ui/webui/resources/{js,html}, that depend on + Polymer or are Polymer related. --> +<grit-part> + <!-- HTML resources --> + <structure name="IDR_WEBUI_HTML_ACTION_LINK_CSS" + file="html/action_link_css.html" type="chrome_html" + compress="gzip" /> + <structure name="IDR_WEBUI_HTML_CR_UI_FOCUS_WITHOUT_INK" + file="html/cr/ui/focus_without_ink.html" type="chrome_html" + compress="gzip" /> + <structure name="IDR_WEBUI_HTML_I18N_BEHAVIOR" + file="html/i18n_behavior.html" type="chrome_html" + compress="gzip" /> + <structure name="IDR_WEBUI_HTML_MD_SELECT_CSS_HTML" + file="html/md_select_css.html" type="chrome_html" + compress="gzip" flattenhtml="true" /> + <structure name="IDR_WEBUI_HTML_POLYMER" + file="html/polymer.html" type="chrome_html" compress="gzip" /> + <structure name="IDR_WEBUI_HTML_WEBUI_LISTENER_BEHAVIOR" + file="html/web_ui_listener_behavior.html" type="chrome_html" + compress="gzip" /> + <structure name="IDR_WEBUI_HTML_SEARCH_HIGHLIGHT_UTILS" + file="html/search_highlight_utils.html" type="chrome_html" + compress="gzip" /> + + <!-- CSS resources --> + <structure name="IDR_WEBUI_CSS_MD_COLORS" + file="css/md_colors.css" type="chrome_html" compress="gzip" /> + + <!-- JS resources --> + <structure name="IDR_WEBUI_JS_I18N_BEHAVIOR" + file="js/i18n_behavior.js" type="chrome_html" + compress="gzip" /> + <structure name="IDR_WEBUI_JS_CR_UI_FOCUS_WITHOUT_INK" + file="js/cr/ui/focus_without_ink.js" type="chrome_html" + compress="gzip" /> + <structure name="IDR_WEBUI_JS_POLYMER_CONFIG" + file="js/polymer_config.js" type="chrome_html" + compress="gzip" /> + <structure name="IDR_WEBUI_JS_WEBUI_LISTENER_BEHAVIOR" + file="js/web_ui_listener_behavior.js" type="chrome_html" + compress="gzip" /> + <structure name="IDR_WEBUI_JS_SEARCH_HIGHLIGHT_UTILS" + file="js/search_highlight_utils.js" type="chrome_html" + compress="gzip" /> +</grit-part> diff --git a/chromium/ui/webui/resources/html/action_link_css.html b/chromium/ui/webui/resources/html/action_link_css.html index 9ece1d5701f..904395b8046 100644 --- a/chromium/ui/webui/resources/html/action_link_css.html +++ b/chromium/ui/webui/resources/html/action_link_css.html @@ -6,7 +6,7 @@ <template> <style> [is='action-link'] { - @apply(--cr-actionable); + @apply --cr-actionable; display: inline-block; text-decoration: none; } diff --git a/chromium/ui/webui/resources/html/search_highlight_utils.html b/chromium/ui/webui/resources/html/search_highlight_utils.html new file mode 100644 index 00000000000..5f7a8836bcc --- /dev/null +++ b/chromium/ui/webui/resources/html/search_highlight_utils.html @@ -0,0 +1 @@ +<script src="chrome://resources/js/search_highlight_utils.js"></script> diff --git a/chromium/ui/webui/resources/images/200-logo_chrome.png b/chromium/ui/webui/resources/images/200-logo_chrome.png Binary files differindex c283720758c..44f808efaf6 100644 --- a/chromium/ui/webui/resources/images/200-logo_chrome.png +++ b/chromium/ui/webui/resources/images/200-logo_chrome.png diff --git a/chromium/ui/webui/resources/images/200-logo_googleg.png b/chromium/ui/webui/resources/images/200-logo_googleg.png Binary files differindex 85f92c09ca9..9ace71c2a9c 100644 --- a/chromium/ui/webui/resources/images/200-logo_googleg.png +++ b/chromium/ui/webui/resources/images/200-logo_googleg.png diff --git a/chromium/ui/webui/resources/images/2x/apps/topbar_button_maximize.png b/chromium/ui/webui/resources/images/2x/apps/topbar_button_maximize.png Binary files differindex 59377a4dc41..96cecc99da1 100644 --- a/chromium/ui/webui/resources/images/2x/apps/topbar_button_maximize.png +++ b/chromium/ui/webui/resources/images/2x/apps/topbar_button_maximize.png diff --git a/chromium/ui/webui/resources/images/2x/apps/topbar_button_minimize.png b/chromium/ui/webui/resources/images/2x/apps/topbar_button_minimize.png Binary files differindex 2c0afdb3eba..437c6f700dd 100644 --- a/chromium/ui/webui/resources/images/2x/apps/topbar_button_minimize.png +++ b/chromium/ui/webui/resources/images/2x/apps/topbar_button_minimize.png diff --git a/chromium/ui/webui/resources/images/apps/button_butter_bar_close.png b/chromium/ui/webui/resources/images/apps/button_butter_bar_close.png Binary files differindex 75edfba33bd..001f22742c3 100644 --- a/chromium/ui/webui/resources/images/apps/button_butter_bar_close.png +++ b/chromium/ui/webui/resources/images/apps/button_butter_bar_close.png diff --git a/chromium/ui/webui/resources/images/apps/topbar_button_maximize.png b/chromium/ui/webui/resources/images/apps/topbar_button_maximize.png Binary files differindex 3bd557fa5a4..7d452702c13 100644 --- a/chromium/ui/webui/resources/images/apps/topbar_button_maximize.png +++ b/chromium/ui/webui/resources/images/apps/topbar_button_maximize.png diff --git a/chromium/ui/webui/resources/images/apps/topbar_button_minimize.png b/chromium/ui/webui/resources/images/apps/topbar_button_minimize.png Binary files differindex 484079d5bdb..33b892dfe3d 100644 --- a/chromium/ui/webui/resources/images/apps/topbar_button_minimize.png +++ b/chromium/ui/webui/resources/images/apps/topbar_button_minimize.png diff --git a/chromium/ui/webui/resources/images/check.png b/chromium/ui/webui/resources/images/check.png Binary files differindex 94c58b78c43..0321d1b45d9 100644 --- a/chromium/ui/webui/resources/images/check.png +++ b/chromium/ui/webui/resources/images/check.png diff --git a/chromium/ui/webui/resources/images/checkbox_black.png b/chromium/ui/webui/resources/images/checkbox_black.png Binary files differindex 3609119e41a..16e82cb2a63 100644 --- a/chromium/ui/webui/resources/images/checkbox_black.png +++ b/chromium/ui/webui/resources/images/checkbox_black.png diff --git a/chromium/ui/webui/resources/images/disabled_select.png b/chromium/ui/webui/resources/images/disabled_select.png Binary files differindex 0aa20000d74..9bce7a30523 100644 --- a/chromium/ui/webui/resources/images/disabled_select.png +++ b/chromium/ui/webui/resources/images/disabled_select.png diff --git a/chromium/ui/webui/resources/images/select.png b/chromium/ui/webui/resources/images/select.png Binary files differindex 2af6f675864..3cb71fb514c 100644 --- a/chromium/ui/webui/resources/images/select.png +++ b/chromium/ui/webui/resources/images/select.png diff --git a/chromium/ui/webui/resources/js/compiled_resources2.gyp b/chromium/ui/webui/resources/js/compiled_resources2.gyp index 25f388bebeb..3b759c04f4b 100644 --- a/chromium/ui/webui/resources/js/compiled_resources2.gyp +++ b/chromium/ui/webui/resources/js/compiled_resources2.gyp @@ -32,6 +32,13 @@ 'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'], }, { + 'target_name': 'search_highlight_utils', + 'dependencies': [ + 'cr', + ], + 'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'], + }, + { 'target_name': 'icon', 'dependencies': [ 'cr', diff --git a/chromium/ui/webui/resources/js/cr/ui/tree.js b/chromium/ui/webui/resources/js/cr/ui/tree.js index 89940b6b66a..87ffb019a71 100644 --- a/chromium/ui/webui/resources/js/cr/ui/tree.js +++ b/chromium/ui/webui/resources/js/cr/ui/tree.js @@ -465,7 +465,7 @@ cr.define('cr.ui', function() { return getComputedStyle(this.labelElement).backgroundImage.slice(4, -1); }, set icon(icon) { - return this.labelElement.style.backgroundImage = url(icon); + return this.labelElement.style.backgroundImage = getUrlForCss(icon); }, /** diff --git a/chromium/ui/webui/resources/js/icon.js b/chromium/ui/webui/resources/js/icon.js index ee8c445f11c..ef025e7133d 100644 --- a/chromium/ui/webui/resources/js/icon.js +++ b/chromium/ui/webui/resources/js/icon.js @@ -45,7 +45,7 @@ cr.define('cr.icon', function() { var replaceStartIndex = path.indexOf('scalefactor'); if (replaceStartIndex < 0) - return url(path); + return getUrlForCss(path); var s = ''; for (var i = 0; i < supportedScaleFactors.length; ++i) { @@ -53,7 +53,7 @@ cr.define('cr.icon', function() { var pathWithScaleFactor = path.substr(0, replaceStartIndex) + scaleFactor + path.substr(replaceStartIndex + 'scalefactor'.length); - s += url(pathWithScaleFactor) + ' ' + scaleFactor + 'x'; + s += getUrlForCss(pathWithScaleFactor) + ' ' + scaleFactor + 'x'; if (i != supportedScaleFactors.length - 1) s += ', '; @@ -72,7 +72,8 @@ cr.define('cr.icon', function() { var chromeThemePath = 'chrome://theme'; var isChromeThemeUrl = (path.slice(0, chromeThemePath.length) == chromeThemePath); - return isChromeThemeUrl ? getImageSet(path + '@scalefactorx') : url(path); + return isChromeThemeUrl ? getImageSet(path + '@scalefactorx') : + getUrlForCss(path); } /** diff --git a/chromium/ui/webui/resources/js/search_highlight_utils.js b/chromium/ui/webui/resources/js/search_highlight_utils.js new file mode 100644 index 00000000000..d7bf3c8acb0 --- /dev/null +++ b/chromium/ui/webui/resources/js/search_highlight_utils.js @@ -0,0 +1,130 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +cr.define('cr.search_highlight_utils', function() { + /** @type {string} */ + const WRAPPER_CSS_CLASS = 'search-highlight-wrapper'; + + /** @type {string} */ + const ORIGINAL_CONTENT_CSS_CLASS = 'search-highlight-original-content'; + + /** @type {string} */ + const HIT_CSS_CLASS = 'search-highlight-hit'; + + /** @type {string} */ + const SEARCH_BUBBLE_CSS_CLASS = 'search-bubble'; + + /** + * Applies the highlight UI (yellow rectangle) around all matches in |node|. + * @param {!Node} node The text node to be highlighted. |node| ends up + * being hidden. + * @param {!Array<string>} tokens The string tokens after splitting on the + * relevant regExp. Even indices hold text that doesn't need highlighting, + * odd indices hold the text to be highlighted. For example: + * const r = new RegExp('(foo)', 'i'); + * 'barfoobar foo bar'.split(r) => ['bar', 'foo', 'bar ', 'foo', ' bar'] + */ + function highlight(node, tokens) { + const wrapper = document.createElement('span'); + wrapper.classList.add(WRAPPER_CSS_CLASS); + // Use existing node as placeholder to determine where to insert the + // replacement content. + node.parentNode.replaceChild(wrapper, node); + + // Keep the existing node around for when the highlights are removed. The + // existing text node might be involved in data-binding and therefore should + // not be discarded. + const span = document.createElement('span'); + span.classList.add(ORIGINAL_CONTENT_CSS_CLASS); + span.style.display = 'none'; + span.appendChild(node); + wrapper.appendChild(span); + + for (let i = 0; i < tokens.length; ++i) { + if (i % 2 == 0) { + wrapper.appendChild(document.createTextNode(tokens[i])); + } else { + const hitSpan = document.createElement('span'); + hitSpan.classList.add(HIT_CSS_CLASS); + hitSpan.style.backgroundColor = '#ffeb3b'; // --var(--paper-yellow-500) + hitSpan.textContent = tokens[i]; + wrapper.appendChild(hitSpan); + } + } + } + + /** + * Finds all previous highlighted nodes under |node| (both within self and + * children's Shadow DOM) and replaces the highlights (yellow rectangles) + * with the original search node. + * @param {!Node} node + * @private + */ + function findAndRemoveHighlights(node) { + const wrappers = node.querySelectorAll(`* /deep/ .${WRAPPER_CSS_CLASS}`); + + for (let i = 0; i < wrappers.length; i++) { + const wrapper = wrappers[i]; + const originalNode = + wrapper.querySelector(`.${ORIGINAL_CONTENT_CSS_CLASS}`); + wrapper.parentElement.replaceChild(originalNode.firstChild, wrapper); + } + } + + /** + * Finds and removes all previously created yellow search bubbles under + * |node| (both within self and children's Shadow DOM). + * @param {!Node} node + * @private + */ + function findAndRemoveBubbles(node) { + const searchBubbles = + node.querySelectorAll(`* /deep/ .${SEARCH_BUBBLE_CSS_CLASS}`); + for (let bubble of searchBubbles) + bubble.remove(); + } + + /** + * Highlights an HTML element by displaying a search bubble. The element + * should already be visible or the bubble will render incorrectly. + * @param {!HTMLElement} element The element to be highlighted. + * @param {string} rawQuery The search query. + * @private + */ + function highlightControlWithBubble(element, rawQuery) { + let searchBubble = element.querySelector(`.${SEARCH_BUBBLE_CSS_CLASS}`); + // If the element has already been highlighted, there is no need to do + // anything. + if (searchBubble) + return; + + searchBubble = document.createElement('div'); + searchBubble.classList.add(SEARCH_BUBBLE_CSS_CLASS); + const innards = document.createElement('div'); + innards.classList.add('search-bubble-innards'); + innards.textContent = rawQuery; + searchBubble.appendChild(innards); + element.appendChild(searchBubble); + + const updatePosition = function() { + searchBubble.style.top = element.offsetTop + + (innards.classList.contains('above') ? -searchBubble.offsetHeight : + element.offsetHeight) + + 'px'; + }; + updatePosition(); + + searchBubble.addEventListener('mouseover', function() { + innards.classList.toggle('above'); + updatePosition(); + }); + } + + return { + highlight: highlight, + highlightControlWithBubble: highlightControlWithBubble, + findAndRemoveBubbles: findAndRemoveBubbles, + findAndRemoveHighlights: findAndRemoveHighlights, + }; +}); diff --git a/chromium/ui/webui/resources/js/util.js b/chromium/ui/webui/resources/js/util.js index 27faa1b60bf..a5099bf9b56 100644 --- a/chromium/ui/webui/resources/js/util.js +++ b/chromium/ui/webui/resources/js/util.js @@ -56,7 +56,7 @@ function announceAccessibleMessage(msg) { * @param {string} s The URL to generate the CSS url for. * @return {string} The CSS url string. */ -function url(s) { +function getUrlForCss(s) { // http://www.w3.org/TR/css3-values/#uris // Parentheses, commas, whitespace characters, single quotes (') and double // quotes (") appearing in a URI must be escaped with a backslash diff --git a/chromium/ui/webui/resources/polymer_resources.grdp b/chromium/ui/webui/resources/polymer_resources.grdp index 6e5f88e36b1..6f4a7f9d3f0 100644 --- a/chromium/ui/webui/resources/polymer_resources.grdp +++ b/chromium/ui/webui/resources/polymer_resources.grdp @@ -276,6 +276,14 @@ file="../../../third_party/polymer/v1_0/components-chromium/iron-overlay-behavior/iron-overlay-manager.html" type="chrome_html" compress="gzip" /> + <structure name="IDR_POLYMER_1_0_IRON_OVERLAY_BEHAVIOR_IRON_SCROLL_MANAGER_EXTRACTED_JS" + file="../../../third_party/polymer/v1_0/components-chromium/iron-overlay-behavior/iron-scroll-manager-extracted.js" + type="chrome_html" + compress="gzip" /> + <structure name="IDR_POLYMER_1_0_IRON_OVERLAY_BEHAVIOR_IRON_SCROLL_MANAGER_HTML" + file="../../../third_party/polymer/v1_0/components-chromium/iron-overlay-behavior/iron-scroll-manager.html" + type="chrome_html" + compress="gzip" /> <structure name="IDR_POLYMER_1_0_IRON_PAGES_IRON_PAGES_EXTRACTED_JS" file="../../../third_party/polymer/v1_0/components-chromium/iron-pages/iron-pages-extracted.js" type="chrome_html" @@ -700,30 +708,6 @@ file="../../../third_party/polymer/v1_0/components-chromium/paper-listbox/paper-listbox.html" type="chrome_html" compress="gzip" /> - <structure name="IDR_POLYMER_1_0_PAPER_MATERIAL_PAPER_MATERIAL_SHARED_STYLES_HTML" - file="../../../third_party/polymer/v1_0/components-chromium/paper-material/paper-material-shared-styles.html" - type="chrome_html" - compress="gzip" /> - <structure name="IDR_POLYMER_1_0_PAPER_MENU_PAPER_MENU_EXTRACTED_JS" - file="../../../third_party/polymer/v1_0/components-chromium/paper-menu/paper-menu-extracted.js" - type="chrome_html" - compress="gzip" /> - <structure name="IDR_POLYMER_1_0_PAPER_MENU_PAPER_MENU_SHARED_STYLES_HTML" - file="../../../third_party/polymer/v1_0/components-chromium/paper-menu/paper-menu-shared-styles.html" - type="chrome_html" - compress="gzip" /> - <structure name="IDR_POLYMER_1_0_PAPER_MENU_PAPER_MENU_HTML" - file="../../../third_party/polymer/v1_0/components-chromium/paper-menu/paper-menu.html" - type="chrome_html" - compress="gzip" /> - <structure name="IDR_POLYMER_1_0_PAPER_MENU_PAPER_SUBMENU_EXTRACTED_JS" - file="../../../third_party/polymer/v1_0/components-chromium/paper-menu/paper-submenu-extracted.js" - type="chrome_html" - compress="gzip" /> - <structure name="IDR_POLYMER_1_0_PAPER_MENU_PAPER_SUBMENU_HTML" - file="../../../third_party/polymer/v1_0/components-chromium/paper-menu/paper-submenu.html" - type="chrome_html" - compress="gzip" /> <structure name="IDR_POLYMER_1_0_PAPER_PROGRESS_PAPER_PROGRESS_EXTRACTED_JS" file="../../../third_party/polymer/v1_0/components-chromium/paper-progress/paper-progress-extracted.js" type="chrome_html" @@ -784,10 +768,6 @@ file="../../../third_party/polymer/v1_0/components-chromium/paper-spinner/paper-spinner-styles.html" type="chrome_html" compress="gzip" /> - <structure name="IDR_POLYMER_1_0_PAPER_STYLES_CLASSES_SHADOW_LAYOUT_HTML" - file="../../../third_party/polymer/v1_0/components-chromium/paper-styles/classes/shadow-layout.html" - type="chrome_html" - compress="gzip" /> <structure name="IDR_POLYMER_1_0_PAPER_STYLES_CLASSES_SHADOW_HTML" file="../../../third_party/polymer/v1_0/components-chromium/paper-styles/classes/shadow.html" type="chrome_html" @@ -804,6 +784,14 @@ file="../../../third_party/polymer/v1_0/components-chromium/paper-styles/default-theme.html" type="chrome_html" compress="gzip" /> + <structure name="IDR_POLYMER_1_0_PAPER_STYLES_ELEMENT_STYLES_PAPER_ITEM_STYLES_HTML" + file="../../../third_party/polymer/v1_0/components-chromium/paper-styles/element-styles/paper-item-styles.html" + type="chrome_html" + compress="gzip" /> + <structure name="IDR_POLYMER_1_0_PAPER_STYLES_ELEMENT_STYLES_PAPER_MATERIAL_STYLES_HTML" + file="../../../third_party/polymer/v1_0/components-chromium/paper-styles/element-styles/paper-material-styles.html" + type="chrome_html" + compress="gzip" /> <structure name="IDR_POLYMER_1_0_PAPER_STYLES_PAPER_STYLES_CLASSES_HTML" file="../../../third_party/polymer/v1_0/components-chromium/paper-styles/paper-styles-classes.html" type="chrome_html" diff --git a/chromium/ui/webui/resources/webui_resources.grd b/chromium/ui/webui/resources/webui_resources.grd index 980b689ac1e..a704601c238 100644 --- a/chromium/ui/webui/resources/webui_resources.grd +++ b/chromium/ui/webui/resources/webui_resources.grd @@ -236,8 +236,6 @@ without changes to the corresponding grd file. --> compress="gzip" /> <structure name="IDR_WEBUI_CSS_LIST" file="css/list.css" type="chrome_html" compress="gzip" /> - <structure name="IDR_WEBUI_CSS_MD_COLORS" - file="css/md_colors.css" type="chrome_html" compress="gzip" /> <structure name="IDR_WEBUI_CSS_MENU" file="css/menu.css" type="chrome_html" compress="gzip" flattenhtml="true" /> @@ -274,9 +272,6 @@ without changes to the corresponding grd file. --> <structure name="IDR_WEBUI_HTML_ACTION_LINK" file="html/action_link.html" type="chrome_html" compress="gzip" /> - <structure name="IDR_WEBUI_HTML_ACTION_LINK_CSS" - file="html/action_link_css.html" type="chrome_html" - compress="gzip" /> <structure name="IDR_WEBUI_HTML_ASSERT" file="html/assert.html" type="chrome_html" compress="gzip" /> <structure name="IDR_WEBUI_HTML_PROMISE_RESOLVER" @@ -319,9 +314,6 @@ without changes to the corresponding grd file. --> <structure name="IDR_WEBUI_HTML_CR_UI_FOCUS_ROW" file="html/cr/ui/focus_row.html" type="chrome_html" compress="gzip" /> - <structure name="IDR_WEBUI_HTML_CR_UI_FOCUS_WITHOUT_INK" - file="html/cr/ui/focus_without_ink.html" type="chrome_html" - compress="gzip" /> <structure name="IDR_WEBUI_HTML_CR_UI_LIST" file="html/cr/ui/list.html" type="chrome_html" compress="gzip" /> @@ -366,25 +358,14 @@ without changes to the corresponding grd file. --> <structure name="IDR_WEBUI_HTML_I18N_TEMPLATE" file="html/i18n_template.html" type="chrome_html" compress="gzip" /> - <structure name="IDR_WEBUI_HTML_MD_SELECT_CSS_HTML" - file="html/md_select_css.html" type="chrome_html" - compress="gzip" flattenhtml="true" /> <structure name="IDR_WEBUI_HTML_LOAD_TIME_DATA" file="html/load_time_data.html" type="chrome_html" compress="gzip" /> <structure name="IDR_WEBUI_HTML_PARSE_HTML_SUBSET" file="html/parse_html_subset.html" type="chrome_html" compress="gzip" /> - <structure name="IDR_WEBUI_HTML_POLYMER" - file="html/polymer.html" type="chrome_html" compress="gzip" /> - <structure name="IDR_WEBUI_HTML_I18N_BEHAVIOR" - file="html/i18n_behavior.html" type="chrome_html" - compress="gzip" /> <structure name="IDR_WEBUI_HTML_UTIL" file="html/util.html" type="chrome_html" compress="gzip" /> - <structure name="IDR_WEBUI_HTML_WEBUI_LISTENER_BEHAVIOR" - file="html/web_ui_listener_behavior.html" type="chrome_html" - compress="gzip" /> <structure name="IDR_WEBUI_HTML_WEBUI_LISTENER_TRACKER" file="html/webui_listener_tracker.html" type="chrome_html" compress="gzip" /> @@ -454,9 +435,6 @@ without changes to the corresponding grd file. --> <structure name="IDR_WEBUI_JS_CR_UI_FOCUS_ROW" file="js/cr/ui/focus_row.js" type="chrome_html" compress="gzip" /> - <structure name="IDR_WEBUI_JS_CR_UI_FOCUS_WITHOUT_INK" - file="js/cr/ui/focus_without_ink.js" type="chrome_html" - compress="gzip" /> <structure name="IDR_WEBUI_JS_CR_UI_LIST" file="js/cr/ui/list.js" type="chrome_html" compress="gzip" /> <structure name="IDR_WEBUI_JS_CR_UI_LIST_ITEM" @@ -546,24 +524,17 @@ without changes to the corresponding grd file. --> <structure name="IDR_WEBUI_JS_PARSE_HTML_SUBSET" file="js/parse_html_subset.js" type="chrome_html" compress="gzip" /> - <structure name="IDR_WEBUI_JS_POLYMER_CONFIG" - file="js/polymer_config.js" type="chrome_html" - compress="gzip" /> - <structure name="IDR_WEBUI_JS_I18N_BEHAVIOR" - file="js/i18n_behavior.js" type="chrome_html" - compress="gzip" /> <structure name="IDR_WEBUI_JS_UTIL" file="js/util.js" type="chrome_html" compress="gzip" flattenhtml="true" /> - <structure name="IDR_WEBUI_JS_WEBUI_LISTENER_BEHAVIOR" - file="js/web_ui_listener_behavior.js" type="chrome_html" - compress="gzip" /> <structure name="IDR_WEBUI_JS_WEBUI_RESOURCE_TEST" file="js/webui_resource_test.js" type="chrome_html" compress="gzip" /> - <if expr="not is_android"> + + <if expr="not is_android and not is_ios"> <part file="cr_components/cr_components_resources.grdp" /> <part file="cr_elements_resources.grdp" /> + <part file="cr_polymer_resources.grdp" /> <part file="polymer_resources.grdp" /> </if> </structures> |