diff options
author | dharcourt@chromium.org <dharcourt@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-11 20:09:03 +0000 |
---|---|---|
committer | dharcourt@chromium.org <dharcourt@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-11 20:09:03 +0000 |
commit | 0b475cc8adb9fc555b14c8f6d3c1d443bb88bd0e (patch) | |
tree | 674920b4f7220caa7774e008c87884de72465540 | |
parent | e4a6d8cb9b5eb4d6aee952c4069182170af94cbc (diff) | |
download | chromium_src-0b475cc8adb9fc555b14c8f6d3c1d443bb88bd0e.zip chromium_src-0b475cc8adb9fc555b14c8f6d3c1d443bb88bd0e.tar.gz chromium_src-0b475cc8adb9fc555b14c8f6d3c1d443bb88bd0e.tar.bz2 |
Updated Notifications Galore! test app for notifications API changes.
Updated this test app to accomodate the API changes committed in
r12212037 (type -> templateType, button{One,Two}* -> buttons, no more
onError event) and in r12313115 (templateType -> type,
chrome.experimental.notification -> chrome.notifications).
Also fixed an issue which caused some image notification's images to not
show up. The fix involved pre-fetching all images, which is a good idea
anyway and may be required by the API in the future.
Also increased the app-data separation by having the test notification
data loaded dynamically. This will allow in the future different test
data sets to be used with with app and it will allow the apps' test data
to be changed without an app update. In addition, API calls are now
fully defined by the test data through "api", "events" and "global"
properties, so this test app's code will not need to change to adjust to
changes in the notifications API.
Also added support for generating notifications using the WebKit
webkitNotifications.createNotification() API.
Finally, also tweaked the user interface to: 1) Have correct cursors
for dragging/button selection; 2) Allow dragging across notification
buttons to change button selection; 3) Allow clearing of the events
log (through an added menu and menu item); and 4) Remember the priority
setting.
BUG=174680
R=miket
Review URL: https://codereview.chromium.org/12489004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@187353 0039d316-1c4b-4281-b951-d872f2087c98
56 files changed, 898 insertions, 455 deletions
diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/controller.js b/chrome/test/data/extensions/api_test/notifications/galore/app/controller.js index 147c3af..6b0fe94 100644 --- a/chrome/test/data/extensions/api_test/notifications/galore/app/controller.js +++ b/chrome/test/data/extensions/api_test/notifications/galore/app/controller.js @@ -5,100 +5,206 @@ var Galore = Galore || {}; Galore.controller = { - - BUTTON_IMAGE_SIZE: 64, - NOTIFICATION_ICON_SIZE: 80, - + /** @constructor */ create: function() { + Galore.identifier = Galore.identifier ? (Galore.identifier + 1) : 1; var controller = Object.create(this); + controller.identifier = Galore.identifier; + controller.api = chrome; controller.counter = 0; - controller.prefix = chrome.runtime.getURL('').slice(0, -1); - controller.view = Galore.view.create(this.prepare_.bind(controller)); - controller.listen_('onDisplayed'); - controller.listen_('onClosed'); - controller.listen_('onClicked'); - controller.listen_('onButtonClicked'); return controller; }, + createWindow: function() { + this.view = Galore.view.create(function() { + var request = new XMLHttpRequest(); + request.open('GET', '/data/notifications.json', true); + request.responseType = 'text'; + request.onload = this.onData_.bind(this, request); + request.send(); + }.bind(this)); + }, + /** @private */ - listen_: function(event) { - var listener = this.event_.bind(this, event); - chrome.notifications[event].addListener(listener); + onData_: function(request) { + var data = JSON.parse(request.response); + var path = data[0].api || 'notifications'; + this.api = chrome; + path.split('.').forEach(function(key) { + var before = this.api; + this.api = this.api && this.api[key]; + }, this); + if (this.api) + this.onApi_(data); + else + this.view.logError('No API found - chrome.' + path + ' is undefined'); }, /** @private */ - prepare_: function() { - Galore.NOTIFICATIONS.forEach(function (type) { - type.notifications.forEach(function (options) { - this.view.addNotificationButton( - type.type, - type.name, - this.replace_(options.iconUrl, this.BUTTON_IMAGE_SIZE), - this.notify_.bind(this, type.type, options)); + onApi_: function(data) { + var count = 0; + var globals = data[0].globals || {}; + (data[0].events || []).forEach(function(event) { + this.addListener_(event); + }, this); + data.forEach(function(section) { + (section.notificationOptions || []).forEach(function(options) { + var button = this.view.addNotificationButton(section.sectionName); + Object.keys(section.globals || globals).forEach(function (key) { + options[key] = options[key] || (section.globals || globals)[key]; + }); + ++count; + this.fetchImages_(options, function() { + var create = this.createNotification_.bind(this, section, options); + var iconUrl = options.galoreIconUrl || options.iconUrl; + delete options.galoreIconUrl; + this.view.setNotificationButtonAction(button, create); + this.view.setNotificationButtonIcon(button, iconUrl, options.title); + if (--count == 0) + this.view.showWindow(); + }.bind(this)); }, this); }, this); }, /** @private */ - id_: function() { + onImages_: function(button, section, options) { + var create = this.createNotification_.bind(this, section, options); + var iconUrl = options.galoreIconUrl || options.iconUrl; + delete options.galoreIconUrl; + this.view.setNotificationButtonAction(button, create); + this.view.setNotificationButtonIcon(button, iconUrl, options.title); + }, + + /** @private */ + fetchImages_: function(options, onFetched) { + var count = 0; + var replacements = {}; + this.mapStrings_(options, function(string) { + if (string.indexOf("/images/") == 0 || string.indexOf("http:/") == 0) { + ++count; + this.fetchImage_(string, function(url) { + replacements[string] = url; + if (--count == 0) { + this.mapStrings_(options, function(string) { + return replacements[string] || string; + }); + onFetched.call(this, options); + } + }); + } + }); + }, + + /** @private */ + fetchImage_: function(url, onFetched) { + var request = new XMLHttpRequest(); + request.open('GET', url, true); + request.responseType = 'blob'; + request.onload = function() { + var url = window.URL.createObjectURL(request.response); + onFetched.call(this, url); + }.bind(this); + request.send(); + }, + + /** @private */ + createNotification_: function(section, options) { + var id = this.getNextId_(); + var type = section.notificationType; + var priority = this.view.settings.priority; + var expanded = this.expandOptions_(options, id, type, priority); + if (type == 'webkit') + this.createWebKitNotification_(expanded); + else + this.createRichNotification_(expanded, id, type, priority); + }, + + /** @private */ + createWebKitNotification_: function(options) { + var iconUrl = options.iconUrl; + var title = options.title; + var message = options.message; + webkitNotifications.createNotification(iconUrl, title, message).show(); + this.handleEvent_('create', '?', 'title: "' + title + '"'); + }, + + /** @private */ + createRichNotification_: function(options, id, type, priority) { + this.api.create(id, options, function() { + var argument1 = 'type: "' + type + '"'; + var argument2 = 'priority: ' + priority; + var argument3 = 'title: "' + options.title + '"'; + this.handleEvent_('create', id, argument1, argument2, argument3); + }.bind(this)); + }, + + /** @private */ + getNextId_: function() { this.counter += 1; return String(this.counter); }, /** @private */ - notify_: function(type, options) { - var id = this.id_(); - var priority = this.view.getPriority(); - var expanded = this.expand_(options, type, priority); - if (chrome.notifications.create) { - chrome.notifications.create(id, expanded, function() {}); + expandOptions_: function(options, id, type, priority) { + var expanded = this.deepCopy_(options); + return this.mapStrings_(expanded, function(string) { + return this.expandOption_(string, id, type, priority); + }, this); + }, + /** @private */ + expandOption_: function(option, id, type, priority) { + if (option == '$!') { + option = priority; // Avoids making priorities into strings. } else { - expanded.replaceId = id; - delete expanded.buttonOneIconUrl; - delete expanded.buttonOneTitle; - delete expanded.buttonTwoIconUrl; - delete expanded.buttonTwoTitle; - chrome.notifications.show(expanded, function() {}); + option = option.replace(/\$#/g, id); + option = option.replace(/\$\?/g, type); + option = option.replace(/\$\!/g, priority); } - this.event_('create', id, 'priority: ' + priority); + return option; }, /** @private */ - expand_: function(options, type, priority) { - var expanded = {type: type, priority: priority}; - Object.keys(options).forEach(function (key) { - expanded[key] = this.replace_(options[key], this.NOTIFICATION_ICON_SIZE); - }, this); - return expanded; + deepCopy_: function(value) { + var copy = value; + if (Array.isArray(value)) { + copy = value.map(this.deepCopy_, this); + } else if (value && typeof value === 'object') { + copy = {} + Object.keys(value).forEach(function (key) { + copy[key] = this.deepCopy_(value[key]); + }, this); + } + return copy; }, /** @private */ - replace_: function(option, size) { - var replaced; - if (typeof option === 'string') { - replaced = option.replace(/\$#/g, this.counter); - replaced = replaced.replace(/\$@/g, this.prefix); - replaced = replaced.replace(/\$%/g, size); - } else if (Array.isArray(option)) { - replaced = []; - option.forEach(function(element) { - replaced.push(this.replace_(element, size)); - }, this); - } else { - replaced = {}; - Object.keys(option).forEach(function (key) { - replaced[key] = this.replace_(option[key], size); + mapStrings_: function(value, map) { + var mapped = value; + if (typeof value === 'string') { + mapped = map.call(this, value); + mapped = (typeof mapped !== 'undefined') ? mapped : value; + } else if (value && typeof value == 'object') { + Object.keys(value).forEach(function (key) { + mapped[key] = this.mapStrings_(value[key], map); }, this); } - return replaced; + return mapped; }, /** @private */ - event_: function(event, id, var_args) { + addListener_: function(event) { + var listener = this.handleEvent_.bind(this, event); + if (this.api[event]) + this.api[event].addListener(listener); + else + console.log('Event ' + event + ' not defined.'); + }, + + /** @private */ + handleEvent_: function(event, id, var_args) { this.view.logEvent('Notification #' + id + ': ' + event + '(' + Array.prototype.slice.call(arguments, 2).join(', ') + ')'); } - }; diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/data/notifications.json b/chrome/test/data/extensions/api_test/notifications/galore/app/data/notifications.json new file mode 100644 index 0000000..fcfca7a --- /dev/null +++ b/chrome/test/data/extensions/api_test/notifications/galore/app/data/notifications.json @@ -0,0 +1,282 @@ +[ + { + "copyright": [ + "Copyright (c) 2013 The Chromium Authors. All rights reserved.", + "Use of this source code is governed by a BSD-style license that can be", + "found in the LICENSE file." + ], + "api": "notifications", + "events": [ + "onDisplayed", + "onClosed", + "onClicked", + "onButtonClicked" + ], + "globals": { + "type": "$?", + "priority": "$!" + } + }, + { + "sectionName": "WebKit Notifications", + "notificationType": "webkit", + "notificationOptions": [ + { + "iconUrl": "/images/man1-80x80.jpg", + "title": "Althe Frazon", + "message": "Lorem ipsum" + }, + { + "iconUrl": "/images/woman1-80x80.jpg", + "title": "Kathrine Doiss", + "message": "Dolor sit amet" + }, + { + "iconUrl": "/images/woman2-80x80.jpg", + "title": "Jamie Haynig", + "message": "Consectetur adipisicing elit" + }, + { + "iconUrl": "/images/woman3-80x80.jpg", + "title": "Maricia Rilari", + "message": "Sed do eiusmod tempor incididunt" + } + ] + }, + { + "sectionName": "Simple Notifications", + "notificationType": "simple", + "notificationOptions": [ + { + "iconUrl": "/images/man1-80x80.jpg", + "title": "Althe Frazon", + "message": "Lorem ipsum" + }, + { + "iconUrl": "/images/woman1-80x80.jpg", + "title": "Kathrine Doiss", + "message": "Dolor sit amet" + }, + { + "iconUrl": "/images/woman2-80x80.jpg", + "title": "Jamie Haynig", + "message": "Consectetur adipisicing elit" + }, + { + "iconUrl": "/images/woman3-80x80.jpg", + "title": "Maricia Rilari", + "message": "Sed do eiusmod tempor incididunt" + } + ] + }, + { + "sectionName": "Basic Notifications", + "notificationType": "basic", + "notificationOptions": [ + { + "iconUrl": "/images/man1-80x80.jpg", + "title": "Althe Frazon", + "message": "Lorem ipsum", + "buttons": [ + {"title": "Call", "iconUrl": "/images/call-16x16.png"}, + {"title": "Send Email", "iconUrl": "/images/send-16x16.png"} + ] + }, + { + "iconUrl": "/images/woman1-80x80.jpg", + "title": "Kathrine Doiss", + "message": "Dolor sit amet" + }, + { + "iconUrl": "/images/woman2-80x80.jpg", + "title": "Jamie Haynig", + "message": "Consectetur adipisicing elit" + }, + { + "iconUrl": "/images/woman3-80x80.jpg", + "title": "Maricia Rilari", + "message": "Sed do eiusmod tempor incididunt" + }, + { + "iconUrl": "/images/fruit1-80x80.jpg", + "title": "Notification #$#: Pears!", + "message": "Pyrus" + }, + { + "iconUrl": "/images/fruit2-80x80.jpg", + "title": "Notification #$#: Oranges!", + "message": "Citrus sinensis" + }, + { + "iconUrl": "/images/fruit3-80x80.jpg", + "title": "Notification #$#: Strawberries!", + "message": "Fragaria ananassa" + }, + { + "iconUrl": "/images/fruit4-80x80.jpg", + "title": "Notification #$#: Raspberries!", + "message": "Rubus idaeus" + }, + { + "iconUrl": "/images/fruit5-80x80.jpg", + "title": "Notification #$#: Blueberries!", + "message": "Vaccinium cyanococcus" + } + ] + }, + { + "sectionName": "Image Notifications", + "notificationType": "image", + "notificationOptions": [ + { + "iconUrl": "/images/woman3-80x80.jpg", + "title": "Maricia Rilari", + "message": "Pictures from Tahoe", + "imageUrl": "/images/tahoe-300x225.jpg" + }, + { + "iconUrl": "/images/flower1-80x80.jpg", + "title": "Notification #$#: Daffodils!", + "message": "Narcissus", + "imageUrl": "/images/image1-300x225.jpg", + "buttons": [ + {"title": "Lorem Ipsum Dolor Sit Amet Consectetur Adipisicing"}, + {"title": "Elit Sed Do"} + ] + }, + { + "iconUrl": "/images/flower2-80x80.jpg", + "title": "Notification #$#: Sunflowers!", + "message": "Helianthus annuus", + "imageUrl": "/images/image2-300x225.jpg" + }, + { + "iconUrl": "/images/flower3-80x80.jpg", + "title": "Notification #$#: Poinsettias!", + "message": "Euphorbia pulcherrima", + "imageUrl": "/images/image3-300x172.jpg" + }, + { + "iconUrl": "/images/flower4-80x80.jpg", + "title": "Notification #$#: Heather!", + "message": "Calluna vulgaris", + "imageUrl": "/images/image4-200x300.jpg" + } + ] + }, + { + "sectionName": "List Notifications", + "notificationType": "list", + "notificationOptions": [ + { + "iconUrl": "/images/inbox-00-80x80.png", + "title": "15 new messages", + "message": "ramon.widdel@example.com", + "items": [ + {"title": "Althe Frazon", "message": "Lorem ipsum dolor sit amet"}, + {"title": "Kathrine Doiss", "message": "Consectetur adipisicing eli"}, + {"title": "Jamie Haynig", "message": "Sed do eiusmod tempor incidid"}, + {"title": "Kelly Seiken", "message": "Ut labore et dolore magna ali"}, + {"title": "Maricia Rilari", "message": "Ut enim ad minim veniam"} + ], + "buttons": [ + {"title": "Send Message", "iconUrl": "/images/send-16x16.png"} + ] + }, + { + "iconUrl": "/images/inbox-01-80x80.png", + "title": "1 new messages", + "message": "ramon.widdel@example.com", + "items": [ + {"title": "Althe Frazon", "message": "Lorem ipsum dolor sit amet"} + ] + }, + { + "iconUrl": "/images/inbox-02-80x80.png", + "title": "2 new messages", + "message": "ramon.widdel@example.com", + "items": [ + {"title": "Althe Frazon", "message": "Lorem ipsum dolor sit amet"}, + {"title": "Kathrine Doiss", "message": "Consectetur adipisicing elit"} + ] + }, + { + "iconUrl": "/images/inbox-03-80x80.png", + "title": "3 new messages", + "message": "ramon.widdel@example.com", + "items": [ + {"title": "Althe Frazon", "message": "Lorem ipsum dolor sit amet"}, + {"title": "Kathrine Doiss", "message": "Consectetur adipisicing eli"}, + {"title": "Jamie Haynig", "message": "Sed do eiusmod tempor incididu"} + ] + }, + { + "iconUrl": "/images/inbox-05-80x80.png", + "title": "5 new messages", + "message": "ramon.widdel@example.com", + "items": [ + {"title": "Althe Frazon", "message": "Lorem ipsum dolor sit amet"}, + {"title": "Kathrine Doiss", "message": "Consectetur adipisicing eli"}, + {"title": "Jamie Haynig", "message": "Sed do eiusmod tempor incidid"}, + {"title": "Kelly Seiken", "message": "Ut labore et dolore magna ali"}, + {"title": "Maricia Rilari", "message": "Ut enim ad minim veniam"} + ] + }, + { + "iconUrl": "/images/inbox-08-80x80.png", + "title": "8 new messages", + "message": "ramon.widdel@example.com", + "items": [ + {"title": "Althe Frazon", "message": "Lorem ipsum dolor sit amet"}, + {"title": "Kathrine Doiss", "message": "Consectetur adipisicing eli"}, + {"title": "Jamie Haynig", "message": "Sed do eiusmod tempor incidid"}, + {"title": "Kelly Seiken", "message": "Ut labore et dolore magna ali"}, + {"title": "Maricia Rilari", "message": "Ut enim ad minim veniam"}, + {"title": "Althe Frazon", "message": "Lorem ipsum dolor sit amet"}, + {"title": "Kathrine Doiss", "message": "Consectetur adipisicing eli"}, + {"title": "Jamie Haynig", "message": "Sed do eiusmod tempor incididu"} + ] + }, + { + "iconUrl": "/images/inbox-13-80x80.png", + "title": "13 new messages", + "message": "ramon.widdel@example.com", + "items": [ + {"title": "Althe Frazon", "message": "Lorem ipsum dolor sit amet"}, + {"title": "Kathrine Doiss", "message": "Consectetur adipisicing eli"}, + {"title": "Jamie Haynig", "message": "Sed do eiusmod tempor incidid"}, + {"title": "Kelly Seiken", "message": "Ut labore et dolore magna ali"}, + {"title": "Maricia Rilari", "message": "Ut enim ad minim veniam"}, + {"title": "Althe Frazon", "message": "Lorem ipsum dolor sit amet"}, + {"title": "Kathrine Doiss", "message": "Consectetur adipisicing eli"}, + {"title": "Jamie Haynig", "message": "Sed do eiusmod tempor incidid"}, + {"title": "Kelly Seiken", "message": "Ut labore et dolore magna ali"}, + {"title": "Maricia Rilari", "message": "Ut enim ad minim veniam"}, + {"title": "Althe Frazon", "message": "Lorem ipsum dolor sit amet"}, + {"title": "Kathrine Doiss", "message": "Consectetur adipisicing eli"}, + {"title": "Jamie Haynig", "message": "Sed do eiusmod tempor incididu"} + ] + }, + { + "iconUrl": "/images/plant1-80x80.jpg", + "title": "Notification #$#: Yucca!", + "message": "Asparagaceae agavoideae", + "items": [ + {"title": "One", "message": "Unus"}, + {"title": "Two", "message": "Duo"}, + {"title": "Three", "message": "Tres"} + ] + }, + { + "iconUrl": "/images/plant2-80x80.jpg", + "title": "Notification #$#: Basil!", + "message": "Ocimum basilicum", + "items": [ + {"title": "One", "message": "Unus"}, + {"title": "Two", "message": "Duo"}, + {"title": "Three", "message": "Tres"} + ] + } + ] + } +] diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/images/close-14x14.png b/chrome/test/data/extensions/api_test/notifications/galore/app/images/close-14x14.png Binary files differnew file mode 100644 index 0000000..1564989 --- /dev/null +++ b/chrome/test/data/extensions/api_test/notifications/galore/app/images/close-14x14.png diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/images/close-26x26.png b/chrome/test/data/extensions/api_test/notifications/galore/app/images/close-26x26.png Binary files differdeleted file mode 100644 index 8d30d47..0000000 --- a/chrome/test/data/extensions/api_test/notifications/galore/app/images/close-26x26.png +++ /dev/null diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/images/close-highlighted-14x14.png b/chrome/test/data/extensions/api_test/notifications/galore/app/images/close-highlighted-14x14.png Binary files differnew file mode 100644 index 0000000..d55a1ae --- /dev/null +++ b/chrome/test/data/extensions/api_test/notifications/galore/app/images/close-highlighted-14x14.png diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/images/flower1-64x64.jpg b/chrome/test/data/extensions/api_test/notifications/galore/app/images/flower1-64x64.jpg Binary files differdeleted file mode 100644 index a710f7f..0000000 --- a/chrome/test/data/extensions/api_test/notifications/galore/app/images/flower1-64x64.jpg +++ /dev/null diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/images/flower2-64x64.jpg b/chrome/test/data/extensions/api_test/notifications/galore/app/images/flower2-64x64.jpg Binary files differdeleted file mode 100644 index dafb7d6..0000000 --- a/chrome/test/data/extensions/api_test/notifications/galore/app/images/flower2-64x64.jpg +++ /dev/null diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/images/flower3-64x64.jpg b/chrome/test/data/extensions/api_test/notifications/galore/app/images/flower3-64x64.jpg Binary files differdeleted file mode 100644 index cec7def..0000000 --- a/chrome/test/data/extensions/api_test/notifications/galore/app/images/flower3-64x64.jpg +++ /dev/null diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/images/flower4-64x64.jpg b/chrome/test/data/extensions/api_test/notifications/galore/app/images/flower4-64x64.jpg Binary files differdeleted file mode 100644 index 3e94ba6..0000000 --- a/chrome/test/data/extensions/api_test/notifications/galore/app/images/flower4-64x64.jpg +++ /dev/null diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/images/fruit1-64x64.jpg b/chrome/test/data/extensions/api_test/notifications/galore/app/images/fruit1-64x64.jpg Binary files differdeleted file mode 100644 index 2175713..0000000 --- a/chrome/test/data/extensions/api_test/notifications/galore/app/images/fruit1-64x64.jpg +++ /dev/null diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/images/fruit1-80x80.jpg b/chrome/test/data/extensions/api_test/notifications/galore/app/images/fruit1-80x80.jpg Binary files differindex a5f720f..f3088e0 100644 --- a/chrome/test/data/extensions/api_test/notifications/galore/app/images/fruit1-80x80.jpg +++ b/chrome/test/data/extensions/api_test/notifications/galore/app/images/fruit1-80x80.jpg diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/images/fruit2-64x64.jpg b/chrome/test/data/extensions/api_test/notifications/galore/app/images/fruit2-64x64.jpg Binary files differdeleted file mode 100644 index b75d376..0000000 --- a/chrome/test/data/extensions/api_test/notifications/galore/app/images/fruit2-64x64.jpg +++ /dev/null diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/images/fruit2-80x80.jpg b/chrome/test/data/extensions/api_test/notifications/galore/app/images/fruit2-80x80.jpg Binary files differindex f3088e0..96fa425 100644 --- a/chrome/test/data/extensions/api_test/notifications/galore/app/images/fruit2-80x80.jpg +++ b/chrome/test/data/extensions/api_test/notifications/galore/app/images/fruit2-80x80.jpg diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/images/fruit3-64x64.jpg b/chrome/test/data/extensions/api_test/notifications/galore/app/images/fruit3-64x64.jpg Binary files differdeleted file mode 100644 index e7a1d11..0000000 --- a/chrome/test/data/extensions/api_test/notifications/galore/app/images/fruit3-64x64.jpg +++ /dev/null diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/images/fruit3-80x80.jpg b/chrome/test/data/extensions/api_test/notifications/galore/app/images/fruit3-80x80.jpg Binary files differindex 96fa425..27d47c2 100644 --- a/chrome/test/data/extensions/api_test/notifications/galore/app/images/fruit3-80x80.jpg +++ b/chrome/test/data/extensions/api_test/notifications/galore/app/images/fruit3-80x80.jpg diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/images/fruit4-64x64.jpg b/chrome/test/data/extensions/api_test/notifications/galore/app/images/fruit4-64x64.jpg Binary files differdeleted file mode 100644 index 2647975..0000000 --- a/chrome/test/data/extensions/api_test/notifications/galore/app/images/fruit4-64x64.jpg +++ /dev/null diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/images/fruit4-80x80.jpg b/chrome/test/data/extensions/api_test/notifications/galore/app/images/fruit4-80x80.jpg Binary files differindex 27d47c2..73503c1 100644 --- a/chrome/test/data/extensions/api_test/notifications/galore/app/images/fruit4-80x80.jpg +++ b/chrome/test/data/extensions/api_test/notifications/galore/app/images/fruit4-80x80.jpg diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/images/fruit5-64x64.jpg b/chrome/test/data/extensions/api_test/notifications/galore/app/images/fruit5-64x64.jpg Binary files differdeleted file mode 100644 index 7292dd1..0000000 --- a/chrome/test/data/extensions/api_test/notifications/galore/app/images/fruit5-64x64.jpg +++ /dev/null diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/images/fruit5-80x80.jpg b/chrome/test/data/extensions/api_test/notifications/galore/app/images/fruit5-80x80.jpg Binary files differindex 73503c1..ac6b89e 100644 --- a/chrome/test/data/extensions/api_test/notifications/galore/app/images/fruit5-80x80.jpg +++ b/chrome/test/data/extensions/api_test/notifications/galore/app/images/fruit5-80x80.jpg diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/images/fruit6-64x64.jpg b/chrome/test/data/extensions/api_test/notifications/galore/app/images/fruit6-64x64.jpg Binary files differdeleted file mode 100644 index 843f65b..0000000 --- a/chrome/test/data/extensions/api_test/notifications/galore/app/images/fruit6-64x64.jpg +++ /dev/null diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/images/fruit6-80x80.jpg b/chrome/test/data/extensions/api_test/notifications/galore/app/images/fruit6-80x80.jpg Binary files differdeleted file mode 100644 index ac6b89e..0000000 --- a/chrome/test/data/extensions/api_test/notifications/galore/app/images/fruit6-80x80.jpg +++ /dev/null diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/images/inbox-00-64x64.png b/chrome/test/data/extensions/api_test/notifications/galore/app/images/inbox-00-64x64.png Binary files differdeleted file mode 100644 index 74ca825..0000000 --- a/chrome/test/data/extensions/api_test/notifications/galore/app/images/inbox-00-64x64.png +++ /dev/null diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/images/inbox-01-64x64.png b/chrome/test/data/extensions/api_test/notifications/galore/app/images/inbox-01-64x64.png Binary files differdeleted file mode 100644 index d43f624..0000000 --- a/chrome/test/data/extensions/api_test/notifications/galore/app/images/inbox-01-64x64.png +++ /dev/null diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/images/inbox-02-64x64.png b/chrome/test/data/extensions/api_test/notifications/galore/app/images/inbox-02-64x64.png Binary files differdeleted file mode 100644 index 3a25def..0000000 --- a/chrome/test/data/extensions/api_test/notifications/galore/app/images/inbox-02-64x64.png +++ /dev/null diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/images/inbox-03-64x64.png b/chrome/test/data/extensions/api_test/notifications/galore/app/images/inbox-03-64x64.png Binary files differdeleted file mode 100644 index 26dc041..0000000 --- a/chrome/test/data/extensions/api_test/notifications/galore/app/images/inbox-03-64x64.png +++ /dev/null diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/images/inbox-05-64x64.png b/chrome/test/data/extensions/api_test/notifications/galore/app/images/inbox-05-64x64.png Binary files differdeleted file mode 100644 index d63c84e..0000000 --- a/chrome/test/data/extensions/api_test/notifications/galore/app/images/inbox-05-64x64.png +++ /dev/null diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/images/inbox-08-64x64.png b/chrome/test/data/extensions/api_test/notifications/galore/app/images/inbox-08-64x64.png Binary files differdeleted file mode 100644 index e41e9a5..0000000 --- a/chrome/test/data/extensions/api_test/notifications/galore/app/images/inbox-08-64x64.png +++ /dev/null diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/images/inbox-13-64x64.png b/chrome/test/data/extensions/api_test/notifications/galore/app/images/inbox-13-64x64.png Binary files differdeleted file mode 100644 index cb5c539..0000000 --- a/chrome/test/data/extensions/api_test/notifications/galore/app/images/inbox-13-64x64.png +++ /dev/null diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/images/man1-64x64.jpg b/chrome/test/data/extensions/api_test/notifications/galore/app/images/man1-64x64.jpg Binary files differdeleted file mode 100644 index 57eadcd..0000000 --- a/chrome/test/data/extensions/api_test/notifications/galore/app/images/man1-64x64.jpg +++ /dev/null diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/images/menu-14x14.png b/chrome/test/data/extensions/api_test/notifications/galore/app/images/menu-14x14.png Binary files differnew file mode 100644 index 0000000..7c277a0 --- /dev/null +++ b/chrome/test/data/extensions/api_test/notifications/galore/app/images/menu-14x14.png diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/images/menu-highlighted-14x14.png b/chrome/test/data/extensions/api_test/notifications/galore/app/images/menu-highlighted-14x14.png Binary files differnew file mode 100644 index 0000000..4eceb2a --- /dev/null +++ b/chrome/test/data/extensions/api_test/notifications/galore/app/images/menu-highlighted-14x14.png diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/images/plant1-64x64.jpg b/chrome/test/data/extensions/api_test/notifications/galore/app/images/plant1-64x64.jpg Binary files differdeleted file mode 100644 index 8953462..0000000 --- a/chrome/test/data/extensions/api_test/notifications/galore/app/images/plant1-64x64.jpg +++ /dev/null diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/images/plant2-64x64.jpg b/chrome/test/data/extensions/api_test/notifications/galore/app/images/plant2-64x64.jpg Binary files differdeleted file mode 100644 index b06d6ef..0000000 --- a/chrome/test/data/extensions/api_test/notifications/galore/app/images/plant2-64x64.jpg +++ /dev/null diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/images/plant2-80x80.jpg b/chrome/test/data/extensions/api_test/notifications/galore/app/images/plant2-80x80.jpg Binary files differindex 4e51cc8..f69d574 100644 --- a/chrome/test/data/extensions/api_test/notifications/galore/app/images/plant2-80x80.jpg +++ b/chrome/test/data/extensions/api_test/notifications/galore/app/images/plant2-80x80.jpg diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/images/plant3-64x64.jpg b/chrome/test/data/extensions/api_test/notifications/galore/app/images/plant3-64x64.jpg Binary files differdeleted file mode 100644 index f1ae350..0000000 --- a/chrome/test/data/extensions/api_test/notifications/galore/app/images/plant3-64x64.jpg +++ /dev/null diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/images/plant3-80x80.jpg b/chrome/test/data/extensions/api_test/notifications/galore/app/images/plant3-80x80.jpg Binary files differdeleted file mode 100644 index f69d574..0000000 --- a/chrome/test/data/extensions/api_test/notifications/galore/app/images/plant3-80x80.jpg +++ /dev/null diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/images/white-40x40.png b/chrome/test/data/extensions/api_test/notifications/galore/app/images/white-40x40.png Binary files differnew file mode 100644 index 0000000..c1bcf31 --- /dev/null +++ b/chrome/test/data/extensions/api_test/notifications/galore/app/images/white-40x40.png diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/images/white-64x64.png b/chrome/test/data/extensions/api_test/notifications/galore/app/images/white-64x64.png Binary files differdeleted file mode 100644 index 6aa3a51..0000000 --- a/chrome/test/data/extensions/api_test/notifications/galore/app/images/white-64x64.png +++ /dev/null diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/images/woman1-64x64.jpg b/chrome/test/data/extensions/api_test/notifications/galore/app/images/woman1-64x64.jpg Binary files differdeleted file mode 100644 index bf532e1..0000000 --- a/chrome/test/data/extensions/api_test/notifications/galore/app/images/woman1-64x64.jpg +++ /dev/null diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/images/woman2-64x64.jpg b/chrome/test/data/extensions/api_test/notifications/galore/app/images/woman2-64x64.jpg Binary files differdeleted file mode 100644 index 8b76ecb..0000000 --- a/chrome/test/data/extensions/api_test/notifications/galore/app/images/woman2-64x64.jpg +++ /dev/null diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/images/woman3-64x64.jpg b/chrome/test/data/extensions/api_test/notifications/galore/app/images/woman3-64x64.jpg Binary files differdeleted file mode 100644 index a62d37c..0000000 --- a/chrome/test/data/extensions/api_test/notifications/galore/app/images/woman3-64x64.jpg +++ /dev/null diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/images/wrench-14x14.png b/chrome/test/data/extensions/api_test/notifications/galore/app/images/wrench-14x14.png Binary files differnew file mode 100644 index 0000000..44de7e6 --- /dev/null +++ b/chrome/test/data/extensions/api_test/notifications/galore/app/images/wrench-14x14.png diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/images/wrench-highlighted-14x14.png b/chrome/test/data/extensions/api_test/notifications/galore/app/images/wrench-highlighted-14x14.png Binary files differnew file mode 100644 index 0000000..f6068ad --- /dev/null +++ b/chrome/test/data/extensions/api_test/notifications/galore/app/images/wrench-highlighted-14x14.png diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/main.js b/chrome/test/data/extensions/api_test/notifications/galore/app/main.js index 2e36eb0..6ec7c87 100644 --- a/chrome/test/data/extensions/api_test/notifications/galore/app/main.js +++ b/chrome/test/data/extensions/api_test/notifications/galore/app/main.js @@ -3,7 +3,8 @@ // found in the LICENSE file. (function() { - var listener = Galore.controller.create.bind(Galore.controller); + var controller = Galore.controller.create(); + var listener = controller.createWindow.bind(controller); chrome.app.runtime.onLaunched.addListener(listener); chrome.app.runtime.onRestarted.addListener(listener); }()); diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/manifest.json b/chrome/test/data/extensions/api_test/notifications/galore/app/manifest.json index fa00a7a..c331653 100644 --- a/chrome/test/data/extensions/api_test/notifications/galore/app/manifest.json +++ b/chrome/test/data/extensions/api_test/notifications/galore/app/manifest.json @@ -1,12 +1,12 @@ { "name": "Notifications Galore!", "description": "A testbed for Chrome notifications", - "version": "0.7", + "version": "0.9", "manifest_version": 2, "minimum_chrome_version": "23", "app": { "background": { - "scripts": ["model.js", "view.js", "controller.js", "main.js"] + "scripts": ["view.js", "controller.js", "main.js"] } }, "icons": { @@ -14,5 +14,5 @@ "48": "images/icon-48x48.png", "128": "images/icon-128x128.png" }, - "permissions": ["notifications"] + "permissions": ["experimental", "notifications", "storage"] } diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/model.js b/chrome/test/data/extensions/api_test/notifications/galore/app/model.js deleted file mode 100644 index df761cf..0000000 --- a/chrome/test/data/extensions/api_test/notifications/galore/app/model.js +++ /dev/null @@ -1,255 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -var Galore = Galore || {}; - -Galore.NOTIFICATIONS = [ - { - name: 'Simple Notifications', - type: 'simple', - notifications: [ - { - iconUrl: '$@/images/man1-$%x$%.jpg', - title: 'Althe Frazon', - message: 'Lorem ipsum' - }, - { - iconUrl: '$@/images/woman1-$%x$%.jpg', - title: 'Kathrine Doiss', - message: 'Dolor sit amet' - }, - { - iconUrl: '$@/images/woman2-$%x$%.jpg', - title: 'Jamie Haynig', - message: 'Consectetur adipisicing elit' - }, - { - iconUrl: '$@/images/woman3-$%x$%.jpg', - title: 'Maricia Rilari', - message: 'Sed do eiusmod tempor incididunt' - } - ] - }, - { - name: 'Basic Notifications', - type: 'basic', - notifications: [ - { - iconUrl: '$@/images/man1-$%x$%.jpg', - title: 'Althe Frazon', - message: 'Lorem ipsum', - buttons: [ - {title: 'Call', iconUrl: '$@/images/call-16x16.png'}, - {title: 'Send Email', iconUrl: '$@/images/send-16x16.png'}, - ] - }, - { - iconUrl: '$@/images/woman1-$%x$%.jpg', - title: 'Kathrine Doiss', - message: 'Dolor sit amet' - }, - { - iconUrl: '$@/images/woman2-$%x$%.jpg', - title: 'Jamie Haynig', - message: 'Consectetur adipisicing elit' - }, - { - iconUrl: '$@/images/woman3-$%x$%.jpg', - title: 'Maricia Rilari', - message: 'Sed do eiusmod tempor incididunt' - }, - { - iconUrl: '$@/images/fruit1-$%x$%.jpg', - title: 'Notification #$#: Apples!', - message: 'Malus domestica' - }, - { - iconUrl: '$@/images/fruit2-$%x$%.jpg', - title: 'Notification #$#: Pears!', - message: 'Pyrus' - }, - { - iconUrl: '$@/images/fruit3-$%x$%.jpg', - title: 'Notification #$#: Oranges!', - message: 'Citrus sinensis' - }, - { - iconUrl: '$@/images/fruit4-$%x$%.jpg', - title: 'Notification #$#: Strawberries!', - message: 'Fragaria ananassa' - }, - { - iconUrl: '$@/images/fruit5-$%x$%.jpg', - title: 'Notification #$#: Raspberries!', - message: 'Rubus idaeus' - }, - { - iconUrl: '$@/images/fruit6-$%x$%.jpg', - title: 'Notification #$#: Blueberries!', - message: 'Vaccinium cyanococcus' - } - ] - }, - { - name: 'Image Notifications', - type: 'image', - notifications: [ - { - iconUrl: '$@/images/woman3-$%x$%.jpg', - title: 'Maricia Rilari', - message: 'Pictures from Tahoe', - imageUrl: '$@/images/tahoe-300x225.jpg' - }, - { - iconUrl: '$@/images/flower1-$%x$%.jpg', - title: 'Notification #$#: Daffodils!', - message: 'Narcissus', - imageUrl: '$@/images/Image1-300x225.jpg' - }, - { - iconUrl: '$@/images/flower2-$%x$%.jpg', - title: 'Notification #$#: Sunflowers!', - message: 'Helianthus annuus', - imageUrl: '$@/images/Image2-300x225.jpg' - }, - { - iconUrl: '$@/images/flower3-$%x$%.jpg', - title: 'Notification #$#: Poinsettias!', - message: 'Euphorbia pulcherrima', - imageUrl: '$@/images/Image3-300x172.jpg' - }, - { - iconUrl: '$@/images/flower4-$%x$%.jpg', - title: 'Notification #$#: Heather!', - message: 'Calluna vulgaris', - imageUrl: '$@/images/Image4-200x300.jpg' - } - ] - }, - { - name: 'List Notifications', - type: 'list', - notifications: [ - { - iconUrl: '$@/images/inbox-00-$%x$%.png', - title: '15 new messages', - message: 'althe.frazon@gmail.com', - items: [ - {title: 'Althe Frazon', message: 'Lorem ipsum dolor sit amet'}, - {title: 'Kathrine Doiss', message: 'Consectetur adipisicing elit'}, - {title: 'Jamie Haynig', message: 'Sed do eiusmod tempor incididunt'}, - {title: 'Kelly Seiken', message: 'Ut labore et dolore magna aliqua'}, - {title: 'Maricia Rilari', message: 'Ut enim ad minim veniam'} - ], - buttons: [ - {title: 'Send Message', iconUrl: '$@/images/send-16x16.png'} - ] - }, - { - iconUrl: '$@/images/inbox-01-$%x$%.png', - title: '1 new message', - message: 'althe.frazon@gmail.com', - items: [ - {title: 'Althe Frazon', message: 'Lorem ipsum dolor sit amet'} - ] - }, - { - iconUrl: '$@/images/inbox-02-$%x$%.png', - title: '2 new messages', - message: 'althe.frazon@gmail.com', - items: [ - {title: 'Althe Frazon', message: 'Lorem ipsum dolor sit amet'}, - {title: 'Kathrine Doiss', message: 'Consectetur adipisicing elit'} - ] - }, - { - iconUrl: '$@/images/inbox-03-$%x$%.png', - title: '3 new messages', - message: 'althe.frazon@gmail.com', - items: [ - {title: 'Althe Frazon', message: 'Lorem ipsum dolor sit amet'}, - {title: 'Kathrine Doiss', message: 'Consectetur adipisicing elit'}, - {title: 'Jamie Haynig', message: 'Sed do eiusmod tempor incididunt'} - ] - }, - { - iconUrl: '$@/images/inbox-05-$%x$%.png', - title: '5 new messages', - message: 'althe.frazon@gmail.com', - items: [ - {title: 'Althe Frazon', message: 'Lorem ipsum dolor sit amet'}, - {title: 'Kathrine Doiss', message: 'Consectetur adipisicing elit'}, - {title: 'Jamie Haynig', message: 'Sed do eiusmod tempor incididunt'}, - {title: 'Kelly Seiken', message: 'Ut labore et dolore magna aliqua'}, - {title: 'Maricia Rilari', message: 'Ut enim ad minim veniam'} - ] - }, - { - iconUrl: '$@/images/inbox-08-$%x$%.png', - title: '8 new messages', - message: 'alex.faa.borg@gmail.com', - items: [ - {title: 'Althe Frazon', message: 'Lorem ipsum dolor sit amet'}, - {title: 'Kathrine Doiss', message: 'Consectetur adipisicing elit'}, - {title: 'Jamie Haynig', message: 'Sed do eiusmod tempor incididunt'}, - {title: 'Kelly Seiken', message: 'Ut labore et dolore magna aliqua'}, - {title: 'Maricia Rilari', message: 'Ut enim ad minim veniam'}, - {title: 'Althe Frazon', message: 'Lorem ipsum dolor sit amet'}, - {title: 'Kathrine Doiss', message: 'Consectetur adipisicing elit'}, - {title: 'Jamie Haynig', message: 'Sed do eiusmod tempor incididunt'} - ] - }, - { - iconUrl: '$@/images/inbox-13-$%x$%.png', - title: '13 new messages', - message: 'alex.faa.borg@gmail.com', - items: [ - {title: 'Althe Frazon', message: 'Lorem ipsum dolor sit amet'}, - {title: 'Kathrine Doiss', message: 'Consectetur adipisicing elit'}, - {title: 'Jamie Haynig', message: 'Sed do eiusmod tempor incididunt'}, - {title: 'Kelly Seiken', message: 'Ut labore et dolore magna aliqua'}, - {title: 'Maricia Rilari', message: 'Ut enim ad minim veniam'}, - {title: 'Althe Frazon', message: 'Lorem ipsum dolor sit amet'}, - {title: 'Kathrine Doiss', message: 'Consectetur adipisicing elit'}, - {title: 'Jamie Haynig', message: 'Sed do eiusmod tempor incididunt'}, - {title: 'Kelly Seiken', message: 'Ut labore et dolore magna aliqua'}, - {title: 'Maricia Rilari', message: 'Ut enim ad minim veniam'}, - {title: 'Althe Frazon', message: 'Lorem ipsum dolor sit amet'}, - {title: 'Kathrine Doiss', message: 'Consectetur adipisicing elit'}, - {title: 'Jamie Haynig', message: 'Sed do eiusmod tempor incididunt'} - ] - }, - { - iconUrl: '$@/images/plant1-$%x$%.jpg', - title: 'Notification #$#: Yucca!', - message: 'Asparagaceae agavoideae', - items: [ - {title: 'One', message: 'Unus'}, - {title: 'Two', message: 'Duo'}, - {title: 'Three', message: 'Tres'} - ] - }, - { - iconUrl: '$@/images/plant2-$%x$%.jpg', - title: 'Notification #$#: Fern!', - message: 'Nephrolepis', - items: [ - {title: 'One', message: 'Unus'}, - {title: 'Two', message: 'Duo'}, - {title: 'Three', message: 'Tres'} - ] - }, - { - iconUrl: '$@/images/plant3-$%x$%.jpg', - title: 'Notification #$#: Basil!', - message: 'Ocimum basilicum', - items: [ - {title: 'One', message: 'Unus'}, - {title: 'Two', message: 'Duo'}, - {title: 'Three', message: 'Tres'} - ] - } - ] - } -]; diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/style.css b/chrome/test/data/extensions/api_test/notifications/galore/app/style.css index ea3a166..50fe0f0 100644 --- a/chrome/test/data/extensions/api_test/notifications/galore/app/style.css +++ b/chrome/test/data/extensions/api_test/notifications/galore/app/style.css @@ -2,129 +2,267 @@ * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ +/* Globals ********************************************************************/ + body { -webkit-app-region: drag; - cursor: -webkit-grab; - font: 16px 'Arimo', 'Gill Sans', 'Open Sans', - 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif; + cursor: default; margin: 0; - padding: 17px 4px 0; + padding: 15px 4px 4px; +} + +.section { + margin: 12px 0 0; + position: relative; + padding: 23px 0 0; +} + +h1 { + /* White with a vertically centered one pixel horizontal black line. */ + background: -webkit-linear-gradient(white, white 59%, + black 60%, black 64%, + white 65%, white); + font: normal 16px 'Arimo', 'Gill Sans', 'Open Sans', + 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif; + left: 0; + margin: 0; + position: absolute; + right: 0; + text-align: center; + top: 0; +} + +h1 span { + background: white; + padding: 0 4px; } button { - -webkit-app-region: no-drag; background: none; border: 1px solid white; - cursor: default; - height: 72px; margin: 0; padding: 3px; - width: 72px; } -button:active { - opacity: 0.5; +::-webkit-scrollbar { + display: none !important; } -button:hover { - border: 1px solid black; -} +/* Template section (invisible) ***********************************************/ -#close { - background: url("/images/close-26x26.png"); - background-size: cover; - border: none; - height: 12px; - opacity: 0.2; +#templates { position: absolute; - right: 8px; - top: 8px; - width: 12px; + visibility: hidden; } -#close:hover { - border: none; - border-radius: 0; - opacity: 0.75; +/* Priority section ***********************************************************/ + +#priority { + font-size: 0; /* To collapse the spaces between buttons. */ } -#close:active:hover { - opacity: 1; +#priority .priority:first-of-type { + margin: 0 0 0 96px; /* Leftmost button is 96 pixels in. */ +} + +button.priority { + font: normal 14px 'Arimo', 'Gill Sans', 'Open Sans', + 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif; + height: 24px; + width: 48px; +} + +/* Notification sections ******************************************************/ + +button.notification { + height: 48px; + width: 48px; } +img { + display: block; + height: 40px; + margin: 0; + padding: 0; + width: 40px; +} + +/* Events section *************************************************************/ + #events { position: relative; + height: 112px; +} + +#events-scroll { + bottom: 4px; + font-weight: lighter; + left: 4px; + padding: 0; + max-height: 119px; + overflow: scroll; + position: absolute; + right: 4px; + -webkit-user-select: text; } #events-fade { background: -webkit-linear-gradient(rgba(255, 255, 255, 1), + rgba(255, 255, 255, 1) 50%, rgba(255, 255, 255, 0)); - height: 48px; + height: 46px; left: 0; pointer-events: none; position: absolute; right: 0; - top: 20px; - z-index: 99; + top: 0; } -#events-scroll { - -webkit-app-region: no-drag; +.event { color: gray; - cursor: text; - font-weight: lighter; - height: 90px; - overflow: scroll; - padding: 0 3px; - -webkit-user-select: text; + font: 11px 'Arimo', 'Gill Sans', 'Open Sans', + 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif; } -h1 { - background: -webkit-linear-gradient(white, white 59%, - black 60%, black 64%, - white 65%, white); - font-size: 16px; - font-weight: normal; - margin: 8px 0 2px; +.error { + color: red; + font: bold 16px 'Arimo', 'Gill Sans', 'Open Sans', + 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif; text-align: center; - z-index: -1; } -h1 span { - background: white; - padding: 0 2px; - position: relative; +/* Menu ***********************************************************************/ + +body[data-active="menu"] #popup, +body[data-popup="true"] #popup { + bottom: 0; + left: 0; + position: absolute; + right: 0; + top: 0; } -img { - display: block; - height: 64px; - margin: 0; +body:not([data-active="menu"]):not([data-popup="true"]) #popup { + left: -9999px !important; + position: absolute !important; + top: -9999px !important; +} + +#shadow { + background: gray; + bottom: 0; + left: 0; + opacity: 0.33; + position: absolute; + right: 0; + top: 0; +} + +#menu { + left: 12px; padding: 0; - width: 64px; + position: absolute; + top: 26px; + width: auto; } -::-webkit-scrollbar { - display: none; +#menu-items { + background: white; + box-shadow: 0px 8px 24px rgba(0, 0, 0, 0.7); + margin: 7px 0 0; + padding: 4px; } -#priority { - -webkit-app-region: no-drag; - margin: 0 0 0 33px; +#menu-items button { + display: block; + text-align: left; + width: 100%; } -#priority input { - margin: 0 8px 0 0; +#show-settings { + /* TODO(dharcourt): Add a settings panel and make this open it. */ + display: none !important; } -#priority label { - display: inline-block; - font-size: 14px; - margin: 0 0 0 23px; - width: 68px +#arrow { + border-bottom: 7px solid white; + border-left: 7px solid transparent; + border-right: 7px solid transparent; + height: 0; + position: absolute; + top: 0; + width: 0; } -#templates { +/* Menu and close buttons *****************************************************/ + +#show-menu, +#close { + border: 1px solid transparent; + height: 16px; + opacity: 0.15; position: absolute; - visibility: hidden; + top: 11px; + width: 16px; +} + +#show-menu { + background: url("/images/menu-14x14.png"); + left: 11px; +} + +#close { + background: url("/images/close-14x14.png"); + right: 11px; +} + +#show-menu:hover, +#close:hover { + opacity: 0.6; +} + +body[data-active="close"] #close, +body[data-active="menu"] #show-menu { + opacity: 1; +} + +/* Highlighting ***************************************************************/ + +body[data-active=""] button[data-hover="true"], +body[data-active="close"] button.close[data-hover="true"], +body[data-active="menu"] button.menu[data-hover="true"], +body[data-active="notification"] button.notification[data-hover="true"], +body[data-active="priority"] button.priority[data-hover="true"] { + border: 1px solid black !important; +} + +body[data-active="notification"] button.notification[data-hover="true"], +body[data-active="priority"] button.priority[data-hover="true"] { + opacity: 0.5; } + +body[data-priority="-2"] button.priority[data-priority="-2"], +body[data-priority="-1"] button.priority[data-priority="-1"], +body[data-priority="0"] button.priority[data-priority="0"], +body[data-priority="1"] button.priority[data-priority="1"], +body[data-priority="2"] button.priority[data-priority="2"] { + background: rgb(255, 255, 85); + -webkit-box-shadow: inset 3px 3px 0 white, inset -3px -3px 0 white; +} + +/* Cursor and dragging control ************************************************/ + +body:not([data-active=""]), +body:not([data-active="menu"]):not([data-popup="true"]) button, +button.menu, +button.close { + -webkit-app-region: no-drag; + cursor: pointer; +} + +body:not([data-active="menu"]):not([data-popup="true") #events { + -webkit-app-region: no-drag; + cursor: text; +} + +/* That's all folks! **********************************************************/ diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/view.js b/chrome/test/data/extensions/api_test/notifications/galore/app/view.js index cc5469a..001a81f 100644 --- a/chrome/test/data/extensions/api_test/notifications/galore/app/view.js +++ b/chrome/test/data/extensions/api_test/notifications/galore/app/view.js @@ -5,88 +5,242 @@ var Galore = Galore || {}; Galore.view = { - create: function(onLoad) { + /** @constructor */ + create: function(onload) { var view = Object.create(this); + view.actions = []; + view.sections = {}; + view.onload = onload; + chrome.storage.sync.get('settings', function(items) { + view.settings = items.settings || {priority: 0}; + view.createWindow_(); + }); + return view; + }, + + addNotificationButton: function(sectionTitle) { + var button = this.getElement_('#templates .notification').cloneNode(true); + this.addButtonListeners_(button); + this.getSection_(sectionTitle).appendChild(button); + return button; + }, + + setNotificationButtonAction: function(button, onClick) { + button.dataset.actionIndex = this.actions.push(onClick) - 1; + }, + + setNotificationButtonIcon: function(button, iconUrl, textAlternative) { + var image = button.querySelector('img'); + image.src = iconUrl; + image.alt = textAlternative; + button.name = textAlternative; + }, + + showWindow: function() { + if (this.window) + this.window.show(); + }, + + logEvent: function(message) { + var event = this.getElement_('#templates .event').cloneNode(true); + event.textContent = message; + this.getElement_('#events-scroll').appendChild(event).scrollIntoView(); + }, + + logError: function(message) { + var events = this.getElement_('#events-scroll'); + var error = this.getElement_('#templates .error').cloneNode(true); + error.textContent = message; + events.appendChild(error).scrollIntoView(); + }, + + /** @private */ + createWindow_: function() { chrome.app.window.create('window.html', { id: 'window', frame: 'none', - defaultWidth: 512, minWidth: 512, maxWidth: 512, - defaultHeight: 736, minHeight: 736, maxHeight: 736, + defaultWidth: 440, minWidth: 440, maxWidth: 440, + defaultHeight: 640, minHeight: 640, maxHeight: 640, + hidden: false // Change to true when http://crbug.com/177706 is fixed. }, function(appWindow) { - view.sections = {} - view.window = appWindow.contentWindow; - view.window.onload = this.loaded_.bind(view, onLoad); + this.window = appWindow; + this.addListener_(this.window.contentWindow, 'load', 'onLoad_'); }.bind(this)); - return view; }, - addNotificationButton: function(sectionId, sectionTitle, imageUrl, onClick) { - var section = this.section_(sectionId, sectionTitle); - var button = this.button_(section, onClick); - this.fetch_(imageUrl, button.querySelector('img')); + /** @private */ + onLoad_: function() { + this.dataset = this.window.contentWindow.document.body.dataset; + this.dataset.priority = this.settings.priority; + this.addListener_('body', 'mousedown', 'onBodyMouseDown_'); + this.addListener_('body', 'mouseup', 'onBodyMouseUp_'); + this.addListener_('#shadow', 'mousemove', 'onButtonMouseMove_'); + this.addButtonListeners_('button, #shadow'); + this.setButtonAction_('.priority', 'changePriority_'); + this.setButtonAction_('#shadow', 'toggleMenu_'); + this.setButtonAction_('#clear-events', 'clearEvents_'); + this.setButtonAction_('#show-menu', 'toggleMenu_'); + this.setButtonAction_('#close', 'close', this.window.contentWindow); + if (this.onload) + this.onload.call(this); }, - getPriority: function() { - var inputs = this.elements_('#priority input'); - var checked = Array.prototype.filter.call(inputs, function(input) { - return input.checked; - }); - return (checked && checked.length) ? Number(checked[0].value) : 0; + /** + * Handling our own mouse events is fun! It also allows us to keep the cursor + * appropriately indicating whether a button press or window drag is happening + * or will happen on mousedown. As a bonus, it allows button to have a + * highlight-as-you-drag behavior similar to menu items. + * + * @private */ + onButtonMouseDown_: function(event) { + // Record the fact that a button in this button's group is active, which + // allows onButtonMouseUp_ to do the right thing and CSS rules to correctly + // set cursor types and button highlighting. + console.log('onButtonMouseDown_'); + var element = event.currentTarget; + this.dataset.active = element.classList[0] || ''; + this.dragging = false; }, - logEvent: function(message) { - var event = this.element_('#templates .event').cloneNode(true); - event.textContent = message; - this.element_('#events-scroll').appendChild(event).scrollIntoView(); + /** + * See the comment for onButtonMouseDown_() above. + * + * @private */ + onButtonMouseMove_: function(event) { + // Buttons that support dragging add this as a listener to their mousemove + // events so a flag can be set during dragging to prevent their actions from + // being fired by the mouseup event that completes the dragging. + this.dragging = true; + }, + + /** + * See the comment for onButtonMouseDown_() above. + * + * @private */ + onButtonMouseOut_: function(event) { + // Record the fact that the mouse is not over this button any more to allow + // CSS rules to stop highlighting it. + event.currentTarget.dataset.hover = 'false'; + }, + + /** + * See the comment for onButtonMouseDown_() above. + * + * @private */ + onButtonMouseOver_: function(event) { + // Record the fact that the mouse is over this button to allow CSS rules to + // highlight it if appropriate. + event.currentTarget.dataset.hover = 'true'; + }, + + /** + * See the comment for onButtonMouseDown_() above. + * + * @private */ + onButtonMouseUp_: function(event) { + // Send a button action if the button in which the mouseup happened is in + // the same group as the one in which the mousedown happened. The regular + // click handling which this replaces would send the action only if the + // mouseup happened in the same button as the mousedown. + var element = event.currentTarget; + var group = (element.classList[0] || 'x'); + console.log(element, group, this.dataset.active, this.dragging); + if (group == this.dataset.active && !this.dragging) + this.actions[element.dataset.actionIndex].call(element, event); + }, + + /** + * See the comment for onButtonMouseDown_() above. + * + * @private */ + onBodyMouseUp_: function(event) { + // Record the fact that no button is active, which allows onButtonMouseUp_ + // to do the right thing and CSS rules to correctly set cursor types and + // button highlighting. + this.dataset.active = ''; }, /** @private */ - loaded_: function(onLoad) { - this.element_('#close').onclick = this.window.close.bind(this.window); - if (onLoad) - onLoad.call(this); + onBodyMouseDown_: function(event) { + // Prevents the cursor from becoming a text cursor during drags. + if (window.getComputedStyle(event.target).cursor != 'text') + event.preventDefault(); }, /** @private */ - fetch_: function(url, image) { - var request = new XMLHttpRequest(); - request.open('GET', url, true); - request.responseType = 'blob'; - request.onload = this.fetched_.bind(this, request, image); - request.send(); + changePriority_: function(event) { + this.settings.priority = Number(event.currentTarget.dataset.priority) || 0; + this.dataset.priority = this.settings.priority; + chrome.storage.sync.set({settings: this.settings}); }, /** @private */ - fetched_: function(request, image) { - image.src = window.URL.createObjectURL(request.response); + toggleMenu_: function() { + console.log('toogleMenu_'); + this.dataset.popup = String(this.dataset.popup != 'true'); }, /** @private */ - section_: function(id, title) { - if (!this.sections[id]) { - this.sections[id] = this.element_('#templates .section').cloneNode(true); - this.sections[id].querySelector('span').textContent = title; - this.element_('#sections').appendChild(this.sections[id]); - } - return this.sections[id]; + clearEvents_: function() { + var events = this.getElement_('#events-scroll'); + while (events.lastChild) + events.removeChild(events.lastChild); + this.dataset.popup = 'false'; }, /** @private */ - button_: function(section, onClick) { - var button = this.element_('#templates button'); - button = button.cloneNode(true); - button.onclick = onClick; - section.appendChild(button); - return button; + getSection_: function(title) { + this.sections[title] = (this.sections[title] || this.makeSection_(title)); + return this.sections[title]; + }, + + /** @private */ + makeSection_: function(title) { + var section = this.getElement_('#templates .section').cloneNode(true); + section.querySelector('span').textContent = title; + return this.getElement_('#notifications').appendChild(section); + }, + + /** @private */ + addButtonListeners_: function(buttons) { + this.addListener_(buttons, 'mousedown', 'onButtonMouseDown_'); + this.addListener_(buttons, 'mouseout', 'onButtonMouseOut_'); + this.addListener_(buttons, 'mouseover', 'onButtonMouseOver_'); + this.addListener_(buttons, 'mouseup', 'onButtonMouseUp_'); + }, + + /** @private */ + setButtonAction_: function(elements, action, target) { + var index = this.actions.push(this.bind_(action, target)) - 1; + this.getElements_(elements).forEach(function(element) { + element.dataset.actionIndex = index; + }); + }, + + /** @private */ + addListener_: function(elements, event, action, target) { + var listener = this.bind_(action, target); + this.getElements_(elements).forEach(function(element) { + element.addEventListener(event, listener); + }); + }, + + /** @private */ + bind_: function(action, target) { + return (target || this)[action].bind(target || this); }, /** @private */ - element_: function(selector) { - return this.window.document.querySelector(selector) + getElement_: function(element) { + return this.getElements_(element)[0]; }, /** @private */ - elements_: function(selector) { - return this.window.document.querySelectorAll(selector) + getElements_: function(elements) { + if (typeof elements === 'string') + elements = this.window.contentWindow.document.querySelectorAll(elements); + if (String(elements) === '[object NodeList]') + elements = Array.prototype.slice.call(elements); + return Array.isArray(elements) ? elements : [elements]; } }; diff --git a/chrome/test/data/extensions/api_test/notifications/galore/app/window.html b/chrome/test/data/extensions/api_test/notifications/galore/app/window.html index dd1cc4dc..15411ae 100644 --- a/chrome/test/data/extensions/api_test/notifications/galore/app/window.html +++ b/chrome/test/data/extensions/api_test/notifications/galore/app/window.html @@ -4,33 +4,44 @@ -- found in the LICENSE file. --> <html> <head> - <title>Garrulous</title> + <title>Notifications Galore!</title> <link rel="stylesheet" type="text/css" href="style.css" /> </head> - <body> - <button id="close"></button> + <body data-active="" data-popup="false"> <div id="templates"> <div class="section"><h1><span/></h1></div> <div class="event"></div> - <button><img src="images/white-64x64.png"></button> + <div class="error"></div> + <div class="spacer"></div> + <button class="notification"> + <img src="images/white-40x40.png"> + </button> </div> - <div> + <div id="priority" class="section"> <h1><span>Priority</span></h1> - <form name="priority" id="priority"> - <label><input type="radio" name="priority" value="-2">-2</label> - <label><input type="radio" name="priority" value="-1">-1</label> - <label> - <input type="radio" name="priority" value="0" checked="true">0 - </label> - <label><input type="radio" name="priority" value="1">1</label> - <label><input type="radio" name="priority" value="2">2</label> - </div> + <button class="priority" data-priority="-2">-2</button> + <button class="priority" data-priority="-1">-1</button> + <button class="priority" data-priority="0">0</button> + <button class="priority" data-priority="1">1</button> + <button class="priority" data-priority="2">2</button> </div> - <div id="sections"></div> - <div id="events"> - <h1><span>Events</span></h1> + <div id="notifications"></div> + <div id="events" class="section"> <div id="events-scroll"></div> <div id="events-fade"></div> + <h1><span>Events</span></h1> + </div> + <div id="popup"> + <div id="shadow" class="shadow"></div> + <div id="menu"> + <div id="menu-items"> + <button id="show-settings" class="menu">Settings...</button> + <button id="clear-events" class="menu">Clear Events</button> + </div> + <div id="arrow"></div> + </div> </div> + <button id="close" class="close" name="Close"></button> + <button id="show-menu" class="menu" name="Show Menu"></button> </body> </html> diff --git a/chrome/test/data/extensions/api_test/notifications/galore/assets/Credits.txt b/chrome/test/data/extensions/api_test/notifications/galore/assets/Credits.txt index 180ce48..6ef7dfe 100644 --- a/chrome/test/data/extensions/api_test/notifications/galore/assets/Credits.txt +++ b/chrome/test/data/extensions/api_test/notifications/galore/assets/Credits.txt @@ -23,3 +23,9 @@ Public domain images and their origins: Woman2.jpg: http://www.publicdomainpictures.net/view-image.php?image=26173 Woman3.jpg: http://publicphoto.org/people/ young-woman-and-girl-with-poppy-flower-in-hair/ + +Other images are: + + Copyright (c) 2013 The Chromium Authors. All rights reserved. + Use of this source code is governed by a BSD-style license that can be + found in the LICENSE file. diff --git a/chrome/test/data/extensions/api_test/notifications/galore/assets/Promotional-1x.jpg b/chrome/test/data/extensions/api_test/notifications/galore/assets/Promotional-1x.jpg Binary files differdeleted file mode 100644 index 656705a..0000000 --- a/chrome/test/data/extensions/api_test/notifications/galore/assets/Promotional-1x.jpg +++ /dev/null diff --git a/chrome/test/data/extensions/api_test/notifications/galore/assets/Promotional-2x.jpg b/chrome/test/data/extensions/api_test/notifications/galore/assets/Promotional-2x.jpg Binary files differdeleted file mode 100644 index cb2a241..0000000 --- a/chrome/test/data/extensions/api_test/notifications/galore/assets/Promotional-2x.jpg +++ /dev/null diff --git a/chrome/test/data/extensions/api_test/notifications/galore/assets/Promotional1.jpg b/chrome/test/data/extensions/api_test/notifications/galore/assets/Promotional1.jpg Binary files differnew file mode 100644 index 0000000..91f9a94 --- /dev/null +++ b/chrome/test/data/extensions/api_test/notifications/galore/assets/Promotional1.jpg diff --git a/chrome/test/data/extensions/api_test/notifications/galore/assets/Promotional2.jpg b/chrome/test/data/extensions/api_test/notifications/galore/assets/Promotional2.jpg Binary files differnew file mode 100644 index 0000000..2081189 --- /dev/null +++ b/chrome/test/data/extensions/api_test/notifications/galore/assets/Promotional2.jpg diff --git a/chrome/test/data/extensions/api_test/notifications/galore/assets/Promotional3.jpg b/chrome/test/data/extensions/api_test/notifications/galore/assets/Promotional3.jpg Binary files differnew file mode 100644 index 0000000..9ad5972 --- /dev/null +++ b/chrome/test/data/extensions/api_test/notifications/galore/assets/Promotional3.jpg diff --git a/chrome/test/data/extensions/api_test/notifications/galore/assets/Screenshot.jpg b/chrome/test/data/extensions/api_test/notifications/galore/assets/Screenshot.jpg Binary files differindex f005871..4068694 100644 --- a/chrome/test/data/extensions/api_test/notifications/galore/assets/Screenshot.jpg +++ b/chrome/test/data/extensions/api_test/notifications/galore/assets/Screenshot.jpg |