Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * @fileoverview | 6 * @fileoverview |
| 7 * ButterBar class that is used to show the butter bar with various | 7 * ButterBar class that is used to show a butter bar with deprecation messages. |
| 8 * notifications. | 8 * Each message is displayed for at most one week. |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 'use strict'; | 11 'use strict'; |
| 12 | 12 |
| 13 /** @suppress {duplicate} */ | 13 /** @suppress {duplicate} */ |
| 14 var remoting = remoting || {}; | 14 var remoting = remoting || {}; |
| 15 | 15 |
| 16 /** | 16 /** |
| 17 * @constructor | 17 * @constructor |
| 18 */ | 18 */ |
| 19 remoting.ButterBar = function() { | 19 remoting.ButterBar = function() { |
| 20 this.storageKey_ = ''; | 20 /** @private @const */ |
| 21 this.messages_ = [ | |
| 22 {id: /*i18n-content*/'WEBSITE_INVITE_BETA', dismissable: true}, | |
| 23 {id: /*i18n-content*/'WEBSITE_INVITE_STABLE', dismissable: true}, | |
| 24 {id: /*i18n-content*/'WEBSITE_INVITE_DEPRECATION_1', dismissable: true}, | |
| 25 {id: /*i18n-content*/'WEBSITE_INVITE_DEPRECATION_2', dismissable: false}, | |
| 26 ]; | |
| 27 // TODO(jamiewalch): Read the message index using metricsPrivate. | |
| 28 this.currentMessage_ = -1; | |
| 29 /** @private {!Element} */ | |
| 30 this.root_ = document.getElementById(remoting.ButterBar.kId_); | |
| 31 /** @private {!Element} */ | |
| 32 this.message_ = document.getElementById(remoting.ButterBar.kMessageId_); | |
| 33 /** @private {!Element} */ | |
| 34 this.dismiss_ = document.getElementById(remoting.ButterBar.kDismissId_); | |
| 35 } | |
| 21 | 36 |
| 22 chrome.storage.sync.get( | 37 remoting.ButterBar.prototype.init = function() { |
| 23 [remoting.ButterBar.kSurveyStorageKey_], | 38 var result = new base.Deferred(); |
| 24 this.onStateLoaded_.bind(this)); | 39 if (this.currentMessage_ > -1) { |
| 40 chrome.storage.sync.get( | |
| 41 [remoting.ButterBar.kStorageKey_], | |
| 42 (syncValues) => { | |
| 43 this.onStateLoaded_(syncValues); | |
| 44 result.resolve(); | |
| 45 }); | |
| 46 } else { | |
| 47 result.resolve(); | |
| 48 } | |
| 49 return result.promise(); | |
| 25 } | 50 } |
| 26 | 51 |
| 27 /** | 52 /** |
| 28 * Shows butter bar with the specified |message| and updates |storageKey| after | 53 * Shows butter bar with the current message. |
| 29 * the bar is dismissed. | |
| 30 * | 54 * |
| 31 * @param {string} messageId | 55 * @param {string} messageId |
| 32 * @param {string|Array} substitutions | 56 * @param {string|Array} substitutions |
| 33 * @param {string} storageKey | 57 * @param {boolean} dismissable |
| 34 * @private | 58 * @private |
| 35 */ | 59 */ |
| 36 remoting.ButterBar.prototype.show_ = | 60 remoting.ButterBar.prototype.show_ = function() { |
| 37 function(messageId, substitutions, storageKey) { | 61 var messageId = this.messages_[this.currentMessage_].id; |
| 38 this.storageKey_ = storageKey; | 62 var substitutions = ['<a href="https://example.com" target="_blank">', '</a>'] ; |
| 39 | 63 var dismissable = this.messages_[this.currentMessage_].dismissable; |
| 40 var messageElement = document.getElementById(remoting.ButterBar.kMessageId_); | 64 l10n.localizeElementFromTag(this.message_, messageId, substitutions, true); |
| 41 l10n.localizeElementFromTag(messageElement, messageId, substitutions, true); | 65 if (dismissable) { |
| 42 var acceptLink = | 66 this.dismiss_.addEventListener( |
| 43 /** @type{Element} */ (messageElement.getElementsByTagName('a')[0]); | 67 'click', this.dismiss.bind(this, false), false); |
|
kelvinp
2017/05/15 22:36:54
dismiss does not take any parameter.
Jamie
2017/05/15 23:43:20
Done, and updated unit tests.
| |
| 44 acceptLink.addEventListener( | 68 } else { |
| 45 'click', this.dismiss.bind(this, true), false); | 69 this.dismiss_.hidden = true; |
| 46 | 70 this.root_.classList.add('important'); |
|
kelvinp
2017/05/15 22:36:54
why is important needed?
Jamie
2017/05/15 23:43:19
It's a class name. I've renamed it though, since i
| |
| 47 document.getElementById(remoting.ButterBar.kDismissId_).addEventListener( | 71 } |
| 48 'click', this.dismiss.bind(this, false), false); | 72 this.root_.hidden = false; |
| 49 | |
| 50 document.getElementById(remoting.ButterBar.kId_).hidden = false; | |
| 51 } | 73 } |
| 52 | 74 |
| 53 /** | 75 /** |
| 54 * @param {Object} syncValues | 76 * @param {Object} syncValues |
| 55 * @private | 77 * @private |
| 56 */ | 78 */ |
| 57 remoting.ButterBar.prototype.onStateLoaded_ = function(syncValues) { | 79 remoting.ButterBar.prototype.onStateLoaded_ = function(syncValues) { |
| 58 /** @type {boolean} */ | 80 /** @type {!Object|undefined} */ |
| 59 var surveyDismissed = !!syncValues[remoting.ButterBar.kSurveyStorageKey_]; | 81 var messageState = syncValues[remoting.ButterBar.kStorageKey_]; |
| 82 if (!messageState) { | |
| 83 messageState = { | |
| 84 index: -1, | |
| 85 timestamp: new Date().getTime(), | |
| 86 hidden: false, | |
| 87 } | |
| 88 } | |
| 60 | 89 |
| 61 if (!surveyDismissed) { | 90 // Show the current message unless it was explicitly dismissed or if it was |
| 62 this.show_(/*i18n-content*/'SURVEY_INVITATION', | 91 // first shown more than a week ago. If it is marked as not dismissable, show |
| 63 ['<a href="http://goo.gl/njH2q" target="_blank">', '</a>'], | 92 // it unconditionally. |
| 64 remoting.ButterBar.kSurveyStorageKey_); | 93 var elapsed = new Date - messageState.timestamp; |
|
kelvinp
2017/05/15 22:36:54
s/Date/Date() for consistency
Jamie
2017/05/15 23:43:20
Done.
| |
| 94 var show = | |
| 95 this.currentMessage_ > messageState.index || | |
| 96 !this.messages_[this.currentMessage_].dismissable || | |
|
kelvinp
2017/05/15 22:36:54
On the first run, messageState.index is set to -1,
Jamie
2017/05/15 23:43:19
We don't call sync.get() if currentMessage_ is -1,
| |
| 97 (!messageState.hidden && elapsed <= remoting.ButterBar.kTimeout_); | |
| 98 | |
| 99 if (show) { | |
| 100 this.show_(); | |
| 101 // If this is the first time this message is being displayed, update the | |
| 102 // saved state. | |
| 103 if (this.currentMessage_ > messageState.index) { | |
| 104 var value = {}; | |
| 105 value[remoting.ButterBar.kStorageKey_] = { | |
| 106 index: this.currentMessage_, | |
| 107 timestamp: new Date().getTime(), | |
| 108 hidden: false | |
| 109 }; | |
| 110 chrome.storage.sync.set(value); | |
| 111 } | |
| 65 } | 112 } |
| 66 }; | 113 }; |
| 67 | 114 |
| 115 /** | |
| 116 * Hide the butter bar request and record the message that was being displayed. | |
| 117 */ | |
| 118 remoting.ButterBar.prototype.dismiss = function() { | |
| 119 var value = {}; | |
| 120 value[remoting.ButterBar.kStorageKey_] = { | |
| 121 index: this.currentMessage_, | |
| 122 timestamp: new Date().getTime(), | |
| 123 hidden: true | |
| 124 }; | |
| 125 chrome.storage.sync.set(value); | |
| 126 | |
| 127 this.root_.hidden = true; | |
| 128 }; | |
| 129 | |
| 68 /** @const @private */ | 130 /** @const @private */ |
| 69 remoting.ButterBar.kId_ = 'butter-bar'; | 131 remoting.ButterBar.kId_ = 'butter-bar'; |
| 70 | 132 |
| 71 /** @const @private */ | 133 /** @const @private */ |
| 72 remoting.ButterBar.kMessageId_ = 'butter-bar-message'; | 134 remoting.ButterBar.kMessageId_ = 'butter-bar-message'; |
| 73 /** @const @private */ | 135 /** @const @private */ |
| 74 remoting.ButterBar.kDismissId_ = 'butter-bar-dismiss'; | 136 remoting.ButterBar.kDismissId_ = 'butter-bar-dismiss'; |
| 75 | 137 |
| 76 /** @const @private */ | 138 /** @const @private */ |
| 77 remoting.ButterBar.kSurveyStorageKey_ = 'feedback-survey-dismissed'; | 139 remoting.ButterBar.kStorageKey_ = 'message-state'; |
| 78 | 140 |
| 79 /** | 141 /** @const @private */ |
| 80 * Hide the butter bar request and record some basic information about the | 142 remoting.ButterBar.kTimeout_ = 7 * 24 * 60 * 60 * 1000; // 1 week |
| 81 * current state of the world in synced storage. This may be useful in the | |
| 82 * future if we want to show the request again. At the moment, the data itself | |
| 83 * is ignored; only its presence or absence is important. | |
| 84 * | |
| 85 * @param {boolean} accepted True if the user clicked the "accept" link; | |
| 86 * false if they clicked the close icon. | |
| 87 */ | |
| 88 remoting.ButterBar.prototype.dismiss = function(accepted) { | |
| 89 var value = {}; | |
| 90 value[this.storageKey_] = { | |
| 91 optIn: accepted, | |
| 92 date: new Date(), | |
| 93 version: chrome.runtime.getManifest().version | |
| 94 }; | |
| 95 chrome.storage.sync.set(value); | |
| 96 | |
| 97 document.getElementById(remoting.ButterBar.kId_).hidden = true; | |
| 98 }; | |
| OLD | NEW |