diff options
author | finnur@chromium.org <finnur@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-07-02 09:30:20 +0000 |
---|---|---|
committer | finnur@chromium.org <finnur@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-07-02 09:30:20 +0000 |
commit | be79f8514da41f9b5cbcadfcfed768c8a390b401 (patch) | |
tree | f0ad97456842c0a5d06373cad7d18d8c30d58874 | |
parent | d274dd580a3b6a3850cca47bd54a60177ec9b3e9 (diff) | |
download | chromium_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.html | 13 | ||||
-rw-r--r-- | chrome/browser/resources/ntp/apps.css | 71 | ||||
-rw-r--r-- | chrome/browser/resources/ntp/apps.js | 138 |
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) { |