Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5016)

Unified Diff: chrome/test/data/extensions/api_test/notifications/galore/app/controller.js

Issue 315053006: Refactor Notifications Galore to simplify, amke more hackable and add 'recording'. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/test/data/extensions/api_test/notifications/galore/app/controller.js
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 5f5aa1ad6f3f19f6a4124318cc0dc4f00440576e..cb594a2fe60ea798ad6f8402da900561782f9446 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
@@ -2,242 +2,245 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-var Galore = Galore || {};
-
-Galore.controller = {
- /** @constructor */
- create: function() {
- var controller = Object.create(this);
- controller.api = chrome;
- controller.counter = 0;
- return controller;
- },
-
- createWindow: function() {
- chrome.storage.sync.get('settings', this.onSettingsFetched_.bind(this));
- },
-
- /** @private */
- onSettingsFetched_: function(items) {
- var request = new XMLHttpRequest();
- var settings = items.settings || {};
- var source = settings.data || '/data/' + this.getDataVersion_();
- request.open('GET', source, true);
- request.responseType = 'text';
- request.onload = this.onDataFetched_.bind(this, settings, request);
- request.send();
- },
-
- /** @private */
- onDataFetched_: function(settings, request) {
- var count = 0;
- var data = JSON.parse(request.response);
+var NOT_RECORDING = "Stopped";
+var RECORDING = "Recording";
+var PAUSED = "Paused";
+var PLAYING = "Playing";
+
+var recordingState = NOT_RECORDING;
+
+// Timestamp when current segment started.
+var segmentStart;
+// Segment duration accumulated before pause button was hit.
+var pausedDuration;
+// The array of segments, with delay and action.
+var recordingList;
+// When this timer fires, the next segment from recordingList should be played.
+var playingTimer;
+var currentSegmentIndex;
+
+function setRecordingState(newState) {
+ controller.view.setRecorderStatusText(newState);
+ recordingState = newState;
+}
+
+function loadRecording() {
+ chrome.storage.local.get("recording", function(items) {
+ recordingList = JSON.parse(items["recording"] || "[]");
+ })
+}
+
+function finalizeRecording() {
+ chrome.storage.local.set({"recording": JSON.stringify(recordingList)});
+}
+
+function setPreviousSegmentDuration() {
+ var now = new Date().getTime();
+ var delay = now - segmentStart;
+ segmentStart = now;
+ recordingList[currentSegmentIndex++].delay = delay;
+}
+
+function recordCreate(id, options) {
+ if (recordingState != RECORDING)
+ return;
+ setPreviousSegmentDuration();
+ recordingList.push({ type: "create", id: id, options: options });
+}
+
+function recordDelete(id) {
+ if (recordingState != RECORDING)
+ return;
+ setPreviousSegmentDuration();
+ recordingList.push({ type: "delete", id: id });
+}
+
+function startPlaying() {
+ if (recordingList.length < 2)
+ return false;
+
+ if (playingTimer)
+ clearTimeout(playingTimer);
+
+ currentSegmentIndex = 0;
+ playingTimer = setTimeout(playNextSegment,
+ recordingList[currentSegmentIndex].delay);
+}
+
+function playNextSegment() {
+ currentSegmentIndex++;
+ var segment = recordingList[currentSegmentIndex];
+ if (!segment)
+ stopPlaying();
+
+ if (segment.type == "create") {
+ chrome.notifications.create(segment.id, segment.options, function() {});
+ } else { // type == "delete"
+ chrome.notifications.clear(segment.id, function() {});
+ }
+ playingTimer = setTimeout(playNextSegment,
+ recordingList[currentSegmentIndex].delay);
+ segmentStart = new Date().getTime();
+}
+
+function stopPlaying() {
+ clearTimeout(playingTimer);
+}
+
+function pausePlaying() {
+ clearTimeout(playingTimer);
+ pausedDuration =
+ recordingList[currentSegmentIndex].delay - (now - segmentStart);
+}
+
+function unpausePlaying() {
+ playingTimer = setTimeout(playNextSegment, pausedDuration);
+ segmentStart = new Date().getTime();
+}
+
+function onRecord() {
+ if (recordingState == NOT_RECORDING) {
+ currentSegmentIndex = 0;
+ segmentStart = new Date().getTime();
+ pausedDuration = 0;
+ // This item is only needed to keep a duration of the delay between start
+ // and first action.
+ recordingList = [ { type:"start" } ];
+ } else if (recordingState == PAUSED) {
+ segmentStart = new Date().getTime() - pausedDuration;
+ pausedDuration = 0;
+ } else {
+ return;
+ }
+ setRecordingState(RECORDING);
+}
+
+function onPause() {
+ if (recordingState == RECORDING) {
+ pausedDuration = new Date().getTime() - segmentStart;
+ segmentStart = 0;
+ } else if (recordingState == PLAYING) {
+ pausePlaying();
+ } else {
+ return;
+ }
+ setRecordingState(PAUSED);
+}
+
+function onStop() {
+ if (recordingState == RECORDING) {
+ finalizeRecording();
+ } else if (recordingState == PAUSED) {
+ segmentStart = new Date().getTime() - pausedDuration;
+ finalizeRecording();
+ } else if (recordingState == PLAYING) {
+ stopPlaying();
+ } else {
+ return;
+ }
+ setRecordingState(NOT_RECORDING);
+}
+
+function onPlay() {
+ if (recordingState == NOT_RECORDING && startPlaying()) {
+ setRecordingState = PLAYING;
+ }
+}
+
+function createWindow() {
+ loadRecording();
+ chrome.storage.local.get('settings', onSettingsFetched);
+}
+
+function onSettingsFetched(items) {
+ settings = items.settings || settings;
+ var request = new XMLHttpRequest();
+ var source = '/data/data.json';
+ request.open('GET', source, true);
+ request.responseType = 'text';
+ request.onload = onDataFetched;
+ request.send();
+}
+
+function onDataFetched() {
+ var data = JSON.parse(this.response);
+ createAppWindow(function() {
+ // Create notification buttons.
data.forEach(function(section) {
+ var type = section.notificationType;
(section.notificationOptions || []).forEach(function(options) {
- ++count;
- this.fetchImages_(options, function() {
- if (--count == 0)
- this.onImagesFetched_(settings, data);
- }.bind(this));
- }, this);
- }, this);
- },
-
- /** @private */
- onImagesFetched_: function(settings, data) {
- this.settings = settings;
- this.view = Galore.view.create(this.settings, function() {
- // Create buttons.
- data.forEach(function(section) {
- var defaults = section.globals || data[0].globals;
- var type = section.notificationType;
- (section.notificationOptions || []).forEach(function(options) {
- var defaulted = this.getDefaultedOptions_(options, defaults);
- var create = this.createNotification_.bind(this, type, defaulted);
- this.view.addNotificationButton(section.sectionName,
- defaulted.title,
- defaulted.iconUrl,
- create);
- }, this);
- }, this);
- // Set the API entry point and use it to set event listeners.
- this.api = this.getApi_(data);
- if (this.api)
- this.addListeners_(this.api, data[0].events);
- // Display the completed and ready window.
- this.view.showWindow();
- }.bind(this), this.onSettingsChange_.bind(this));
- },
-
- /** @private */
- fetchImages_: function(options, onFetched) {
- var count = 0;
- var replacements = {};
- this.mapStrings_(options, function(string) {
- if (string.indexOf("/images/") == 0 || string.search(/https?:\//) == 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 */
- onSettingsChange_: function(settings) {
- this.settings = settings;
- chrome.storage.sync.set({settings: this.settings});
- },
-
- /** @private */
- createNotification_: function(type, options) {
- var id = this.getNextId_();
- var priority = Number(this.settings.priority || 0);
- var expanded = this.getExpandedOptions_(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;
- new Notification(title, {
- body: message,
- icon: iconUrl
- });
- 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 */
- getDefaultedOptions_: function(options, defaults) {
- var defaulted = this.deepCopy_(options);
- Object.keys(defaults || {}).forEach(function (key) {
- defaulted[key] = options[key] || defaults[key];
+ addNotificationButton(section.sectionName,
+ options.title,
+ options.iconUrl,
+ function() { createNotification(type, options) });
+ });
});
- return defaulted;
- },
-
- /** @private */
- getExpandedOptions_: function(options, id, type, priority) {
- var expanded = this.deepCopy_(options);
- return this.mapStrings_(expanded, function(string) {
- return this.getExpandedOption_(string, id, type, priority);
- }, this);
- },
-
- /** @private */
- getExpandedOption_: function(option, id, type, priority) {
- if (option == '$!') {
- option = priority; // Avoids making priorities into strings.
- } else {
- option = option.replace(/\$#/g, id);
- option = option.replace(/\$\?/g, type);
- option = option.replace(/\$\!/g, priority);
- }
- return option;
- },
-
- /** @private */
- 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 */
- 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 mapped;
- },
-
- /** @private */
- addListeners_: function(api, events) {
- (events || []).forEach(function(event) {
- var listener = this.handleEvent_.bind(this, event);
- if (api[event])
- api[event].addListener(listener);
- else
- console.log('Event ' + event + ' not defined.');
- }, this);
- },
-
- /** @private */
- handleEvent_: function(event, id, var_args) {
- this.view.logEvent('Notification #' + id + ': ' + event + '(' +
- Array.prototype.slice.call(arguments, 2).join(', ') +
- ')');
- },
-
- /** @private */
- getDataVersion_: function() {
- var version = navigator.appVersion.replace(/^.* Chrome\//, '');
- return (version > '28.0.1500.70') ? '28.0.1500.70.json' :
- (version > '27.0.1433.1') ? '27.0.1433.1.json' :
- (version > '27.0.1432.2') ? '27.0.1432.2.json' :
- '27.0.0.0.json';
- },
-
- /** @private */
- getApi_: function(data) {
- var path = data[0].api || 'notifications';
- var api = chrome;
- path.split('.').forEach(function(key) { api = api && api[key]; });
- if (!api)
- this.view.logError('No API found - chrome.' + path + ' is undefined');
- return api;
- }
-
-};
+ addListeners();
+ showWindow();
+ });
+}
+
+function onSettingsChange(settings) {
+ chrome.storage.local.set({settings: settings});
+}
+
+function createNotification(type, options) {
+var id = getNextId();
+var priority = Number(settings.priority || 0);
+if (type == 'webkit')
+ createWebKitNotification(options);
+ else
+ createRichNotification(id, type, priority, options);
+}
+
+function createWebKitNotification(options) {
dewittj 2014/06/06 17:54:22 s/webkit/w3c/ or web
Dmitry Titov 2014/06/06 22:57:18 Done.
+ var iconUrl = options.iconUrl;
+ var title = options.title;
+ var message = options.message;
+ new Notification(title, {
+ body: message,
+ icon: iconUrl
dewittj 2014/06/06 17:54:22 add tag?
Dmitry Titov 2014/06/06 22:57:18 Done. We currently don't seem to catch/log any ev
+ });
+ logCreate('created WebKit', '', 'title: "' + title + '"');
+}
+
+function createRichNotification(id, type, priority, options) {
+ options["type"] = type;
+ options["priority"] = priority;
+ chrome.notifications.create(id, options, function() {
+ var argument1 = 'type: "' + type + '"';
+ var argument2 = 'priority: ' + priority;
+ var argument3 = 'title: "' + options.title + '"';
+ logCreate('created Rich', id, argument1, argument2, argument3);
+ });
+ recordCreate(id, options);
+}
+
+var counter = 0;
+function getNextId() {
+ return String(counter++);
+}
+
+function addListeners() {
+ chrome.notifications.onClosed.addListener(onClosed);
+ chrome.notifications.onClicked.addListener(onClicked);
+ chrome.notifications.onButtonClicked.addListener(onButtonClicked);
+}
+
+function logCreate(event, id, var_args) {
+ logEvent('Notification #' + id + ': ' + event + '(' +
+ Array.prototype.slice.call(arguments, 2).join(', ') + ')');
+}
+
+function onClosed(id) {
+ logEvent('Notification #' + id + ': onClosed');
+ recordDelete(id);
+}
+
+function onClicked(id) {
+ logEvent('Notification #' + id + ': onClicked');
+}
+
+function onButtonClicked(id, index) {
+ logEvent('Notification #' + id + ': onButtonClicked, btn: ' + index);
+}

Powered by Google App Engine
This is Rietveld 408576698