Added keyboard shortcuts (part 1) (#70)

Scrolling in message view (#109)
This commit is contained in:
RainLoop Team 2014-04-08 01:03:58 +04:00
parent 3936a818b7
commit 8979687f88
37 changed files with 2095 additions and 333 deletions

View file

@ -1,5 +1,6 @@
<div id="rl-sub-left">
<div class="messageList g-ui-user-select-none" data-bind="css: {'message-selected': isMessageSelected, 'loading': messageListCompleteLoadingThrottle, 'hideMessageListCheckbox': !useCheckboxesInList() }">
<div class="messageList g-ui-user-select-none"
data-bind="css: {'message-selected': isMessageSelected, 'message-focused': message.focused, 'loading': messageListCompleteLoadingThrottle, 'hideMessageListCheckbox': !useCheckboxesInList() }">
<div class="toolbar">
<div class="btn-toolbar">
<div class="btn-group">
@ -111,10 +112,6 @@
</a>
</div>
<i class="checkboxCkeckAll" data-bind="css: checkAll() ? (isIncompleteChecked() ? 'icon-checkbox-partial' : 'icon-checkbox-checked') : 'icon-checkbox-unchecked'"></i>
<!--
<i class="checkboxCkeckAll" data-bind="css: checkAll() ? (isIncompleteChecked() ? 'icon-checkbox-partial' : 'icon-checkbox-checked') : 'icon-checkbox-unchecked', visible: !messageListCompleteLoadingThrottle()"></i>
<i class="icon-spinner animated" style="margin-top: 4px;" data-bind="visible: messageListCompleteLoadingThrottle"></i>
-->
</div>
</div>
<div class="mainDelimiter toolbarDelimiter"></div>

View file

@ -1,5 +1,5 @@
<div id="rl-sub-right">
<div class="messageView" data-bind="css: {'message-selected': isMessageSelected}">
<div class="messageView" data-bind="css: {'message-selected': isMessageSelected, 'message-focused': message.focused}">
<div class="toolbar g-ui-user-select-none">
<div class="messageButtons btn-toolbar">
<div class="btn-group" data-placement="bottom" data-bind="visible: !usePreviewPane(), tooltip: 'MESSAGE/BUTTON_CLOSE'">
@ -131,7 +131,7 @@
</div>
<div data-bind="visible: message">
<div class="messageItem" data-bind="css: viewLineAsCcc(), nano: true">
<div class="content g-scrollbox">
<div class="content g-scrollbox" tabindex="0" data-bind="hasfocus: messageDomFocused">
<div class="content-wrapper">
<div>
<span class="buttonUp" data-bind="click: scrollToTop">

View file

@ -0,0 +1,17 @@
<div class="popups">
<div class="modal hide b-shortcuts-content" data-bind="modal: modalVisibility">
<div class="modal-header">
<button type="button" class="close" data-bind="command: cancelCommand">&times;</button>
<h3>
Keyboard shortcuts help
</h3>
</div>
<div class="modal-body">
<br />
Coming soon!
<br />
<br />
<br />
</div>
</div>
</div>

View file

@ -6416,6 +6416,9 @@ html.rl-no-preview-pane #rl-right .ui-resizable-handle {
.popups .b-ask-content .desc-place {
font-size: 18px;
}
.popups .b-shortcuts-content .modal-header {
background-color: #fff;
}
.b-folders .b-toolbar {
position: absolute;
top: 0;
@ -7048,6 +7051,10 @@ html.rl-no-preview-pane .messageList.message-selected {
.messageList .b-content .messageListItem.flagged .flagOn {
display: inline-block;
}
.messageList.message-focused .b-content {
opacity: 0.97;
filter: alpha(opacity=97);
}
.messageList.hideMessageListCheckbox .checkedParent,
.messageList.hideMessageListCheckbox .checkboxCkeckAll {
display: none !important;
@ -7096,10 +7103,9 @@ html.rl-no-preview-pane .messageView.message-selected {
top: 58px;
bottom: 13px;
right: 8px;
left: 0;
left: -1px;
overflow: hidden;
border: 1px solid #aaaaaa;
border-left: 0px;
-webkit-border-top-right-radius: 3px;
-moz-border-radius-topright: 3px;
border-top-right-radius: 3px;
@ -7380,6 +7386,19 @@ html.rl-no-preview-pane .messageView.message-selected {
border-left: 2px solid red;
color: red;
}
.messageView.message-focused .messageItemHeader {
background-color: #fafafa !important;
}
.messageView.message-focused .b-content {
z-index: 102;
-webkit-box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.3);
-moz-box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.3);
box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.3);
border-color: #9d9d9d;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
}
html.rl-no-preview-pane .messageView .toolbar {
padding-left: 1px;
}

File diff suppressed because one or more lines are too long

View file

@ -367,6 +367,18 @@ Enums.StateType = {
'Admin': 1
};
/**
* @enum {string}
*/
Enums.KeyState = {
'None': 'none',
'ContactList': 'contact-list',
'MessageList': 'message-list',
'MessageView': 'message-view',
'Compose': 'compose',
'PopupAsk': 'popup-ask'
};
/**
* @enum {number}
*/
@ -2421,6 +2433,34 @@ Utils.selectElement = function (element)
/* jshint onevar: true */
};
Utils.disableKeyFilter = function ()
{
if (window.key)
{
key.filter = function () {
return true;
};
}
};
Utils.restoreKeyFilter = function ()
{
if (window.key)
{
key.filter = function (event) {
var
element = event.target || event.srcElement,
tagName = element ? element.tagName : ''
;
tagName = tagName.toUpperCase();
return !(tagName === 'INPUT' || tagName === 'SELECT' || tagName === 'TEXTAREA' ||
(element && tagName === 'DIV' && 'editorHtmlArea' === element.className && element.contentEditable)
);
};
}
};
// Base64 encode / decode
// http://www.webtoolkit.info/
@ -3889,16 +3929,13 @@ KnoinAbstractViewModel.prototype.cancelCommand = KnoinAbstractViewModel.prototyp
KnoinAbstractViewModel.prototype.registerPopupEscapeKey = function ()
{
var self = this;
$window.on('keydown', function (oEvent) {
if (oEvent && Enums.EventKeyCode.Esc === oEvent.keyCode && self.modalVisibility())
key('esc', _.bind(function () {
if (this.modalVisibility && this.modalVisibility())
{
Utils.delegateRun(self, 'cancelCommand');
Utils.delegateRun(this, 'cancelCommand');
return false;
}
return true;
});
}, this));
};
/**
@ -5072,16 +5109,13 @@ PopupsPluginViewModel.prototype.tryToClosePopup = function ()
PopupsPluginViewModel.prototype.onBuild = function ()
{
var self = this;
$window.on('keydown', function (oEvent) {
var bResult = true;
if (oEvent && Enums.EventKeyCode.Esc === oEvent.keyCode && self.modalVisibility())
key('esc', _.bind(function () {
if (this.modalVisibility())
{
self.tryToClosePopup();
bResult = false;
this.tryToClosePopup();
return false;
}
return bResult;
});
}));
};
/**
@ -5279,6 +5313,7 @@ function PopupsAskViewModel()
this.fNoAction = null;
this.bDisabeCloseOnEsc = true;
this.sKeyScope = Enums.KeyState.MessageList;
Knoin.constructorEnd(this);
}
@ -5300,22 +5335,22 @@ PopupsAskViewModel.prototype.clearPopup = function ()
PopupsAskViewModel.prototype.yesClick = function ()
{
this.cancelCommand();
if (Utils.isFunc(this.fYesAction))
{
this.fYesAction.call(null);
}
this.cancelCommand();
};
PopupsAskViewModel.prototype.noClick = function ()
{
this.cancelCommand();
if (Utils.isFunc(this.fNoAction))
{
this.fNoAction.call(null);
}
this.cancelCommand();
};
/**
@ -5342,6 +5377,9 @@ PopupsAskViewModel.prototype.onShow = function (sAskDesc, fYesFunc, fNoFunc, sYe
{
this.yesButton(sNoButton);
}
this.sKeyScope = RL.data().keyScope();
RL.data().keyScope(Enums.KeyState.PopupAsk);
};
PopupsAskViewModel.prototype.onFocus = function ()
@ -5351,32 +5389,26 @@ PopupsAskViewModel.prototype.onFocus = function ()
PopupsAskViewModel.prototype.onHide = function ()
{
RL.data().keyScope(this.sKeyScope);
};
PopupsAskViewModel.prototype.onBuild = function ()
{
var self = this;
$window.on('keydown', function (oEvent) {
var bResult = true;
if (oEvent && self.modalVisibility())
key('tab, right, left', Enums.KeyState.PopupAsk, _.bind(function () {
if (this.modalVisibility())
{
if (Enums.EventKeyCode.Tab === oEvent.keyCode || Enums.EventKeyCode.Right === oEvent.keyCode || Enums.EventKeyCode.Left === oEvent.keyCode)
if (this.yesFocus())
{
if (self.yesFocus())
{
self.noFocus(true);
}
else
{
self.yesFocus(true);
}
bResult = false;
this.noFocus(true);
}
else
{
this.yesFocus(true);
}
}
return bResult;
});
return false;
}
}, this));
};

File diff suppressed because one or more lines are too long

View file

@ -1,5 +1,5 @@
/*! RainLoop Webmail Main Module (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
(function (window, $, ko, crossroads, hasher, moment, Jua, _, ifvisible) {
(function (window, $, ko, crossroads, hasher, moment, Jua, _, ifvisible, key) {
'use strict';
@ -371,6 +371,18 @@ Enums.StateType = {
'Admin': 1
};
/**
* @enum {string}
*/
Enums.KeyState = {
'None': 'none',
'ContactList': 'contact-list',
'MessageList': 'message-list',
'MessageView': 'message-view',
'Compose': 'compose',
'PopupAsk': 'popup-ask'
};
/**
* @enum {number}
*/
@ -2425,6 +2437,34 @@ Utils.selectElement = function (element)
/* jshint onevar: true */
};
Utils.disableKeyFilter = function ()
{
if (window.key)
{
key.filter = function () {
return true;
};
}
};
Utils.restoreKeyFilter = function ()
{
if (window.key)
{
key.filter = function (event) {
var
element = event.target || event.srcElement,
tagName = element ? element.tagName : ''
;
tagName = tagName.toUpperCase();
return !(tagName === 'INPUT' || tagName === 'SELECT' || tagName === 'TEXTAREA' ||
(element && tagName === 'DIV' && 'editorHtmlArea' === element.className && element.contentEditable)
);
};
}
};
// Base64 encode / decode
// http://www.webtoolkit.info/
@ -3979,10 +4019,12 @@ Selector.prototype.goUp = function ()
this.newSelectPosition(Enums.EventKeyCode.Up, false);
};
Selector.prototype.init = function (oContentVisible, oContentScrollable)
Selector.prototype.init = function (oContentVisible, oContentScrollable, sKeyScope)
{
this.oContentVisible = oContentVisible;
this.oContentScrollable = oContentScrollable;
sKeyScope = sKeyScope || 'all';
if (this.oContentVisible && this.oContentScrollable)
{
@ -4025,27 +4067,43 @@ Selector.prototype.init = function (oContentVisible, oContentScrollable)
})
;
$(window.document).on('keydown', function (oEvent) {
var bResult = true;
if (oEvent && self.bUseKeyboard && !Utils.inFocus())
key('space, enter', sKeyScope, function () {
return false;
});
key('up, shift+up, down, shift+down, insert, home, end, pageup, pagedown', sKeyScope, function (event, handler) {
if (event && handler && handler.shortcut)
{
if (-1 < Utils.inArray(oEvent.keyCode, [Enums.EventKeyCode.Up, Enums.EventKeyCode.Down, Enums.EventKeyCode.Insert,
Enums.EventKeyCode.Home, Enums.EventKeyCode.End, Enums.EventKeyCode.PageUp, Enums.EventKeyCode.PageDown]))
var iKey = 0, aCodes = null;
switch (handler.shortcut)
{
self.newSelectPosition(oEvent.keyCode, oEvent.shiftKey);
bResult = false;
case 'up':
case 'shift+up':
iKey = Enums.EventKeyCode.Up;
break;
case 'down':
case 'shift+down':
iKey = Enums.EventKeyCode.Down;
break;
case 'insert':
case 'home':
case 'end':
case 'pageup':
case 'pagedown':
aCodes = key.getPressedKeyCodes();
if (aCodes && aCodes[0])
{
iKey = aCodes[0];
}
break;
}
else if (Enums.EventKeyCode.Delete === oEvent.keyCode && !oEvent.ctrlKey && !oEvent.shiftKey)
if (0 < iKey)
{
if (self.oCallbacks['onDelete'])
{
self.oCallbacks['onDelete']();
}
bResult = false;
self.newSelectPosition(iKey, key.shift);
return false;
}
}
return bResult;
});
}
};
@ -4706,16 +4764,13 @@ KnoinAbstractViewModel.prototype.cancelCommand = KnoinAbstractViewModel.prototyp
KnoinAbstractViewModel.prototype.registerPopupEscapeKey = function ()
{
var self = this;
$window.on('keydown', function (oEvent) {
if (oEvent && Enums.EventKeyCode.Esc === oEvent.keyCode && self.modalVisibility())
key('esc', _.bind(function () {
if (this.modalVisibility && this.modalVisibility())
{
Utils.delegateRun(self, 'cancelCommand');
Utils.delegateRun(this, 'cancelCommand');
return false;
}
return true;
});
}, this));
};
/**
@ -5556,8 +5611,9 @@ function ContactModel()
this.readOnly = false;
this.scopeType = Enums.ContactScopeType.Default;
this.checked = ko.observable(false);
this.focused = ko.observable(false);
this.selected = ko.observable(false);
this.checked = ko.observable(false);
this.deleted = ko.observable(false);
this.shared = ko.observable(false);
}
@ -5662,6 +5718,10 @@ ContactModel.prototype.lineAsCcc = function ()
{
aResult.push('shared');
}
if (this.focused())
{
aResult.push('focused');
}
return aResult.join(' ');
};
@ -6020,6 +6080,7 @@ function MessageModel()
this.forwarded = ko.observable(false);
this.isReadReceipt = ko.observable(false);
this.focused = ko.observable(false);
this.selected = ko.observable(false);
this.checked = ko.observable(false);
this.hasAttachments = ko.observable(false);
@ -6499,6 +6560,10 @@ MessageModel.prototype.lineAsCcc = function ()
{
aResult.push('forwarded');
}
if (this.focused())
{
aResult.push('focused');
}
if (this.hasAttachments())
{
aResult.push('withAttachments');
@ -7189,6 +7254,7 @@ function FolderModel()
this.type = ko.observable(Enums.FolderType.User);
this.focused = ko.observable(false);
this.selected = ko.observable(false);
this.edited = ko.observable(false);
this.collapsed = ko.observable(true);
@ -8262,7 +8328,8 @@ function PopupsComposeViewModel()
// this.driveCallback = _.bind(this.driveCallback, this);
this.bDisabeCloseOnEsc = true;
this.sKeyScope = Enums.KeyState.MessageList;
Knoin.constructorEnd(this);
}
@ -8479,6 +8546,8 @@ PopupsComposeViewModel.prototype.onHide = function ()
{
this.reset();
kn.routeOn();
RL.data().keyScope(this.sKeyScope);
};
/**
@ -8550,6 +8619,9 @@ PopupsComposeViewModel.prototype.editor = function (fOnInit)
PopupsComposeViewModel.prototype.onShow = function (sType, oMessageOrArray, aToEmails)
{
kn.routeOff();
this.sKeyScope = RL.data().keyScope();
RL.data().keyScope(Enums.KeyState.Compose);
var
self = this,
@ -8825,6 +8897,11 @@ PopupsComposeViewModel.prototype.tryToClosePopup = function ()
}]);
};
PopupsComposeViewModel.prototype.useShortcuts = function ()
{
return this.modalVisibility() && RL.data().useKeyboardShortcuts();
};
PopupsComposeViewModel.prototype.onBuild = function ()
{
this.initUploader();
@ -8834,29 +8911,25 @@ PopupsComposeViewModel.prototype.onBuild = function ()
oScript = null
;
$window.on('keydown', function (oEvent) {
var bResult = true;
if (oEvent && self.modalVisibility() && RL.data().useKeyboardShortcuts())
key('ctrl+s, command+s', Enums.KeyState.Compose, function () {
if (self.useShortcuts())
{
if (oEvent.ctrlKey && !oEvent.shiftKey && !oEvent.altKey && Enums.EventKeyCode.S === oEvent.keyCode)
{
self.saveCommand();
bResult = false;
}
else if (oEvent.ctrlKey && !oEvent.shiftKey && !oEvent.altKey && Enums.EventKeyCode.Enter === oEvent.keyCode)
{
self.sendCommand();
bResult = false;
}
else if (Enums.EventKeyCode.Esc === oEvent.keyCode)
{
self.tryToClosePopup();
bResult = false;
}
self.saveCommand();
return false;
}
});
return bResult;
key('ctrl+enter, command+enter', Enums.KeyState.Compose, function () {
if (self.useShortcuts())
{
self.sendCommand();
return false;
}
});
key('esc', Enums.KeyState.Compose, function () {
self.tryToClosePopup();
return false;
});
$window.on('resize', function () {
@ -9569,10 +9642,6 @@ function PopupsContactsViewModel()
return oContact ? oContact.generateUid() : '';
});
this.selector.on('onDelete', _.bind(function () {
this.deleteCommand();
}, this));
this.newCommand = Utils.createCommand(this, function () {
this.populateViewContact(null);
this.currentContact(null);
@ -9705,6 +9774,8 @@ function PopupsContactsViewModel()
}
}, this);
this.sKeyScope = Enums.KeyState.MessageList;
Knoin.constructorEnd(this);
}
@ -9975,10 +10046,18 @@ PopupsContactsViewModel.prototype.onBuild = function (oDom)
this.oContentVisible = $('.b-list-content', oDom);
this.oContentScrollable = $('.content', this.oContentVisible);
this.selector.init(this.oContentVisible, this.oContentScrollable);
this.selector.init(this.oContentVisible, this.oContentScrollable, Enums.KeyState.ContactList);
var self = this;
key('delete', Enums.KeyState.ContactList, function () {
if (RL.data().useKeyboardShortcuts())
{
self.deleteCommand();
return false;
}
});
ko.computed(function () {
var
bModalVisibility = this.modalVisibility(),
@ -10005,6 +10084,9 @@ PopupsContactsViewModel.prototype.onShow = function ()
{
kn.routeOff();
this.reloadContactList(true);
this.sKeyScope = RL.data().keyScope();
RL.data().keyScope(Enums.KeyState.ContactList);
};
PopupsContactsViewModel.prototype.onHide = function ()
@ -10017,6 +10099,8 @@ PopupsContactsViewModel.prototype.onHide = function ()
_.each(this.contacts(), function (oItem) {
oItem.checked(false);
});
RL.data().keyScope(this.sKeyScope);
};
/**
@ -10936,6 +11020,7 @@ function PopupsAskViewModel()
this.fNoAction = null;
this.bDisabeCloseOnEsc = true;
this.sKeyScope = Enums.KeyState.MessageList;
Knoin.constructorEnd(this);
}
@ -10957,22 +11042,22 @@ PopupsAskViewModel.prototype.clearPopup = function ()
PopupsAskViewModel.prototype.yesClick = function ()
{
this.cancelCommand();
if (Utils.isFunc(this.fYesAction))
{
this.fYesAction.call(null);
}
this.cancelCommand();
};
PopupsAskViewModel.prototype.noClick = function ()
{
this.cancelCommand();
if (Utils.isFunc(this.fNoAction))
{
this.fNoAction.call(null);
}
this.cancelCommand();
};
/**
@ -10999,6 +11084,9 @@ PopupsAskViewModel.prototype.onShow = function (sAskDesc, fYesFunc, fNoFunc, sYe
{
this.yesButton(sNoButton);
}
this.sKeyScope = RL.data().keyScope();
RL.data().keyScope(Enums.KeyState.PopupAsk);
};
PopupsAskViewModel.prototype.onFocus = function ()
@ -11008,35 +11096,55 @@ PopupsAskViewModel.prototype.onFocus = function ()
PopupsAskViewModel.prototype.onHide = function ()
{
RL.data().keyScope(this.sKeyScope);
};
PopupsAskViewModel.prototype.onBuild = function ()
{
var self = this;
$window.on('keydown', function (oEvent) {
var bResult = true;
if (oEvent && self.modalVisibility())
key('tab, right, left', Enums.KeyState.PopupAsk, _.bind(function () {
if (this.modalVisibility())
{
if (Enums.EventKeyCode.Tab === oEvent.keyCode || Enums.EventKeyCode.Right === oEvent.keyCode || Enums.EventKeyCode.Left === oEvent.keyCode)
if (this.yesFocus())
{
if (self.yesFocus())
{
self.noFocus(true);
}
else
{
self.yesFocus(true);
}
bResult = false;
this.noFocus(true);
}
else
{
this.yesFocus(true);
}
}
return bResult;
});
return false;
}
}, this));
};
/**
* @constructor
* @extends KnoinAbstractViewModel
*/
function PopupsKeyboardShortcutsHelpViewModel()
{
KnoinAbstractViewModel.call(this, 'Popups', 'PopupsKeyboardShortcutsHelp');
this.sKeyScope = Enums.KeyState.None;
Knoin.constructorEnd(this);
}
Utils.extendAsViewModel('PopupsKeyboardShortcutsHelpViewModel', PopupsKeyboardShortcutsHelpViewModel);
PopupsKeyboardShortcutsHelpViewModel.prototype.onShow = function ()
{
this.sKeyScope = RL.data().keyScope();
RL.data().keyScope(Enums.KeyState.None);
};
PopupsKeyboardShortcutsHelpViewModel.prototype.onHide = function ()
{
RL.data().keyScope(this.sKeyScope);
};
/**
* @constructor
* @extends KnoinAbstractViewModel
@ -11461,11 +11569,19 @@ Utils.extendAsViewModel('MailBoxFolderListViewModel', MailBoxFolderListViewModel
MailBoxFolderListViewModel.prototype.onBuild = function (oDom)
{
oDom
.on('click', '.b-folders .b-content', function () {
if (RL.data().useKeyboardShortcuts() && RL.data().message.focused())
{
RL.data().message.focused(false);
}
})
.on('click', '.b-folders .e-item .e-link .e-collapsed-sign', function (oEvent) {
var
var
oFolder = ko.dataFor(this),
bCollapsed = false
;
if (oFolder && oEvent)
{
bCollapsed = oFolder.collapsed();
@ -11582,6 +11698,7 @@ function MailBoxMessageListViewModel()
this.popupVisibility = RL.popupVisibility;
this.message = oData.message;
this.messageList = oData.messageList;
this.currentMessage = oData.currentMessage;
this.isMessageSelected = oData.isMessageSelected;
@ -11780,13 +11897,6 @@ function MailBoxMessageListViewModel()
return oMessage ? oMessage.generateUid() : '';
});
this.selector.on('onDelete', _.bind(function () {
if (0 < RL.data().messageListCheckedOrSelected().length)
{
this.deleteCommand();
}
}, this));
RL
.sub('mailbox.message-list.selector.go-down', function () {
this.selector.goDown();
@ -12106,31 +12216,15 @@ MailBoxMessageListViewModel.prototype.onBuild = function (oDom)
return false;
});
this.selector.init(this.oContentVisible, this.oContentScrollable);
$document.on('keydown', function (oEvent) {
var
bResult = true,
iKeyCode = oEvent ? oEvent.keyCode : 0
;
if (oEvent && self.viewModelVisibility() && oData.useKeyboardShortcuts() && !RL.popupVisibility() && !oData.messageFullScreenMode() && !Utils.inFocus())
{
if (Enums.Layout.NoPreview !== oData.layout() || (!oData.message() && (Enums.EventKeyCode.Delete === iKeyCode || Enums.EventKeyCode.A === iKeyCode)))
{
if (oEvent.ctrlKey && Enums.EventKeyCode.A === iKeyCode)
{
self.checkAll(!(self.checkAll() && !self.isIncompleteChecked()));
bResult = false;
}
}
}
return bResult;
});
this.selector.init(this.oContentVisible, this.oContentScrollable, Enums.KeyState.MessageList);
oDom
.on('click', '.messageList .b-message-list-wrapper', function () {
if (oData.useKeyboardShortcuts() && self.message.focused())
{
self.message.focused(false);
}
})
.on('click', '.e-pagenator .e-page', function () {
var oPage = ko.dataFor(this);
if (oPage)
@ -12191,6 +12285,7 @@ MailBoxMessageListViewModel.prototype.onBuild = function (oDom)
}, this).extend({'notify': 'always'});
this.initUploaderForAppend();
this.initShortcuts();
if (!Globals.bMobileDevice && !!RL.settingsGet('AllowPrefetch') && ifvisible)
{
@ -12202,6 +12297,121 @@ MailBoxMessageListViewModel.prototype.onBuild = function (oDom)
}
};
MailBoxMessageListViewModel.prototype.initShortcuts = function ()
{
var
self = this,
oData = RL.data()
;
// disable print
key('ctrl+p, command+p', Enums.KeyState.MessageList, function () {
if (oData.useKeyboardShortcuts())
{
return false;
}
});
// delete
key('delete, shift+delete', Enums.KeyState.MessageList, function (event, handler) {
if (oData.useKeyboardShortcuts() && event)
{
if (0 < RL.data().messageListCheckedOrSelected().length)
{
if (handler && 'shift+delete' === handler.shortcut)
{
self.deleteWithoutMoveCommand();
}
else
{
self.deleteCommand();
}
}
return false;
}
});
// check all
key('ctrl+a, command+a', Enums.KeyState.MessageList, function () {
if (oData.useKeyboardShortcuts())
{
self.checkAll(!(self.checkAll() && !self.isIncompleteChecked()));
return false;
}
});
// new message (open compose popup)
key('c,n', [Enums.KeyState.MessageList, Enums.KeyState.MessageView], function () {
if (oData.useKeyboardShortcuts())
{
kn.showScreenPopup(PopupsComposeViewModel);
return false;
}
});
// shortcuts help
key('shift+/', [Enums.KeyState.MessageList, Enums.KeyState.MessageView], function () {
if (oData.useKeyboardShortcuts())
{
kn.showScreenPopup(PopupsKeyboardShortcutsHelpViewModel);
return false;
}
});
// search input focus
key('/', [Enums.KeyState.MessageList, Enums.KeyState.MessageView], function () {
if (oData.useKeyboardShortcuts())
{
if (self.message())
{
self.message.focused(false);
}
self.inputMessageListSearchFocus(true);
return false;
}
});
// cancel search
key('esc', Enums.KeyState.MessageList, function () {
if (oData.useKeyboardShortcuts() && '' !== self.messageListSearchDesc())
{
self.cancelSearch();
return false;
}
});
// change focused state
key('tab, enter', Enums.KeyState.MessageList, function () {
if (oData.useKeyboardShortcuts())
{
if (self.message())
{
self.message.focused(true);
}
return false;
}
});
key('ctrl+left, command+left', Enums.KeyState.MessageView, function () {
if (oData.useKeyboardShortcuts())
{
// TODO
return false;
}
});
key('ctrl+right, command+right', Enums.KeyState.MessageView, function () {
if (oData.useKeyboardShortcuts())
{
// TODO
return false;
}
});
};
MailBoxMessageListViewModel.prototype.prefetchNextTick = function ()
{
if (!this.bPrefetch && !ifvisible.now() && this.viewModelVisibility())
@ -12329,6 +12539,7 @@ function MailBoxMessageViewViewModel()
this.oMessageScrollerDom = null;
this.keyScope = oData.keyScope;
this.message = oData.message;
this.messageLoading = oData.messageLoading;
this.messageLoadingThrottle = oData.messageLoadingThrottle;
@ -12344,6 +12555,7 @@ function MailBoxMessageViewViewModel()
this.fullScreenMode = oData.messageFullScreenMode;
this.showFullInfo = ko.observable(false);
this.messageDomFocused = ko.observable(false);
this.messageVisibility = ko.computed(function () {
return !this.messageLoadingThrottle() && !!this.message();
@ -12376,36 +12588,39 @@ function MailBoxMessageViewViewModel()
}, this.messageVisibility);
this.deleteCommand = Utils.createCommand(this, function () {
if (this.message())
{
RL.deleteMessagesFromFolder(Enums.FolderType.Trash,
this.message().folderFullNameRaw,
[this.message().uid], true);
}
}, this.messageVisibility);
this.deleteWithoutMoveCommand = Utils.createCommand(this, function () {
if (this.message())
{
RL.deleteMessagesFromFolder(Enums.FolderType.Trash,
RL.data().currentFolderFullNameRaw(),
RL.data().messageListCheckedOrSelectedUidsWithSubMails(), false);
}
}, this.messageVisibility);
this.archiveCommand = Utils.createCommand(this, function () {
if (this.message())
{
RL.deleteMessagesFromFolder(Enums.FolderType.Archive,
this.message().folderFullNameRaw,
[this.message().uid], true);
}
}, this.messageVisibility);
this.spamCommand = Utils.createCommand(this, function () {
if (this.message())
{
RL.deleteMessagesFromFolder(Enums.FolderType.Spam,
this.message().folderFullNameRaw,
[this.message().uid], true);
}
}, this.messageVisibility);
// viewer
@ -12599,29 +12814,14 @@ MailBoxMessageViewViewModel.prototype.onBuild = function (oDom)
self = this,
oData = RL.data()
;
$document.on('keydown', function (oEvent) {
var
bResult = true,
iKeyCode = oEvent ? oEvent.keyCode : 0
;
if (0 < iKeyCode && (Enums.EventKeyCode.Esc === iKeyCode) &&
self.viewModelVisibility() && oData.useKeyboardShortcuts() && !Utils.inFocus() && oData.message())
this.fullScreenMode.subscribe(function (bValue) {
if (bValue)
{
self.fullScreenMode(false);
if (Enums.Layout.NoPreview === oData.layout())
{
RL.historyBack();
}
bResult = false;
self.message.focused(true);
}
return bResult;
});
}, this);
$('.attachmentsPlace', oDom).magnificPopup({
'delegate': '.magnificPopupImage:visible',
'type': 'image',
@ -12643,6 +12843,12 @@ MailBoxMessageViewViewModel.prototype.onBuild = function (oDom)
});
oDom
.on('click', '.messageView .messageItem', function () {
if (oData.useKeyboardShortcuts() && self.message())
{
self.message.focused(true);
}
})
.on('mousedown', 'a', function (oEvent) {
// setup maito protocol
return !(oEvent && 3 !== oEvent['which'] && RL.mailToHelper($(this).attr('href')));
@ -12666,8 +12872,171 @@ MailBoxMessageViewViewModel.prototype.onBuild = function (oDom)
})
;
this.message.focused.subscribe(function (bValue) {
this.messageDomFocused(!!bValue);
}, this);
this.keyScope.subscribe(function (sValue) {
if (Enums.KeyState.MessageView === sValue && this.message.focused())
{
this.messageDomFocused(true);
}
}, this);
this.oMessageScrollerDom = oDom.find('.messageItem .content');
this.oMessageScrollerDom = this.oMessageScrollerDom && this.oMessageScrollerDom[0] ? this.oMessageScrollerDom : null;
this.initShortcuts();
};
/**
* @return {boolean}
*/
MailBoxMessageViewViewModel.prototype.escShortcuts = function ()
{
if (this.viewModelVisibility() && RL.data().useKeyboardShortcuts() && this.message())
{
if (this.fullScreenMode())
{
this.fullScreenMode(false);
}
else
{
this.message.focused(false);
}
if (Enums.Layout.NoPreview === RL.data().layout())
{
RL.historyBack();
}
return false;
}
};
MailBoxMessageViewViewModel.prototype.initShortcuts = function ()
{
var
self = this,
oData = RL.data()
;
// exit fullscreen, back
key('esc', Enums.KeyState.MessageView, _.bind(this.escShortcuts, this));
// fullscreen
key('enter', Enums.KeyState.MessageView, function () {
if (oData.useKeyboardShortcuts())
{
self.toggleFullScreen();
return false;
}
});
// reply
key('r', Enums.KeyState.MessageView, function () {
if (oData.useKeyboardShortcuts())
{
self.replyCommand();
return false;
}
});
// replaAll
key('a', Enums.KeyState.MessageView, function () {
if (oData.useKeyboardShortcuts())
{
self.replyAllCommand();
return false;
}
});
// forward
key('f', Enums.KeyState.MessageView, function () {
if (oData.useKeyboardShortcuts())
{
self.forwardCommand();
return false;
}
});
// message information
key('i', Enums.KeyState.MessageView, function () {
if (oData.useKeyboardShortcuts())
{
self.showFullInfo(!self.showFullInfo());
return false;
}
});
key('ctrl+left, command+left', Enums.KeyState.MessageView, function () {
if (oData.useKeyboardShortcuts())
{
self.goDownCommand();
return false;
}
});
key('ctrl+right, command+right', Enums.KeyState.MessageView, function () {
if (oData.useKeyboardShortcuts())
{
self.goUpCommand();
return false;
}
});
// print
key('ctrl+p, command+p', Enums.KeyState.MessageView, function () {
if (oData.useKeyboardShortcuts())
{
if (self.message())
{
self.message().printMessage();
}
return false;
}
});
// archive
// key('delete', Enums.KeyState.MessageView, function () {
// if (oData.useKeyboardShortcuts())
// {
// self.archiveCommand();
// return false;
// }
// });
// delete
key('delete, shift+delete', Enums.KeyState.MessageView, function (event, handler) {
if (oData.useKeyboardShortcuts() && event)
{
self.deleteCommand();
if (handler && 'shift+delete' === handler.shortcut)
{
// self.deleteWithoutMoveCommand();
self.deleteCommand();
}
else
{
self.deleteCommand();
}
return false;
}
});
// change focused state
key('tab', Enums.KeyState.MessageView, function () {
if (oData.useKeyboardShortcuts())
{
if (self.message())
{
self.message.focused(false);
}
return false;
}
});
};
/**
@ -14241,12 +14610,27 @@ function WebMailDataStorage()
this.accountIncLogin = ko.observable('');
this.accountOutLogin = ko.observable('');
this.projectHash = ko.observable('');
this.threading = ko.observable(false);
this.lastFoldersHash = '';
this.lastFoldersHash = '';
this.remoteSuggestions = false;
this.keyScope = ko.observable(Enums.KeyState.None);
this.keyScope.subscribe(function (sValue) {
if (Enums.KeyState.Compose === sValue)
{
Utils.disableKeyFilter();
}
else
{
Utils.restoreKeyFilter();
}
// window.console.log(sValue);
key.setScope(sValue);
});
// system folders
this.sentFolder = ko.observable('');
this.draftFolder = ko.observable('');
@ -14461,6 +14845,23 @@ function WebMailDataStorage()
this.messageLoading = ko.observable(false);
this.messageLoadingThrottle = ko.observable(false).extend({'throttle': 50});
this.message.focused = ko.observable(false);
this.message.subscribe(function (oMessage) {
if (!oMessage)
{
this.message.focused(false);
}
else if (Enums.Layout.NoPreview === this.layout())
{
this.message.focused(true);
}
}, this);
this.message.focused.subscribe(function (bValue) {
RL.data().keyScope(bValue ? Enums.KeyState.MessageView : Enums.KeyState.MessageList);
});
this.messageLoading.subscribe(function (bValue) {
this.messageLoadingThrottle(bValue);
}, this);
@ -17063,6 +17464,13 @@ MailBoxScreen.prototype.setNewTitle = function ()
MailBoxScreen.prototype.onShow = function ()
{
this.setNewTitle();
RL.data().keyScope(Enums.KeyState.MessageList);
};
MailBoxScreen.prototype.onHide = function ()
{
RL.data().keyScope(Enums.KeyState.None);
};
/**
@ -18752,4 +19160,4 @@ if (window.SimplePace) {
window.SimplePace.add(10);
}
}(window, jQuery, ko, crossroads, hasher, moment, Jua, _, ifvisible));
}(window, jQuery, ko, crossroads, hasher, moment, Jua, _, ifvisible, key));

File diff suppressed because one or more lines are too long

View file

@ -227,6 +227,314 @@ this.j[c]=i,g.on("click",function(){var a=b.b.d("onDialog");a&&a()}).on("change"
j.c=e;j.h=0;j.a={};j.m={};j.q=f;j.e=f;j.on=function(a,b){this.m[a]=b;return this};j.g=function(a,b){this.m[a]&&this.m[a].apply(f,b||[])};j.d=function(a){return this.m[a]||f};j.cancel=function(a){this.e.cancel(a)};j.p=function(){return B.p};j.v=function(a){this.c=!!a};j.k=function(){return this.e.k()};j.s=function(a){this.r(w(),a)};
j.r=function(a,b){var c=this.d("onSelect");if(b&&(!c||h!==c(a,b))){this.e.t(a);var g=this.e.u,d=this.e;this.q.defer(function(){return g.apply(q(d)?f:d,Array.prototype.slice.call(arguments))},a,b)}else this.e.cancel(a)};l.Jua=B;
// keymaster.js
// (c) 2011-2013 Thomas Fuchs
// keymaster.js may be freely distributed under the MIT license.
;(function(global){
var k,
_handlers = {},
_mods = { 16: false, 18: false, 17: false, 91: false },
_scope = 'all',
// modifier keys
_MODIFIERS = {
'⇧': 16, shift: 16,
'⌥': 18, alt: 18, option: 18,
'⌃': 17, ctrl: 17, control: 17,
'⌘': 91, command: 91
},
// special keys
_MAP = {
backspace: 8, tab: 9, clear: 12,
enter: 13, 'return': 13,
esc: 27, escape: 27, space: 32,
left: 37, up: 38,
right: 39, down: 40,
insert: 45,
del: 46, 'delete': 46,
home: 36, end: 35,
pageup: 33, pagedown: 34,
',': 188, '.': 190, '/': 191,
'`': 192, '-': 189, '=': 187,
';': 186, '\'': 222,
'[': 219, ']': 221, '\\': 220
},
code = function(x){
return _MAP[x] || x.toUpperCase().charCodeAt(0);
},
_downKeys = [];
for(k=1;k<20;k++) _MAP['f'+k] = 111+k;
// IE doesn't support Array#indexOf, so have a simple replacement
function index(array, item){
var i = array.length;
while(i--) if(array[i]===item) return i;
return -1;
}
// for comparing mods before unassignment
function compareArray(a1, a2) {
if (a1.length != a2.length) return false;
for (var i = 0; i < a1.length; i++) {
if (a1[i] !== a2[i]) return false;
}
return true;
}
var modifierMap = {
16:'shiftKey',
18:'altKey',
17:'ctrlKey',
91:'metaKey'
};
function updateModifierKey(event) {
for(k in _mods) _mods[k] = event[modifierMap[k]];
};
// handle keydown event
function dispatch(event) {
var key, handler, k, i, modifiersMatch, scope;
key = event.keyCode;
if (index(_downKeys, key) == -1) {
_downKeys.push(key);
}
// if a modifier key, set the key.<modifierkeyname> property to true and return
if(key == 93 || key == 224) key = 91; // right command on webkit, command on Gecko
if(key in _mods) {
_mods[key] = true;
// 'assignKey' from inside this closure is exported to window.key
for(k in _MODIFIERS) if(_MODIFIERS[k] == key) assignKey[k] = true;
return;
}
updateModifierKey(event);
// see if we need to ignore the keypress (filter() can can be overridden)
// by default ignore key presses if a select, textarea, or input is focused
if(!assignKey.filter.call(this, event)) return;
// abort if no potentially matching shortcuts found
if (!(key in _handlers)) return;
scope = getScope();
// for each potential shortcut
for (i = 0; i < _handlers[key].length; i++) {
handler = _handlers[key][i];
// see if it's in the current scope
if(handler.scope == scope || handler.scope == 'all'){
// check if modifiers match if any
modifiersMatch = handler.mods.length > 0;
for(k in _mods)
if((!_mods[k] && index(handler.mods, +k) > -1) ||
(_mods[k] && index(handler.mods, +k) == -1)) modifiersMatch = false;
// call the handler and stop the event if neccessary
if((handler.mods.length == 0 && !_mods[16] && !_mods[18] && !_mods[17] && !_mods[91]) || modifiersMatch){
if(handler.method(event, handler)===false){
if(event.preventDefault) event.preventDefault();
else event.returnValue = false;
if(event.stopPropagation) event.stopPropagation();
if(event.cancelBubble) event.cancelBubble = true;
}
}
}
}
};
// unset modifier keys on keyup
function clearModifier(event){
var key = event.keyCode, k,
i = index(_downKeys, key);
// remove key from _downKeys
if (i >= 0) {
_downKeys.splice(i, 1);
}
if(key == 93 || key == 224) key = 91;
if(key in _mods) {
_mods[key] = false;
for(k in _MODIFIERS) if(_MODIFIERS[k] == key) assignKey[k] = false;
}
};
function resetModifiers() {
for(k in _mods) _mods[k] = false;
for(k in _MODIFIERS) assignKey[k] = false;
};
// parse and assign shortcut
function assignKey(key, scope, method){
var keys, mods, bScopeIsArray = false;
keys = getKeys(key);
if (method === undefined) {
method = scope;
scope = 'all';
}
bScopeIsArray = !!(typeof scope !== 'string' && scope.length && typeof scope[0] === 'string');
// for each shortcut
for (var i = 0; i < keys.length; i++) {
// set modifier keys if any
mods = [];
key = keys[i].split('+');
if (key.length > 1){
mods = getMods(key);
key = [key[key.length-1]];
}
// convert to keycode and...
key = key[0];
key = code(key);
// ...store handler
if (!(key in _handlers)) _handlers[key] = [];
if (bScopeIsArray) {
for (var j = 0; j < scope.length; j++) {
_handlers[key].push({ shortcut: keys[i], scope: scope[j], method: method, key: keys[i], mods: mods });
}
} else {
_handlers[key].push({ shortcut: keys[i], scope: scope, method: method, key: keys[i], mods: mods });
}
}
};
// unbind all handlers for given key in current scope
function unbindKey(key, scope) {
var multipleKeys, keys,
mods = [],
i, j, obj;
multipleKeys = getKeys(key);
for (j = 0; j < multipleKeys.length; j++) {
keys = multipleKeys[j].split('+');
if (keys.length > 1) {
mods = getMods(keys);
key = keys[keys.length - 1];
}
key = code(key);
if (scope === undefined) {
scope = getScope();
}
if (!_handlers[key]) {
return;
}
for (i = 0; i < _handlers[key].length; i++) {
obj = _handlers[key][i];
// only clear handlers if correct scope and mods match
if (obj.scope === scope && compareArray(obj.mods, mods)) {
_handlers[key][i] = {};
}
}
}
};
// Returns true if the key with code 'keyCode' is currently down
// Converts strings into key codes.
function isPressed(keyCode) {
if (typeof(keyCode)=='string') {
keyCode = code(keyCode);
}
return index(_downKeys, keyCode) != -1;
}
function getPressedKeyCodes() {
return _downKeys.slice(0);
}
function filter(event){
var tagName = (event.target || event.srcElement).tagName;
// ignore keypressed in any elements that support keyboard data input
return !(tagName == 'INPUT' || tagName == 'SELECT' || tagName == 'TEXTAREA');
}
// initialize key.<modifier> to false
for(k in _MODIFIERS) assignKey[k] = false;
// set current scope (default 'all')
function setScope(scope){ _scope = scope || 'all' };
function getScope(){ return _scope || 'all' };
// delete all handlers for a given scope
function deleteScope(scope){
var key, handlers, i;
for (key in _handlers) {
handlers = _handlers[key];
for (i = 0; i < handlers.length; ) {
if (handlers[i].scope === scope) handlers.splice(i, 1);
else i++;
}
}
};
// abstract key logic for assign and unassign
function getKeys(key) {
var keys;
key = key.replace(/\s/g, '');
keys = key.split(',');
if ((keys[keys.length - 1]) == '') {
keys[keys.length - 2] += ',';
}
return keys;
}
// abstract mods logic for assign and unassign
function getMods(key) {
var mods = key.slice(0, key.length - 1);
for (var mi = 0; mi < mods.length; mi++)
mods[mi] = _MODIFIERS[mods[mi]];
return mods;
}
// cross-browser events
function addEvent(object, event, method) {
if (object.addEventListener)
object.addEventListener(event, method, false);
else if(object.attachEvent)
object.attachEvent('on'+event, function(){ method(window.event) });
};
// set the handlers globally on document
addEvent(document, 'keydown', function(event) { dispatch(event) }); // Passing _scope to a callback to ensure it remains the same by execution. Fixes #48
addEvent(document, 'keyup', clearModifier);
// reset modifiers to false whenever the window is (re)focused.
addEvent(window, 'focus', resetModifiers);
// store previously defined key
var previousKey = global.key;
// restore previously defined key and return reference to our key object
function noConflict() {
var k = global.key;
global.key = previousKey;
return k;
}
// set window.key and window.key.set/get/deleteScope, and the default filter
global.key = assignKey;
global.key.setScope = setScope;
global.key.getScope = getScope;
global.key.deleteScope = deleteScope;
global.key.filter = filter;
global.key.isPressed = isPressed;
global.key.getPressedKeyCodes = getPressedKeyCodes;
global.key.noConflict = noConflict;
global.key.unbind = unbindKey;
if(typeof module !== 'undefined') module.exports = key;
})(this);
/*!ifvisible.js v1.0.0 (c) 2013 Serkan Yersen | MIT */
(function(){"use strict";var a,b,c,d,e,f,g,h,i,j,k,l,m,n;i={},c=document,k=!1,l="active",g=6e4,f=!1,b=function(){var a,b,c,d,e,f;return a=function(){return(65536*(1+Math.random())|0).toString(16).substring(1)},e=function(){return a()+a()+"-"+a()+"-"+a()+"-"+a()+"-"+a()+a()+a()},f={},c="__ceGUID",b=function(a,b,d){return a[c]=void 0,a[c]||(a[c]="ifvisible.object.event.identifier"),f[a[c]]||(f[a[c]]={}),f[a[c]][b]||(f[a[c]][b]=[]),f[a[c]][b].push(d)},d=function(a,b,d){var e,g,h,i,j;if(a[c]&&f[a[c]]&&f[a[c]][b]){for(i=f[a[c]][b],j=[],g=0,h=i.length;h>g;g++)e=i[g],j.push(e(d||{}));return j}},{add:b,fire:d}}(),a=function(){var a;return a=!1,function(b,c,d){return a||(a=b.addEventListener?function(a,b,c){return a.addEventListener(b,c,!1)}:b.attachEvent?function(a,b,c){return a.attachEvent("on"+b,c,!1)}:function(a,b,c){return a["on"+b]=c}),a(b,c,d)}}(),d=function(a,b){var d;return c.createEventObject?a.fireEvent("on"+b,d):(d=c.createEvent("HTMLEvents"),d.initEvent(b,!0,!0),!a.dispatchEvent(d))},h=function(){var a,b,d,e,f;for(e=void 0,f=3,d=c.createElement("div"),a=d.getElementsByTagName("i"),b=function(){return d.innerHTML="<!--[if gt IE "+ ++f+"]><i></i><![endif]-->",a[0]};b(););return f>4?f:e}(),e=!1,n=void 0,"undefined"!=typeof c.hidden?(e="hidden",n="visibilitychange"):"undefined"!=typeof c.mozHidden?(e="mozHidden",n="mozvisibilitychange"):"undefined"!=typeof c.msHidden?(e="msHidden",n="msvisibilitychange"):"undefined"!=typeof c.webkitHidden&&(e="webkitHidden",n="webkitvisibilitychange"),m=function(){var b,d;return b=!1,d=function(){return clearTimeout(b),"active"!==l&&i.wakeup(),f=+new Date,b=setTimeout(function(){return"active"===l?i.idle():void 0},g)},d(),a(c,"mousemove",d),a(c,"keyup",d),a(window,"scroll",d),i.focus(d)},j=function(){var b;return k?!0:(e===!1?(b="blur",9>h&&(b="focusout"),a(window,b,function(){return i.blur()}),a(window,"focus",function(){return i.focus()})):a(c,n,function(){return c[e]?i.blur():i.focus()},!1),k=!0,m())},i={setIdleDuration:function(a){return g=1e3*a},getIdleDuration:function(){return g},getIdleInfo:function(){var a,b;return a=+new Date,b={},"idle"===l?(b.isIdle=!0,b.idleFor=a-f,b.timeLeft=0,b.timeLeftPer=100):(b.isIdle=!1,b.idleFor=a-f,b.timeLeft=f+g-a,b.timeLeftPer=(100-100*b.timeLeft/g).toFixed(2)),b},focus:function(a){return"function"==typeof a?this.on("focus",a):(l="active",b.fire(this,"focus"),b.fire(this,"wakeup"),b.fire(this,"statusChanged",{status:l}))},blur:function(a){return"function"==typeof a?this.on("blur",a):(l="hidden",b.fire(this,"blur"),b.fire(this,"idle"),b.fire(this,"statusChanged",{status:l}))},idle:function(a){return"function"==typeof a?this.on("idle",a):(l="idle",b.fire(this,"idle"),b.fire(this,"statusChanged",{status:l}))},wakeup:function(a){return"function"==typeof a?this.on("wakeup",a):(l="active",b.fire(this,"wakeup"),b.fire(this,"statusChanged",{status:l}))},on:function(a,c){return j(),b.add(this,a,c)},onEvery:function(a,b){var c;return j(),c=setInterval(function(){return"active"===l?b():void 0},1e3*a),{stop:function(){return clearInterval(c)},code:c,callback:b}},now:function(){return j(),"active"===l}},"function"==typeof define&&define.amd?define(function(){return i}):window.ifvisible=i}).call(this);