summaryrefslogtreecommitdiffstats
path: root/chrome/browser/resources/ntp
diff options
context:
space:
mode:
authorarv@chromium.org <arv@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-09-06 18:34:06 +0000
committerarv@chromium.org <arv@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-09-06 18:34:06 +0000
commit02b18209b05fc5c465d4518b9d7a4df1135c1a95 (patch)
tree1f79efbfd51b38a30f5441962e86752ea76956ca /chrome/browser/resources/ntp
parent004f80b0ab3bc8467b4df5a15b3e2fe040569aee (diff)
downloadchromium_src-02b18209b05fc5c465d4518b9d7a4df1135c1a95.zip
chromium_src-02b18209b05fc5c465d4518b9d7a4df1135c1a95.tar.gz
chromium_src-02b18209b05fc5c465d4518b9d7a4df1135c1a95.tar.bz2
NTP: Adds a context menu to the apps section
This uses the cr Menu system and replaces the old options menu with a cr Menu. BUG=52446 TEST=Start chrome with enable-apps. Install some apps. Right clicking on an app should show a context menu. Clicking the wrench should show the same menu. Review URL: http://codereview.chromium.org/3315005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@58648 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/resources/ntp')
-rw-r--r--chrome/browser/resources/ntp/apps.css77
-rw-r--r--chrome/browser/resources/ntp/apps.js235
-rw-r--r--chrome/browser/resources/ntp/most_visited.js21
3 files changed, 174 insertions, 159 deletions
diff --git a/chrome/browser/resources/ntp/apps.css b/chrome/browser/resources/ntp/apps.css
index 1527d9b..9c51f44 100644
--- a/chrome/browser/resources/ntp/apps.css
+++ b/chrome/browser/resources/ntp/apps.css
@@ -13,8 +13,6 @@
width: 124px; /* 920 / 7 - margin * 2 */
}
-.app > .front,
-.app > .back,
.app a {
border-radius: 10px;
bottom: 0;
@@ -24,12 +22,6 @@
top: 0;
}
-.app > .front,
-.app > .back {
- -webkit-backface-visibility: hidden;
- -webkit-transition: -webkit-transform .15s;
-}
-
.app a {
-webkit-transition: background-color .5s;
background: rgba(255, 255, 255, 0) /* transparent white */
@@ -45,8 +37,9 @@
white-space: nowrap;
}
-.app .flip {
+.app .app-settings {
background-color: transparent;
+ background-position: center center;
border: 0;
height: 14px;
padding: 0;
@@ -56,49 +49,24 @@
width: 14px;
}
-.app > .front > .flip {
+.app > .app-settings {
-webkit-transition: opacity .3s;
-webkit-transition-delay: 0;
background-image: url(chrome://theme/IDR_BALLOON_WRENCH);
opacity: 0;
}
-.app > .front > .flip:hover {
+.app > .app-settings:hover {
-webkit-transition: none;
background-image: url(chrome://theme/IDR_BALLOON_WRENCH_H);
}
-.app:hover > .front > .flip,
-.app > .front > .flip:focus {
+.app:hover > .app-settings,
+.app > .app-settings:focus {
-webkit-transition-delay: .5s;
opacity: .9;
}
-.app > .back > .flip {
- background-image: url(chrome://theme/IDR_BALLOON_CLOSE);
- opacity: .9;
-}
-
-.app > .back > .flip:hover {
- background-image: url(chrome://theme/IDR_BALLOON_CLOSE_HOVER);
-}
-
-.app > .back {
- padding: 10px;
-}
-
-.app > .back > h2 {
- font-size: 100%;
- margin: 10px 0;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-.app > .back > button:not(.flip) {
- width: 100%;
-}
-
@-webkit-keyframes bounce {
0% {
-webkit-transform: scale(0, 0);
@@ -122,37 +90,10 @@
-webkit-transition: opacity .5s;
}
-a[app_id=web-store-entry] {
+a[app-id=web-store-entry] {
background-image: url("web_store_icon.png");
}
-/* Make items on the wrong side non focusable by hiding them. */
-.app:not(.config) > .back button,
-.app.config > .front button,
-.app.config > .front a {
- display: none;
-}
-
-html[has_3d=true] .app.config > .front {
- -webkit-transform: rotateY(180deg);
-}
-
-html[has_3d=true] .app > .back {
- -webkit-transform: rotateY(-180deg);
-}
-
-html[has_3d=true] .app.config > .back {
- -webkit-transform: rotateY(0deg);
-}
-
-html[has_3d=false] .app.config > .front {
- display: none;
-}
-
-html[has_3d=false] .app > .back {
- display: none;
-}
-
-html[has_3d=false] .app.config > .back {
- display: block;
+menu > button.default {
+ font-weight: bold;
}
diff --git a/chrome/browser/resources/ntp/apps.js b/chrome/browser/resources/ntp/apps.js
index 0099634..c946b4d 100644
--- a/chrome/browser/resources/ntp/apps.js
+++ b/chrome/browser/resources/ntp/apps.js
@@ -30,111 +30,164 @@ function getAppsCallback(data) {
layoutSections();
}
-var apps = {
- /**
- * @this {!HTMLAnchorElement}
- */
- handleClick_: function() {
+var apps = (function() {
+
+ function createElement(app) {
+ var div = document.createElement('div');
+ div.className = 'app';
+
+ var a = div.appendChild(document.createElement('a'));
+ a.setAttribute('app-id', app['id']);
+ a.xtitle = a.textContent = app['name'];
+ a.href = app['launch_url'];
+
+ return div;
+ }
+
+ function createContextMenu(app) {
+ var menu = new cr.ui.Menu;
+ var button = document.createElement(button);
+ }
+
+ function launchApp(appId) {
+ var appsSection = $('apps');
+ var expanded = !appsSection.classList.contains('hidden');
+ var element = document.querySelector(
+ (expanded ? '.maxiview' : '.miniview') + ' a[app-id=' + appId + ']');
+
// TODO(arv): Handle zoom?
- var rect = this.getBoundingClientRect();
- var cs = getComputedStyle(this);
+ var rect = element.getBoundingClientRect();
+ var cs = getComputedStyle(element);
var size = cs.backgroundSize.split(/\s+/); // background-size has the
// format '123px 456px'.
+
var width = parseInt(size[0], 10);
var height = parseInt(size[1], 10);
- // We are using background-position-x 50%.
- var left = rect.left + ((rect.width - width) >> 1); // Integer divide by 2.
- var top = rect.top + parseInt(cs.backgroundPositionY, 10);
- chrome.send('launchApp', [this.getAttribute("app_id"),
+ var top, left;
+ if (expanded) {
+ // We are using background-position-x 50%.
+ top = rect.top + parseInt(cs.backgroundPositionY, 10);
+ left = rect.left + ((rect.width - width) >> 1); // Integer divide by 2.
+
+ } else {
+ // We are using background-position-y 50%.
+ top = rect.top + ((rect.height - width) >> 1); // Integer divide by 2.
+ if (getComputedStyle(element).direction == 'rtl')
+ left = rect.left + rect.width - width;
+ else
+ left = rect.left;
+ }
+
+ chrome.send('launchApp', [appId,
String(left), String(top),
String(width), String(height)]);
+ }
+
+ /**
+ * @this {!HTMLAnchorElement}
+ */
+ function handleClick(e) {
+ var appId = e.currentTarget.getAttribute('app-id');
+ launchApp(appId);
return false;
- },
+ }
- createElement_: function(app) {
- var div = document.createElement('div');
- div.className = 'app';
+ var currentApp;
- var front = div.appendChild(document.createElement('div'));
- front.className = 'front';
+ function addContextMenu(el, app) {
+ el.addEventListener('contextmenu', cr.ui.contextMenuHandler);
+ el.addEventListener('keydown', cr.ui.contextMenuHandler);
+ el.addEventListener('keyup', cr.ui.contextMenuHandler);
- var a = front.appendChild(document.createElement('a'));
- a.setAttribute('app_id', app['id']);
- a.xtitle = a.textContent = app['name'];
- a.href = app['launch_url'];
+ Object.defineProperty(el, 'contextMenu', {
+ get: function() {
+ currentApp = app;
- return div;
- },
-
- createElement: function(app) {
- var div = this.createElement_(app);
- var front = div.firstChild;
- var a = front.firstChild;
-
- a.onclick = apps.handleClick_;
- a.style.backgroundImage = url(app['icon_big']);
- if (hashParams['app-id'] == app['id']) {
- div.setAttribute('new', 'new');
- // Delay changing the attribute a bit to let the page settle down a bit.
- setTimeout(function() {
- div.setAttribute('new', 'installed');
- }, 500);
- }
+ $('apps-launch-command').label = app['name'];
+ $('apps-options-command').canExecuteChange();
- var settingsButton = front.appendChild(document.createElement('button'));
- settingsButton.className = 'flip';
- settingsButton.title = localStrings.getString('appsettings');
-
- var back = div.appendChild(document.createElement('div'));
- back.className = 'back';
-
- var header = back.appendChild(document.createElement('h2'));
- header.textContent = app['name'];
-
- var optionsButton = back.appendChild(document.createElement('button'));
- optionsButton.textContent = localStrings.getString('appoptions');
- optionsButton.disabled = !app['options_url'];
- optionsButton.onclick = function() {
- window.location = app['options_url'];
- };
-
- var uninstallButton = back.appendChild(document.createElement('button'));
- uninstallButton.textContent = uninstallButton.xtitle =
- localStrings.getString('appuninstall');
- uninstallButton.onclick = function() {
- chrome.send('uninstallApp', [app['id']]);
- };
-
- var closeButton = back.appendChild(document.createElement('button'));
- closeButton.title = localStrings.getString('close');
- closeButton.className = 'flip';
- closeButton.onclick = settingsButton.onclick = function() {
- div.classList.toggle('config');
- };
+ return $('app-context-menu');
+ }
+ });
+ }
- return div;
- },
+ document.addEventListener('command', function(e) {
+ if (!currentApp)
+ return;
+
+ switch (e.command.id) {
+ case 'apps-options-command':
+ window.location = currentApp['options_url'];
+ break;
+ case 'apps-launch-command':
+ launchApp(currentApp['id']);
+ break;
+ case 'apps-uninstall-command':
+ chrome.send('uninstallApp', [currentApp['id']]);
+ break;
+ }
+ });
- createMiniviewElement: function(app) {
- var span = document.createElement('span');
- var a = span.appendChild(document.createElement('a'));
+ document.addEventListener('canExecute', function(e) {
+ switch (e.command.id) {
+ case 'apps-options-command':
+ e.canExecute = currentApp && currentApp['options_url'];
+ break;
+ case 'apps-launch-command':
+ case 'apps-uninstall-command':
+ e.canExecute = true;
+ break;
+ }
+ });
- a.setAttribute('app_id', app['id']);
- a.textContent = app['name'];
- a.href = app['launch_url'];
- a.onclick = apps.handleClick_;
- a.style.backgroundImage = url(app['icon_small']);
- a.className = 'item';
- span.appendChild(a);
- return span;
- },
-
- createWebStoreElement: function() {
- return this.createElement_({
- 'id': 'web-store-entry',
- 'name': localStrings.getString('web_store_title'),
- 'launch_url': localStrings.getString('web_store_url')
- });
- }
-};
+ return {
+ createElement: function(app) {
+ var div = createElement(app);
+ var a = div.firstChild;
+
+ a.onclick = handleClick;
+ a.style.backgroundImage = url(app['icon_big']);
+ if (hashParams['app-id'] == app['id']) {
+ div.setAttribute('new', 'new');
+ // Delay changing the attribute a bit to let the page settle down a bit.
+ setTimeout(function() {
+ div.setAttribute('new', 'installed');
+ }, 500);
+ }
+
+ var settingsButton = div.appendChild(new cr.ui.ContextMenuButton);
+ settingsButton.className = 'app-settings';
+ settingsButton.title = localStrings.getString('appsettings');
+
+ addContextMenu(div, app);
+
+ return div;
+ },
+
+ createMiniviewElement: function(app) {
+ var span = document.createElement('span');
+ var a = span.appendChild(document.createElement('a'));
+
+ a.setAttribute('app-id', app['id']);
+ a.textContent = app['name'];
+ a.href = app['launch_url'];
+ a.onclick = handleClick;
+ a.style.backgroundImage = url(app['icon_small']);
+ a.className = 'item';
+ span.appendChild(a);
+
+ addContextMenu(span, app);
+
+ return span;
+ },
+
+ createWebStoreElement: function() {
+ return createElement({
+ 'id': 'web-store-entry',
+ 'name': localStrings.getString('web_store_title'),
+ 'launch_url': localStrings.getString('web_store_url')
+ });
+ }
+ };
+})();
diff --git a/chrome/browser/resources/ntp/most_visited.js b/chrome/browser/resources/ntp/most_visited.js
index 7dac8a4..bff2c1f 100644
--- a/chrome/browser/resources/ntp/most_visited.js
+++ b/chrome/browser/resources/ntp/most_visited.js
@@ -56,6 +56,10 @@ var MostVisited = (function() {
document.addEventListener('DOMContentLoaded',
bind(this.ensureSmallGridCorrect, this));
+ // Commands
+ document.addEventListener('command', bind(this.handleCommand_, this));
+ document.addEventListener('canExecute', bind(this.handleCanExecute_, this));
+
// DND
el.addEventListener('dragstart', bind(this.handleDragStart_, this));
el.addEventListener('dragenter', bind(this.handleDragEnter_, this));
@@ -300,6 +304,23 @@ var MostVisited = (function() {
return this.getMostVisitedLayoutRects_()[index];
},
+ // Commands
+
+ handleCommand_: function(e) {
+ var commandId = e.command.id;
+ switch (commandId) {
+ case 'clear-all-blacklisted':
+ this.clearAllBlacklisted();
+ chrome.send('getMostVisited');
+ break;
+ }
+ },
+
+ handleCanExecute_: function(e) {
+ if (e.command.id == 'clear-all-blacklisted')
+ e.canExecute = true;
+ },
+
// DND
currentOverItem_: null,