Skip to content
Browse files

Small refactoring: extracting the notification code from the statusbar

  • Loading branch information...
1 parent 0baef69 commit c3d4e13c45376da488e0b0d9df8d0a6724187768 @etiennesegonzac committed May 15, 2012
View
4 apps/system/index.html
@@ -23,6 +23,10 @@
<link rel="stylesheet" type="text/css" href="style/statusbar/statusbar.css">
<script defer src="js/statusbar/statusbar.js"></script>
+ <!-- Notifications -->
+ <link rel="stylesheet" type="text/css" href="style/notifications/notifications.css">
+ <script defer src="js/notifications/notifications.js"></script>
+
<!-- Dialogs -->
<link rel="stylesheet" type="text/css" href="style/dialogs/request.css">
<script defer src="js/dialogs/request.js"></script>
View
219 apps/system/js/notifications/notifications.js
@@ -0,0 +1,219 @@
+/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
+/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
+
+'use strict';
+
+var NotificationScreen = {
+ get touchable() {
+ return this.touchables[this.locked ? 0 : 1];
+ },
+
+ get screenHeight() {
+ var screenHeight = this._screenHeight;
+ if (!screenHeight) {
+ screenHeight = this.touchables[0].getBoundingClientRect().height;
+ this._screenHeight = screenHeight;
+ }
+ return screenHeight;
+ },
+
+ get container() {
+ delete this.container;
+ return this.container = document.getElementById('notifications-container');
+ },
+
+ init: function ns_init(touchables) {
+ this.touchables = touchables;
+ this.attachEvents(touchables);
+
+ window.addEventListener('mozChromeEvent', function notificationListener(e) {
+ var detail = e.detail;
+ switch (detail.type) {
+ case 'desktop-notification':
+ NotificationScreen.addNotification('desktop-notification',
+ detail.title, detail.text,
+ detail.id);
+
+ var hasNotifications = document.getElementById('state-notifications');
+ hasNotifications.dataset.visible = 'true';
+ break;
+
+ default:
+ // XXX Needs to implements more UI but for now let's allow stuffs
+ var event = document.createEvent('CustomEvent');
+ event.initCustomEvent('mozContentEvent', true, true, {
+ type: 'permission-allow',
+ id: detail.id
+ });
+ window.dispatchEvent(event);
+ break;
+
+ break;
+ }
+ });
+
+ var self = this;
+ var notifications = this.container;
+ notifications.addEventListener('click', function notificationClick(evt) {
+ var target = evt.target;
+ var closing = false;
+
+ // Handling the close button
+ if (target.classList.contains('close')) {
+ closing = true;
+ target = target.parentNode;
+ }
+
+ self.removeNotification(target);
+
+ var type = target.dataset.type;
+ if (type != 'desktop-notification')
+ return;
+
+ var event = document.createEvent('CustomEvent');
+ event.initCustomEvent('mozContentEvent', true, true, {
+ type: closing ?
+ 'desktop-notification-close' : 'desktop-notification-click',
+ id: target.dataset.notificationID
+ });
+ window.dispatchEvent(event);
+
+ // And hide the notification tray
+ if (!closing)
+ self.unlock();
+ });
+ },
+
+ onTouchStart: function ns_onTouchStart(e) {
+ this.startX = e.pageX;
+ this.startY = e.pageY;
+ this.onTouchMove({ pageY: e.pageY + 32 });
+ },
+
+ onTouchMove: function ns_onTouchMove(e) {
+ var dy = -(this.startY - e.pageY);
+ if (this.locked)
+ dy += this.screenHeight;
+ dy = Math.min(this.screenHeight, dy);
+
+ var style = this.touchables[0].style;
+ style.MozTransition = '';
+ style.MozTransform = 'translateY(' + dy + 'px)';
+ },
+
+ onTouchEnd: function ns_onTouchEnd(e) {
+ var dy = -(this.startY - e.pageY);
+ var offset = Math.abs(dy);
+ if ((!this.locked && offset > this.screenHeight / 4) ||
+ (this.locked && offset < 10))
+ this.lock();
+ else
+ this.unlock();
+ },
+
+ unlock: function ns_unlock(instant) {
+ var style = this.touchables[0].style;
+ style.MozTransition = instant ? '' : '-moz-transform 0.2s linear';
+ style.MozTransform = 'translateY(0)';
+ this.locked = false;
+ },
+
+ lock: function ns_lock(dy) {
+ var style = this.touchables[0].style;
+ style.MozTransition = '-moz-transform 0.2s linear';
+ style.MozTransform = 'translateY(100%)';
+ this.locked = true;
+ },
+
+ attachEvents: function ns_attachEvents(view) {
+ AddEventHandlers(window, this, ['touchstart', 'touchmove', 'touchend']);
+ },
+
+ detachEvents: function ns_detachEvents() {
+ RemoveEventHandlers(window, this, ['touchstart', 'touchmove', 'touchend']);
+ },
+
+ handleEvent: function(evt) {
+ var target = evt.target;
+ switch (evt.type) {
+ case 'touchstart':
+ if (LockScreen.locked)
+ return;
+ if (target != this.touchable)
+ return;
+ this.active = true;
+
+ target.setCapture(this);
+ this.onTouchStart(evt.touches[0]);
+ break;
+ case 'touchmove':
+ if (!this.active)
+ return;
+
+ this.onTouchMove(evt.touches[0]);
+ break;
+ case 'touchend':
+ if (!this.active)
+ return;
+ this.active = false;
+
+ document.releaseCapture();
+ this.onTouchEnd(evt.changedTouches[0]);
+ break;
+ default:
+ return;
+ }
+
+ evt.preventDefault();
+ },
+
+ addNotification: function ns_addNotification(type, nTitle, body, nID) {
+ var notifications = this.container;
+
+ var notification = document.createElement('div');
+ notification.className = 'notification';
+ notification.dataset.type = type;
+
+ if (type == 'desktop-notification') {
+ notification.dataset.notificationID = nID;
+ }
+
+ var title = document.createElement('div');
+ title.textContent = nTitle;
+ notification.appendChild(title);
+
+ var message = document.createElement('div');
+ message.classList.add('detail');
+ message.textContent = body;
+ notification.appendChild(message);
+
+ var close = document.createElement('a');
+ close.className = 'close';
+ notification.appendChild(close);
+
+ notifications.appendChild(notification);
+ },
+
+ removeNotification: function ns_removeNotification(notification) {
+ notification.parentNode.removeChild(notification);
+
+ // Hiding the notification indicator in the status bar
+ // if this is the last desktop notification
+ var notifSelector = 'div[data-type="desktop-notification"]';
+ var desktopNotifications = this.container.querySelectorAll(notifSelector);
+ if (desktopNotifications.length == 0) {
+ var hasNotifications = document.getElementById('state-notifications');
+ delete hasNotifications.dataset.visible;
+ }
+ },
+
+ removeNotifications: function ns_removeNotifications(type) {
+ var notifications = this.container;
+ var typeSelector = 'div[data-type="' + type + '"]';
+ var children = notifications.querySelectorAll(typeSelector);
+ for (var i = children.length - 1; i >= 0; i--) {
+ var notification = children[i];
+ notification.parentNode.removeChild(notification);
+ }
+ }
+};
View
215 apps/system/js/statusbar/statusbar.js
@@ -21,221 +21,6 @@ var StatusBar = {
}
};
-var NotificationScreen = {
- get touchable() {
- return this.touchables[this.locked ? 0 : 1];
- },
-
- get screenHeight() {
- var screenHeight = this._screenHeight;
- if (!screenHeight) {
- screenHeight = this.touchables[0].getBoundingClientRect().height;
- this._screenHeight = screenHeight;
- }
- return screenHeight;
- },
-
- get container() {
- delete this.container;
- return this.container = document.getElementById('notifications-container');
- },
-
- init: function ns_init(touchables) {
- this.touchables = touchables;
- this.attachEvents(touchables);
-
- window.addEventListener('mozChromeEvent', function notificationListener(e) {
- var detail = e.detail;
- switch (detail.type) {
- case 'desktop-notification':
- NotificationScreen.addNotification('desktop-notification',
- detail.title, detail.text,
- detail.id);
-
- var hasNotifications = document.getElementById('state-notifications');
- hasNotifications.dataset.visible = 'true';
- break;
-
- default:
- // XXX Needs to implements more UI but for now let's allow stuffs
- var event = document.createEvent('CustomEvent');
- event.initCustomEvent('mozContentEvent', true, true, {
- type: 'permission-allow',
- id: detail.id
- });
- window.dispatchEvent(event);
- break;
-
- break;
- }
- });
-
- var self = this;
- var notifications = this.container;
- notifications.addEventListener('click', function notificationClick(evt) {
- var target = evt.target;
- var closing = false;
-
- // Handling the close button
- if (target.classList.contains('close')) {
- closing = true;
- target = target.parentNode;
- }
-
- self.removeNotification(target);
-
- var type = target.dataset.type;
- if (type != 'desktop-notification')
- return;
-
- var event = document.createEvent('CustomEvent');
- event.initCustomEvent('mozContentEvent', true, true, {
- type: closing ?
- 'desktop-notification-close' : 'desktop-notification-click',
- id: target.dataset.notificationID
- });
- window.dispatchEvent(event);
-
- // And hide the notification tray
- if (!closing)
- self.unlock();
- });
- },
-
- onTouchStart: function ns_onTouchStart(e) {
- this.startX = e.pageX;
- this.startY = e.pageY;
- this.onTouchMove({ pageY: e.pageY + 32 });
- },
-
- onTouchMove: function ns_onTouchMove(e) {
- var dy = -(this.startY - e.pageY);
- if (this.locked)
- dy += this.screenHeight;
- dy = Math.min(this.screenHeight, dy);
-
- var style = this.touchables[0].style;
- style.MozTransition = '';
- style.MozTransform = 'translateY(' + dy + 'px)';
- },
-
- onTouchEnd: function ns_onTouchEnd(e) {
- var dy = -(this.startY - e.pageY);
- var offset = Math.abs(dy);
- if ((!this.locked && offset > this.screenHeight / 4) ||
- (this.locked && offset < 10))
- this.lock();
- else
- this.unlock();
- },
-
- unlock: function ns_unlock(instant) {
- var style = this.touchables[0].style;
- style.MozTransition = instant ? '' : '-moz-transform 0.2s linear';
- style.MozTransform = 'translateY(0)';
- this.locked = false;
- },
-
- lock: function ns_lock(dy) {
- var style = this.touchables[0].style;
- style.MozTransition = '-moz-transform 0.2s linear';
- style.MozTransform = 'translateY(100%)';
- this.locked = true;
- },
-
- attachEvents: function ns_attachEvents(view) {
- AddEventHandlers(window, this, ['touchstart', 'touchmove', 'touchend']);
- },
-
- detachEvents: function ns_detachEvents() {
- RemoveEventHandlers(window, this, ['touchstart', 'touchmove', 'touchend']);
- },
-
- handleEvent: function(evt) {
- var target = evt.target;
- switch (evt.type) {
- case 'touchstart':
- if (LockScreen.locked)
- return;
- if (target != this.touchable)
- return;
- this.active = true;
-
- target.setCapture(this);
- this.onTouchStart(evt.touches[0]);
- break;
- case 'touchmove':
- if (!this.active)
- return;
-
- this.onTouchMove(evt.touches[0]);
- break;
- case 'touchend':
- if (!this.active)
- return;
- this.active = false;
-
- document.releaseCapture();
- this.onTouchEnd(evt.changedTouches[0]);
- break;
- default:
- return;
- }
-
- evt.preventDefault();
- },
-
- addNotification: function ns_addNotification(type, nTitle, body, nID) {
- var notifications = this.container;
-
- var notification = document.createElement('div');
- notification.className = 'notification';
- notification.dataset.type = type;
-
- if (type == 'desktop-notification') {
- notification.dataset.notificationID = nID;
- }
-
- var title = document.createElement('div');
- title.textContent = nTitle;
- notification.appendChild(title);
-
- var message = document.createElement('div');
- message.classList.add('detail');
- message.textContent = body;
- notification.appendChild(message);
-
- var close = document.createElement('a');
- close.className = 'close';
- notification.appendChild(close);
-
- notifications.appendChild(notification);
- },
-
- removeNotification: function ns_removeNotification(notification) {
- notification.parentNode.removeChild(notification);
-
- // Hiding the notification indicator in the status bar
- // if this is the last desktop notification
- var notifSelector = 'div[data-type="desktop-notification"]';
- var desktopNotifications = this.container.querySelectorAll(notifSelector);
- if (desktopNotifications.length == 0) {
- var hasNotifications = document.getElementById('state-notifications');
- delete hasNotifications.dataset.visible;
- }
- },
-
- removeNotifications: function ns_removeNotifications(type) {
- var notifications = this.container;
- var typeSelector = 'div[data-type="' + type + '"]';
- var children = notifications.querySelectorAll(typeSelector);
- for (var i = children.length - 1; i >= 0; i--) {
- var notification = children[i];
- notification.parentNode.removeChild(notification);
- }
- }
-};
-
// Update the clock and schedule a new update if appropriate
function updateClock() {
if (!navigator.mozPower.screenEnabled)
View
18 apps/system/style/notifications/notifications.css
@@ -0,0 +1,18 @@
+
+#statusbar {
+ display: -moz-box;
+ overflow: hidden;
+ position: relative;
+ z-index: 20001;
+ -moz-box-orient: horizontal;
+
+ width: 100%;
+ -moz-box-sizing: border-box;
+ height: 32px;
+ padding: 2px;
+}
+
+#statusbar > * {
+ -moz-box-flex: 0;
+ pointer-events: none;
+}
View
19 apps/system/style/statusbar/statusbar.css
@@ -1,22 +1,3 @@
-
-#statusbar {
- display: -moz-box;
- overflow: hidden;
- position: relative;
- z-index: 20001;
- -moz-box-orient: horizontal;
-
- width: 100%;
- -moz-box-sizing: border-box;
- height: 32px;
- padding: 2px;
-}
-
-#statusbar > * {
- -moz-box-flex: 0;
- pointer-events: none;
-}
-
#screen.fullscreen > :-moz-any(#statusbar,#notifications-screen) {
display: none;
}

2 comments on commit c3d4e13

@daleharvey

just a nit

Can we not put vim modelines in these files, especially ones that override JavaScript mode and put us in Java mode :) you can setup those defaults outside the film in vim for .js files right?

@etiennesegonzac
Owner

It's part of the boilerplate I guess.

I personally have nothing against removing them, as long as we continue to lint :)

Please sign in to comment.
Something went wrong with that request. Please try again.