Release fixes

This commit is contained in:
RainLoop Team 2015-05-15 00:10:58 +04:00
parent 5e31c01344
commit 9a98bff931
30 changed files with 143 additions and 76 deletions

View file

@ -675,8 +675,8 @@
bCheck = false,
sUid = '',
aList = [],
bUnreadCountChange = false,
oFlags = null
oFlags = null,
bUnreadCountChange = false
;
if (oFolder)

View file

@ -254,7 +254,7 @@
sTagName = sTagName.toUpperCase();
return !(sTagName === 'INPUT' || sTagName === 'SELECT' || sTagName === 'TEXTAREA' ||
(oElement && sTagName === 'DIV' && 'editorHtmlArea' === oElement.className && oElement.contentEditable)
(oElement && sTagName === 'DIV' && ('editorHtmlArea' === oElement.className || 'true' === '' + oElement.contentEditable))
);
}

View file

@ -269,8 +269,6 @@
window.CKEDITOR.env.isCompatible = true;
}
window.CKEDITOR.dtd.$removeEmpty['p'] = 1;
self.editor = window.CKEDITOR.appendTo(self.$element[0], oConfig);
self.editor.on('key', function(oEvent) {
@ -307,9 +305,6 @@
self.editor.removeMenuItem('paste');
}
self.editor.setKeystroke(window.CKEDITOR.CTRL + 65 /* A */, 'selectAll');
self.__resizable = true;
self.__inited = true;

View file

@ -534,14 +534,14 @@
oEvent.preventDefault();
return;
}
if (oSender && oSender.tagName && oSender.tagName.match(/INPUT|TEXTAREA/i))
else if (iKey === Enums.EventKeyCode.A)
{
return;
}
if (oSender && ('true' === '' + oSender.contentEditable ||
(oSender.tagName && oSender.tagName.match(/INPUT|TEXTAREA/i))))
{
return;
}
if (iKey === Enums.EventKeyCode.A)
{
if (window.getSelection)
{
window.getSelection().removeAllRanges();

View file

@ -53,14 +53,8 @@
_.extend(AbstracCheckbox.prototype, AbstractComponent.prototype);
AbstracCheckbox.prototype.click = function() {
if (!this.readOnly && this.enable() && !this.disable())
{
this.value(!this.value());
}
};
AbstracCheckbox.prototype.keypress = function() {
AbstracCheckbox.prototype.click = function()
{
if (!this.readOnly && this.enable() && !this.disable())
{
this.value(!this.value());

27
dev/External/ko.js vendored
View file

@ -315,18 +315,6 @@
}
};
ko.bindingHandlers.keypress = {
'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel) {
$(oElement).on('keypress.koKeyPress', function (oEvent) {
fValueAccessor().call(oViewModel, oEvent);
});
ko.utils.domNodeDisposal.addDisposeCallback(oElement, function () {
$(oElement).off('keypress.koKeyPress');
});
}
};
ko.bindingHandlers.onEnter = {
'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel) {
$(oElement).on('keypress.koOnEnter', function (oEvent) {
@ -343,6 +331,21 @@
}
};
ko.bindingHandlers.onSpace = {
'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel) {
$(oElement).on('keyup.koOnSpace', function (oEvent) {
if (oEvent && 32 === window.parseInt(oEvent.keyCode, 10))
{
fValueAccessor().call(oViewModel, oEvent);
}
});
ko.utils.domNodeDisposal.addDisposeCallback(oElement, function () {
$(oElement).off('keyup.koOnSpace');
});
}
};
ko.bindingHandlers.onTab = {
'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel) {
$(oElement).on('keydown.koOnTab', function (oEvent) {

View file

@ -90,6 +90,15 @@
if (oCacheFolder)
{
if (!FolderStore.displaySpecSetting())
{
oCacheFolder.checkable(true);
}
else
{
oCacheFolder.checkable(!!oFolder.Checkable);
}
oCacheFolder.collapsed(!self.isFolderExpanded(oCacheFolder.fullNameHash));
if (oFolder.Extended)
@ -131,6 +140,14 @@
if (oData && 'Collection/FolderCollection' === oData['@Object'] &&
oData['@Collection'] && Utils.isArray(oData['@Collection']))
{
var
iLimit = Utils.pInt(Settings.settingsGet('FolderSpecLimit')),
iC = Utils.pInt(oData['CountRec'])
;
iLimit = 100 < iLimit ? 100 : (10 > iLimit ? 10 : iLimit);
FolderStore.displaySpecSetting(0 >= iC || iLimit < iC);
FolderStore.folderList(this.folderResponseParseRec(
Utils.isUnd(oData.Namespace) ? '' : oData.Namespace, oData['@Collection']));
}

View file

@ -72,10 +72,10 @@
'SettingsSecurity', 'SETTINGS_LABELS/LABEL_SECURITY_NAME', 'security');
}
if (AccountStore.isRootAccount() &&
if (AccountStore.isRootAccount() && (
(Settings.settingsGet('AllowGoogleSocial') && Settings.settingsGet('AllowGoogleSocialAuth')) ||
Settings.settingsGet('AllowFacebookSocial') ||
Settings.settingsGet('AllowTwitterSocial'))
Settings.settingsGet('AllowTwitterSocial')))
{
kn.addSettingsViewModel(require('Settings/User/Social'),
'SettingsSocial', 'SETTINGS_LABELS/LABEL_SOCIAL_NAME', 'social');

View file

@ -26,6 +26,7 @@
*/
function FoldersUserSettings()
{
this.displaySpecSetting = FolderStore.displaySpecSetting;
this.folderList = FolderStore.folderList;
this.folderListHelp = ko.observable('').extend({'throttle': 100});

View file

@ -19,6 +19,8 @@
*/
function FolderUserStore()
{
this.displaySpecSetting = ko.observable(true);
this.sentFolder = ko.observable('');
this.draftFolder = ko.observable('');
this.spamFolder = ko.observable('');

View file

@ -1207,7 +1207,8 @@
});
sText = '<br /><br />' + sReplyTitle + ':' +
'<blockquote><p>' + Utils.trim(sText) + '</p></blockquote>';
'<blockquote>' + Utils.trim(sText) + '</blockquote>';
// '<blockquote><p>' + Utils.trim(sText) + '</p></blockquote>';
break;
@ -1223,6 +1224,7 @@
'<br />' + Translator.i18n('COMPOSE/FORWARD_MESSAGE_TOP_SUBJECT') + ': ' + Utils.encodeHtml(sSubject) +
'<br /><br />' + Utils.trim(sText) + '<br /><br />';
break;
case Enums.ComposeType.ForwardAsAttachment:
sText = '';
break;

1
dev/bootstrap.js vendored
View file

@ -23,7 +23,6 @@
Globals.$win
.keydown(Utils.kill_CtrlA_CtrlS)
.keyup(Utils.kill_CtrlA_CtrlS)
.unload(function () {
Globals.bUnload = true;
})

View file

@ -4,8 +4,8 @@
var
pkg = require('./package.json'),
head = {
cc: '/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */',
agpl: '/* RainLoop Webmail (c) RainLoop Team | Licensed under AGPL 3 */'
rainloop: '/* RainLoop Webmail (c) RainLoop Team | Licensed under RainLoop Software License */',
agpl: '/* RainLoop Webmail (c) RainLoop Team | Licensed under AGPL v3 */'
},
cfg = {
devVersion: '0.0.0',
@ -46,7 +46,7 @@ var
function getHead()
{
return !cfg.community ? head.cc : head.agpl;
return !cfg.community ? head.rainloop : head.agpl;
}
function regOtherMinTask(sName, sPath, sInc, sOut, sHeader)
@ -454,7 +454,6 @@ gulp.task('ckeditor:copy-plugins', ['ckeditor:copy'], function() {
gulp.task('ckeditor', ['ckeditor:copy-plugins'], function () {
return gulp.src('rainloop/v/' + cfg.devVersion + '/static/ckeditor/*.js')
.pipe(stripbom())
// .pipe(replace("\u200B", "\\u200B"))
.pipe(replace('console.log("Detecting changes using MutationObservers")', 'true'))
.pipe(header("\uFEFF")) // BOM
.pipe(gulp.dest('rainloop/v/' + cfg.devVersion + '/static/ckeditor'));
@ -565,7 +564,7 @@ gulp.task('rainloop:owncloud:setup', ['rainloop:owncloud:copy',
fs.writeFileSync(dist + 'rainloop/appinfo/info.xml',
fs.readFileSync(dist + 'rainloop/appinfo/info.xml', 'utf8')
.replace('<version>0.0</version>', '<version>' + versionFull + '</version>')
.replace('<licence></licence>', '<licence>' + (cfg.community ? 'AGPLv3' : 'CC BY-NC-SA 3.0') + '</licence>')
.replace('<licence></licence>', '<licence>' + (cfg.community ? 'AGPLv3' : 'RainLoop Software License') + '</licence>')
);
fs.writeFileSync(dist + 'rainloop/appinfo/version', versionFull);
@ -574,7 +573,7 @@ gulp.task('rainloop:owncloud:setup', ['rainloop:owncloud:copy',
cfg.destPath = cfg.releasesPath + '/owncloud/' + versionFull + '/';
cfg.cleanPath = dist;
cfg.zipSrcPath = dist;
cfg.zipFile = 'rainloop-owncloud-app-' + (cfg.community ? '' : 'cc-') + versionFull + '.zip';
cfg.zipFile = 'rainloop-owncloud-app-' + (cfg.community ? '' : 'standard-') + versionFull + '.zip';
cfg.md5File = cfg.zipFile;
});

View file

@ -1,8 +1,8 @@
{
"name": "RainLoop",
"title": "RainLoop Webmail",
"version": "1.9.0",
"release": "327",
"version": "1.9.1",
"release": "329",
"description": "Simple, modern & fast web-based email client",
"homepage": "http://rainloop.net",
"main": "gulpfile.js",
@ -19,6 +19,10 @@
{
"type": "AGPL 3.0",
"ulr": "http://www.gnu.org/licenses/agpl-3.0.html"
},
{
"type": "RainLoop Software License",
"ulr": "http://www.rainloop.net/licensing/"
}
],
"bugs": {
@ -36,7 +40,7 @@
"plugins"
],
"readmeFilename": "README.md",
"ownCloudPackageVersion": "4.0",
"ownCloudPackageVersion": "4.1",
"engines": {
"node": ">= 0.10.0"
},

View file

@ -20,7 +20,7 @@ class FolderCollection extends \MailSo\Base\Collection
/**
* @var string
*/
private $sNamespace;
public $Namespace;
/**
* @var string
@ -49,7 +49,7 @@ class FolderCollection extends \MailSo\Base\Collection
{
parent::__construct();
$this->sNamespace = '';
$this->Namespace = '';
$this->FoldersHash = '';
$this->SystemFolders = array();
$this->IsThreadsSupported = false;
@ -96,12 +96,30 @@ class FolderCollection extends \MailSo\Base\Collection
return $mResult;
}
/**
* @return int
*/
public function CountRec()
{
$iResult = $this->Count();
foreach ($this->aItems as /* @var $oFolder \MailSo\Mail\Folder */ $oFolder)
{
if ($oFolder)
{
$oSub = $oFolder->SubFolders();
$iResult += $oSub ? $oSub->CountRec() : 0;
}
}
return $iResult;
}
/**
* @return string
*/
public function GetNamespace()
{
return $this->sNamespace;
return $this->Namespace;
}
/**
@ -110,7 +128,7 @@ class FolderCollection extends \MailSo\Base\Collection
public function FindDelimiter()
{
$sDelimiter = '/';
$oFolder = $this->GetByFullNameRaw('INBOX');
if (!$oFolder)
{
@ -132,7 +150,7 @@ class FolderCollection extends \MailSo\Base\Collection
*/
public function SetNamespace($sNamespace)
{
$this->sNamespace = $sNamespace;
$this->Namespace = $sNamespace;
return $this;
}

View file

@ -1373,7 +1373,11 @@ class MailClient
$sCriteriasResult = \trim($sCriteriasResult);
if ('' === $sCriteriasResult)
{
$sCriteriasResult = 'ALL';
$sCriteriasResult = 'NOT DELETED'; // ALL
}
else
{
$sCriteriasResult .= ' NOT DELETED';
}
return $sCriteriasResult;

View file

@ -201,6 +201,8 @@ class Email
}
$sEmail = \trim(\trim($sEmail), '<>');
$sEmail = \rtrim(\trim($sEmail), '.');
$sEmail = \trim($sEmail);
$sName = \trim(\trim($sName), '"');
$sName = \trim($sName, '\'');

View file

@ -1353,6 +1353,7 @@ class Actions
'UseImapSubscribe' => (bool) $oConfig->Get('labs', 'use_imap_list_subscribe', true),
'AllowAppendMessage' => (bool) $oConfig->Get('labs', 'allow_message_append', false),
'MaterialDesign' => (bool) $oConfig->Get('labs', 'use_material_design', true),
'FolderSpecLimit' => (int) $oConfig->Get('labs', 'folders_spec_limit', 50),
'Community' => true,
'PremType' => false,
'Admin' => array(),
@ -9496,6 +9497,7 @@ class Actions
'FoldersHash' => isset($mResponse->FoldersHash) ? $mResponse->FoldersHash : '',
'IsThreadsSupported' => $mResponse->IsThreadsSupported,
'Optimized' => $mResponse->Optimized,
'CountRec' => $mResponse->CountRec(),
'SystemFolders' => isset($mResponse->SystemFolders) && \is_array($mResponse->SystemFolders) ?
$mResponse->SystemFolders : array()
));

View file

@ -304,6 +304,7 @@ Enables caching in the system'),
'smtp_show_server_errors' => array(false),
'sieve_allow_raw_script' => array(false),
'sieve_utf8_folder_name' => array(true),
'folders_spec_limit' => array(50),
'owncloud_save_folder' => array('Attachments'),
'curl_proxy' => array(''),
'curl_proxy_auth' => array(''),

View file

@ -15,7 +15,7 @@
<span class="flag-wrapper">
<span data-bind="css: 'flag flag-' + language()" style=""></span>
</span>
<span class="flag-name" tabindex="0" data-bind="text: languageFullName, click: selectLanguage, keypress: selectLanguage"></span>
<span class="flag-name" tabindex="0" data-bind="text: languageFullName, click: selectLanguage, onSpace: selectLanguage, onEnter: selectLanguage"></span>
&nbsp;&nbsp;
<div data-bind="component: {
name: 'SaveTrigger',
@ -31,7 +31,7 @@
<span class="flag-wrapper">
<span data-bind="css: 'flag flag-' + languageAdmin()" style=""></span>
</span>
<span class="flag-name" tabindex="0" data-bind="text: languageAdminFullName, click: selectLanguageAdmin, keypress: selectLanguageAdmin"></span>
<span class="flag-name" tabindex="0" data-bind="text: languageAdminFullName, click: selectLanguageAdmin, onSpace: selectLanguageAdmin, onEnter: selectLanguageAdmin"></span>
&nbsp;&nbsp;
<div data-bind="component: {
name: 'SaveTrigger',

View file

@ -2,14 +2,8 @@
<div class="row">
<div class="alert alert-info span8" style="margin-top: 10px;">
<span data-i18n="[html]TAB_LICENSING/HTML_ALERT_TOP_1"></span>
<br />
<b>Creative Commons Attribution-NonCommercial-ShareAlike 3.0 (CC BY-NC-SA)</b>.
<br />
<br />
<span data-i18n="[html]TAB_LICENSING/HTML_ALERT_TOP_2"></span>
<br />
<br />
<span data-i18n="[html]TAB_LICENSING/HTML_ALERT_TOP_3"></span>
&nbsp;
<a href=http://www.rainloop.net/licensing/ target=_blank>RainLoop Software License</a>.
</div>
</div>
<br />

View file

@ -1,4 +1,4 @@
<span class="e-component e-checkbox inline" tabindex="0" data-bind="click: click, keypress: keypress, css: { 'disabled': disable() || !enable() }">
<span class="e-component e-checkbox inline" tabindex="0" data-bind="click: click, onSpace: click, css: { 'disabled': disable() || !enable() }">
<i role="checkbox" class="e-checkbox-icon" data-bind="css: value() ?
(inverted ? 'icon-checkbox-unchecked' : 'icon-checkbox-checked') :
(inverted ? 'icon-checkbox-checked' : 'icon-checkbox-unchecked')

View file

@ -1,4 +1,4 @@
<span class="e-component e-checkbox material-design inline" tabindex="0" data-bind="click: click, keypress: keypress, css: { 'disabled': disable() || !enable() }">
<span class="e-component e-checkbox material-design inline" tabindex="0" data-bind="click: click, onSpace: click, css: { 'disabled': disable() || !enable() }">
<div class="sub-checkbox-container" role="checkbox">
<div class="sub-checkbox" data-bind="css: {'checked': (value() && !inverted) || (!value() && inverted),
'unchecked': (!value() && !inverted) || (value() && inverted),

View file

@ -117,7 +117,7 @@
<label class="flag-selector">
<i data-bind="css: langRequest() ? 'icon-spinner animated' : 'icon-world'"></i>
&nbsp;&nbsp;
<span class="flag-name" tabindex="0" data-bind="text: languageFullName, click: selectLanguage, keypress: selectLanguage, onTab: selectLanguageOnTab"></span>
<span class="flag-name" tabindex="0" data-bind="text: languageFullName, click: selectLanguage, onSpace: selectLanguage, onEnter: selectLanguage, onTab: selectLanguageOnTab"></span>
</label>
</div>
{{INCLUDE/BottomFooter/PLACE}}

View file

@ -25,7 +25,7 @@
<i class="icon-eye"></i>
</span>
</td>
<td class="check-folder-parent">
<td class="check-folder-parent" data-bind="visible: $root.displaySpecSetting">
<span class="uncheck-folder" data-bind="visible: canBeChecked() && subScribed() && !checkable(), click: function(oFolder) { $root.checkableTrueFolder(oFolder); }">
<i class="icon-check-mark-circle-two"></i>
</span>

View file

@ -32,7 +32,7 @@
<col />
<col style="width: 1%" />
<col style="width: 1%" />
<col style="width: 1%" />
<col style="width: 1%" data-bind="visible: displaySpecSetting" />
</colgroup>
<tbody data-bind="template: { name: 'SettingsFolderItem', foreach: folderList }"></tbody>
</table>

View file

@ -12,7 +12,7 @@
<span class="flag-wrapper">
<span data-bind="css: 'flag flag-' + language()" style=""></span>
</span>
<span class="flag-name" tabindex="0" data-bind="text: languageFullName, click: selectLanguage, keypress: selectLanguage"></span>
<span class="flag-name" tabindex="0" data-bind="text: languageFullName, click: selectLanguage, onSpace: selectLanguage, onEnter: selectLanguage"></span>
&nbsp;&nbsp;
<div data-bind="component: {
name: 'SaveTrigger',

View file

@ -27,7 +27,7 @@
<div class="controls">
<i class="icon-lock" />
&nbsp;
<span class="i18n g-ui-link" tabindex="0" data-i18n="SETTINGS_SECURITY/LABEL_CONFIGURATE_TWO_FACTOR" data-bind="click: configureTwoFactor, keypress: configureTwoFactor"></span>
<span class="i18n g-ui-link" tabindex="0" data-i18n="SETTINGS_SECURITY/LABEL_CONFIGURATE_TWO_FACTOR" data-bind="click: configureTwoFactor, onSpace: configureTwoFactor, onEnter: configureTwoFactor"></span>
</div>
</div>
</div>

View file

@ -9,13 +9,26 @@ rl_signature_replacer = function (editor, sText, sSignature, bHtml, bInsertBefor
;
}
sText = sText.replace(/\u0002([\s\S]*)\u0002/gm, '');
var
bEmptyText = '' === $.trim(sText),
sP = '~~~~@~~~~',
bEmptyText = false,
sNewLine = (bHtml ? '<br />' : "\n")
;
sText = sText.replace(/\u0002([\s\S]*)\u0002/gm, sP + '$1' + sP);
if (editor.__previos_signature)
{
sText = sText
.replace(sP + editor.__previos_signature + sP, '')
.replace(sP + editor.__previos_signature + sP, '')
.replace(sP + editor.__previos_signature + sP, '')
;
}
sText = sText.replace(sP, '').replace(sP, '').replace(sP, '').replace(sP, '');
bEmptyText = '' === $.trim(sText);
if (!bEmptyText && bHtml)
{
bEmptyText = '' !== $.trim(editor.__plainUtils.htmlToPlain(sText));
@ -24,10 +37,12 @@ rl_signature_replacer = function (editor, sText, sSignature, bHtml, bInsertBefor
if (bInsertBefore)
{
sText = "\u0002" + sSignature + (bEmptyText ? '' : sNewLine) + "\u0002" + sText;
editor.__previos_signature = sSignature + (bEmptyText ? '' : sNewLine);
}
else
{
sText = sText + "\u0002" + (bEmptyText ? '' : sNewLine) + sSignature + "\u0002";
editor.__previos_signature = (bEmptyText ? '' : sNewLine) + sSignature;
}
if (!bHtml)

View file

@ -9,13 +9,26 @@ rl_signature_replacer = function (editor, sText, sSignature, bHtml, bInsertBefor
;
}
sText = sText.replace(/\u0002([\s\S]*)\u0002/gm, '');
var
bEmptyText = '' === $.trim(sText),
sP = '~~~~@~~~~',
bEmptyText = false,
sNewLine = (bHtml ? '<br />' : "\n")
;
sText = sText.replace(/\u0002([\s\S]*)\u0002/gm, sP + '$1' + sP);
if (editor.__previos_signature)
{
sText = sText
.replace(sP + editor.__previos_signature + sP, '')
.replace(sP + editor.__previos_signature + sP, '')
.replace(sP + editor.__previos_signature + sP, '')
;
}
sText = sText.replace(sP, '').replace(sP, '').replace(sP, '').replace(sP, '');
bEmptyText = '' === $.trim(sText);
if (!bEmptyText && bHtml)
{
bEmptyText = '' !== $.trim(editor.__plainUtils.htmlToPlain(sText));
@ -24,10 +37,12 @@ rl_signature_replacer = function (editor, sText, sSignature, bHtml, bInsertBefor
if (bInsertBefore)
{
sText = "\u0002" + sSignature + (bEmptyText ? '' : sNewLine) + "\u0002" + sText;
editor.__previos_signature = sSignature + (bEmptyText ? '' : sNewLine);
}
else
{
sText = sText + "\u0002" + (bEmptyText ? '' : sNewLine) + sSignature + "\u0002";
editor.__previos_signature = (bEmptyText ? '' : sNewLine) + sSignature;
}
if (!bHtml)