summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorfinnur@chromium.org <finnur@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-02 09:30:20 +0000
committerfinnur@chromium.org <finnur@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-02 09:30:20 +0000
commitbe79f8514da41f9b5cbcadfcfed768c8a390b401 (patch)
treef0ad97456842c0a5d06373cad7d18d8c30d58874
parentd274dd580a3b6a3850cca47bd54a60177ec9b3e9 (diff)
downloadchromium_src-be79f8514da41f9b5cbcadfcfed768c8a390b401.zip
chromium_src-be79f8514da41f9b5cbcadfcfed768c8a390b401.tar.gz
chromium_src-be79f8514da41f9b5cbcadfcfed768c8a390b401.tar.bz2
Wire up notifications to the New Tab page.
BUG=88067 TEST=asargent has an extension to test this with. Review URL: http://codereview.chromium.org/7291004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@91420 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/resources/new_tab.html13
-rw-r--r--chrome/browser/resources/ntp/apps.css71
-rw-r--r--chrome/browser/resources/ntp/apps.js138
3 files changed, 217 insertions, 5 deletions
diff --git a/chrome/browser/resources/new_tab.html b/chrome/browser/resources/new_tab.html
index 9726b9e..96e2a08 100644
--- a/chrome/browser/resources/new_tab.html
+++ b/chrome/browser/resources/new_tab.html
@@ -151,6 +151,19 @@ if ('mode' in hashParams) {
<button id="apps-promo-hide"></button>
</div>
<div id="apps-content"></div>
+ <div id="app-notification-bubble" class="notification-bubble">
+ <img id="app-notification-close" src="chrome://theme/IDR_CLOSE_BAR"
+ class="app-notification-close">
+ <strong id="app-notification-title"></strong><br>
+ <span id="app-notification-message"></span><br><br>
+ <a id="app-notification-link"></a>
+ </div>
+ <div id="arrow-contents"
+ class="arrow arrow-contents notification-bubble-closed"></div>
+ <div id="arrow-border"
+ class="arrow arrow-border notification-bubble-closed"></div>
+ <div id="arrow-shadow"
+ class="arrow arrow-shadow notification-bubble-closed"></div>
</div>
<div class="maxiview" id="most-visited-maxiview"></div>
diff --git a/chrome/browser/resources/ntp/apps.css b/chrome/browser/resources/ntp/apps.css
index 479a108..2f9340e 100644
--- a/chrome/browser/resources/ntp/apps.css
+++ b/chrome/browser/resources/ntp/apps.css
@@ -30,7 +30,7 @@ enough extra space in the small grid layout.
color: black;
margin: 5px 3px;
position: absolute;
- height: 136px;
+ height: 150px;
width: 124px; /* 920 / 7 - margin * 2 */
visibility: hidden;
}
@@ -98,6 +98,23 @@ enough extra space in the small grid layout.
opacity: .7;
}
+.app_notification {
+ color: gray;
+ display: block;
+ -webkit-transition: color .15s linear;
+}
+.app_notification:hover {
+ color: Blue;
+}
+
+.app-notification-close {
+ height: 14px;
+ position: absolute;
+ right: 6px;
+ top: 6px;
+ width: 14px;
+}
+
#apps-content[launcher-animations=true] .app {
-webkit-transition: top .2s, left .2s, right .2s, opacity .2s;
}
@@ -199,3 +216,55 @@ html[dir=rtl] .app.web-store-entry.loner {
padding: 2px 10px;
white-space: nowrap;
}
+
+.notification-bubble {
+ background-color: White;
+ border: 1px solid #B5B5B5;
+ font-family: Helvetica, Arial, sans-serif;
+ font-size : 107%;
+ min-height: 100px;
+ min-width: 200px;
+ opacity: 0;
+ padding: 10px;
+ position: absolute;
+ width: 200px;
+ -webkit-border-radius: 5px;
+ -webkit-box-shadow: 0 0 2px 1px rgba(0, 0, 0, 0.2);
+ -webkit-transition: opacity 0.2s linear;
+}
+.notification-bubble:focus {
+ outline: none;
+}
+
+.notification-bubble-opened {
+ opacity: 1;
+ pointer-events: auto;
+}
+.notification-bubble-closed {
+ opacity: 0;
+ pointer-events: none;
+}
+
+/* A content-less div with this setting, will create an arrow when coupled
+ with the arrow_* styles below it. */
+div.arrow {
+ border-style: solid;
+ border-width: 12px;
+ height: 0px;
+ width: 0px;
+ position: absolute;
+}
+div.arrow-contents {
+ border-color: transparent white transparent transparent;
+ z-index: 2;
+ -webkit-transition: opacity 0.2s linear;
+}
+div.arrow-shadow {
+ border-color: transparent gray transparent transparent;
+ -webkit-transition: opacity 0.2s linear;
+}
+div.arrow-border {
+ border-color: transparent #B5B5B5 transparent transparent;
+ z-index: 1;
+ -webkit-transition: opacity 0.2s linear;
+}
diff --git a/chrome/browser/resources/ntp/apps.js b/chrome/browser/resources/ntp/apps.js
index fe53705..0d26621 100644
--- a/chrome/browser/resources/ntp/apps.js
+++ b/chrome/browser/resources/ntp/apps.js
@@ -150,7 +150,9 @@ function appsPrefChangeCallback(data) {
}
function appNotificationChanged(id, lastNotification) {
- // TODO(asargent/finnur) use this when we hook up notifications into the NTP.
+ // TODO(asargent/finnur): Don't update all apps at once, do it in a more
+ // fine grained way.
+ chrome.send('getApps');
}
// Launches the specified app using the APP_LAUNCH_NTP_APP_RE_ENABLE histogram.
@@ -159,6 +161,77 @@ function launchAppAfterEnable(appId) {
chrome.send('launchApp', [appId, APP_LAUNCH.NTP_APP_RE_ENABLE]);
}
+// Shows the notification bubble for a given app (the one clicked on).
+function showNotificationBubble(event) {
+ var item = findAncestorByClass(event.target, 'app-anchor');
+ var title = item.getAttribute('notification-title');
+ var message = item.getAttribute('notification-message');
+ var link = item.getAttribute('notification-link');
+ var link_message = item.getAttribute('notification-link-message');
+
+ if (!title || !message)
+ return;
+
+ // Set the content to the right text.
+ $('app-notification-title').textContent = title;
+ $('app-notification-message').textContent = message;
+ $('app-notification-link').href = link;
+ $('app-notification-link').textContent = link_message;
+
+ var target = event.target;
+ while (target.parentElement && target.tagName != "A") {
+ target = target.parentElement;
+ }
+
+ // Move the bubble to the right location.
+ var bubble = $('app-notification-bubble');
+ var x = target.parentElement.offsetLeft +
+ target.parentElement.offsetWidth - 20;
+ var y = target.parentElement.offsetTop + 20;
+ bubble.style.left = x + "px";
+ bubble.style.top = y + "px";
+
+ // Move the arrow and shadow to the right location.
+ var arrow = $('arrow-contents');
+ var border = $('arrow-border');
+ var shadow = $('arrow-shadow');
+ y += 26;
+ x -= arrow.style.width + 23;
+ arrow.style.left = x + "px";
+ arrow.style.top = y + "px";
+ x -= 1;
+ border.style.left = x + "px";
+ border.style.top = y + "px";
+ x -= 1;
+ shadow.style.left = x + "px";
+ shadow.style.top = y + "px";
+
+ // Animate the bubble into view.
+ bubble.classList.add("notification-bubble-opened");
+ bubble.classList.remove("notification-bubble-closed");
+ arrow.classList.add("notification-bubble-opened");
+ arrow.classList.remove("notification-bubble-closed");
+ border.classList.add("notification-bubble-opened");
+ border.classList.remove("notification-bubble-closed");
+ shadow.classList.add("notification-bubble-opened");
+ shadow.classList.remove("notification-bubble-closed");
+
+ bubble.focus();
+}
+
+// Hide the notification bubble.
+function hideNotificationBubble(event) {
+ // This will fade the bubble out of existence.
+ $('app-notification-bubble').classList.add("notification-bubble-closed");
+ $('app-notification-bubble').classList.remove("notification-bubble-opened");
+ $('arrow-border').classList.add("notification-bubble-closed");
+ $('arrow-border').classList.remove("notification-bubble-opened");
+ $('arrow-shadow').classList.add("notification-bubble-closed");
+ $('arrow-shadow').classList.remove("notification-bubble-opened");
+ $('arrow-contents').classList.add("notification-bubble-closed");
+ $('arrow-contents').classList.remove("notification-bubble-opened");
+}
+
var apps = (function() {
function createElement(app) {
@@ -166,12 +239,37 @@ var apps = (function() {
div.className = 'app';
var a = div.appendChild(document.createElement('a'));
+ a.className = 'app-anchor';
a.setAttribute('app-id', app['id']);
a.setAttribute('launch-type', app['launch_type']);
+ if (typeof(app['notification']) != "undefined") {
+ a.setAttribute('notification-title', app['notification']['title']);
+ a.setAttribute('notification-message', app['notification']['body']);
+ if (typeof(app['notification']['linkUrl']) != "undefined" &&
+ typeof(app['notification']['linkText']) != "undefined") {
+ a.setAttribute('notification-link', app['notification']['linkUrl']);
+ a.setAttribute('notification-link-message',
+ app['notification']['linkText']);
+ }
+ }
a.draggable = false;
- a.xtitle = a.textContent = app['name'];
a.href = app['launch_url'];
+ var span = a.appendChild(document.createElement('span'));
+ span.textContent = app['name'];
+
+ span = a.appendChild(document.createElement('span'));
+ span.className = "app_notification";
+ span.textContent =
+ typeof(app['notification']) != "undefined" &&
+ typeof(app['notification']['title']) != "undefined" ?
+ app['notification']['title'] : "";
+ span.onclick = handleClick;
+
+ $("app-notification-close").onclick = hideNotificationBubble;
+ $("app-notification-bubble").setAttribute("tabIndex", 0);
+ $("app-notification-bubble").onblur = hideNotificationBubble;
+
return div;
}
@@ -219,6 +317,12 @@ var apps = (function() {
*/
function handleClick(e) {
var appId = e.currentTarget.getAttribute('app-id');
+ if (appId == null) {
+ showNotificationBubble(e);
+ e.stopPropagation();
+ return false;
+ }
+
if (!appDragAndDrop.isDragging())
launchApp(appId, e);
return false;
@@ -321,7 +425,7 @@ var apps = (function() {
e.canExecute = true;
break;
case 'apps-uninstall-command':
- e.canExecute = !currentApp['can_uninstall'];
+ e.canExecute = currentApp && !currentApp['can_uninstall'];
break;
}
});
@@ -684,7 +788,9 @@ var apps = (function() {
},
createElement: function(app) {
+ var container = document.createElement('div');
var div = createElement(app);
+ container.appendChild(div);
var a = div.firstChild;
a.onclick = handleClick;
@@ -719,7 +825,31 @@ var apps = (function() {
addContextMenu(div, app);
}
- return div;
+ if (app.notifications && app.notifications.length > 0) {
+ // Create the notification div below the app icon that is used to
+ // trigger the hidden notification bubble to appear.
+ var notification = document.createElement('div')
+ container.appendChild(notification);
+ var title = document.createElement('span');
+ title.innerText = app.notifications[0].title;
+ notification.appendChild(title);
+ notification.appendChild(document.createElement('br'));
+
+ var body = document.createElement('span');
+ container.appendChild(body);
+ body.innerText = app.notifications[0].body;
+ notification.appendChild(body);
+ if (app.notifications[0].linkUrl) {
+ notification.appendChild(document.createElement('br'));
+ var link = document.createElement('a');
+ link.href = app.notifications[0].linkUrl;
+ link.innerText = app.notifications[0].linkText ?
+ app.notifications[0].linkText : "link";
+ notification.appendChild(link);
+ }
+ }
+
+ return container;
},
createMiniviewElement: function(app) {