Commit 970e8d5e authored by yoz@chromium.org's avatar yoz@chromium.org

Show app disable and enable on NTP, and desaturate non-offline-enabled apps when offline.

Refactor to put the logic for NTP app grayscaling in Javascript.
Disabled and terminated apps don't disappear from the NTP.
Update the NTP apps when offline status changes.

Caveat: the webstore icon doesn't get desaturated.

BUG=89655,94322,90433
TEST=Open NTP with packaged apps in disabled/enabled state; observe them changing
color when disabled/enabled via chrome://extensions page. Observe color changes
when network interface is unplugged.

Review URL: http://codereview.chromium.org/7792024

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@98908 0039d316-1c4b-4281-b951-d872f2087c98
parent 413b279e
...@@ -119,7 +119,7 @@ cr.define('ntp4', function() { ...@@ -119,7 +119,7 @@ cr.define('ntp4', function() {
launchTypeButton.checked = app.appData.launch_type == id; launchTypeButton.checked = app.appData.launch_type == id;
}); });
this.options_.disabled = !app.appData.options_url; this.options_.disabled = !app.appData.options_url || !app.appData.enabled;
this.uninstall_.disabled = !app.appData.can_uninstall; this.uninstall_.disabled = !app.appData.can_uninstall;
}, },
...@@ -189,8 +189,8 @@ cr.define('ntp4', function() { ...@@ -189,8 +189,8 @@ cr.define('ntp4', function() {
this.useSmallIcon_ = true; this.useSmallIcon_ = true;
var appImg = this.ownerDocument.createElement('img'); var appImg = this.ownerDocument.createElement('img');
appImg.src = this.useSmallIcon_ ? this.appData_.icon_small : this.appImg_ = appImg;
this.appData_.icon_big; this.setIcon();
appImgContainer.appendChild(appImg); appImgContainer.appendChild(appImg);
if (this.useSmallIcon_) { if (this.useSmallIcon_) {
...@@ -204,7 +204,6 @@ cr.define('ntp4', function() { ...@@ -204,7 +204,6 @@ cr.define('ntp4', function() {
appImgContainer.addEventListener('click', this.onClick_.bind(this)); appImgContainer.addEventListener('click', this.onClick_.bind(this));
appContents.appendChild(appImgContainer); appContents.appendChild(appImgContainer);
} }
this.appImg_ = appImg;
var appSpan = this.ownerDocument.createElement('span'); var appSpan = this.ownerDocument.createElement('span');
appSpan.textContent = this.appData_.name; appSpan.textContent = this.appData_.name;
...@@ -243,6 +242,19 @@ cr.define('ntp4', function() { ...@@ -243,6 +242,19 @@ cr.define('ntp4', function() {
tile.doRemove(); tile.doRemove();
}, },
/**
* Set the app's icon image from the appData.
* @private
*/
setIcon: function() {
this.appImg_.src = this.useSmallIcon_ ? this.appData_.icon_small :
this.appData_.icon_big;
if (!this.appData_.enabled ||
(!this.appData_.offline_enabled && !navigator.onLine)) {
this.appImg_.src += '?grayscale=true';
}
},
/** /**
* Creates the apps-promo section of the app (should only be called for the * Creates the apps-promo section of the app (should only be called for the
* webstore app). * webstore app).
...@@ -346,6 +358,15 @@ cr.define('ntp4', function() { ...@@ -346,6 +358,15 @@ cr.define('ntp4', function() {
this.classList.remove('right-mouse-down'); this.classList.remove('right-mouse-down');
}, },
/**
* Change the appData and update the appearance of the app.
* @param {Object} appData The new data object that describes the app.
*/
replaceAppData: function(appData) {
this.appData_ = appData;
this.setIcon();
},
/** /**
* The data and preferences for this app. * The data and preferences for this app.
* @type {Object} * @type {Object}
......
...@@ -319,17 +319,18 @@ cr.define('ntp4', function() { ...@@ -319,17 +319,18 @@ cr.define('ntp4', function() {
} }
/** /**
* Called by chrome when a new app has been added to chrome. * Called by chrome when a new app has been added to chrome or has been
* @param {Object} app A data structure full of relevant information for the * enabled if previously disabled.
* app. * @param {Object} appData A data structure full of relevant information for
* the app.
*/ */
function appAdded(app, opt_highlight) { function appAdded(appData, opt_highlight) {
if (app.id == highlightAppId) { if (appData.id == highlightAppId) {
opt_highlight = true; opt_highlight = true;
highlightAppId = null; highlightAppId = null;
} }
var pageIndex = app.page_index || 0; var pageIndex = appData.page_index || 0;
if (pageIndex >= appsPages.length) { if (pageIndex >= appsPages.length) {
while (pageIndex >= appsPages.length) { while (pageIndex >= appsPages.length) {
...@@ -339,7 +340,11 @@ cr.define('ntp4', function() { ...@@ -339,7 +340,11 @@ cr.define('ntp4', function() {
} }
var page = appsPages[pageIndex]; var page = appsPages[pageIndex];
page.appendApp(app, opt_highlight); var app = $(appData.id);
if (app)
app.replaceAppData(appData);
else
page.appendApp(appData, opt_highlight);
} }
/** /**
...@@ -351,15 +356,21 @@ cr.define('ntp4', function() { ...@@ -351,15 +356,21 @@ cr.define('ntp4', function() {
} }
/** /**
* Called by chrome when an existing app has been removed/uninstalled from * Called by chrome when an existing app has been disabled or
* chrome. * removed/uninstalled from chrome.
* @param {Object} appData A data structure full of relevant information for * @param {Object} appData A data structure full of relevant information for
* the app. * the app.
* @param {boolean} isUninstall True if the app is being uninstalled;
* false if the app is being disabled.
*/ */
function appRemoved(appData) { function appRemoved(appData, isUninstall) {
var app = $(appData.id); var app = $(appData.id);
assert(app, 'trying to remove an app that doesn\'t exist'); assert(app, 'trying to remove an app that doesn\'t exist');
app.remove();
if (!isUninstall)
app.replaceAppData(appData);
else
app.remove();
} }
/** /**
...@@ -390,6 +401,18 @@ cr.define('ntp4', function() { ...@@ -390,6 +401,18 @@ cr.define('ntp4', function() {
} }
} }
/**
* Listener for offline status change events. Updates apps that are
* not offline-enabled to be grayscale if the browser is offline.
*/
function updateOfflineEnabledApps() {
var apps = document.querySelectorAll('.app');
for (var i = 0; i < apps.length; ++i) {
if (apps[i].appData.enabled && !apps[i].appData.offline_enabled)
apps[i].setIcon();
}
}
function getCardSlider() { function getCardSlider() {
return cardSlider; return cardSlider;
} }
...@@ -795,7 +818,8 @@ cr.define('ntp4', function() { ...@@ -795,7 +818,8 @@ cr.define('ntp4', function() {
setMostVisitedPages: setMostVisitedPages, setMostVisitedPages: setMostVisitedPages,
setRecentlyClosedTabs: setRecentlyClosedTabs, setRecentlyClosedTabs: setRecentlyClosedTabs,
showNotification: showNotification, showNotification: showNotification,
themeChanged: themeChanged themeChanged: themeChanged,
updateOfflineEnabledApps: updateOfflineEnabledApps
}; };
}); });
...@@ -810,3 +834,5 @@ var recentlyClosedTabs = ntp4.setRecentlyClosedTabs; ...@@ -810,3 +834,5 @@ var recentlyClosedTabs = ntp4.setRecentlyClosedTabs;
var setMostVisitedPages = ntp4.setMostVisitedPages; var setMostVisitedPages = ntp4.setMostVisitedPages;
document.addEventListener('DOMContentLoaded', ntp4.initialize); document.addEventListener('DOMContentLoaded', ntp4.initialize);
window.addEventListener('online', ntp4.updateOfflineEnabledApps);
window.addEventListener('offline', ntp4.updateOfflineEnabledApps);
...@@ -117,24 +117,27 @@ void AppLauncherHandler::CreateAppInfo(const Extension* extension, ...@@ -117,24 +117,27 @@ void AppLauncherHandler::CreateAppInfo(const Extension* extension,
bool enabled = service->IsExtensionEnabled(extension->id()) && bool enabled = service->IsExtensionEnabled(extension->id()) &&
!service->GetTerminatedExtension(extension->id()); !service->GetTerminatedExtension(extension->id());
bool icon_big_exists = true; bool icon_big_exists = true;
// Instead of setting grayscale here, we do it in apps_page.js in NTP4.
bool grayscale = NewTabUI::NTP4Enabled() ? false : !enabled;
GURL icon_big = GURL icon_big =
ExtensionIconSource::GetIconURL(extension, ExtensionIconSource::GetIconURL(extension,
Extension::EXTENSION_ICON_LARGE, Extension::EXTENSION_ICON_LARGE,
ExtensionIconSet::MATCH_EXACTLY, ExtensionIconSet::MATCH_EXACTLY,
!enabled, &icon_big_exists); grayscale, &icon_big_exists);
bool icon_small_exists = true; bool icon_small_exists = true;
GURL icon_small = GURL icon_small =
ExtensionIconSource::GetIconURL(extension, ExtensionIconSource::GetIconURL(extension,
Extension::EXTENSION_ICON_BITTY, Extension::EXTENSION_ICON_BITTY,
ExtensionIconSet::MATCH_BIGGER, ExtensionIconSet::MATCH_BIGGER,
!enabled, &icon_small_exists); grayscale, &icon_small_exists);
value->Clear(); value->Clear();
value->SetString("id", extension->id()); value->SetString("id", extension->id());
value->SetString("name", extension->name()); value->SetString("name", extension->name());
value->SetString("description", extension->description()); value->SetString("description", extension->description());
value->SetString("launch_url", extension->GetFullLaunchURL().spec()); value->SetString("launch_url", extension->GetFullLaunchURL().spec());
if (enabled) value->SetBoolean("enabled", enabled);
if (NewTabUI::NTP4Enabled() || enabled)
value->SetString("options_url", extension->options_url().spec()); value->SetString("options_url", extension->options_url().spec());
value->SetBoolean("can_uninstall", value->SetBoolean("can_uninstall",
Extension::UserMayDisable(extension->location())); Extension::UserMayDisable(extension->location()));
...@@ -147,6 +150,7 @@ void AppLauncherHandler::CreateAppInfo(const Extension* extension, ...@@ -147,6 +150,7 @@ void AppLauncherHandler::CreateAppInfo(const Extension* extension,
value->SetInteger("launch_type", value->SetInteger("launch_type",
prefs->GetLaunchType(extension->id(), prefs->GetLaunchType(extension->id(),
ExtensionPrefs::LAUNCH_DEFAULT)); ExtensionPrefs::LAUNCH_DEFAULT));
value->SetBoolean("offline_enabled", extension->offline_enabled());
value->SetBoolean("is_component", value->SetBoolean("is_component",
extension->location() == Extension::COMPONENT); extension->location() == Extension::COMPONENT);
value->SetBoolean("is_webstore", value->SetBoolean("is_webstore",
...@@ -319,8 +323,14 @@ void AppLauncherHandler::Observe(int type, ...@@ -319,8 +323,14 @@ void AppLauncherHandler::Observe(int type,
} }
scoped_ptr<DictionaryValue> app_info(GetAppInfo(extension)); scoped_ptr<DictionaryValue> app_info(GetAppInfo(extension));
if (app_info.get()) scoped_ptr<base::FundamentalValue> uninstall_value(
web_ui_->CallJavascriptFunction("ntp4.appRemoved", *app_info); Value::CreateBooleanValue(
Details<UnloadedExtensionInfo>(details)->reason ==
extension_misc::UNLOAD_REASON_UNINSTALL));
if (app_info.get()) {
web_ui_->CallJavascriptFunction(
"ntp4.appRemoved", *app_info, *uninstall_value);
}
break; break;
} }
case chrome::NOTIFICATION_EXTENSION_LAUNCHER_REORDERED: case chrome::NOTIFICATION_EXTENSION_LAUNCHER_REORDERED:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment