Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F9785404
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
167 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/program/js/editor.js b/program/js/editor.js
index 0facfd948..26b6927f5 100644
--- a/program/js/editor.js
+++ b/program/js/editor.js
@@ -1,779 +1,779 @@
/**
* Roundcube editor js library
*
* This file is part of the Roundcube Webmail client
*
* @licstart The following is the entire license notice for the
* JavaScript code in this file.
*
* Copyright (c) 2006-2014, The Roundcube Dev Team
*
* The JavaScript code in this page is free software: you can
* redistribute it and/or modify it under the terms of the GNU
* General Public License (GNU GPL) as published by the Free Software
* Foundation, either version 3 of the License, or (at your option)
* any later version. The code is distributed WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.
*
* As additional permission under GNU GPL version 3 section 7, you
* may distribute non-source (e.g., minimized or compacted) forms of
* that code without the copy of the GNU GPL normally required by
* section 4, provided you include this license notice and a URL
* through which recipients can access the Corresponding Source.
*
* @licend The above is the entire license notice
* for the JavaScript code in this file.
*
* @author Eric Stadtherr <estadtherr@gmail.com>
* @author Aleksander Machniak <alec@alec.pl>
*/
/**
* Roundcube Text Editor Widget class
* @constructor
*/
function rcube_text_editor(config, id)
{
var ref = this,
conf = {
selector: '#' + ($('#' + id).is('.mce_editor') ? id : 'fake-editor-id'),
theme: 'modern',
language: config.lang,
- content_css: 'program/js/tinymce/roundcube/content.css?v1',
+ content_css: 'program/js/tinymce/roundcube/content.css?v2',
menubar: false,
statusbar: false,
toolbar_items_size: 'small',
extended_valid_elements: 'font[face|size|color|style],span[id|class|align|style]',
relative_urls: false,
remove_script_host: false,
convert_urls: false, // #1486944
image_description: false,
paste_webkit_style: "color font-size font-family",
paste_data_images: true,
browser_spellcheck: true
};
// register spellchecker for plain text editor
this.spellcheck_observer = function() {};
if (config.spellchecker) {
this.spellchecker = config.spellchecker;
if (config.spellcheck_observer) {
this.spellchecker.spelling_state_observer = this.spellcheck_observer = config.spellcheck_observer;
}
}
// minimal editor
if (config.mode == 'identity') {
$.extend(conf, {
plugins: 'autolink charmap code colorpicker hr image link paste tabfocus textcolor',
toolbar: 'bold italic underline alignleft aligncenter alignright alignjustify'
+ ' | outdent indent charmap hr link unlink image code forecolor'
+ ' | fontselect fontsizeselect',
file_browser_callback: function(name, url, type, win) { ref.file_browser_callback(name, url, type); },
file_browser_callback_types: 'image'
});
}
// full-featured editor
else {
$.extend(conf, {
plugins: 'autolink charmap code colorpicker directionality emoticons link image media nonbreaking'
+ ' paste table tabfocus textcolor searchreplace' + (config.spellcheck ? ' spellchecker' : ''),
toolbar: 'bold italic underline | alignleft aligncenter alignright alignjustify'
+ ' | bullist numlist outdent indent ltr rtl blockquote | forecolor backcolor | fontselect fontsizeselect'
+ ' | link unlink table | emoticons charmap image media | code searchreplace undo redo',
spellchecker_rpc_url: '../../../../../?_task=utils&_action=spell_html&_remote=1',
spellchecker_language: rcmail.env.spell_lang,
accessibility_focus: false,
file_browser_callback: function(name, url, type, win) { ref.file_browser_callback(name, url, type); },
// @todo: support more than image (types: file, image, media)
file_browser_callback_types: 'image media'
});
}
// support external configuration settings e.g. from skin
if (window.rcmail_editor_settings)
$.extend(conf, window.rcmail_editor_settings);
conf.setup = function(ed) {
ed.on('init', function(ed) { ref.init_callback(ed); });
// add handler for spellcheck button state update
ed.on('SpellcheckStart SpellcheckEnd', function(args) {
ref.spellcheck_active = args.type == 'spellcheckstart';
ref.spellcheck_observer();
});
ed.on('keypress', function() {
rcmail.compose_type_activity++;
});
// secure spellchecker requests with Roundcube token
tinymce.util.XHR.on('beforeSend', function(e) {
e.xhr.setRequestHeader('X-Roundcube-Request', rcmail.env.request_token);
});
};
// textarea identifier
this.id = id;
// reference to active editor (if in HTML mode)
this.editor = null;
tinymce.init(conf);
// react to real individual tinyMCE editor init
this.init_callback = function(event)
{
this.editor = event.target;
if (rcmail.env.action != 'compose') {
return;
}
var css = {},
elem = rcube_find_object('_from'),
fe = rcmail.env.compose_focus_elem;
if (rcmail.env.default_font)
css['font-family'] = rcmail.env.default_font;
if (rcmail.env.default_font_size)
css['font-size'] = rcmail.env.default_font_size;
if (css['font-family'] || css['font-size'])
$(this.editor.getBody()).css(css);
if (elem && elem.type == 'select-one') {
// insert signature (only for the first time)
if (!rcmail.env.identities_initialized)
rcmail.change_identity(elem);
// Focus previously focused element
if (fe && fe.id != this.id) {
// use setTimeout() for IE9 (#1488541)
window.setTimeout(function() {
window.focus(); // for WebKit (#1486674)
fe.focus();
}, 10);
}
}
// set tabIndex and set focus to element that was focused before
this.tabindex(fe && fe.id == this.id);
// Trigger resize (needed for proper editor resizing in some browsers)
window.setTimeout(function() { $(window).resize(); }, 100);
};
// set tabIndex on tinymce editor
this.tabindex = function(focus)
{
if (rcmail.env.task == 'mail' && this.editor) {
var textarea = this.editor.getElement(),
node = this.editor.getContentAreaContainer().childNodes[0];
if (textarea && node)
node.tabIndex = textarea.tabIndex;
if (focus)
this.editor.getBody().focus();
// find :prev and :next elements to get focus when tabbing away
if (textarea.tabIndex > 0) {
var x = null,
editor = this.editor,
tabfocus_elements = [':prev',':next'],
el = tinymce.DOM.select('*[tabindex='+textarea.tabIndex+']:not(iframe)');
tinymce.each(el, function(e, i) { if (e.id == editor.id) { x = i; return false; } });
if (x !== null) {
if (el[x-1] && el[x-1].id) {
tabfocus_elements[0] = el[x-1].id;
}
if (el[x+1] && el[x+1].id) {
tabfocus_elements[1] = el[x+1].id;
}
editor.settings.tabfocus_elements = tabfocus_elements.join(',');
}
}
}
};
// switch html/plain mode
this.toggle = function(ishtml, noconvert)
{
var curr, content, result,
// these non-printable chars are not removed on text2html and html2text
// we can use them as temp signature replacement
sig_mark = "\u0002\u0003",
input = $('#' + this.id),
signature = rcmail.env.identity ? rcmail.env.signatures[rcmail.env.identity] : null,
is_sig = signature && signature.text && signature.text.length > 1;
// apply spellcheck changes if spell checker is active
this.spellcheck_stop();
if (ishtml) {
content = input.val();
// replace current text signature with temp mark
if (is_sig)
content = content.replace(signature.text, sig_mark);
var init_editor = function(data) {
// replace signature mark with html version of the signature
if (is_sig)
data = data.replace(sig_mark, '<div id="_rc_sig">' + signature.html + '</div>');
input.val(data);
tinymce.execCommand('mceAddEditor', false, ref.id);
setTimeout(function() {
if (ref.editor) {
if (rcmail.env.default_font)
$(ref.editor.getBody()).css('font-family', rcmail.env.default_font);
// #1486593
ref.tabindex(true);
}
}, 500);
};
// convert to html
if (!noconvert) {
result = rcmail.plain2html(content, init_editor);
}
else {
init_editor(content);
result = true;
}
}
else if (this.editor) {
if (is_sig) {
// get current version of signature, we'll need it in
// case of html2text conversion abort
if (curr = this.editor.dom.get('_rc_sig'))
curr = curr.innerHTML;
// replace current signature with some non-printable characters
// we use non-printable characters, because this replacement
// is visible to the user
// doing this after getContent() would be hard
this.editor.dom.setHTML('_rc_sig', sig_mark);
}
// get html content
content = this.editor.getContent();
var init_plaintext = function(data) {
tinymce.execCommand('mceRemoveEditor', false, ref.id);
ref.editor = null;
// replace signture mark with text version of the signature
if (is_sig)
data = data.replace(sig_mark, "\n" + signature.text);
input.val(data).focus();
};
// convert html to text
if (!noconvert) {
result = rcmail.html2plain(content, init_plaintext);
}
else {
init_plaintext(input.val());
result = true;
}
// bring back current signature
if (!result && curr)
this.editor.dom.setHTML('_rc_sig', curr);
}
return result;
};
// start spellchecker
this.spellcheck_start = function()
{
if (this.editor) {
tinymce.execCommand('mceSpellCheck', true);
this.spellcheck_observer();
}
else if (this.spellchecker && this.spellchecker.spellCheck) {
this.spellchecker.spellCheck();
}
};
// stop spellchecker
this.spellcheck_stop = function()
{
var ed = this.editor;
if (ed) {
if (ed.plugins && ed.plugins.spellchecker && this.spellcheck_active) {
ed.execCommand('mceSpellCheck', false);
this.spellcheck_observer();
}
}
else if (ed = this.spellchecker) {
if (ed.state && ed.state != 'ready' && ed.state != 'no_error_found')
$(ed.spell_span).trigger('click');
}
};
// spellchecker state
this.spellcheck_state = function()
{
var ed;
if (this.editor)
return this.spellcheck_active;
else if ((ed = this.spellchecker) && ed.state)
return ed.state != 'ready' && ed.state != 'no_error_found';
};
// resume spellchecking, highlight provided mispellings without a new ajax request
this.spellcheck_resume = function(data)
{
var ed = this.editor;
if (ed) {
ed.plugins.spellchecker.markErrors(data);
}
else if (ed = this.spellchecker) {
ed.prepare(false, true);
ed.processData(data);
}
};
// get selected (spellcheker) language
this.get_language = function()
{
if (this.editor) {
return this.editor.settings.spellchecker_language || rcmail.env.spell_lang;
}
else if (this.spellchecker) {
return GOOGIE_CUR_LANG;
}
};
// set language for spellchecking
this.set_language = function(lang)
{
var ed = this.editor;
if (ed) {
ed.settings.spellchecker_language = lang;
}
if (ed = this.spellchecker) {
ed.setCurrentLanguage(lang);
}
};
// replace selection with text snippet
this.replace = function(text)
{
var ed = this.editor;
// insert into tinymce editor
if (ed) {
ed.getWin().focus(); // correct focus in IE & Chrome
ed.selection.setContent(rcmail.quote_html(text).replace(/\r?\n/g, '<br/>'), { format:'text' });
}
// replace selection in compose textarea
else if (ed = rcube_find_object(this.id)) {
var selection = $(ed).is(':focus') ? rcmail.get_input_selection(ed) : { start:0, end:0 },
inp_value = ed.value;
pre = inp_value.substring(0, selection.start),
end = inp_value.substring(selection.end, inp_value.length);
// insert response text
ed.value = pre + text + end;
// set caret after inserted text
rcmail.set_caret_pos(ed, selection.start + text.length);
ed.focus();
}
};
// get selected text (if no selection returns all text) from the editor
this.get_content = function(selected, plain)
{
// apply spellcheck changes if spell checker is active
this.spellcheck_stop();
var sigstart, ed = this.editor,
format = plain ? 'text' : 'html',
text = '', strip = false;
// get selected text from tinymce editor
if (ed) {
ed.getWin().focus(); // correct focus in IE & Chrome
if (selected)
text = ed.selection.getContent({format: format});
if (!text) {
text = ed.getContent({format: format});
strip = true;
}
}
// get selected text from compose textarea
else if (ed = rcube_find_object(this.id)) {
if (selected && $(ed).is(':focus')) {
text = rcmail.get_input_selection(ed).text;
}
if (!text) {
text = ed.value;
strip = true;
}
}
// strip off signature
if (strip) {
sigstart = text.indexOf('-- \n');
if (sigstart > 0) {
text = text.substring(0, sigstart);
}
}
return text;
};
// change user signature text
this.change_signature = function(id, show_sig)
{
var cursor_pos, p = -1,
input_message = $('#' + this.id),
message = input_message.val(),
sig = rcmail.env.identity;
if (!this.editor) { // plain text mode
// remove the 'old' signature
if (show_sig && sig && rcmail.env.signatures && rcmail.env.signatures[sig]) {
sig = rcmail.env.signatures[sig].text;
sig = sig.replace(/\r\n/g, '\n');
p = rcmail.env.top_posting ? message.indexOf(sig) : message.lastIndexOf(sig);
if (p >= 0)
message = message.substring(0, p) + message.substring(p+sig.length, message.length);
}
// add the new signature string
if (show_sig && rcmail.env.signatures && rcmail.env.signatures[id]) {
sig = rcmail.env.signatures[id].text;
sig = sig.replace(/\r\n/g, '\n');
if (rcmail.env.top_posting) {
if (p >= 0) { // in place of removed signature
message = message.substring(0, p) + sig + message.substring(p, message.length);
cursor_pos = p - 1;
}
else if (!message) { // empty message
cursor_pos = 0;
message = '\n\n' + sig;
}
else if (pos = rcmail.get_caret_pos(input_message.get(0))) { // at cursor position
message = message.substring(0, pos) + '\n' + sig + '\n\n' + message.substring(pos, message.length);
cursor_pos = pos;
}
else { // on top
cursor_pos = 0;
message = '\n\n' + sig + '\n\n' + message.replace(/^[\r\n]+/, '');
}
}
else {
message = message.replace(/[\r\n]+$/, '');
cursor_pos = !rcmail.env.top_posting && message.length ? message.length+1 : 0;
message += '\n\n' + sig;
}
}
else
cursor_pos = rcmail.env.top_posting ? 0 : message.length;
input_message.val(message);
// move cursor before the signature
rcmail.set_caret_pos(input_message.get(0), cursor_pos);
}
else if (show_sig && rcmail.env.signatures) { // html
var sigElem = this.editor.dom.get('_rc_sig');
// Append the signature as a div within the body
if (!sigElem) {
var body = this.editor.getBody(),
doc = this.editor.getDoc();
sigElem = doc.createElement('div');
sigElem.setAttribute('id', '_rc_sig');
if (rcmail.env.top_posting) {
// if no existing sig and top posting then insert at caret pos
this.editor.getWin().focus(); // correct focus in IE & Chrome
var node = this.editor.selection.getNode();
if (node.nodeName == 'BODY') {
// no real focus, insert at start
body.insertBefore(sigElem, body.firstChild);
body.insertBefore(doc.createElement('br'), body.firstChild);
}
else {
body.insertBefore(sigElem, node.nextSibling);
body.insertBefore(doc.createElement('br'), node.nextSibling);
}
}
else {
body.appendChild(sigElem);
}
}
if (rcmail.env.signatures[id]) {
sigElem.innerHTML = rcmail.env.signatures[id].html;
}
}
};
// trigger content save
this.save = function()
{
if (this.editor) {
this.editor.save();
}
};
// focus the editing area
this.focus = function()
{
(this.editor || rcube_find_object(this.id)).focus();
};
// image selector
this.file_browser_callback = function(field_name, url, type)
{
var i, elem, cancel, dialog, fn, list = [];
// open image selector dialog
dialog = this.editor.windowManager.open({
title: rcmail.gettext('select' + type),
width: 500,
height: 300,
html: '<div id="image-selector-list"><ul></ul></div>'
+ '<div id="image-selector-form"><div id="image-upload-button" class="mce-widget mce-btn" role="button" tabindex="0"></div></div>',
buttons: [{text: 'Cancel', onclick: function() { ref.file_browser_close(); }}]
});
rcmail.env.file_browser_field = field_name;
rcmail.env.file_browser_type = type;
// fill images list with available images
for (i in rcmail.env.attachments) {
if (elem = ref.file_browser_entry(i, rcmail.env.attachments[i])) {
list.push(elem);
}
}
if (list.length) {
$('#image-selector-list > ul').append(list).find('li:first').focus();
}
// add hint about max file size (in dialog footer)
$('div.mce-abs-end', dialog.getEl()).append($('<div class="hint">')
.text($('div.hint', rcmail.gui_objects.uploadform).text()));
// init upload button
elem = $('#image-upload-button').append($('<span>').text(rcmail.gettext('add' + type)));
cancel = elem.parents('.mce-panel').find('button:last').parent();
// we need custom Tab key handlers, until we find out why
// tabindex do not work here as expected
elem.keydown(function(e) {
if (e.which == 9) {
// on Tab + Shift focus first file
if (rcube_event.get_modifier(e) == SHIFT_KEY)
$('#image-selector-list li:last').focus();
// on Tab focus Cancel button
else
cancel.focus();
return false;
}
});
cancel.keydown(function(e) {
if (e.which == 9) {
// on Tab + Shift focus upload button
if (rcube_event.get_modifier(e) == SHIFT_KEY)
elem.focus();
else
$('#image-selector-list li:first').focus();
return false;
}
});
// enable (smart) upload button
this.hack_file_input(elem, rcmail.gui_objects.uploadform);
// enable drag-n-drop area
if ((window.XMLHttpRequest && XMLHttpRequest.prototype && XMLHttpRequest.prototype.sendAsBinary) || window.FormData) {
if (!rcmail.env.filedrop) {
rcmail.env.filedrop = {};
}
if (rcmail.gui_objects.filedrop) {
rcmail.env.old_file_drop = rcmail.gui_objects.filedrop;
}
rcmail.gui_objects.filedrop = $('#image-selector-form');
rcmail.gui_objects.filedrop.addClass('droptarget')
.bind('dragover dragleave', function(e) {
e.preventDefault();
e.stopPropagation();
$(this)[(e.type == 'dragover' ? 'addClass' : 'removeClass')]('hover');
})
.get(0).addEventListener('drop', function(e) { return rcmail.file_dropped(e); }, false);
}
// register handler for successful file upload
if (!rcmail.env.file_dialog_event) {
rcmail.env.file_dialog_event = true;
rcmail.addEventListener('fileuploaded', function(attr) {
var elem;
if (elem = ref.file_browser_entry(attr.name, attr.attachment)) {
$('#image-selector-list > ul').prepend(elem);
elem.focus();
}
});
}
// @todo: upload progress indicator
};
// close file browser window
this.file_browser_close = function(url)
{
var input = $('#' + rcmail.env.file_browser_field);
if (url)
input.val(url);
this.editor.windowManager.close();
input.focus();
if (rcmail.env.old_file_drop)
rcmail.gui_objects.filedrop = rcmail.env.old_file_drop;
};
// creates file browser entry
this.file_browser_entry = function(file_id, file)
{
if (!file.complete || !file.mimetype) {
return;
}
if (rcmail.file_upload_id) {
rcmail.set_busy(false, null, rcmail.file_upload_id);
}
var rx, img_src;
switch (rcmail.env.file_browser_type) {
case 'image':
rx = /^image\//i;
break;
case 'media':
rx = /^video\//i;
img_src = 'program/js/tinymce/roundcube/video.png';
break;
default:
return;
}
if (rx.test(file.mimetype)) {
var path = rcmail.env.comm_path + '&_from=' + rcmail.env.action,
action = rcmail.env.compose_id ? '&_id=' + rcmail.env.compose_id + '&_action=display-attachment' : '&_action=upload-display',
href = path + action + '&_file=' + file_id,
img = $('<img>').attr({title: file.name, src: img_src ? img_src : href + '&_thumbnail=1'});
return $('<li>').attr({tabindex: 0})
.data('url', href)
.append($('<span class="img">').append(img))
.append($('<span class="name">').text(file.name))
.click(function() { ref.file_browser_close($(this).data('url')); })
.keydown(function(e) {
if (e.which == 13) {
ref.file_browser_close($(this).data('url'));
}
// we need custom Tab key handlers, until we find out why
// tabindex do not work here as expected
else if (e.which == 9) {
if (rcube_event.get_modifier(e) == SHIFT_KEY) {
if (!$(this).prev().focus().length)
$('#image-upload-button').parents('.mce-panel').find('button:last').parent().focus();
}
else {
if (!$(this).next().focus().length)
$('#image-upload-button').focus();
}
return false;
}
});
}
};
// create smart files upload button
this.hack_file_input = function(elem, clone_form)
{
var link = $(elem),
file = $('<input>').attr('name', '_file[]'),
form = $('<form>').attr({method: 'post', enctype: 'multipart/form-data'}),
offset = link.offset();
// clone existing upload form
if (clone_form) {
file.attr('name', $('input[type="file"]', clone_form).attr('name'));
form.attr('action', $(clone_form).attr('action'))
.append($('<input>').attr({type: 'hidden', name: '_token', value: rcmail.env.request_token}));
}
function move_file_input(e) {
file.css({top: (e.pageY - offset.top - 10) + 'px', left: (e.pageX - offset.left - 10) + 'px'});
}
file.attr({type: 'file', multiple: 'multiple', size: 5, title: '', tabindex: -1})
.change(function() { rcmail.upload_file(form, 'upload'); })
.click(function() { setTimeout(function() { link.mouseleave(); }, 20); })
// opacity:0 does the trick, display/visibility doesn't work
.css({opacity: 0, cursor: 'pointer', position: 'relative', outline: 'none'})
.appendTo(form);
// In FF and IE we need to move the browser file-input's button under the cursor
// Thanks to the size attribute above we know the length of the input field
if (navigator.userAgent.match(/Firefox|MSIE/))
file.css({marginLeft: '-80px'});
// Note: now, I observe problem with cursor style on FF < 4 only
link.css({overflow: 'hidden', cursor: 'pointer'})
.mouseenter(function() { this.__active = true; })
// place button under the cursor
.mousemove(function(e) {
if (this.__active)
move_file_input(e);
// move the input away if button is disabled
else
$(this).mouseleave();
})
.mouseleave(function() {
file.css({top: '-10000px', left: '-10000px'});
this.__active = false;
})
.click(function(e) {
// forward click if mouse-enter event was missed
if (!this.__active) {
this.__active = true;
move_file_input(e);
file.trigger(e);
}
})
.keydown(function(e) {
if (e.which == 13) file.trigger('click');
})
.mouseleave()
.append(form);
};
}
diff --git a/program/js/googiespell.js b/program/js/googiespell.js
index 707efd165..8c17508dd 100644
--- a/program/js/googiespell.js
+++ b/program/js/googiespell.js
@@ -1,1150 +1,1152 @@
/**
* Roundcube SpellCheck script
*
* jQuery'fied spell checker based on GoogieSpell 4.0
* (which was published under GPL "version 2 or any later version")
*
* @licstart The following is the entire license notice for the
* JavaScript code in this file.
*
* Copyright (C) 2006 Amir Salihefendic
* Copyright (C) 2009 The Roundcube Dev Team
* Copyright (C) 2011 Kolab Systems AG
*
* The JavaScript code in this page is free software: you can
* redistribute it and/or modify it under the terms of the GNU
* General Public License (GNU GPL) as published by the Free Software
* Foundation, either version 3 of the License, or (at your option)
* any later version. The code is distributed WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.
*
* As additional permission under GNU GPL version 3 section 7, you
* may distribute non-source (e.g., minimized or compacted) forms of
* that code without the copy of the GNU GPL normally required by
* section 4, provided you include this license notice and a URL
* through which recipients can access the Corresponding Source.
*
* @licend The above is the entire license notice
* for the JavaScript code in this file.
*
* @author 4mir Salihefendic <amix@amix.dk>
* @author Aleksander Machniak - <alec [at] alec.pl>
*/
var GOOGIE_CUR_LANG,
GOOGIE_DEFAULT_LANG = 'en';
function GoogieSpell(img_dir, server_url, has_dict)
{
var ref = this,
cookie_value = rcmail.get_cookie('language');
GOOGIE_CUR_LANG = cookie_value != null ? cookie_value : GOOGIE_DEFAULT_LANG;
this.array_keys = function(arr) {
var res = [];
for (var key in arr) { res.push([key]); }
return res;
}
this.img_dir = img_dir;
this.server_url = server_url;
this.org_lang_to_word = {
"da": "Dansk", "de": "Deutsch", "en": "English",
"es": "Español", "fr": "Français", "it": "Italiano",
"nl": "Nederlands", "pl": "Polski", "pt": "Português",
"ru": "Русский", "fi": "Suomi", "sv": "Svenska"
};
this.lang_to_word = this.org_lang_to_word;
this.langlist_codes = this.array_keys(this.lang_to_word);
this.show_change_lang_pic = true;
this.change_lang_pic_placement = 'right';
this.report_state_change = true;
this.ta_scroll_top = 0;
this.el_scroll_top = 0;
this.lang_chck_spell = "Check spelling";
this.lang_revert = "Revert to";
this.lang_close = "Close";
this.lang_rsm_edt = "Resume editing";
this.lang_no_error_found = "No spelling errors found";
this.lang_no_suggestions = "No suggestions";
this.lang_learn_word = "Add to dictionary";
this.show_spell_img = false; // roundcube mod.
this.decoration = true;
this.use_close_btn = false;
this.edit_layer_dbl_click = true;
this.report_ta_not_found = true;
// Extensions
this.custom_ajax_error = null;
this.custom_no_spelling_error = null;
this.custom_menu_builder = []; // Should take an eval function and a build menu function
this.custom_item_evaulator = null; // Should take an eval function and a build menu function
this.extra_menu_items = [];
this.custom_spellcheck_starter = null;
this.main_controller = true;
this.has_dictionary = has_dict;
// Observers
this.lang_state_observer = null;
this.spelling_state_observer = null;
this.show_menu_observer = null;
this.all_errors_fixed_observer = null;
// Focus links - used to give the text box focus
this.use_focus = false;
this.focus_link_t = null;
this.focus_link_b = null;
// Counters
this.cnt_errors = 0;
this.cnt_errors_fixed = 0;
// Set document's onclick to hide the language and error menu
$(document).bind('click', function(e) {
var target = $(e.target);
if(target.attr('googie_action_btn') != '1' && ref.isLangWindowShown())
ref.hideLangWindow();
if(target.attr('googie_action_btn') != '1' && ref.isErrorWindowShown())
ref.hideErrorWindow();
});
this.decorateTextarea = function(id)
{
this.text_area = typeof id === 'string' ? document.getElementById(id) : id;
if (this.text_area) {
if (!this.spell_container && this.decoration) {
var table = document.createElement('table'),
tbody = document.createElement('tbody'),
tr = document.createElement('tr'),
spell_container = document.createElement('td'),
r_width = this.isDefined(this.force_width) ? this.force_width : this.text_area.offsetWidth,
r_height = this.isDefined(this.force_height) ? this.force_height : 16;
tr.appendChild(spell_container);
tbody.appendChild(tr);
$(table).append(tbody).insertBefore(this.text_area).width('100%').height(r_height);
$(spell_container).height(r_height).width(r_width).css('text-align', 'right');
this.spell_container = spell_container;
}
this.checkSpellingState();
}
else if (this.report_ta_not_found)
alert('Text area not found');
};
//////
// API Functions (the ones that you can call)
/////
this.setSpellContainer = function(id)
{
this.spell_container = typeof id === 'string' ? document.getElementById(id) : id;
};
this.setLanguages = function(lang_dict)
{
this.lang_to_word = lang_dict;
this.langlist_codes = this.array_keys(lang_dict);
};
this.setCurrentLanguage = function(lan_code)
{
GOOGIE_CUR_LANG = lan_code;
//Set cookie
var now = new Date();
now.setTime(now.getTime() + 365 * 24 * 60 * 60 * 1000);
rcmail.set_cookie('language', lan_code, now);
};
this.setForceWidthHeight = function(width, height)
{
// Set to null if you want to use one of them
this.force_width = width;
this.force_height = height;
};
this.setDecoration = function(bool)
{
this.decoration = bool;
};
this.dontUseCloseButtons = function()
{
this.use_close_btn = false;
};
this.appendNewMenuItem = function(name, call_back_fn, checker)
{
this.extra_menu_items.push([name, call_back_fn, checker]);
};
this.appendCustomMenuBuilder = function(eval_fn, builder)
{
this.custom_menu_builder.push([eval_fn, builder]);
};
this.setFocus = function()
{
try {
this.focus_link_b.focus();
this.focus_link_t.focus();
return true;
}
catch(e) {
return false;
}
};
//////
// Set functions (internal)
/////
this.setStateChanged = function(current_state)
{
this.state = current_state;
if (this.spelling_state_observer != null && this.report_state_change)
this.spelling_state_observer(current_state, this);
};
this.setReportStateChange = function(bool)
{
this.report_state_change = bool;
};
//////
// Request functions
/////
this.getUrl = function()
{
return this.server_url + GOOGIE_CUR_LANG;
};
this.escapeSpecial = function(val)
{
return val ? val.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">") : '';
};
this.createXMLReq = function (text)
{
return '<?xml version="1.0" encoding="utf-8" ?>'
+ '<spellrequest textalreadyclipped="0" ignoredups="0" ignoredigits="1" ignoreallcaps="1">'
+ '<text>' + text + '</text></spellrequest>';
};
this.spellCheck = function(ignore)
{
this.prepare(ignore);
var req_text = this.escapeSpecial(this.orginal_text),
ref = this;
$.ajax({ type: 'POST', url: this.getUrl(), data: this.createXMLReq(req_text), dataType: 'text',
error: function(o) {
if (ref.custom_ajax_error)
ref.custom_ajax_error(ref);
else
alert('An error was encountered on the server. Please try again later.');
if (ref.main_controller) {
$(ref.spell_span).remove();
ref.removeIndicator();
}
ref.checkSpellingState();
},
success: function(data) {
ref.processData(data);
if (!ref.results.length) {
if (!ref.custom_no_spelling_error)
ref.flashNoSpellingErrorState();
else
ref.custom_no_spelling_error(ref);
}
ref.removeIndicator();
}
});
};
this.learnWord = function(word, id)
{
word = this.escapeSpecial(word.innerHTML);
var ref = this,
req_text = '<?xml version="1.0" encoding="utf-8" ?><learnword><text>' + word + '</text></learnword>';
$.ajax({ type: 'POST', url: this.getUrl(), data: req_text, dataType: 'text',
error: function(o) {
if (ref.custom_ajax_error)
ref.custom_ajax_error(ref);
else
alert('An error was encountered on the server. Please try again later.');
},
success: function(data) {
}
});
};
//////
// Spell checking functions
/////
this.prepare = function(ignore, no_indicator)
{
this.cnt_errors_fixed = 0;
this.cnt_errors = 0;
this.setStateChanged('checking_spell');
this.orginal_text = '';
if (!no_indicator && this.main_controller)
this.appendIndicator(this.spell_span);
this.error_links = [];
this.ta_scroll_top = this.text_area.scrollTop;
this.ignore = ignore;
this.hideLangWindow();
- if ($(this.text_area).val() == '' || ignore) {
+ var area = $(this.text_area);
+
+ if (area.val() == '' || ignore) {
if (!this.custom_no_spelling_error)
this.flashNoSpellingErrorState();
else
this.custom_no_spelling_error(this);
this.removeIndicator();
return;
}
- this.createEditLayer(this.text_area.offsetWidth, this.text_area.offsetHeight);
+ this.createEditLayer(area.width(), area.height());
this.createErrorWindow();
$('body').append(this.error_window);
try { netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead"); }
catch (e) { }
if (this.main_controller)
$(this.spell_span).unbind('click');
- this.orginal_text = $(this.text_area).val();
+ this.orginal_text = area.val();
};
this.parseResult = function(r_text)
{
// Returns an array: result[item] -> ['attrs'], ['suggestions']
var re_split_attr_c = /\w+="(\d+|true)"/g,
re_split_text = /\t/g,
matched_c = r_text.match(/<c[^>]*>[^<]*<\/c>/g),
results = [];
if (matched_c == null)
return results;
for (var i=0, len=matched_c.length; i < len; i++) {
var item = [];
this.errorFound();
// Get attributes
item['attrs'] = [];
var c_attr, val,
split_c = matched_c[i].match(re_split_attr_c);
for (var j=0; j < split_c.length; j++) {
c_attr = split_c[j].split(/=/);
val = c_attr[1].replace(/"/g, '');
item['attrs'][c_attr[0]] = val != 'true' ? parseInt(val) : val;
}
// Get suggestions
item['suggestions'] = [];
var only_text = matched_c[i].replace(/<[^>]*>/g, ''),
split_t = only_text.split(re_split_text);
for (var k=0; k < split_t.length; k++) {
if(split_t[k] != '')
item['suggestions'].push(split_t[k]);
}
results.push(item);
}
return results;
};
this.processData = function(data)
{
this.results = this.parseResult(data);
if (this.results.length) {
this.showErrorsInIframe();
this.resumeEditingState();
}
};
//////
// Error menu functions
/////
this.createErrorWindow = function()
{
this.error_window = document.createElement('div');
$(this.error_window).addClass('googie_window popupmenu').attr('googie_action_btn', '1');
};
this.isErrorWindowShown = function()
{
return $(this.error_window).is(':visible');
};
this.hideErrorWindow = function()
{
$(this.error_window).hide();
$(this.error_window_iframe).hide();
};
this.updateOrginalText = function(offset, old_value, new_value, id)
{
var part_1 = this.orginal_text.substring(0, offset),
part_2 = this.orginal_text.substring(offset+old_value.length),
add_2_offset = new_value.length - old_value.length;
this.orginal_text = part_1 + new_value + part_2;
$(this.text_area).val(this.orginal_text);
for (var j=0, len=this.results.length; j<len; j++) {
// Don't edit the offset of the current item
if (j != id && j > id)
this.results[j]['attrs']['o'] += add_2_offset;
}
};
this.saveOldValue = function(elm, old_value) {
elm.is_changed = true;
elm.old_value = old_value;
};
this.createListSeparator = function()
{
var td = document.createElement('td'),
tr = document.createElement('tr');
$(td).html(' ').attr('googie_action_btn', '1')
.css({'cursor': 'default', 'font-size': '3px', 'border-top': '1px solid #ccc', 'padding-top': '3px'});
tr.appendChild(td);
return tr;
};
this.correctError = function(id, elm, l_elm, rm_pre_space)
{
var old_value = elm.innerHTML,
new_value = l_elm.nodeType == 3 ? l_elm.nodeValue : l_elm.innerHTML,
offset = this.results[id]['attrs']['o'];
if (rm_pre_space) {
var pre_length = elm.previousSibling.innerHTML;
elm.previousSibling.innerHTML = pre_length.slice(0, pre_length.length-1);
old_value = " " + old_value;
offset--;
}
this.hideErrorWindow();
this.updateOrginalText(offset, old_value, new_value, id);
$(elm).html(new_value).css('color', 'green').attr('is_corrected', true);
this.results[id]['attrs']['l'] = new_value.length;
if (!this.isDefined(elm.old_value))
this.saveOldValue(elm, old_value);
this.errorFixed();
};
this.ignoreError = function(elm, id)
{
// @TODO: ignore all same words
$(elm).removeAttr('class').css('color', '').unbind();
this.hideErrorWindow();
};
this.showErrorWindow = function(elm, id)
{
if (this.show_menu_observer)
this.show_menu_observer(this);
var ref = this,
pos = $(elm).offset(),
table = document.createElement('table'),
list = document.createElement('tbody');
$(this.error_window).html('');
$(table).addClass('googie_list').attr('googie_action_btn', '1');
// Check if we should use custom menu builder, if not we use the default
var changed = false;
for (var k=0; k<this.custom_menu_builder.length; k++) {
var eb = this.custom_menu_builder[k];
if (eb[0](this.results[id])) {
changed = eb[1](this, list, elm);
break;
}
}
if (!changed) {
// Build up the result list
var suggestions = this.results[id]['suggestions'],
offset = this.results[id]['attrs']['o'],
len = this.results[id]['attrs']['l'],
row, item, dummy;
// [Add to dictionary] button
if (this.has_dictionary && !$(elm).attr('is_corrected')) {
row = document.createElement('tr'),
item = document.createElement('td'),
dummy = document.createElement('span');
$(dummy).text(this.lang_learn_word);
$(item).attr('googie_action_btn', '1').css('cursor', 'default')
.mouseover(ref.item_onmouseover)
.mouseout(ref.item_onmouseout)
.click(function(e) {
ref.learnWord(elm, id);
ref.ignoreError(elm, id);
});
item.appendChild(dummy);
row.appendChild(item);
list.appendChild(row);
}
/*
if (suggestions.length == 0) {
row = document.createElement('tr'),
item = document.createElement('td'),
dummy = document.createElement('span');
$(dummy).text(this.lang_no_suggestions);
$(item).attr('googie_action_btn', '1').css('cursor', 'default');
item.appendChild(dummy);
row.appendChild(item);
list.appendChild(row);
}
*/
for (var i=0, len=suggestions.length; i < len; i++) {
row = document.createElement('tr'),
item = document.createElement('td'),
dummy = document.createElement('span');
$(dummy).html(suggestions[i]);
$(item).mouseover(this.item_onmouseover).mouseout(this.item_onmouseout)
.click(function(e) { ref.correctError(id, elm, e.target.firstChild) });
item.appendChild(dummy);
row.appendChild(item);
list.appendChild(row);
}
// The element is changed, append the revert
if (elm.is_changed && elm.innerHTML != elm.old_value) {
var old_value = elm.old_value,
revert_row = document.createElement('tr'),
revert = document.createElement('td'),
rev_span = document.createElement('span');
$(rev_span).addClass('googie_list_revert').html(this.lang_revert + ' ' + old_value);
$(revert).mouseover(this.item_onmouseover).mouseout(this.item_onmouseout)
.click(function(e) {
ref.updateOrginalText(offset, elm.innerHTML, old_value, id);
$(elm).removeAttr('is_corrected').css('color', '#b91414').html(old_value);
ref.hideErrorWindow();
});
revert.appendChild(rev_span);
revert_row.appendChild(revert);
list.appendChild(revert_row);
}
// Append the edit box
var edit_row = document.createElement('tr'),
edit = document.createElement('td'),
edit_input = document.createElement('input'),
ok_pic = document.createElement('img'),
edit_form = document.createElement('form');
var onsub = function () {
if (edit_input.value != '') {
if (!ref.isDefined(elm.old_value))
ref.saveOldValue(elm, elm.innerHTML);
ref.updateOrginalText(offset, elm.innerHTML, edit_input.value, id);
$(elm).attr('is_corrected', true).css('color', 'green').text(edit_input.value);
ref.hideErrorWindow();
}
return false;
};
$(edit_input).width(120)
.css({'margin': 0, 'padding': 0})
.val($(elm).text()).attr('googie_action_btn', '1');
$(edit).css('cursor', 'default').attr('googie_action_btn', '1');
$(ok_pic).attr('src', this.img_dir + 'ok.gif')
.width(32).height(16)
.css({'cursor': 'pointer', 'margin-left': '2px', 'margin-right': '2px'})
.click(onsub);
$(edit_form).attr('googie_action_btn', '1')
.css({'margin': 0, 'padding': 0, 'cursor': 'default', 'white-space': 'nowrap'})
.submit(onsub);
edit_form.appendChild(edit_input);
edit_form.appendChild(ok_pic);
edit.appendChild(edit_form);
edit_row.appendChild(edit);
list.appendChild(edit_row);
// Append extra menu items
if (this.extra_menu_items.length > 0)
list.appendChild(this.createListSeparator());
var loop = function(i) {
if (i < ref.extra_menu_items.length) {
var e_elm = ref.extra_menu_items[i];
if (!e_elm[2] || e_elm[2](elm, ref)) {
var e_row = document.createElement('tr'),
e_col = document.createElement('td');
$(e_col).html(e_elm[0])
.mouseover(ref.item_onmouseover)
.mouseout(ref.item_onmouseout)
.click(function() { return e_elm[1](elm, ref) });
e_row.appendChild(e_col);
list.appendChild(e_row);
}
loop(i+1);
}
};
loop(0);
loop = null;
//Close button
if (this.use_close_btn) {
list.appendChild(this.createCloseButton(this.hideErrorWindow));
}
}
table.appendChild(list);
this.error_window.appendChild(table);
// calculate and set position
var height = $(this.error_window).height(),
width = $(this.error_window).width(),
pageheight = $(document).height(),
pagewidth = $(document).width(),
top = pos.top + height + 20 < pageheight ? pos.top + 20 : pos.top - height,
left = pos.left + width < pagewidth ? pos.left : pos.left - width;
$(this.error_window).css({'top': top+'px', 'left': left+'px'}).show();
// Dummy for IE - dropdown bug fix
if (document.all && !window.opera) {
if (!this.error_window_iframe) {
var iframe = $('<iframe>').css({'position': 'absolute', 'z-index': -1});
$('body').append(iframe);
this.error_window_iframe = iframe;
}
$(this.error_window_iframe)
.css({'top': this.error_window.offsetTop, 'left': this.error_window.offsetLeft,
'width': this.error_window.offsetWidth, 'height': this.error_window.offsetHeight})
.show();
}
};
//////
// Edit layer (the layer where the suggestions are stored)
//////
this.createEditLayer = function(width, height)
{
this.edit_layer = document.createElement('div');
$(this.edit_layer).addClass('googie_edit_layer').attr('id', 'googie_edit_layer')
- .width('auto').height(height);
+ .width(width).height(height);
if (this.text_area.nodeName.toLowerCase() != 'input' || $(this.text_area).val() == '') {
- $(this.edit_layer).css('overflow', 'auto').height(height-4);
+ $(this.edit_layer).css('overflow', 'auto');
} else {
$(this.edit_layer).css('overflow', 'hidden');
}
var ref = this;
if (this.edit_layer_dbl_click) {
$(this.edit_layer).dblclick(function(e) {
if (e.target.className != 'googie_link' && !ref.isErrorWindowShown()) {
ref.resumeEditing();
var fn1 = function() {
$(ref.text_area).focus();
fn1 = null;
};
window.setTimeout(fn1, 10);
}
return false;
});
}
};
this.resumeEditing = function()
{
this.setStateChanged('ready');
if (this.edit_layer)
this.el_scroll_top = this.edit_layer.scrollTop;
this.hideErrorWindow();
if (this.main_controller)
$(this.spell_span).removeClass().addClass('googie_no_style');
if (!this.ignore) {
if (this.use_focus) {
$(this.focus_link_t).remove();
$(this.focus_link_b).remove();
}
$(this.edit_layer).remove();
$(this.text_area).show();
if (this.el_scroll_top != undefined)
this.text_area.scrollTop = this.el_scroll_top;
}
this.checkSpellingState(false);
};
this.createErrorLink = function(text, id)
{
var elm = document.createElement('span'),
ref = this,
d = function (e) {
ref.showErrorWindow(elm, id);
d = null;
return false;
};
$(elm).html(text).addClass('googie_link').click(d).removeAttr('is_corrected')
.attr({'googie_action_btn' : '1', 'g_id' : id});
return elm;
};
this.createPart = function(txt_part)
{
if (txt_part == " ")
return document.createTextNode(" ");
txt_part = this.escapeSpecial(txt_part);
txt_part = txt_part.replace(/\n/g, "<br>");
txt_part = txt_part.replace(/ /g, " ");
txt_part = txt_part.replace(/^ /g, " ");
txt_part = txt_part.replace(/ $/g, " ");
var span = document.createElement('span');
$(span).html(txt_part);
return span;
};
this.showErrorsInIframe = function()
{
var output = document.createElement('div'),
pointer = 0,
results = this.results;
if (results.length > 0) {
for (var i=0, length=results.length; i < length; i++) {
var offset = results[i]['attrs']['o'],
len = results[i]['attrs']['l'],
part_1_text = this.orginal_text.substring(pointer, offset),
part_1 = this.createPart(part_1_text);
output.appendChild(part_1);
pointer += offset - pointer;
// If the last child was an error, then insert some space
var err_link = this.createErrorLink(this.orginal_text.substr(offset, len), i);
this.error_links.push(err_link);
output.appendChild(err_link);
pointer += len;
}
// Insert the rest of the orginal text
var part_2_text = this.orginal_text.substr(pointer, this.orginal_text.length),
part_2 = this.createPart(part_2_text);
output.appendChild(part_2);
}
else
output.innerHTML = this.orginal_text;
$(output).css('text-align', 'left');
var me = this;
if (this.custom_item_evaulator)
$.map(this.error_links, function(elm){me.custom_item_evaulator(me, elm)});
$(this.edit_layer).append(output);
// Hide text area and show edit layer
$(this.text_area).hide();
$(this.edit_layer).insertBefore(this.text_area);
if (this.use_focus) {
this.focus_link_t = this.createFocusLink('focus_t');
this.focus_link_b = this.createFocusLink('focus_b');
$(this.focus_link_t).insertBefore(this.edit_layer);
$(this.focus_link_b).insertAfter(this.edit_layer);
}
// this.edit_layer.scrollTop = this.ta_scroll_top;
};
//////
// Choose language menu
//////
this.createLangWindow = function()
{
this.language_window = document.createElement('div');
$(this.language_window).addClass('googie_window popupmenu')
.width(100).attr('googie_action_btn', '1');
// Build up the result list
var table = document.createElement('table'),
list = document.createElement('tbody'),
ref = this,
row, item, span;
$(table).addClass('googie_list').width('100%');
this.lang_elms = [];
for (i=0; i < this.langlist_codes.length; i++) {
row = document.createElement('tr');
item = document.createElement('td');
span = document.createElement('span');
$(span).text(this.lang_to_word[this.langlist_codes[i]]);
this.lang_elms.push(item);
$(item).attr('googieId', this.langlist_codes[i])
.bind('click', function(e) {
ref.deHighlightCurSel();
ref.setCurrentLanguage($(this).attr('googieId'));
if (ref.lang_state_observer != null) {
ref.lang_state_observer();
}
ref.highlightCurSel();
ref.hideLangWindow();
})
.bind('mouseover', function(e) {
if (this.className != "googie_list_selected")
this.className = "googie_list_onhover";
})
.bind('mouseout', function(e) {
if (this.className != "googie_list_selected")
this.className = "googie_list_onout";
});
item.appendChild(span);
row.appendChild(item);
list.appendChild(row);
}
// Close button
if (this.use_close_btn) {
list.appendChild(this.createCloseButton(function () { ref.hideLangWindow.apply(ref) }));
}
this.highlightCurSel();
table.appendChild(list);
this.language_window.appendChild(table);
};
this.isLangWindowShown = function()
{
return $(this.language_window).is(':visible');
};
this.hideLangWindow = function()
{
$(this.language_window).hide();
$(this.switch_lan_pic).removeClass().addClass('googie_lang_3d_on');
};
this.showLangWindow = function(elm)
{
if (this.show_menu_observer)
this.show_menu_observer(this);
this.createLangWindow();
$('body').append(this.language_window);
var pos = $(elm).offset(),
height = $(elm).height(),
width = $(elm).width(),
h = $(this.language_window).height(),
pageheight = $(document).height(),
left = this.change_lang_pic_placement == 'right' ?
pos.left - 100 + width : pos.left + width,
top = pos.top + h < pageheight ? pos.top + height : pos.top - h - 4;
$(this.language_window).css({'top' : top+'px','left' : left+'px'}).show();
this.highlightCurSel();
};
this.deHighlightCurSel = function()
{
$(this.lang_cur_elm).removeClass().addClass('googie_list_onout');
};
this.highlightCurSel = function()
{
if (GOOGIE_CUR_LANG == null)
GOOGIE_CUR_LANG = GOOGIE_DEFAULT_LANG;
for (var i=0; i < this.lang_elms.length; i++) {
if ($(this.lang_elms[i]).attr('googieId') == GOOGIE_CUR_LANG) {
this.lang_elms[i].className = 'googie_list_selected';
this.lang_cur_elm = this.lang_elms[i];
}
else {
this.lang_elms[i].className = 'googie_list_onout';
}
}
};
this.createChangeLangPic = function()
{
var img = $('<img>')
.attr({src: this.img_dir + 'change_lang.gif', 'alt': 'Change language', 'googie_action_btn': '1'}),
switch_lan = document.createElement('span');
ref = this;
$(switch_lan).addClass('googie_lang_3d_on')
.append(img)
.bind('click', function(e) {
var elm = this.tagName.toLowerCase() == 'img' ? this.parentNode : this;
if($(elm).hasClass('googie_lang_3d_click')) {
elm.className = 'googie_lang_3d_on';
ref.hideLangWindow();
}
else {
elm.className = 'googie_lang_3d_click';
ref.showLangWindow(elm);
}
});
return switch_lan;
};
this.createSpellDiv = function()
{
var span = document.createElement('span');
$(span).addClass('googie_check_spelling_link').text(this.lang_chck_spell);
if (this.show_spell_img) {
$(span).append(' ').append($('<img>').attr('src', this.img_dir + 'spellc.gif'));
}
return span;
};
//////
// State functions
/////
this.flashNoSpellingErrorState = function(on_finish)
{
this.setStateChanged('no_error_found');
var ref = this;
if (this.main_controller) {
var no_spell_errors;
if (on_finish) {
var fn = function() {
on_finish();
ref.checkSpellingState();
};
no_spell_errors = fn;
}
else
no_spell_errors = function () { ref.checkSpellingState() };
var rsm = $('<span>').text(this.lang_no_error_found);
$(this.switch_lan_pic).hide();
$(this.spell_span).empty().append(rsm)
.removeClass().addClass('googie_check_spelling_ok');
window.setTimeout(no_spell_errors, 1000);
}
};
this.resumeEditingState = function()
{
this.setStateChanged('resume_editing');
//Change link text to resume
if (this.main_controller) {
var rsm = $('<span>').text(this.lang_rsm_edt);
var ref = this;
$(this.switch_lan_pic).hide();
$(this.spell_span).empty().unbind().append(rsm)
.bind('click', function() { ref.resumeEditing() })
.removeClass().addClass('googie_resume_editing');
}
try { this.edit_layer.scrollTop = this.ta_scroll_top; }
catch (e) {};
};
this.checkSpellingState = function(fire)
{
if (fire)
this.setStateChanged('ready');
if (this.show_change_lang_pic)
this.switch_lan_pic = this.createChangeLangPic();
else
this.switch_lan_pic = document.createElement('span');
var span_chck = this.createSpellDiv(),
ref = this;
if (this.custom_spellcheck_starter)
$(span_chck).bind('click', function(e) { ref.custom_spellcheck_starter() });
else {
$(span_chck).bind('click', function(e) { ref.spellCheck() });
}
if (this.main_controller) {
if (this.change_lang_pic_placement == 'left') {
$(this.spell_container).empty().append(this.switch_lan_pic).append(' ').append(span_chck);
} else {
$(this.spell_container).empty().append(span_chck).append(' ').append(this.switch_lan_pic);
}
}
this.spell_span = span_chck;
};
//////
// Misc. functions
/////
this.isDefined = function(o)
{
return (o !== undefined && o !== null)
};
this.errorFixed = function()
{
this.cnt_errors_fixed++;
if (this.all_errors_fixed_observer)
if (this.cnt_errors_fixed == this.cnt_errors) {
this.hideErrorWindow();
this.all_errors_fixed_observer();
}
};
this.errorFound = function()
{
this.cnt_errors++;
};
this.createCloseButton = function(c_fn)
{
return this.createButton(this.lang_close, 'googie_list_close', c_fn);
};
this.createButton = function(name, css_class, c_fn)
{
var btn_row = document.createElement('tr'),
btn = document.createElement('td'),
spn_btn;
if (css_class) {
spn_btn = document.createElement('span');
$(spn_btn).addClass(css_class).html(name);
} else {
spn_btn = document.createTextNode(name);
}
$(btn).bind('click', c_fn)
.bind('mouseover', this.item_onmouseover)
.bind('mouseout', this.item_onmouseout);
btn.appendChild(spn_btn);
btn_row.appendChild(btn);
return btn_row;
};
this.removeIndicator = function(elm)
{
//$(this.indicator).remove();
// roundcube mod.
if (window.rcmail)
rcmail.set_busy(false, null, this.rc_msg_id);
};
this.appendIndicator = function(elm)
{
// modified by roundcube
if (window.rcmail)
this.rc_msg_id = rcmail.set_busy(true, 'checking');
/*
this.indicator = document.createElement('img');
$(this.indicator).attr('src', this.img_dir + 'indicator.gif')
.css({'margin-right': '5px', 'text-decoration': 'none'}).width(16).height(16);
if (elm)
$(this.indicator).insertBefore(elm);
else
$('body').append(this.indicator);
*/
}
this.createFocusLink = function(name)
{
var link = document.createElement('a');
$(link).attr({'href': 'javascript:;', 'name': name});
return link;
};
this.item_onmouseover = function(e)
{
if (this.className != 'googie_list_revert' && this.className != 'googie_list_close')
this.className = 'googie_list_onhover';
else
this.parentNode.className = 'googie_list_onhover';
};
this.item_onmouseout = function(e)
{
if (this.className != 'googie_list_revert' && this.className != 'googie_list_close')
this.className = 'googie_list_onout';
else
this.parentNode.className = 'googie_list_onout';
};
};
diff --git a/program/js/tinymce/roundcube/content.css b/program/js/tinymce/roundcube/content.css
index 67480ab77..0ad246ea0 100644
--- a/program/js/tinymce/roundcube/content.css
+++ b/program/js/tinymce/roundcube/content.css
@@ -1,26 +1,24 @@
/* This file contains the CSS data for the editable area(iframe) of TinyMCE */
body, td, pre {
font-family: "Lucida Grande", Verdana, Arial, Helvetica, sans-serif;
font-size: 12px;
}
body {
background-color: #FFFFFF;
- margin-left: 4px;
- margin-right: 4px;
- margin-top: 2px;
+ margin: 4px;
}
div.pre {
margin: 0;
padding: 0;
font-family: monospace;
}
blockquote
{
border-left: #1010ff 2px solid;
margin: 0;
padding: 0 0.4em;
}
diff --git a/skins/classic/functions.js b/skins/classic/functions.js
index 2bf1538c4..aaa4f7288 100644
--- a/skins/classic/functions.js
+++ b/skins/classic/functions.js
@@ -1,1052 +1,1053 @@
/**
* Roundcube functions for default skin interface
*
* @licstart The following is the entire license notice for the
* JavaScript code in this file.
*
* Copyright (c) 2006-2014, The Roundcube Dev Team
*
* The JavaScript code in this page is free software: you can redistribute it
* and/or modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* @licend The above is the entire license notice
* for the JavaScript code in this file.
*/
/**
* Settings
*/
function rcube_init_settings_tabs()
{
var el, cl, container = $('#tabsbar'),
last_tab = $('span:last', container),
tab = '#settingstabpreferences',
action = window.rcmail && rcmail.env.action ? rcmail.env.action : null;
// move About tab to the end
if (last_tab && last_tab.attr('id') != 'settingstababout' && (el = $('#settingstababout'))) {
cl = el.clone(true);
el.remove();
last_tab.after(cl);
}
// get selected tab
if (action)
tab = '#settingstab' + (action.indexOf('identity')>0 ? 'identities' : action.replace(/\./g, ''));
$(tab).addClass('tablink-selected');
$('a', tab).removeAttr('onclick').click(function() { return false; });
}
// Fieldsets-to-tabs converter
// Warning: don't place "caller" <script> inside page element (id)
function rcube_init_tabs(id, current)
{
var content = $('#'+id),
fs = content.children('fieldset');
if (!fs.length)
return;
current = current ? current : 0;
// first hide not selected tabs
fs.each(function(idx) { if (idx != current) $(this).hide(); });
// create tabs container
var tabs = $('<div>').addClass('tabsbar').appendTo(content);
// convert fildsets into tabs
fs.each(function(idx) {
var tab, a, elm = $(this), legend = elm.children('legend');
// create a tab
a = $('<a>').text(legend.text()).attr('href', '#');
tab = $('<span>').attr({'id': 'tab'+idx, 'class': 'tablink'})
.click(function() { rcube_show_tab(id, idx); return false })
// remove legend
legend.remove();
// style fieldset
elm.addClass('tabbed');
// style selected tab
if (idx == current)
tab.addClass('tablink-selected');
// add the tab to container
tab.append(a).appendTo(tabs);
});
}
function rcube_show_tab(id, index)
{
var fs = $('#'+id).children('fieldset');
fs.each(function(idx) {
// Show/hide fieldset (tab content)
$(this)[index==idx ? 'show' : 'hide']();
// Select/unselect tab
$('#tab'+idx).toggleClass('tablink-selected', idx==index);
});
}
/**
* Mail UI
*/
function rcube_mail_ui()
{
this.popups = {
markmenu: {id:'markmessagemenu'},
replyallmenu: {id:'replyallmenu'},
forwardmenu: {id:'forwardmenu', editable:1},
searchmenu: {id:'searchmenu', editable:1},
messagemenu: {id:'messagemenu'},
attachmentmenu: {id:'attachmentmenu'},
dragmenu: {id:'dragmenu', sticky:1},
groupmenu: {id:'groupoptionsmenu', above:1},
mailboxmenu: {id:'mailboxoptionsmenu', above:1},
composemenu: {id:'composeoptionsmenu', editable:1, overlap:1},
spellmenu: {id:'spellmenu'},
responsesmenu: {id:'responsesmenu'},
// toggle: #1486823, #1486930
uploadmenu: {id:'attachment-form', editable:1, above:1, toggle:!bw.ie&&!bw.linux },
uploadform: {id:'upload-form', editable:1, toggle:!bw.ie&&!bw.linux }
};
var obj;
for (var k in this.popups) {
obj = $('#'+this.popups[k].id)
if (obj.length)
this.popups[k].obj = obj;
else {
delete this.popups[k];
}
}
}
rcube_mail_ui.prototype = {
show_popup: function(popup, show, config)
{
var obj;
// auto-register menu object
if (!this.popups[popup] && (obj = $('#'+popup)) && obj.length)
this.popups[popup] = $.extend(config, {id: popup, obj: obj});
if (typeof this[popup] == 'function')
return this[popup](show);
else
return this.show_popupmenu(popup, show);
},
show_popupmenu: function(popup, show)
{
var obj = this.popups[popup].obj,
above = this.popups[popup].above,
ref = $(this.popups[popup].link ? this.popups[popup].link : rcube_find_object(popup+'link'));
if (typeof show == 'undefined')
show = obj.is(':visible') ? false : true;
else if (this.popups[popup].toggle && show && this.popups[popup].obj.is(':visible') )
show = false;
if (show && ref.length) {
var parent = ref.parent(),
win = $(window),
pos = parent.hasClass('dropbutton') ? parent.offset() : ref.offset();
if (!above && pos.top + ref.height() + obj.height() > win.height())
above = true;
if (pos.left + obj.width() > win.width())
pos.left = win.width() - obj.width() - 30;
obj.css({ left:pos.left, top:(pos.top + (above ? -obj.height() : ref.height())) });
}
obj[show?'show':'hide']();
},
dragmenu: function(show)
{
this.popups.dragmenu.obj[show?'show':'hide']();
},
forwardmenu: function(show)
{
$("input[name='forwardtype'][value="+(rcmail.env.forward_attachment ? 1 : 0)+"]", this.popups.forwardmenu.obj)
.prop('checked', true);
this.show_popupmenu('forwardmenu', show);
},
uploadmenu: function(show)
{
if (typeof show == 'object') // called as event handler
show = false;
// clear upload form
if (!show) {
try { $('#attachment-form form')[0].reset(); }
catch(e){} // ignore errors
}
this.show_popupmenu('uploadmenu', show);
if (!document.all && this.popups.uploadmenu.obj.is(':visible'))
$('#attachment-form input[type=file]').click();
},
searchmenu: function(show)
{
var obj = this.popups.searchmenu.obj,
ref = rcube_find_object('searchmenulink');
if (typeof show == 'undefined')
show = obj.is(':visible') ? false : true;
if (show && ref) {
var pos = $(ref).offset();
obj.css({left:pos.left, top:(pos.top + ref.offsetHeight + 2)});
if (rcmail.env.search_mods) {
var n, all,
list = $('input:checkbox[name="s_mods[]"]', obj),
mbox = rcmail.env.mailbox,
mods = rcmail.env.search_mods,
scope = rcmail.env.search_scope || 'base';
if (rcmail.env.task == 'mail') {
mods = mods[mbox] ? mods[mbox] : mods['*'];
all = 'text';
$('input:radio[name="s_scope"]').prop('checked', false).filter('#s_scope_'+scope).prop('checked', true);
}
else {
all = '*';
}
if (mods[all])
list.map(function() {
this.checked = true;
this.disabled = this.value != all;
});
else {
list.prop('disabled', false).prop('checked', false);
for (n in mods)
$('#s_mod_' + n).prop('checked', true);
}
}
}
obj[show?'show':'hide']();
},
set_searchmod: function(elem)
{
var all, m, task = rcmail.env.task,
mods = rcmail.env.search_mods,
mbox = rcmail.env.mailbox,
scope = $('input[name="s_scope"]:checked').val();
if (scope == 'all')
mbox = '*';
if (!mods)
mods = {};
if (task == 'mail') {
if (!mods[mbox])
mods[mbox] = rcube_clone_object(mods['*']);
m = mods[mbox];
all = 'text';
}
else { //addressbook
m = mods;
all = '*';
}
if (!elem.checked)
delete(m[elem.value]);
else
m[elem.value] = 1;
// mark all fields
if (elem.value == all) {
$('input:checkbox[name="s_mods[]"]').map(function() {
if (this == elem)
return;
this.checked = true;
if (elem.checked) {
this.disabled = true;
delete m[this.value];
}
else {
this.disabled = false;
m[this.value] = 1;
}
});
}
rcmail.set_searchmods(m);
},
show_listmenu: function(p)
{
var self = this, buttons = {}, $dialog = $('#listmenu');
// close the dialog
if ($dialog.is(':visible')) {
$dialog.dialog('close', p.originalEvent);
return;
}
// set form values
$('input[name="sort_col"][value="'+rcmail.env.sort_col+'"]').prop('checked', true);
$('input[name="sort_ord"][value="DESC"]').prop('checked', rcmail.env.sort_order == 'DESC');
$('input[name="sort_ord"][value="ASC"]').prop('checked', rcmail.env.sort_order != 'DESC');
$('input[name="view"][value="thread"]').prop('checked', rcmail.env.threading ? true : false);
$('input[name="view"][value="list"]').prop('checked', rcmail.env.threading ? false : true);
// set checkboxes
$('input[name="list_col[]"]').each(function() {
$(this).prop('checked', $.inArray(this.value, rcmail.env.listcols) != -1);
});
buttons[rcmail.gettext('save')] = function(e) {
$dialog.dialog('close', e);
self.save_listmenu();
};
$dialog.dialog({
modal: true,
resizable: false,
closeOnEscape: true,
title: null,
open: function(e) {
var maxheight = 0;
$('#listmenu fieldset').each(function() {
var height = $(this).height();
if (height > maxheight) {
maxheight = height;
}
}).css("min-height", maxheight+"px").height(maxheight);
setTimeout(function() { $dialog.find('a, input:not(:disabled)').not('[aria-disabled=true]').first().focus(); }, 100);
},
close: function(e) {
$dialog.dialog('destroy').hide();
if (e.originalEvent && rcube_event.is_keyboard(e.originalEvent))
$('#listmenulink').focus();
},
buttons: buttons,
minWidth: 500,
width: $dialog.width()+20
}).show();
},
save_listmenu: function()
{
var sort = $('input[name="sort_col"]:checked').val(),
ord = $('input[name="sort_ord"]:checked').val(),
thread = $('input[name="view"]:checked').val(),
cols = $('input[name="list_col[]"]:checked')
.map(function(){ return this.value; }).get();
rcmail.set_list_options(cols, sort, ord, thread == 'thread' ? 1 : 0);
},
spellmenu: function(show)
{
var link, li,
lang = rcmail.spellcheck_lang(),
menu = this.popups.spellmenu.obj,
ul = $('ul', menu);
if (!ul.length) {
ul = $('<ul>');
for (i in rcmail.env.spell_langs) {
li = $('<li>');
link = $('<a href="#"></a>').text(rcmail.env.spell_langs[i])
.addClass('active').data('lang', i)
.click(function() {
rcmail.spellcheck_lang_set($(this).data('lang'));
});
link.appendTo(li);
li.appendTo(ul);
}
ul.appendTo(menu);
}
// select current language
$('li', ul).each(function() {
var el = $('a', this);
if (el.data('lang') == lang)
el.addClass('selected');
else if (el.hasClass('selected'))
el.removeClass('selected');
});
this.show_popupmenu('spellmenu', show);
},
show_attachmentmenu: function(elem, event)
{
var id = elem.parentNode.id.replace(/^attach/, '');
$('#attachmenuopen').unbind('click').attr('onclick', '').click(function(e) {
return rcmail.command('open-attachment', id, this);
});
$('#attachmenudownload').unbind('click').attr('onclick', '').click(function() {
rcmail.command('download-attachment', id, this);
});
this.popups.attachmentmenu.link = elem;
rcmail.command('menu-open', {menu: 'attachmentmenu', id: id}, elem, event);
},
menu_open: function(p)
{
if (p && p.name == 'messagelistmenu')
this.show_listmenu();
},
body_mouseup: function(e)
{
var target = e.target; ref = this;
$.each(this.popups, function(i, popup) {
if (popup.obj.is(':visible') && target != rcube_find_object(i + 'link')
&& !popup.toggle
&& target != popup.obj.get(0) // check if scroll bar was clicked (#1489832)
&& (!popup.editable || !ref.target_overlaps(target, popup.id))
&& (!popup.sticky || !rcube_mouse_is_over(e, rcube_find_object(popup.id)))
&& !$(target).is('.folder-selector-link') && !$(target).children('.folder-selector-link').length
) {
window.setTimeout('rcmail_ui.show_popup("'+i+'",false);', 50);
}
});
},
target_overlaps: function (target, elementid)
{
var element = rcube_find_object(elementid);
while (target.parentNode) {
if (target.parentNode == element)
return true;
target = target.parentNode;
}
return false;
},
body_keydown: function(e)
{
if (e.keyCode == 27) {
for (var k in this.popups) {
if (this.popups[k].obj.is(':visible'))
this.show_popup(k, false);
}
}
},
switch_preview_pane: function(elem)
{
var uid, prev_frm = $('#mailpreviewframe');
if (elem.checked) {
rcmail.env.contentframe = 'messagecontframe';
if (mailviewsplit.layer) {
mailviewsplit.resize();
mailviewsplit.layer.elm.style.display = '';
}
else
mailviewsplit.init();
if (bw.opera) {
$('#messagelistcontainer').css({height: ''});
}
prev_frm.show();
if (uid = rcmail.message_list.get_single_selection())
rcmail.show_message(uid, false, true);
}
else {
prev_frm.hide();
if (bw.ie7) {
var fr = document.getElementById('mailcontframe');
fr.style.bottom = 0;
fr.style.height = parseInt(fr.parentNode.offsetHeight)+'px';
}
else {
$('#mailcontframe').css({height: 'auto', bottom: 0});
if (bw.opera)
$('#messagelistcontainer').css({height: 'auto'});
}
if (mailviewsplit.layer)
mailviewsplit.layer.elm.style.display = 'none';
rcmail.env.contentframe = null;
rcmail.show_contentframe(false);
}
rcmail.command('save-pref', {name: 'preview_pane', value: (elem.checked?1:0)});
},
/* Message composing */
init_compose_form: function()
{
var f, v, field, fields = ['cc', 'bcc', 'replyto', 'followupto'],
div = document.getElementById('compose-div'),
headers_div = document.getElementById('compose-headers-div');
// Show input elements with non-empty value
for (f=0; f<fields.length; f++) {
v = fields[f]; field = $('#_'+v);
if (field.length) {
field.on('change', {v:v}, function(e) { if (this.value) rcmail_ui.show_header_form(e.data.v); });
if (field.val() != '')
rcmail_ui.show_header_form(v);
}
}
// prevent from form data loss when pressing ESC key in IE
if (bw.ie) {
var form = rcube_find_object('form');
form.onkeydown = function (e) {
if (rcube_event.get_keycode(e) == 27)
rcube_event.cancel(e);
};
}
$(window).resize(function() {
rcmail_ui.resize_compose_body();
});
$('#compose-container').resize(function() {
rcmail_ui.resize_compose_body();
});
div.style.top = (parseInt(headers_div.offsetHeight, 10) + 3) + 'px';
$(window).resize();
// fixes contacts-table position when there's more than one addressbook
$('#contacts-table').css('top', $('#directorylist').height() + 24 + 'px');
// contacts search submit
$('#quicksearchbox').keydown(function(e) {
if (rcube_event.get_keycode(e) == 13)
rcmail.command('search');
});
},
resize_compose_body: function()
{
var div = $('#compose-div .boxlistcontent'),
- w = div.width() - 2, h = div.height(),
+ w = div.width() - 6,
+ h = div.height() - 2,
x = bw.ie || bw.opera ? 4 : 0;
- $('#compose-body_ifr').width(w+3).height(h-2 - $('div.mce-toolbar').height());
+ $('#compose-body_ifr').width(w + 6).height(h - 1 - $('div.mce-toolbar').height());
$('#compose-body').width(w-x).height(h);
- $('#googie_edit_layer').height(h);
+ $('#googie_edit_layer').width(w).height(h);
},
resize_compose_body_ev: function()
{
window.setTimeout(function(){rcmail_ui.resize_compose_body();}, 100);
},
show_header_form: function(id)
{
var row, s,
link = document.getElementById(id + '-link');
if ((s = this.next_sibling(link)))
s.style.display = 'none';
else if ((s = this.prev_sibling(link)))
s.style.display = 'none';
link.style.display = 'none';
if ((row = document.getElementById('compose-' + id))) {
var div = document.getElementById('compose-div'),
headers_div = document.getElementById('compose-headers-div');
$(row).show();
div.style.top = (parseInt(headers_div.offsetHeight, 10) + 3) + 'px';
this.resize_compose_body();
}
return false;
},
hide_header_form: function(id)
{
var row, ns,
link = document.getElementById(id + '-link'),
parent = link.parentNode,
links = parent.getElementsByTagName('a');
link.style.display = '';
for (var i=0; i<links.length; i++)
if (links[i].style.display != 'none')
for (var j=i+1; j<links.length; j++)
if (links[j].style.display != 'none')
if ((ns = this.next_sibling(links[i]))) {
ns.style.display = '';
break;
}
document.getElementById('_' + id).value = '';
if ((row = document.getElementById('compose-' + id))) {
var div = document.getElementById('compose-div'),
headers_div = document.getElementById('compose-headers-div');
row.style.display = 'none';
div.style.top = (parseInt(headers_div.offsetHeight, 10) + 1) + 'px';
this.resize_compose_body();
}
return false;
},
next_sibling: function(elm)
{
var ns = elm.nextSibling;
while (ns && ns.nodeType == 3)
ns = ns.nextSibling;
return ns;
},
prev_sibling: function(elm)
{
var ps = elm.previousSibling;
while (ps && ps.nodeType == 3)
ps = ps.previousSibling;
return ps;
},
enable_command: function(p)
{
if (p.command == 'reply-list' && rcmail.env.reply_all_mode == 1) {
var label = rcmail.gettext(p.status ? 'replylist' : 'replyall');
$('a.button.replyAll').attr('title', label);
}
},
folder_search_init: function(container)
{
// animation to unfold list search box
$('.boxtitle a.search', container).click(function(e) {
var title = $('.boxtitle', container),
box = $('.listsearchbox', container),
dir = box.is(':visible') ? -1 : 1,
height = 24 + ($('select', box).length ? 24 : 0);
box.slideToggle({
duration: 160,
progress: function(animation, progress) {
if (dir < 0) progress = 1 - progress;
$('.boxlistcontent', container).css('top', (title.outerHeight() + height * progress) + 'px');
},
complete: function() {
box.toggleClass('expanded');
if (box.is(':visible')) {
box.find('input[type=text]').focus();
}
else {
$('a.reset', box).click();
}
// TODO: save state in cookie
}
});
return false;
});
}
};
/**
* Roundcube generic layer (floating box) class
*
* @constructor
*/
function rcube_layer(id, attributes)
{
this.name = id;
// create a new layer in the current document
this.create = function(arg)
{
var l = (arg.x) ? arg.x : 0,
t = (arg.y) ? arg.y : 0,
w = arg.width,
h = arg.height,
z = arg.zindex,
vis = arg.vis,
parent = arg.parent,
obj = document.createElement('DIV');
obj.id = this.name;
obj.style.position = 'absolute';
obj.style.visibility = (vis) ? (vis==2) ? 'inherit' : 'visible' : 'hidden';
obj.style.left = l+'px';
obj.style.top = t+'px';
if (w)
obj.style.width = w.toString().match(/\%$/) ? w : w+'px';
if (h)
obj.style.height = h.toString().match(/\%$/) ? h : h+'px';
if (z)
obj.style.zIndex = z;
if (parent)
parent.appendChild(obj);
else
document.body.appendChild(obj);
this.elm = obj;
};
// create new layer
if (attributes != null) {
this.create(attributes);
this.name = this.elm.id;
}
else // just refer to the object
this.elm = document.getElementById(id);
if (!this.elm)
return false;
// ********* layer object properties *********
this.css = this.elm.style;
this.event = this.elm;
this.width = this.elm.offsetWidth;
this.height = this.elm.offsetHeight;
this.x = parseInt(this.elm.offsetLeft);
this.y = parseInt(this.elm.offsetTop);
this.visible = (this.css.visibility=='visible' || this.css.visibility=='show' || this.css.visibility=='inherit') ? true : false;
// ********* layer object methods *********
// move the layer to a specific position
this.move = function(x, y)
{
this.x = x;
this.y = y;
this.css.left = Math.round(this.x)+'px';
this.css.top = Math.round(this.y)+'px';
};
// change the layers width and height
this.resize = function(w,h)
{
this.css.width = w+'px';
this.css.height = h+'px';
this.width = w;
this.height = h;
};
// show or hide the layer
this.show = function(a)
{
if(a == 1) {
this.css.visibility = 'visible';
this.visible = true;
}
else if(a == 2) {
this.css.visibility = 'inherit';
this.visible = true;
}
else {
this.css.visibility = 'hidden';
this.visible = false;
}
};
// write new content into a Layer
this.write = function(cont)
{
this.elm.innerHTML = cont;
};
};
/**
* Scroller
*
* @deprecated Use treelist widget
*/
function rcmail_scroller(list, top, bottom)
{
var ref = this;
this.list = $(list);
this.top = $(top);
this.bottom = $(bottom);
this.step_size = 6;
this.step_time = 20;
this.delay = 500;
this.top
.mouseenter(function() { ref.ts = window.setTimeout(function() { ref.scroll('down'); }, ref.delay); })
.mouseout(function() { if (ref.ts) window.clearTimeout(ref.ts); });
this.bottom
.mouseenter(function() { ref.ts = window.setTimeout(function() { ref.scroll('up'); }, ref.delay); })
.mouseout(function() { if (ref.ts) window.clearTimeout(ref.ts); });
this.scroll = function(dir)
{
var ref = this, size = this.step_size;
if (!rcmail.drag_active)
return;
if (dir == 'down')
size *= -1;
this.list.get(0).scrollTop += size;
this.ts = window.setTimeout(function() { ref.scroll(dir); }, this.step_time);
};
};
// Events handling in iframes (eg. preview pane)
function iframe_events()
{
// this==iframe
try {
var doc = this.contentDocument ? this.contentDocument : this.contentWindow ? this.contentWindow.document : null;
$(doc).mouseup(function(e) { rcmail_ui.body_mouseup(e); });
}
catch (e) {
// catch possible "Permission denied" error in IE
};
};
// Abbreviate mailbox names to fit width of the container
function rcube_render_mailboxlist()
{
var list = $('#mailboxlist > li > a, #mailboxlist ul:visible > li > a');
// it's too slow with really big number of folders, especially on IE
if (list.length > (bw.ie && bw.vendver < 9 ? 40 : 100))
return;
list.each(function() {
var elem = $(this),
text = elem.data('text');
if (!text) {
text = elem.text().replace(/\s+\([0-9]+\)$/, '');
elem.data('text', text);
}
if (text.length < 6)
return;
var abbrev = fit_string_to_size(text, elem, elem.width() - elem.children('span.unreadcount').width() - 16);
if (abbrev != text)
elem.attr('title', text);
elem.contents().filter(function(){ return (this.nodeType == 3); }).get(0).data = abbrev;
});
};
// inspired by https://gist.github.com/24261/7fdb113f1e26111bd78c0c6fe515f6c0bf418af5
function fit_string_to_size(str, elem, len)
{
var w, span, $span, result = str, ellip = '...';
if (!rcmail.env.tmp_span) {
// it should be appended to elem to use the same css style
// but for performance reasons we'll append it to body (once)
span = $('<b>').css({visibility: 'hidden', padding: '0px',
'font-family': elem.css('font-family'),
'font-size': elem.css('font-size')})
.appendTo($('body', document)).get(0);
rcmail.env.tmp_span = span;
}
else {
span = rcmail.env.tmp_span;
}
$span = $(span);
$span.text(result);
// on first run, check if string fits into the length already.
w = span.offsetWidth;
if (w > len) {
var cut = Math.max(1, Math.floor(str.length * ((w - len) / w) / 2)),
mid = Math.floor(str.length / 2),
offLeft = mid,
offRight = mid;
while (true) {
offLeft = mid - cut;
offRight = mid + cut;
$span.text(str.substring(0,offLeft) + ellip + str.substring(offRight));
// break loop if string fits size
if (offLeft < 3 || span.offsetWidth)
break;
cut++;
}
// build resulting string
result = str.substring(0,offLeft) + ellip + str.substring(offRight);
}
return result;
};
function update_quota(data)
{
percent_indicator(rcmail.gui_objects.quotadisplay, data);
if (data.table) {
var menu = $('#quotamenu');
if (!menu.length)
menu = $('<div id="quotamenu" class="popupmenu">').appendTo($('body'));
menu.html(data.table);
$('#quotaimg').css('cursor', 'pointer').off('click').on('click', function(e) {
return rcmail.command('menu-open', 'quotamenu', e.target, e);
});
}
};
// percent (quota) indicator
function percent_indicator(obj, data)
{
if (!data || !obj)
return false;
var limit_high = 80,
limit_mid = 55,
width = data.width ? data.width : rcmail.env.indicator_width ? rcmail.env.indicator_width : 100,
height = data.height ? data.height : rcmail.env.indicator_height ? rcmail.env.indicator_height : 14,
quota = data.percent ? Math.abs(parseInt(data.percent)) : 0,
quota_width = parseInt(quota / 100 * width),
pos = $(obj).position();
// workarounds for Opera and Webkit bugs
pos.top = Math.max(0, pos.top);
pos.left = Math.max(0, pos.left);
rcmail.env.indicator_width = width;
rcmail.env.indicator_height = height;
// overlimit
if (quota_width > width) {
quota_width = width;
quota = 100;
}
if (data.title)
data.title = rcmail.get_label('quota') + ': ' + data.title;
// main div
var main = $('<div>');
main.css({position: 'absolute', top: pos.top, left: pos.left,
width: width + 'px', height: height + 'px', zIndex: 100, lineHeight: height + 'px'})
.attr('title', data.title).addClass('quota_text').html(quota + '%');
// used bar
var bar1 = $('<div>');
bar1.css({position: 'absolute', top: pos.top + 1, left: pos.left + 1,
width: quota_width + 'px', height: height + 'px', zIndex: 99});
// background
var bar2 = $('<div>');
bar2.css({position: 'absolute', top: pos.top + 1, left: pos.left + 1,
width: width + 'px', height: height + 'px', zIndex: 98})
.addClass('quota_bg');
if (quota >= limit_high) {
main.addClass(' quota_text_high');
bar1.addClass('quota_high');
}
else if(quota >= limit_mid) {
main.addClass(' quota_text_mid');
bar1.addClass('quota_mid');
}
else {
main.addClass(' quota_text_low');
bar1.addClass('quota_low');
}
// replace quota image
$(obj).html('').append(bar1).append(bar2).append(main);
// update #quotaimg title
$('#quotaimg').attr('title', data.title);
};
// Optional parameters used by TinyMCE
var rcmail_editor_settings = {};
var rcmail_ui;
function rcube_init_mail_ui()
{
rcmail_ui = new rcube_mail_ui();
$(document.body).mouseup(function(e) { rcmail_ui.body_mouseup(e); })
.mousedown(function(e) { rcmail_ui.body_keydown(e); });
rcmail.addEventListener('init', function() {
if (rcmail.env.quota_content)
update_quota(rcmail.env.quota_content);
rcmail.addEventListener('setquota', update_quota);
$('iframe').load(iframe_events)
.contents().mouseup(function(e) { rcmail_ui.body_mouseup(e); });
if (rcmail.env.task == 'mail') {
rcmail.addEventListener('enable-command', 'enable_command', rcmail_ui)
.addEventListener('menu-open', 'menu_open', rcmail_ui)
.addEventListener('aftersend-attachment', 'uploadmenu', rcmail_ui)
.addEventListener('aftertoggle-editor', 'resize_compose_body_ev', rcmail_ui)
.gui_object('dragmenu', 'dragmenu');
if (rcmail.gui_objects.mailboxlist) {
rcmail.treelist.addEventListener('expand', rcube_render_mailboxlist);
rcmail.addEventListener('responseaftermark', rcube_render_mailboxlist)
.addEventListener('responseaftergetunread', rcube_render_mailboxlist)
.addEventListener('responseaftercheck-recent', rcube_render_mailboxlist)
.addEventListener('responseafterrefresh', rcube_render_mailboxlist)
.addEventListener('afterimport-messages', function(){ rcmail_ui.show_popup('uploadform', false); });
}
if (rcmail.env.action == 'compose')
rcmail_ui.init_compose_form();
else if (rcmail.env.action == 'show' || rcmail.env.action == 'preview')
// add menu link for each attachment
$('#attachment-list > li[id^="attach"]').each(function() {
$(this).append($('<a class="drop"></a>').bind('click keypress', function(e) {
if (e.type != 'keypress' || e.which == 13) {
rcmail_ui.show_attachmentmenu(this, e);
return false;
}
}));
});
}
else if (rcmail.env.task == 'addressbook') {
rcmail.addEventListener('afterupload-photo', function(){ rcmail_ui.show_popup('uploadform', false); })
.gui_object('dragmenu', 'dragmenu');
}
else if (rcmail.env.task == 'settings') {
if (rcmail.env.action == 'folders') {
rcmail_ui.folder_search_init($('#folder-manager'));
}
}
});
}
diff --git a/skins/classic/googiespell.css b/skins/classic/googiespell.css
index b4fab5bdb..fc6b069a1 100644
--- a/skins/classic/googiespell.css
+++ b/skins/classic/googiespell.css
@@ -1,118 +1,118 @@
/***** modified styles for GoogieSpell *****/
.googie_window {
font-size: 11px;
width: 185px;
margin: 0;
padding: 0;
}
.googie_edit_layer {
background-color: #ffffff;
- padding: 0 4px;
+ padding: 1px 3px;
font-size: 9pt;
font-family: monospace;
}
.googie_edit_layer span {
font-family: monospace;
}
.googie_list {
width: 100%;
margin: 0;
padding: 0;
}
.googie_list td {
font-size: 11px;
padding-left: 10px;
padding-right: 10px;
padding-top: 2px;
padding-bottom: 2px;
cursor: pointer;
list-style-type: none;
}
.googie_list_onhover {
color: #FFFFFF;
background-color: #CC3333;
}
.googie_list_onout {
background-color: #fff;
}
.googie_list_selected {
background-color: #cccccc;
font-weight: bold;
}
.googie_list_close {
font-size: 11px;
color: #b91414;
}
.googie_list_onhover .googie_list_close {
color: #FFFFFF;
}
.googie_list_revert {
font-size: 11px;
color: #b91414;
}
.googie_list_revert:hover {
color: #fff;
}
.googie_link {
color: #b91414;
text-decoration: underline;
cursor: pointer;
font-size: 9pt;
font-family: monospace;
}
.googie_check_spelling_link {
color: #CC0000;
font-size: 11px;
text-decoration: none;
cursor: pointer;
}
.googie_check_spelling_link:hover {
text-decoration: underline;
}
.googie_no_style {
text-decoration: none;
}
.googie_check_spelling_ok,
.googie_resume_editing {
color: green;
font-size: 11px;
cursor: pointer;
}
.googie_check_spelling_ok:hover,
.googie_resume_editing:hover {
text-decoration: underline;
}
.googie_lang_3d_click img {
vertical-align: middle;
border-top: 1px solid #555;
border-left: 1px solid #555;
border-right: 1px solid #b1b1b1;
border-bottom: 1px solid #b1b1b1;
}
.googie_lang_3d_on img {
vertical-align: middle;
border-top: 1px solid #b1b1b1;
border-left: 1px solid #b1b1b1;
border-right: 1px solid #555;
border-bottom: 1px solid #555;
}
diff --git a/skins/larry/googiespell.css b/skins/larry/googiespell.css
index d2f1cea78..2241ccd58 100644
--- a/skins/larry/googiespell.css
+++ b/skins/larry/googiespell.css
@@ -1,97 +1,94 @@
/***** modified styles for GoogieSpell *****/
.googie_window {
font-size: 11px;
width: 185px;
margin: 0;
padding: 0;
}
.googie_edit_layer {
- position: relative;
- top: 1px;
- left: 1px;
- padding: 8px;
+ padding: 4px;
font-size: 9pt;
font-family: monospace;
background-color: #fff;
border: 0;
}
.googie_edit_layer span {
font-family: monospace;
}
.googie_list {
width: 100%;
margin: 0;
padding: 0;
- border-spacing: 0;
+ border-spacing: 0;
}
.googie_list td {
min-width: 80px;
width: auto;
}
.googie_list td.googie_list_selected {
background: #4db0d2;
}
.googie_list_close {
font-size: 11px;
color: #b91414;
}
.googie_list_onhover .googie_list_close {
color: #fff;
}
.googie_list_revert {
font-size: 11px;
color: #b91414;
}
.googie_list_revert:hover {
color: #fff;
}
.googie_link {
color: #b91414;
text-decoration: underline;
cursor: pointer;
font-size: 9pt;
font-family: monospace;
}
.googie_check_spelling_link {
color: #0069A6;
font-size: 11px;
text-decoration: underline;
cursor: pointer;
}
.googie_no_style {
text-decoration: none;
}
.googie_check_spelling_ok,
.googie_resume_editing {
color: green;
font-size: 11px;
cursor: pointer;
text-decoration: underline;
}
.googie_check_spelling_ok:hover,
.googie_resume_editing:hover {
text-decoration: underline;
}
.googie_lang_3d_click img,
.googie_lang_3d_on img {
vertical-align: middle;
cursor: pointer;
border: 0;
}
diff --git a/skins/larry/mail.css b/skins/larry/mail.css
index 0f1eaa8a7..9a2fe6974 100644
--- a/skins/larry/mail.css
+++ b/skins/larry/mail.css
@@ -1,1385 +1,1385 @@
/**
* Roundcube webmail styles for the Email section
*
* Copyright (c) 2012, The Roundcube Dev Team
* Screendesign by FLINT / Büro für Gestaltung, bueroflint.com
*
* The contents are subject to the Creative Commons Attribution-ShareAlike
* License. It is allowed to copy, distribute, transmit and to adapt the work
* by keeping credits to the original autors in the README file.
* See http://creativecommons.org/licenses/by-sa/3.0/ for details.
*/
#mailview-left {
position: absolute;
top: 0;
left: 0;
width: 200px;
bottom: 0;
z-index: 2;
}
#mailview-right {
position: absolute;
top: 0;
left: 212px;
right: 0;
bottom: 0;
z-index: 3;
}
#mailview-right.fullwidth {
left: 0;
}
#mailview-top {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0px;
}
html.ie #mailview-top {
overflow: visible; /* fixes display issues of fixed list header in IE */
}
#mailview-bottom {
display: none;
position: absolute;
left: 0;
bottom: 0;
right: 0;
height: 0;
border-radius: 4px;
border-top: none;
}
#composeview-right #mailview-bottom {
border-radius: 0 0 4px 4px;
}
#mailboxcontainer,
#messagelistcontainer {
position: absolute;
top: 0;
left: 0;
width: 100%;
bottom: 0;
}
#messagelistcontainer {
top: 0;
bottom: 30px;
overflow: auto;
}
/* Real browsers accept this (not IE) */
html>/**/body #messagelist {
overflow: auto;
overflow-x: hidden;
}
#messagelistfooter {
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 22px;
padding: 4px 6px;
border-top: 1px solid #ddd;
background: #ebebeb;
background: -moz-linear-gradient(top, #ebebeb 0%, #c6c6c6 100%);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ebebeb), color-stop(100%,#c6c6c6));
background: -o-linear-gradient(top, #ebebeb 0%, #c6c6c6 100%);
background: -ms-linear-gradient(top, #ebebeb 0%, #c6c6c6 100%);
background: linear-gradient(to bottom, #ebebeb 0%, #c6c6c6 100%);
border-radius: 0 0 4px 4px;
white-space: nowrap;
}
#messagelistfooter.rightalign {
text-align: right;
}
#messagelistfooter #countcontrols {
display: inline-block;
}
#messagelistfooter #listcontrols,
#messagelistfooter #listselectors {
display: inline-block;
margin-right: 2em;
vertical-align: middle;
}
#messagelistfooter #listselectors .menuselector {
margin-top: -2px;
}
a.iconbutton.listmode {
width: 26px;
height: 20px;
background-position: 0 -477px;
}
a.iconbutton.threadmode {
width: 26px;
height: 20px;
background-position: 0 -497px;
}
a.iconbutton.listmode.selected {
background-position: -26px -477px;
}
a.iconbutton.threadmode.selected {
background-position: -26px -497px;
}
#mailboxlist > li:first-child {
border-top: 0;
}
html.mozilla #mailboxlist > li:first-child {
border-radius: 4px 4px 0 0;
}
#mailboxlist li.mailbox.unread > a {
padding-right: 36px;
}
#mailboxlist li.unread {
font-weight: bold;
}
#mailboxlist li.recent > a {
color: #017cb4;
}
#mailboxlist li.mailbox .unreadcount {
position: absolute;
top: 3px;
right: 6px;
min-width: 1.8em;
line-height: 15px;
padding: 2px 4px;
background: #82acb5;
background: -moz-linear-gradient(top, #82acb5 0%, #6a939f 100%);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#82acb5), color-stop(100%,#6a939f));
background: -o-linear-gradient(top, #82acb5 0%, #6a939f 100%);
background: -ms-linear-gradient(top, #82acb5 0%, #6a939f 100%);
background: linear-gradient(to bottom, #82acb5 0%, #6a939f 100%);
box-shadow: inset 0 1px 1px 0 #536d72;
-webkit-box-shadow: inset 0 1px 1px 0 #536d72;
border-radius: 9px;
color: #fff;
text-align: center;
font-weight: bold;
text-shadow: none;
}
#mailboxlist li.mailbox.selected > a .unreadcount {
background: #005d76;
background: -moz-linear-gradient(top, #005d76 0%, #004558 100%);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#005d76), color-stop(100%,#004558));
background: -o-linear-gradient(top, #005d76 0%, #004558 100%);
background: -ms-linear-gradient(top, #005d76 0%, #004558 100%);
background: linear-gradient(to bottom, #005d76 0%, #004558 100%);
box-shadow: inset 0 1px 1px 0 #003645;
-webkit-box-shadow: inset 0 1px 1px 0 #003645;
}
#mailboxlist li.mailbox.recent > a .unreadcount {
background: #017cb4;
background: -moz-linear-gradient(top, #017cb4 0%, #006ca4 100%);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#017cb4), color-stop(100%,#006ca4));
background: -o-linear-gradient(top, #017cb4 0%, #006ca4 100%);
background: -ms-linear-gradient(top, #017cb4 0%, #006ca4 100%);
background: linear-gradient(to bottom, #017cb4 0%, #006ca4 100%);
box-shadow: inset 0 1px 1px 0 #005080;
-webkit-box-shadow: inset 0 1px 1px 0 #005080;
}
#searchfilter {
position: absolute;
right: 256px;
width: auto;
top: 2px;
}
#searchfilter select {
height: 26px;
}
#mailview-left select.mailboxlist {
position: relative;
top: 10px;
width: 100%;
}
#messagetoolbar {
position: absolute;
top: -6px;
left: 0;
height: 40px;
white-space: nowrap;
z-index: 10;
}
#messagetoolbar.fullwidth {
right: 0;
}
#messagesearchtools {
position: absolute;
right: 0;
top: 0;
}
#mailpreviewtoggle {
display: block;
position: absolute;
top: 7px;
right: 4px;
width: 20px;
height: 18px;
background: url(images/buttons.png) -3px -458px no-repeat;
}
#mailpreviewtoggle.enabled {
background-position: -28px -458px;
}
/*** message list ***/
table.messagelist {
z-index: 1;
}
table.messagelist.fixedcopy {
z-index: 2;
}
.messagelist thead th:first-child {
border-radius: 4px 0 0 0; /* for Chrome */
}
.messagelist tr > .attachment,
.messagelist tr > .threads,
.messagelist tr > .status,
.messagelist tr > .flag,
.messagelist tr > .priority {
width: 20px;
padding: 2px 3px !important;
}
.messagelist tr > .threads {
width: 26px;
}
.messagelist tr > .threads + td,
.messagelist tr > .threads + th {
border-left: 0;
}
.messagelist tr > .size {
width: 60px;
text-align: right;
}
.messagelist thead tr th.size {
text-align: left;
}
.messagelist tr > .fromto,
.messagelist tr > .from,
.messagelist tr > .to,
.messagelist tr > .cc,
.messagelist tr > .replyto {
width: 200px;
}
.messagelist tr > .date {
width: 155px;
}
.messagelist tr > .folder {
width: 135px;
}
.messagelist tr > .hidden {
display: none;
}
.messagelist tr.message {
/* background-color: #fff; */
}
.messagelist tr.thread.expanded td {
background-color: #ededed;
}
.messagelist tr.unread {
font-weight: bold;
/* background-color: #fff; */
}
.messagelist tr.flagged th,
.messagelist tr.flagged td,
.messagelist tr.flagged td a {
color: #f30;
}
.messagelist thead tr th.sortedASC a,
.messagelist thead tr th.sortedDESC a {
color: #004458;
text-decoration: underline;
background-image: url(images/listicons.png);
background-repeat: no-repeat;
background-position: right -912px;
}
.messagelist thead tr th.sortedASC a {
background-position: right -944px;
}
.messagelist td img {
vertical-align: middle;
display: inline-block;
}
.messagelist tbody td a {
color: #333;
text-decoration: none;
white-space: nowrap;
cursor: default;
}
.messagelist tbody tr td.flag,
.messagelist tbody tr td.status,
.messagelist tbody tr td.subject span.status {
cursor: pointer;
}
.messagelist tr > .flag span,
.messagelist tr > .status span,
.messagelist tr > .attachment span,
.messagelist tr > .priority span {
display: block;
width: 20px;
text-indent: -5000px;
overflow: hidden;
}
.messagelist tr td div.collapsed,
.messagelist tr td div.expanded,
.messagelist tr > .threads .listmenu,
.messagelist tr > .attachment span.attachment,
.messagelist tr > .attachment span.report,
.messagelist tr > .priority span.priority,
.messagelist tr > .priority span.prio1,
.messagelist tr > .priority span.prio2,
.messagelist tr > .priority span.prio3,
.messagelist tr > .priority span.prio4,
.messagelist tr > .priority span.prio5,
.messagelist tr > .flag span.flagged,
.messagelist tr > .flag span.unflagged,
.messagelist tr > .flag span.unflagged:hover,
.messagelist tr > .status span.status,
.messagelist tr > .status span.msgicon,
.messagelist tr > .status span.deleted,
.messagelist tr > .status span.unread,
.messagelist tr > .status span.unreadchildren,
.messagelist tr > .subject span.msgicon,
.messagelist tr > .subject span.deleted,
.messagelist tr > .subject span.unread,
.messagelist tr > .subject span.replied,
.messagelist tr > .subject span.forwarded,
.messagelist tr > .subject span.unreadchildren {
display: inline-block;
vertical-align: middle;
height: 18px;
width: 20px;
padding: 0;
background: url(images/listicons.png) -100px 0 no-repeat;
}
.messagelist tbody tr td.attachment span.attachment {
background-position: 0 -996px;
}
.messagelist thead tr th.attachment span.attachment {
background-position: -24px -996px;
}
.messagelist tbody tr td.attachment span.report {
background-position: -24px -1116px;
}
.messagelist thead tr th.priority span.priority {
background-position: -25px -1845px;
}
.messagelist tr td.priority span.prio5 {
background-position: 0 -1905px;
}
.messagelist tr td.priority span.prio4 {
background-position: 0 -1885px;
}
.messagelist tr td.priority span.prio2 {
background-position: 0 -1865px;
}
.messagelist tr td.priority span.prio1 {
background-position: 0 -1845px;
}
.messagelist tbody tr td.flag span.flagged {
background-position: 0 -1036px;
}
.messagelist thead tr th.flag span.flagged {
background-position: -22px -1037px;
}
.messagelist tr:hover td.status span.msgicon {
background-position: -23px -1057px;
}
.messagelist tr:hover td.flag span.unflagged {
background-position: -23px -1076px;
}
.messagelist tr td.subject span.msgicon,
.messagelist tr td.subject span.unreadchildren {
background-position: 0 -1056px;
margin: 0 1px 0 0;
width: 24px;
}
.messagelist tr td.subject span.replied {
background-position: 0 -1076px;
}
.messagelist tr td.subject span.forwarded {
background-position: 0 -1096px;
}
.messagelist tr td.subject span.replied.forwarded {
background-position: 0 -1116px;
}
.messagelist tr td.status span.msgicon,
.messagelist tr td.flag span.unflagged,
.messagelist tr td.status span.unreadchildren {
background-position: 0 1056px; /* no icon */
}
/*
.messagelist tr td.status span.msgicon:hover {
background-position: 0 -272px;
}
*/
.messagelist tr td.status span.deleted,
.messagelist tr:hover td.status span.deleted,
.messagelist tr td.subject span.deleted {
background-position: -21px -1096px;
}
.messagelist tr td.status span.status,
.messagelist tr td.status span.unread,
.messagelist tr td.subject span.unread,
.messagelist tr td.status span.unread:hover {
background-position: 0 -1017px;
}
.messagelist thead tr th.status span.status {
background-position: -23px -1017px;
}
.messagelist tr td div.collapsed {
background-position: 0 -1137px;
cursor: pointer;
}
.messagelist tr td div.expanded {
background-position: 0 -1157px;
cursor: pointer;
}
.messagelist tr th.threads .listmenu {
background-position: 4px -972px;
cursor: pointer;
width: 24px;
height: 21px;
overflow: hidden;
text-indent: -5000px;
margin: -3px -5px -2px -6px;
padding: 3px 5px 2px 6px;
}
.messagelist tr th.threads .listmenu:focus {
background-color: rgba(73,180,210,0.7);
outline: none;
}
.messagelist thead tr th.subject,
.messagelist tbody tr td.subject {
width: 99%;
white-space: nowrap;
}
.messagelist tbody tr td.subject a {
cursor: default;
vertical-align: middle; /* #1487091 */
}
/* thread parent message with unread children */
.messagelist tbody tr.unroot td.subject a {
text-decoration: underline;
}
/**** tree indicators ****/
.messagelist tbody tr td span.branch div {
display: inline-block;
}
.messagelist tbody tr td span.branch div.tree {
width: 15px;
}
#listoptions ul.proplist {
min-width: 16em;
}
/**** message view ****/
#mailpreviewframe {
display: none;
position: absolute;
top: 0;
left: 0;
width: 100%;
bottom: 0px;
}
#messagecontframe {
border: 0;
border-radius: 4px;
}
#messagecontent {
position: absolute;
top: 110px;
left: 0;
width: 100%;
bottom: 1px;
overflow: auto;
-webkit-overflow-scrolling: touch;
}
#messageheader,
#composeheaders {
position: relative;
padding: 3px 0;
background: #f9f9f9;
background: -moz-linear-gradient(top, #fff 0%, #f0f0f0 100%);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#fff), color-stop(100%,#f0f0f0));
background: -o-linear-gradient(top, #fff 0%, #f0f0f0 100%);
background: -ms-linear-gradient(top, #fff 0%, #f0f0f0 100%);
background: linear-gradient(to bottom, #fff 0%, #f0f0f0 100%);
border-bottom: 1px solid #dfdfdf;
}
#mailview-right #messageheader {
border-radius: 4px 4px 0 0;
padding-left: 78px;
/* avoid headers eating up all the vertical space */
max-height: 50%;
overflow: auto;
}
h2.subject {
font-size: 15px;
margin: 0 15em 0 0;
padding: 4px 8px 2px 8px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
#mailview-right #messageheader h2.subject {
margin-left: -56px;
}
h3.subject {
font-size: 14px;
margin: 0 15em 0 0;
padding: 8px 8px 4px 8px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.headers-table td {
color: #666;
padding: 2px 8px;
}
.headers-table td.header,
.ui-dialog-content.popup span.adr {
font-weight: bold;
}
.headers-table td.header-title {
white-space: nowrap;
}
.headers-table td.header a,
.ui-dialog-content.popup span.adr a {
color: #666;
text-decoration: none;
}
.headers-table td.header a:hover,
.ui-dialog-content.popup span.adr a:hover {
text-decoration: underline;
}
.headers-table td.subject {
color: #333;
font-size: 110%;
font-weight: bold;
}
.headers-table td.header span,
.ui-dialog-content.popup span.adr {
white-space: nowrap;
}
.headers-table td.header a.morelink {
color: #0069a6;
white-space: nowrap;
font-weight: normal;
}
.rcmaddcontact {
position: relative;
top: 1px;
margin-left: 0.5em;
}
.rcmaddcontact imp {
width: 20px;
height: 13px;
}
#preview-allheaders {
display: none;
}
#preview-allheaders td.header-title,
#preview-shortheaders td.header-title {
padding-left: 0;
}
#preview-shortheaders td.header {
padding-right: 18px;
}
.moreheaderstoggle {
display: block;
position: absolute;
top: 0;
left: 0;
bottom: 0;
width: 18px;
padding: 0;
outline: none;
background: #f2f2f2;
background: -moz-linear-gradient(left, #fbfbfb 0, #e9e9e9 100%);
background: -webkit-gradient(linear, left top, right top, color-stop(0,#fbfbfb), color-stop(100%,#e9e9e9));
background: -o-linear-gradient(left, #fbfbfb 0, #e9e9e9 100%);
background: -ms-linear-gradient(left, #fbfbfb 0, #e9e9e9 100%);
background: linear-gradient(left, #fbfbfb 0, #e9e9e9 100%);
border-right: 1px solid #dfdfdf;
border-radius: 3px 0 0 0; /* for Opera */
}
.moreheaderstoggle:focus {
background: #f2f2f2;
background: -moz-linear-gradient(left, #66bcd9 0, #49b3d2 100%);
background: -webkit-gradient(linear, left top, right top, color-stop(0,#66bcd9), color-stop(100%,#49b3d2));
background: -o-linear-gradient(left, #66bcd9 0, #49b3d2 100%);
background: -ms-linear-gradient(left, #66bcd9 0, #49b3d2 100%);
background: linear-gradient(left, #66bcd9 0, #49b3d2 100%);
border-right-color: #149cc5;
}
.moreheaderstoggle .iconlink {
display: inline-block;
position: absolute;
top: 8px;
left: 0;
width: 18px;
height: 16px;
background: url(images/buttons.png) -27px -242px no-repeat;
}
.moreheaderstoggle.remove .iconlink {
top: auto;
bottom: 5px;
background-position: -5px -242px;
}
#full-headers {
position: relative;
}
div.more-headers {
position: absolute;
top: -12px;
right: 10px;
width: 12px;
height: 10px;
cursor: pointer;
background: url(images/buttons.png) center -1579px no-repeat;
}
div.hide-headers {
background-position: center -1590px;
}
#all-headers {
position: relative;
margin: 4px 10px;
padding: 0;
height: 180px;
border: 1px solid #ccc;
border-radius: 4px;
background: #fdfdfd;
box-shadow: inset 0 0 1px 1px rgba(0,0,0, 0.1);
-webkit-box-shadow: inset 0 0 1px 1px rgba(0,0,0, 0.1);
}
#headers-source {
display: none;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
padding: 3px 6px;
overflow: auto;
text-align: left;
color: #333;
}
#messageheader.previewheader #all-headers {
margin-left: 0;
}
#messageheader.previewheader {
position: relative;
height: auto;
min-height: 52px;
padding: 0 0 3px 72px;
}
#messageheader.previewheader h3.subject {
padding: 8px 8px 2px 0;
}
#messageheader.previewheader #contactphoto {
display: block;
position: absolute;
top: 11px;
left: 30px;
width: 32px;
height: 32px;
overflow: hidden;
background: url(images/contactpic_32px.png) center center no-repeat #fff;
border-radius: 3px;
}
#messageheader.previewheader #contactphoto img {
width: 32px;
height: auto;
border-radius: 3px;
}
#messageheader .message-headers {
min-height: 60px;
}
#messageheader #contactphoto {
display: block;
position: absolute;
top: 34px;
left: 30px;
width: 48px;
height: 48px;
overflow: hidden;
border-radius: 4px;
border: 1px solid #e6e6e6;
background: url(images/contactpic_48px.png) center center no-repeat #fff;
}
#messageheader #contactphoto img {
width: 48px;
height: auto;
border-radius: 4px;
}
#messageheader #countcontrols,
#messageheader #formatcontrols {
position: absolute;
top: 8px;
right: 8px;
text-align: right;
white-space: nowrap;
}
#messageheader #formatcontrols {
top: 38px;
right: 8px;
}
#messageheader .pagenav .countdisplay {
padding-right: 0.5em;
white-space: nowrap;
}
#messagecontent .leftcol,
#messagepreview .leftcol {
margin-right: 252px;
}
#messagecontent .rightcol,
#messagepreview .rightcol {
float: right;
/*
position: absolute;
top: 10px;
right: 10px;
height: 90%;
*/
width: 230px;
margin: 8px;
min-height: 200px;
background: #f0f0f0;
padding: 8px;
border-radius: 4px;
}
#messagebody {
position: relative;
margin: 8px;
}
#message-objects div,
#messagebody span.part-notice {
margin: 8px;
}
#message-objects div.notice {
display: block;
color: #960;
border: 1px solid #ffdf0e;
background-color: #fef893;
background-position: 5px -83px;
padding: 6px 12px 6px 30px;
white-space: normal;
}
#message-objects div a.button,
#messagebody span.part-notice a.button {
margin-left: 10px;
margin-top: -1px;
}
div.message-part,
div.message-htmlpart,
div.message-partheaders {
padding: 10px 2px;
border-top: 1px solid #ccc;
}
#messagebody div:first-child {
padding-top: 0;
border-top: 0;
}
div.message-part div.pre {
margin: 0;
padding: 0;
font-family: monospace;
font-size: 12px;
}
div.message-part span.sig {
color: #666;
}
div.message-part blockquote {
color: blue;
border-left: 2px solid blue;
border-right: 2px solid blue;
background-color: #F6F6F6;
margin: 2px 0;
padding: 0 0.4em;
overflow: hidden;
text-overflow: ellipsis;
}
div.message-part blockquote blockquote {
color: green;
border-left: 2px solid green;
border-right: 2px solid green;
}
div.message-part blockquote blockquote blockquote {
color: #900;
border-left: 2px solid #b00;
border-right: 2px solid #b00;
}
div.message-partheaders {
margin-top: 8px;
padding: 8px 0;
}
div.message-partheaders .headers-table {
width: 100%;
}
div.message-partheaders .headers-table td.header-title {
width: auto;
padding-left: 0;
}
div.message-partheaders .headers-table td.header {
width: 88%;
}
#messagebody > hr {
color: #fff;
background: #fff;
border: 0;
border-bottom: 2px solid #f0f0f0;
}
#messagebody fieldset.image-attachment {
border: 0;
border-top: 1px solid #ccc;
margin-top: 1em;
}
#messagebody fieldset.image-attachment p > img {
max-width: 80%;
}
#messagebody legend.image-filename {
color: #999;
font-size: 0.9em;
margin: 0 1em;
}
#messagebody p.image-attachment {
position: relative;
padding: 1em;
border-top: 1px solid #ccc;
}
#messagebody p.image-attachment a.image-link {
float: left;
display: block;
margin-right: 2em;
min-width: 160px;
min-height: 60px;
text-align: center;
}
#messagebody p.image-attachment .image-filename {
display: block;
font-weight: bold;
line-height: 1.6em;
}
#messagebody p.image-attachment .image-filesize {
padding-right: 1em;
}
#messagebody p.image-attachment .attachment-links a {
margin-right: 0.6em;
}
#messagepartcontainer {
position: absolute;
top: 0;
left: 232px;
right: 0;
bottom: 0;
}
#messagepartframe {
border: 0;
width: 100%;
height: 100%;
}
#messagepartheader {
position: absolute;
top: 0;
left: 0;
width: 220px;
bottom: 0;
}
#messagepartheader table {
table-layout: fixed;
overflow: hidden;
}
#messagepartheader table td {
text-overflow: ellipsis;
overflow: hidden;
}
#messagepartheader table td.title {
width: 60px;
padding-right: 0;
}
/*** message composition ***/
#composeview-left {
position: absolute;
top: 0;
left: 0;
width: 200px;
bottom: 0;
}
#composeview-right {
position: absolute;
top: 0;
left: 212px;
right: 0;
bottom: 0;
}
#compose-contacts {
position: absolute;
top: 0;
left: 0;
width: 100%;
bottom: 0;
}
#compose-contacts .listsearchbox {
display: block;
}
#compose-contacts #directorylist {
border-bottom: 4px solid #c7e3ef;
}
#compose-contacts .scroller {
top: 65px;
border-top: 1px solid #fff;
}
#contacts-table {
table-layout: fixed;
}
#contacts-table td {
width: 100%;
}
#contacts-table td span {
display: block;
}
#contacts-table td span.email {
display: inline;
color: #69939e;
font-style: italic;
margin-left: 0.5em;
}
#compose-contacts li a,
#contacts-table td {
background-image: url(images/listicons.png);
background-position: -100px 0;
background-repeat: no-repeat;
overflow: hidden;
text-overflow: ellipsis;
}
#compose-contacts li a {
padding-left: 36px;
}
#contacts-table td.contactgroup a {
color: #376572;
text-decoration: none;
}
#contacts-table td.contactgroup a span {
display: inline-block;
font-size: 16px;
font-weight: bold;
line-height: 11px;
margin-left: 0.3em;
}
#contacts-table tr:first-child td {
border-top: 0;
}
#compose-contacts li.addressbook a {
background-position: 6px -766px;
}
#compose-contacts li.addressbook a:focus,
#compose-contacts li.addressbook.selected a {
background-position: 6px -791px;
}
#contacts-table td.contactgroup {
background-position: 6px -1555px;
}
#contacts-table tr.selected td.contactgroup {
background-position: 6px -1579px;
}
#contacts-table td.contact {
background-position: 6px -1603px;
}
#contacts-table tr.selected td.contact {
background-position: 6px -1627px;
}
#compose-content {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0px;
overflow: hidden;
}
#composeheaders {
border-radius: 4px 4px 0 0;
padding-left: 19px;
}
#composebuttons {
position: absolute;
top: 6px;
right: 6px;
width: auto;
white-space: nowrap;
z-index: 100;
}
#composebuttons a.button.extwin {
padding: 2px 3px;
}
.compose-headers {
width: 99%;
margin-bottom: 2px;
}
.compose-headers td {
padding: 2px 4px;
}
.compose-headers td.title {
width: 11%;
white-space: nowrap;
padding-left: 6px;
}
.compose-headers td.title label {
float: left;
}
.compose-headers td.title a.iconbutton {
float: right;
position: relative;
top: -2px;
width: 15px;
}
.compose-headers td.editfield {
width: 90%;
padding-left: 4px;
}
.compose-headers td.editfield a.iconlink {
margin-left: 0.5em;
}
.compose-headers td.formlinks {
padding: 0 4px;
}
.compose-headers td.top {
vertical-align: top;
padding-top: 10px;
}
.compose-headers td textarea,
.compose-headers td input {
width: 100%;
resize: none;
}
#compose-cc, #compose-bcc, #compose-replyto, #compose-followupto {
display: none;
}
#composeoptions {
display: none;
padding: 2px 0 0 8px;
white-space: normal;
border-top: 1px solid #dfdfdf;
box-shadow: inset 0 1px 0 0 #fff;
-webkit-box-shadow: inset 0 1px 0 0 #fff;
}
.composeoption {
color: #666;
padding-right: 22px;
white-space: nowrap;
}
#composeoptions .composeoption {
display: inline-block;
padding: 4px 22px 4px 0;
}
#composeoptions .composeoption:last-child {
padding-right: 4px;
}
.mozilla .composeoption input {
vertical-align: -3px;
}
#composeview-bottom {
position: relative;
width: 100%;
height: 200px;
}
#composebodycontainer {
position: absolute;
top: 0;
left: 0;
right: 260px;
bottom: 0;
border-radius: 0 0 0 4px;
}
#composebodycontainer.buttons {
bottom: 42px;
}
#composebody {
position: absolute;
top: 0;
left: 0;
bottom: 0;
width: 99%;
border: 0;
border-radius: 0 0 0 4px;
- padding: 8px 0 8px 8px;
+ padding: 4px;
resize: none;
font-family: monospace;
font-size: 9pt;
outline: none;
- box-shadow: inset 0 0 2px 1px rgba(0,0,0, 0.2);
- -webkit-box-shadow: inset 0 0 2px 1px rgba(0,0,0, 0.2);
+ box-shadow: inset 0 0 2px 1px rgba(0,0,0, 0.1);
+ -webkit-box-shadow: inset 0 0 2px 1px rgba(0,0,0, 0.1);
}
#composebody:active,
#composebody:focus {
box-shadow: inset 0 0 3px 2px rgba(71,135,177, 0.9);
-webkit-box-shadow: inset 0 0 3px 2px rgba(71,135,177, 0.9);
}
#compose-attachments {
position: absolute;
right: 0;
top: 1px;
bottom: 0;
width: 240px;
background: #f0f0f0;
border-style: solid;
border-color: #f0f0f0 #f0f0f0 #f0f0f0 #ddd;
border-width: 1px;
padding: 8px;
overflow: auto;
}
#compose-attachments.droptarget {
background-image: url(images/filedrop.png);
background-position: center bottom;
background-repeat: no-repeat;
}
#compose-attachments.droptarget.hover,
#compose-attachments.droptarget.active {
border-color: #019bc6;
box-shadow: 0 0 3px 2px rgba(71,135,177, 0.5);
-webkit-box-shadow: 0 0 3px 2px rgba(71,135,177, 0.5);
}
#compose-attachments.droptarget.hover {
background-color: #d9ecf4;
box-shadow: 0 0 5px 2px rgba(71,135,177, 0.9);
-webkit-box-shadow: 0 0 5px 2px rgba(71,135,177, 0.9);
}
#composeview-bottom .formbuttons.floating {
position: absolute;
width: auto;
right: 260px;
z-index: 200;
padding-bottom: 8px;
}
#composebodycontainer .mce-tinymce {
border: 0 !important;
margin-top: 1px;
}
#composebodycontainer .mce-panel {
border-color: #ccc !important;
background: #f0f0f0;
}
#composebody_toolbargroup {
border-bottom: 1px solid #ddd;
}
#uploadform a.iconlink {
margin-left: 1em;
text-indent: -5000px;
}
#uploadform form div {
margin: 4px 0;
}
diff --git a/skins/larry/ui.js b/skins/larry/ui.js
index 5cd216724..c8204b603 100644
--- a/skins/larry/ui.js
+++ b/skins/larry/ui.js
@@ -1,1464 +1,1464 @@
// @license http://creativecommons.org/publicdomain/zero/1.0/legalcode CC0
/**
* Roundcube functions for default skin interface
*
* Copyright (c) 2013, The Roundcube Dev Team
*
* The contents are subject to the Creative Commons Attribution-ShareAlike
* License. It is allowed to copy, distribute, transmit and to adapt the work
* by keeping credits to the original autors in the README file.
* See http://creativecommons.org/licenses/by-sa/3.0/ for details.
*/
function rcube_mail_ui()
{
var env = {};
var popups = {};
var popupconfig = {
forwardmenu: { editable:1 },
searchmenu: { editable:1, callback:searchmenu },
attachmentmenu: { },
listoptions: { editable:1 },
groupmenu: { above:1 },
mailboxmenu: { above:1 },
spellmenu: { callback: spellmenu },
'folder-selector': { iconized:1 }
};
var me = this;
var mailviewsplit;
var compose_headers = {};
var prefs;
// export public methods
this.set = setenv;
this.init = init;
this.init_tabs = init_tabs;
this.show_about = show_about;
this.show_popup = show_popup;
this.toggle_popup = toggle_popup;
this.add_popup = add_popup;
this.set_searchmod = set_searchmod;
this.set_searchscope = set_searchscope;
this.show_uploadform = show_uploadform;
this.show_header_row = show_header_row;
this.hide_header_row = hide_header_row;
this.update_quota = update_quota;
this.get_pref = get_pref;
this.save_pref = save_pref;
this.folder_search_init = folder_search_init;
// set minimal mode on small screens (don't wait for document.ready)
if (window.$ && document.body) {
var minmode = get_pref('minimalmode');
if (parseInt(minmode) || (minmode === null && $(window).height() < 850)) {
$(document.body).addClass('minimal');
}
if (bw.tablet) {
$('#viewport').attr('content', "width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0");
}
}
/**
*
*/
function setenv(key, val)
{
env[key] = val;
}
/**
* Get preference stored in browser
*/
function get_pref(key)
{
if (!prefs) {
prefs = rcmail.local_storage_get_item('prefs.larry', {});
}
// fall-back to cookies
if (prefs[key] == null) {
var cookie = rcmail.get_cookie(key);
if (cookie != null) {
prefs[key] = cookie;
// copy value to local storage and remove cookie (if localStorage is supported)
if (rcmail.local_storage_set_item('prefs.larry', prefs)) {
rcmail.set_cookie(key, cookie, new Date()); // expire cookie
}
}
}
return prefs[key];
}
/**
* Saves preference value to browser storage
*/
function save_pref(key, val)
{
prefs[key] = val;
// write prefs to local storage (if supported)
if (!rcmail.local_storage_set_item('prefs.larry', prefs)) {
// store value in cookie
var exp = new Date();
exp.setYear(exp.getFullYear() + 1);
rcmail.set_cookie(key, val, exp);
}
}
/**
* Initialize UI
* Called on document.ready
*/
function init()
{
rcmail.addEventListener('message', message_displayed);
/*** prepare minmode functions ***/
$('#taskbar a').each(function(i,elem){
$(elem).append('<span class="tooltip">' + $('.button-inner', this).html() + '</span>')
});
$('#taskbar .minmodetoggle').click(function(e){
var ismin = $(document.body).toggleClass('minimal').hasClass('minimal');
save_pref('minimalmode', ismin?1:0);
$(window).resize();
});
/*** mail task ***/
if (rcmail.env.task == 'mail') {
rcmail.addEventListener('menu-open', menu_toggle)
.addEventListener('menu-close', menu_toggle)
.addEventListener('menu-save', save_listoptions)
.addEventListener('responseafterlist', function(e){ switch_view_mode(rcmail.env.threading ? 'thread' : 'list', true) })
.addEventListener('responseaftersearch', function(e){ switch_view_mode(rcmail.env.threading ? 'thread' : 'list', true) });
var dragmenu = $('#dragmessagemenu');
if (dragmenu.length) {
rcmail.gui_object('dragmenu', 'dragmessagemenu');
popups.dragmenu = dragmenu;
}
if (rcmail.env.action == 'show' || rcmail.env.action == 'preview') {
rcmail.addEventListener('enable-command', enable_command)
.addEventListener('aftershow-headers', function() { layout_messageview(); })
.addEventListener('afterhide-headers', function() { layout_messageview(); });
$('#previewheaderstoggle').click(function(e){ toggle_preview_headers(); return false });
// add menu link for each attachment
$('#attachment-list > li').each(function() {
$(this).append($('<a class="drop" tabindex="0" aria-haspopup="true">Show options</a>')
.bind('click keypress', function(e) {
if (e.type != 'keypress' || rcube_event.get_keycode(e) == 13) {
attachmentmenu(this, e);
return false;
}
})
);
});
if (get_pref('previewheaders') == '1') {
toggle_preview_headers();
}
}
else if (rcmail.env.action == 'compose') {
rcmail.addEventListener('aftersend-attachment', show_uploadform)
.addEventListener('add-recipient', function(p){ show_header_row(p.field, true); })
.addEventListener('aftertoggle-editor', function(e){
window.setTimeout(function(){ layout_composeview() }, 200);
if (e && e.mode)
$("select[name='editorSelector']").val(e.mode);
});
// Show input elements with non-empty value
var f, v, field, fields = ['cc', 'bcc', 'replyto', 'followupto'];
for (f=0; f < fields.length; f++) {
v = fields[f]; field = $('#_'+v);
if (field.length) {
field.on('change', {v: v}, function(e) { if (this.value) show_header_row(e.data.v, true); });
if (field.val() != '')
show_header_row(v, true);
}
}
$('#composeoptionstoggle').click(function(e){
var expanded = $('#composeoptions').toggle().is(':visible');
$('#composeoptionstoggle').toggleClass('remove').attr('aria-expanded', expanded ? 'true' : 'false');
layout_composeview();
save_pref('composeoptions', expanded ? '1' : '0');
if (!rcube_event.is_keyboard(e))
this.blur();
return false;
}).css('cursor', 'pointer');
if (get_pref('composeoptions') !== '0') {
$('#composeoptionstoggle').click();
}
// adjust hight when textarea starts to scroll
$("textarea[name='_to'], textarea[name='_cc'], textarea[name='_bcc']").change(function(e){ adjust_compose_editfields(this); }).change();
rcmail.addEventListener('autocomplete_insert', function(p){ adjust_compose_editfields(p.field); });
// toggle compose options if opened in new window and they were visible before
var opener_rc = rcmail.opener();
if (opener_rc && opener_rc.env.action == 'compose' && $('#composeoptionstoggle', opener.document).hasClass('remove'))
$('#composeoptionstoggle').click();
new rcube_splitter({ id:'composesplitterv', p1:'#composeview-left', p2:'#composeview-right',
orientation:'v', relative:true, start:206, min:170, size:12, render:layout_composeview }).init();
}
else if (rcmail.env.action == 'list' || !rcmail.env.action) {
var previewframe = $('#mailpreviewframe').is(':visible');
$('#mailpreviewtoggle').addClass(previewframe ? 'enabled' : 'closed').attr('aria-expanded', previewframe ? 'true' : 'false')
.click(function(e) { toggle_preview_pane(e); return false; });
$('#maillistmode').addClass(rcmail.env.threading ? '' : 'selected').click(function(e) { switch_view_mode('list'); return false; });
$('#mailthreadmode').addClass(rcmail.env.threading ? 'selected' : '').click(function(e) { switch_view_mode('thread'); return false; });
mailviewsplit = new rcube_splitter({ id:'mailviewsplitter', p1:'#mailview-top', p2:'#mailview-bottom',
orientation:'h', relative:true, start:310, min:150, size:12, offset:4 });
if (previewframe)
mailviewsplit.init();
rcmail.addEventListener('setquota', update_quota)
.addEventListener('enable-command', enable_command)
.addEventListener('afterimport-messages', show_uploadform);
}
else if (rcmail.env.action == 'get') {
new rcube_splitter({ id:'mailpartsplitterv', p1:'#messagepartheader', p2:'#messagepartcontainer',
orientation:'v', relative:true, start:226, min:150, size:12}).init();
}
if ($('#mailview-left').length) {
new rcube_splitter({ id:'mailviewsplitterv', p1:'#mailview-left', p2:'#mailview-right',
orientation:'v', relative:true, start:206, min:150, size:12, callback:render_mailboxlist, render:resize_leftcol }).init();
}
}
/*** settings task ***/
else if (rcmail.env.task == 'settings') {
rcmail.addEventListener('init', function(){
var tab = '#settingstabpreferences';
if (rcmail.env.action)
tab = '#settingstab' + (rcmail.env.action.indexOf('identity')>0 ? 'identities' : rcmail.env.action.replace(/\./g, ''));
$(tab).addClass('selected')
.children().first().removeAttr('onclick').click(function() { return false; });
});
if (rcmail.env.action == 'folders') {
new rcube_splitter({ id:'folderviewsplitter', p1:'#folderslist', p2:'#folder-details',
orientation:'v', relative:true, start:266, min:180, size:12 }).init();
rcmail.addEventListener('setquota', update_quota);
folder_search_init($('#folderslist'));
}
else if (rcmail.env.action == 'identities') {
new rcube_splitter({ id:'identviewsplitter', p1:'#identitieslist', p2:'#identity-details',
orientation:'v', relative:true, start:266, min:180, size:12 }).init();
}
else if (rcmail.env.action == 'responses') {
new rcube_splitter({ id:'responseviewsplitter', p1:'#identitieslist', p2:'#identity-details',
orientation:'v', relative:true, start:266, min:180, size:12 }).init();
}
else if (rcmail.env.action == 'preferences' || !rcmail.env.action) {
new rcube_splitter({ id:'prefviewsplitter', p1:'#sectionslist', p2:'#preferences-box',
orientation:'v', relative:true, start:266, min:180, size:12 }).init();
}
else if (rcmail.env.action == 'edit-prefs') {
$('<a href="#toggle"></a>')
.text(env.toggleoptions)
.attr('title', env.toggleoptions)
.addClass('advanced-toggle')
.appendTo('#preferences-details fieldset.advanced legend');
$('#preferences-details fieldset.advanced legend').click(function(e){
var collapsed = $(this).hasClass('collapsed'),
toggle = $('.advanced-toggle', this).html(collapsed ? '▲' : '▼');
$(this)
.toggleClass('collapsed')
.closest('fieldset').children('.propform').toggle()
}).addClass('collapsed')
}
}
/*** addressbook task ***/
else if (rcmail.env.task == 'addressbook') {
rcmail.addEventListener('afterupload-photo', show_uploadform)
.addEventListener('beforepushgroup', push_contactgroup)
.addEventListener('beforepopgroup', pop_contactgroup);
if (rcmail.env.action == '') {
new rcube_splitter({ id:'addressviewsplitterd', p1:'#addressview-left', p2:'#addressview-right',
orientation:'v', relative:true, start:206, min:150, size:12, render:resize_leftcol }).init();
new rcube_splitter({ id:'addressviewsplitter', p1:'#addresslist', p2:'#contacts-box',
orientation:'v', relative:true, start:266, min:260, size:12 }).init();
}
var dragmenu = $('#dragcontactmenu');
if (dragmenu.length) {
rcmail.gui_object('dragmenu', 'dragcontactmenu');
popups.dragmenu = dragmenu;
}
}
// turn a group of fieldsets into tabs
$('.tabbed').each(function(idx, elem){ init_tabs(elem); })
// decorate select elements
$('select.decorated').each(function(){
if (bw.opera) {
$(this).removeClass('decorated');
return;
}
var select = $(this),
parent = select.parent(),
height = Math.max(select.height(), 26) - 2,
width = select.width() - 22,
title = $('option', this).first().text();
if ($('option:selected', this).val() != '')
title = $('option:selected', this).text();
var overlay = $('<a class="menuselector" tabindex="-1"><span class="handle">' + title + '</span></a>')
.css('position', 'absolute')
.offset(select.position())
.insertAfter(select);
overlay.children().width(width).height(height).css('line-height', (height - 1) + 'px');
if (parent.css('position') != 'absolute')
parent.css('position', 'relative');
// re-set original select width to fix click action and options width in some browsers
select.width(overlay.width())
.on(bw.mz ? 'change keyup' : 'change', function() {
var val = $('option:selected', this).text();
$(this).next().children().text(val);
});
select
.on('focus', function(e){ overlay.addClass('focus'); })
.on('blur', function(e){ overlay.removeClass('focus'); });
});
// set min-width to show all toolbar buttons
var screen = $('body.minwidth');
if (screen.length) {
screen.css('min-width', $('.toolbar').width() + $('#quicksearchbar').width() + $('#searchfilter').width() + 30);
}
// don't use $(window).resize() due to some unwanted side-effects
window.onresize = resize;
resize();
}
/**
* Update UI on window resize
*/
function resize(e)
{
// resize in intervals to prevent lags and double onresize calls in Chrome (#1489005)
var interval = e ? 10 : 0;
if (rcmail.resize_timeout)
window.clearTimeout(rcmail.resize_timeout);
rcmail.resize_timeout = window.setTimeout(function() {
if (rcmail.env.task == 'mail') {
if (rcmail.env.action == 'show' || rcmail.env.action == 'preview')
layout_messageview();
else if (rcmail.env.action == 'compose')
layout_composeview();
}
// make iframe footer buttons float if scrolling is active
$('body.iframe .footerleft').each(function(){
var footer = $(this),
body = $(document.body),
floating = footer.hasClass('floating'),
overflow = body.outerHeight(true) > $(window).height();
if (overflow != floating) {
var action = overflow ? 'addClass' : 'removeClass';
footer[action]('floating');
body[action]('floatingbuttons');
}
});
}, interval);
}
/**
* Triggered when a new user message is displayed
*/
function message_displayed(p)
{
var siblings = $(p.object).siblings('div');
if (siblings.length)
$(p.object).insertBefore(siblings.first());
// show a popup dialog on errors
if (p.type == 'error' && rcmail.env.task != 'login') {
// hide original message object, we don't want both
rcmail.hide_message(p.object);
if (me.message_timer) {
window.clearTimeout(me.message_timer);
}
if (!me.messagedialog) {
me.messagedialog = $('<div>').addClass('popupdialog').hide();
}
var msg = p.message,
dialog_close = function() {
// check if dialog is still displayed, to prevent from js error
me.messagedialog.is(':visible') && me.messagedialog.dialog('destroy').hide();
};
if (me.messagedialog.is(':visible'))
msg = me.messagedialog.html() + '<p>' + p.message + '</p>';
me.messagedialog.html(msg)
.dialog({
resizable: false,
closeOnEscape: true,
dialogClass: 'popupmessage ' + p.type,
title: env.errortitle,
close: dialog_close,
position: ['center', 'center'],
hide: {effect: 'fadeOut'},
width: 420,
minHeight: 90
}).show();
me.messagedialog.closest('div[role=dialog]').attr('role', 'alertdialog');
if (p.timeout > 0)
me.message_timer = window.setTimeout(dialog_close, p.timeout);
}
}
/**
* Adjust UI objects of the mail view screen
*/
function layout_messageview()
{
$('#messagecontent').css('top', ($('#messageheader').outerHeight() + 1) + 'px');
$('#message-objects div a').addClass('button');
if (!$('#attachment-list li').length) {
$('div.rightcol').hide().attr('aria-hidden', 'true');
$('div.leftcol').css('margin-right', '0');
}
}
function render_mailboxlist(splitter)
{
// TODO: implement smart shortening of long folder names
}
function resize_leftcol(splitter)
{
// STUB
}
function adjust_compose_editfields(elem)
{
if (elem.nodeName == 'TEXTAREA') {
var $elem = $(elem), line_height = 14, // hard-coded because some browsers only provide the outer height in elem.clientHeight
content_height = elem.scrollHeight,
rows = elem.value.length > 80 && content_height > line_height*1.5 ? 2 : 1;
$elem.css('height', (line_height*rows) + 'px');
layout_composeview();
}
}
function layout_composeview()
{
var body = $('#composebody'),
form = $('#compose-content'),
bottom = $('#composeview-bottom'),
w, h, bh, ovflw, btns = 0,
minheight = 300,
bh = form.height() - bottom.position().top;
ovflw = minheight - bh;
btns = ovflw > -100 ? 0 : 40;
bottom.height(Math.max(minheight, bh));
form.css('overflow', ovflw > 0 ? 'auto' : 'hidden');
w = body.parent().width() - 5;
h = body.parent().height() - 8;
body.width(w).height(h);
$('#composebodycontainer > div').width(w+8);
$('#composebody_ifr').height(h + 4 - $('div.mce-toolbar').height());
- $('#googie_edit_layer').height(h - 8);
+ $('#googie_edit_layer').width(w).height(h);
// $('#composebodycontainer')[(btns ? 'addClass' : 'removeClass')]('buttons');
// $('#composeformbuttons')[(btns ? 'show' : 'hide')]();
var abooks = $('#directorylist');
if (abooks.length)
$('#compose-contacts .scroller').css('top', abooks.position().top + abooks.outerHeight());
}
function update_quota(p)
{
var element = $('#quotadisplay'), menu = $('#quotamenu'),
step = 24, step_count = 20,
y = p.total ? Math.ceil(p.percent / 100 * step_count) * step : 0;
// never show full-circle if quota is close to 100% but below.
if (p.total && y == step * step_count && p.percent < 100)
y -= step;
element.css('background-position', '0 -' + y + 'px');
if (p.table) {
if (!menu.length)
menu = $('<div id="quotamenu" class="popupmenu">').appendTo($('body'));
menu.html(p.table);
element.css('cursor', 'pointer').off('click').on('click', function(e) {
return rcmail.command('menu-open', 'quotamenu', e.target, e);
});
}
}
function folder_search_init(container)
{
// animation to unfold list search box
$('.boxtitle a.search', container).click(function(e) {
var title = $('.boxtitle', container),
box = $('.listsearchbox', container),
dir = box.is(':visible') ? -1 : 1,
height = 34 + ($('select', box).length ? 22 : 0);
box.slideToggle({
duration: 160,
progress: function(animation, progress) {
if (dir < 0) progress = 1 - progress;
$('.scroller', container).css('top', (title.outerHeight() + height * progress) + 'px');
},
complete: function() {
box.toggleClass('expanded');
if (box.is(':visible')) {
box.find('input[type=text]').focus();
height = 34 + ($('select', box).length ? $('select', box).outerHeight() + 4 : 0);
$('.scroller', container).css('top', (title.outerHeight() + height) + 'px');
}
else {
$('a.reset', box).click();
}
// TODO: save state in localStorage
}
});
return false;
});
}
function enable_command(p)
{
if (p.command == 'reply-list' && rcmail.env.reply_all_mode == 1) {
var label = rcmail.gettext(p.status ? 'replylist' : 'replyall');
if (rcmail.env.action == 'preview')
$('a.button.replyall').attr('title', label);
else
$('a.button.reply-all').text(label).attr('title', label);
}
}
/**
* Register a popup menu
*/
function add_popup(popup, config)
{
var obj = popups[popup] = $('#'+popup);
obj.appendTo(document.body); // move it to top for proper absolute positioning
if (obj.length)
popupconfig[popup] = $.extend(popupconfig[popup] || {}, config || {});
}
/**
* Trigger for popup menus
*/
function toggle_popup(popup, e, config)
{
// auto-register menu object
if (config || !popupconfig[popup])
add_popup(popup, config);
return rcmail.command('menu-open', popup, e.target, e);
}
/**
* (Deprecated) trigger for popup menus
*/
function show_popup(popup, show, config)
{
// auto-register menu object
if (config || !popupconfig[popup])
add_popup(popup, config);
config = popupconfig[popup] || {};
var ref = $(config.link ? config.link : '#'+popup+'link'),
pos = ref.offset();
if (ref.has('.inner'))
ref = ref.children('.inner');
// fire command with simulated mouse click event
return rcmail.command('menu-open',
{ menu:popup, show:show },
ref.get(0),
$.Event('click', { target:ref.get(0), pageX:pos.left, pageY:pos.top, clientX:pos.left, clientY:pos.top }));
}
/**
* Show/hide the preview pane
*/
function toggle_preview_pane(e)
{
var button = $(e.target),
frame = $('#mailpreviewframe'),
visible = !frame.is(':visible'),
splitter = mailviewsplit.pos || parseInt(get_pref('mailviewsplitter') || 320),
topstyles, bottomstyles, uid;
frame.toggle();
button.toggleClass('enabled closed').attr('aria-expanded', visible ? 'true' : 'false');
if (visible) {
$('#mailview-top').removeClass('fullheight').css({ bottom:'auto' });
$('#mailview-bottom').css({ height:'auto' }).show();
rcmail.env.contentframe = 'messagecontframe';
if (uid = rcmail.message_list.get_single_selection())
rcmail.show_message(uid, false, true);
// let the splitter set the correct size and position
if (mailviewsplit.handle) {
mailviewsplit.handle.show();
mailviewsplit.resize();
}
else
mailviewsplit.init();
}
else {
rcmail.env.contentframe = null;
rcmail.show_contentframe(false);
$('#mailview-top').addClass('fullheight').css({ height:'auto', bottom:'0px' });
$('#mailview-bottom').css({ top:'auto', height:'0px' }).hide();
if (mailviewsplit.handle)
mailviewsplit.handle.hide();
}
if (rcmail.message_list) {
if (visible && uid)
rcmail.message_list.scrollto(uid);
rcmail.message_list.resize();
}
rcmail.command('save-pref', { name:'preview_pane', value:(visible?1:0) });
}
/**
* Switch between short and full headers display in message preview
*/
function toggle_preview_headers()
{
$('#preview-shortheaders').toggle();
var full = $('#preview-allheaders').toggle(),
button = $('a#previewheaderstoggle');
// add toggle button to full headers table
if (full.is(':visible'))
button.attr('href', '#hide').removeClass('add').addClass('remove').attr('aria-expanded', 'true');
else
button.attr('href', '#details').removeClass('remove').addClass('add').attr('aria-expanded', 'false');
save_pref('previewheaders', full.is(':visible') ? '1' : '0');
}
/**
*
*/
function switch_view_mode(mode, force)
{
if (force || !$('#mail'+mode+'mode').hasClass('disabled')) {
$('#maillistmode, #mailthreadmode').removeClass('selected').attr('tabindex', '0').attr('aria-disabled', 'false');
$('#mail'+mode+'mode').addClass('selected').attr('tabindex', '-1').attr('aria-disabled', 'true');
}
}
/**** popup menu callbacks ****/
/**
* Handler for menu-open and menu-close events
*/
function menu_toggle(p)
{
if (p && p.name == 'messagelistmenu') {
show_listoptions(p);
}
else if (p) {
// adjust menu position according to config
var config = popupconfig[p.name] || {},
ref = $(config.link || '#'+p.name+'link'),
visible = p.obj && p.obj.is(':visible'),
above = config.above;
// fix position according to config
if (p.obj && visible && ref.length) {
var parent = ref.parent(),
win = $(window), pos;
if (parent.hasClass('dropbutton'))
ref = parent;
if (config.above || ref.hasClass('dropbutton')) {
pos = ref.offset();
p.obj.css({ left:pos.left+'px', top:(pos.top + (config.above ? -p.obj.height() : ref.outerHeight()))+'px' });
}
}
// add the right classes
if (p.obj && config.iconized) {
p.obj.children('ul').addClass('iconized');
}
// apply some data-attributes from menu config
if (p.obj && config.editable)
p.obj.attr('data-editable', 'true');
// trigger callback function
if (typeof config.callback == 'function') {
config.callback(visible, p);
}
}
}
function searchmenu(show)
{
if (show && rcmail.env.search_mods) {
var n, all,
obj = popups['searchmenu'],
list = $('input:checkbox[name="s_mods[]"]', obj),
mbox = rcmail.env.mailbox,
mods = rcmail.env.search_mods,
scope = rcmail.env.search_scope || 'base';
if (rcmail.env.task == 'mail') {
if (scope == 'all')
mbox = '*';
mods = mods[mbox] ? mods[mbox] : mods['*'];
all = 'text';
$('input:radio[name="s_scope"]').prop('checked', false).filter('#s_scope_'+scope).prop('checked', true);
}
else {
all = '*';
}
if (mods[all])
list.map(function() {
this.checked = true;
this.disabled = this.value != all;
});
else {
list.prop('disabled', false).prop('checked', false);
for (n in mods)
$('#s_mod_' + n).prop('checked', true);
}
}
}
function attachmentmenu(elem, event)
{
var id = elem.parentNode.id.replace(/^attach/, '');
$('#attachmenuopen').unbind('click').attr('onclick', '').click(function(e) {
return rcmail.command('open-attachment', id, this);
});
$('#attachmenudownload').unbind('click').attr('onclick', '').click(function() {
rcmail.command('download-attachment', id, this);
});
popupconfig.attachmentmenu.link = elem;
rcmail.command('menu-open', {menu: 'attachmentmenu', id: id}, elem, event);
}
function spellmenu(show, p)
{
var k, link, li,
lang = rcmail.spellcheck_lang(),
ul = $('ul', p.obj);
if (!ul.length) {
ul = $('<ul class="toolbarmenu selectable" role="menu">');
for (k in rcmail.env.spell_langs) {
li = $('<li role="menuitem">');
link = $('<a href="#'+k+'" tabindex="0"></a>').text(rcmail.env.spell_langs[k])
.addClass('active').data('lang', k)
.bind('click keypress', function(e) {
if (e.type != 'keypress' || rcube_event.get_keycode(e) == 13) {
rcmail.spellcheck_lang_set($(this).data('lang'));
rcmail.hide_menu('spellmenu', e);
return false;
}
});
link.appendTo(li);
li.appendTo(ul);
}
ul.appendTo(p.obj);
}
// select current language
$('li', ul).each(function() {
var el = $('a', this);
if (el.data('lang') == lang)
el.addClass('selected').attr('aria-selected', 'true');
else if (el.hasClass('selected'))
el.removeClass('selected').removeAttr('aria-selected');
});
}
/**
*
*/
function show_listoptions(p)
{
var $dialog = $('#listoptions');
// close the dialog
if ($dialog.is(':visible')) {
$dialog.dialog('close', p.originalEvent);
return;
}
// set form values
$('input[name="sort_col"][value="'+rcmail.env.sort_col+'"]').prop('checked', true);
$('input[name="sort_ord"][value="DESC"]').prop('checked', rcmail.env.sort_order == 'DESC');
$('input[name="sort_ord"][value="ASC"]').prop('checked', rcmail.env.sort_order != 'DESC');
// set checkboxes
$('input[name="list_col[]"]').each(function() {
$(this).prop('checked', $.inArray(this.value, rcmail.env.listcols) != -1);
});
$dialog.dialog({
modal: true,
resizable: false,
closeOnEscape: true,
title: null,
open: function(e) {
setTimeout(function(){ $dialog.find('a, input:not(:disabled)').not('[aria-disabled=true]').first().focus(); }, 100);
},
close: function(e) {
$dialog.dialog('destroy').hide();
if (e.originalEvent && rcube_event.is_keyboard(e.originalEvent))
$('#listmenulink').focus();
},
minWidth: 500,
width: $dialog.width()+25
}).show();
}
/**
*
*/
function save_listoptions(p)
{
$('#listoptions').dialog('close');
if (rcube_event.is_keyboard(p.originalEvent))
$('#listmenulink').focus();
var sort = $('input[name="sort_col"]:checked').val(),
ord = $('input[name="sort_ord"]:checked').val(),
cols = $('input[name="list_col[]"]:checked')
.map(function(){ return this.value; }).get();
rcmail.set_list_options(cols, sort, ord, rcmail.env.threading);
}
/**
*
*/
function set_searchmod(elem)
{
var all, m, task = rcmail.env.task,
mods = rcmail.env.search_mods,
mbox = rcmail.env.mailbox,
scope = $('input[name="s_scope"]:checked').val();
if (scope == 'all')
mbox = '*';
if (!mods)
mods = {};
if (task == 'mail') {
if (!mods[mbox])
mods[mbox] = rcube_clone_object(mods['*']);
m = mods[mbox];
all = 'text';
}
else { //addressbook
m = mods;
all = '*';
}
if (!elem.checked)
delete(m[elem.value]);
else
m[elem.value] = 1;
// mark all fields
if (elem.value == all) {
$('input:checkbox[name="s_mods[]"]').map(function() {
if (this == elem)
return;
this.checked = true;
if (elem.checked) {
this.disabled = true;
delete m[this.value];
}
else {
this.disabled = false;
m[this.value] = 1;
}
});
}
rcmail.set_searchmods(m);
}
function set_searchscope(elem)
{
rcmail.set_searchscope(elem.value);
}
function push_contactgroup(p)
{
// lets the contacts list swipe to the left, nice!
var table = $('#contacts-table'),
scroller = table.parent().css('overflow', 'hidden');
table.clone()
.css({ position:'absolute', top:'0', left:'0', width:table.width()+'px', 'z-index':10 })
.appendTo(scroller)
.animate({ left: -(table.width()+5) + 'px' }, 300, 'swing', function(){
$(this).remove();
scroller.css('overflow', 'auto')
});
}
function pop_contactgroup(p)
{
// lets the contacts list swipe to the left, nice!
var table = $('#contacts-table'),
scroller = table.parent().css('overflow', 'hidden'),
clone = table.clone().appendTo(scroller);
table.css({ position:'absolute', top:'0', left:-(table.width()+5) + 'px', width:table.width()+'px', height:table.height()+'px', 'z-index':10 })
.animate({ left:'0' }, 300, 'linear', function(){
clone.remove();
$(this).css({ position:'relative', left:'0', width:'100%', height:'auto', 'z-index':1 });
scroller.css('overflow', 'auto')
});
}
function show_uploadform(e)
{
var $dialog = $('#upload-dialog');
// close the dialog
if ($dialog.is(':visible')) {
$dialog.dialog('close');
return;
}
// add icons to clone file input field
if (rcmail.env.action == 'compose' && !$dialog.data('extended')) {
$('<a>')
.addClass('iconlink add')
.attr('href', '#add')
.html('Add')
.appendTo($('input[type="file"]', $dialog).parent())
.click(add_uploadfile);
$dialog.data('extended', true);
}
$dialog.dialog({
modal: true,
resizable: false,
closeOnEscape: true,
title: $dialog.attr('title'),
open: function(e) {
if (!document.all)
$('input[type=file]', $dialog).first().click();
},
close: function() {
try { $('#upload-dialog form').get(0).reset(); }
catch(e){ } // ignore errors
$dialog.dialog('destroy').hide();
$('div.addline', $dialog).remove();
},
width: 480
}).show();
}
function add_uploadfile(e)
{
var div = $(this).parent();
var clone = div.clone().addClass('addline').insertAfter(div);
clone.children('.iconlink').click(add_uploadfile);
clone.children('input').val('');
if (!document.all)
$('input[type=file]', clone).click();
}
/**
*
*/
function show_header_row(which, updated)
{
var row = $('#compose-' + which);
if (row.is(':visible'))
return; // nothing to be done here
if (compose_headers[which] && !updated)
$('#_' + which).val(compose_headers[which]);
row.show();
$('#' + which + '-link').hide();
layout_composeview();
$('input,textarea', row).focus();
return false;
}
/**
*
*/
function hide_header_row(which)
{
// copy and clear field value
var field = $('#_' + which);
compose_headers[which] = field.val();
field.val('');
$('#compose-' + which).hide();
$('#' + which + '-link').show();
layout_composeview();
return false;
}
/**
* Fieldsets-to-tabs converter
*/
function init_tabs(elem, current)
{
var content = $(elem),
id = content.get(0).id,
fs = content.children('fieldset');
if (!fs.length)
return;
if (!id) {
id = 'rcmtabcontainer';
content.attr('id', id);
}
// create tabs container
var tabs = $('<ul>').addClass('tabsbar').prependTo(content);
// convert fildsets into tabs
fs.each(function(idx) {
var tab, a, elm = $(this),
legend = elm.children('legend'),
tid = id + '-t' + idx;
// create a tab
a = $('<a>').text(legend.text()).attr('href', '#' + tid);
tab = $('<li>').addClass('tablink');
// remove legend
legend.remove();
// link fieldset with tab item
elm.attr('id', tid);
// add the tab to container
tab.append(a).appendTo(tabs);
});
// use jquery UI tabs widget to do the interaction and styling
content.tabs({
active: current || 0,
heightStyle: 'content',
activate: function(e, ui) {resize(); }
});
}
/**
* Show about page as jquery UI dialog
*/
function show_about(elem)
{
var frame = $('<iframe>').attr('id', 'aboutframe')
.attr('src', rcmail.url('settings/about'))
.attr('frameborder', '0')
.appendTo(document.body);
var h = Math.floor($(window).height() * 0.75);
var buttons = {};
var supportln = $('#supportlink');
if (supportln.length && (env.supporturl = supportln.attr('href')))
buttons[supportln.html()] = function(e){ env.supporturl.indexOf('mailto:') < 0 ? window.open(env.supporturl) : location.href = env.supporturl };
frame.dialog({
modal: true,
resizable: false,
closeOnEscape: true,
title: elem ? elem.title || elem.innerHTML : null,
close: function() {
frame.dialog('destroy').remove();
},
buttons: buttons,
width: 640,
height: h
}).width(640);
}
}
/**
* Roundcube Scroller class
*
* @deprecated Use treelist widget
*/
function rcube_scroller(list, top, bottom)
{
var ref = this;
this.list = $(list);
this.top = $(top);
this.bottom = $(bottom);
this.step_size = 6;
this.step_time = 20;
this.delay = 500;
this.top
.mouseenter(function() { if (rcmail.drag_active) ref.ts = window.setTimeout(function() { ref.scroll('down'); }, ref.delay); })
.mouseout(function() { if (ref.ts) window.clearTimeout(ref.ts); });
this.bottom
.mouseenter(function() { if (rcmail.drag_active) ref.ts = window.setTimeout(function() { ref.scroll('up'); }, ref.delay); })
.mouseout(function() { if (ref.ts) window.clearTimeout(ref.ts); });
this.scroll = function(dir)
{
var ref = this, size = this.step_size;
if (!rcmail.drag_active)
return;
if (dir == 'down')
size *= -1;
this.list.get(0).scrollTop += size;
this.ts = window.setTimeout(function() { ref.scroll(dir); }, this.step_time);
};
};
/**
* Roundcube UI splitter class
*
* @constructor
*/
function rcube_splitter(p)
{
this.p = p;
this.id = p.id;
this.horizontal = (p.orientation == 'horizontal' || p.orientation == 'h');
this.halfsize = (p.size !== undefined ? p.size : 10) / 2;
this.pos = p.start || 0;
this.min = p.min || 20;
this.offset = p.offset || 0;
this.relative = p.relative ? true : false;
this.drag_active = false;
this.render = p.render;
this.callback = p.callback;
var me = this;
rcube_splitter._instances[this.id] = me;
this.init = function()
{
this.p1 = $(this.p.p1);
this.p2 = $(this.p.p2);
this.parent = this.p1.parent();
// check if referenced elements exist, otherwise abort
if (!this.p1.length || !this.p2.length)
return;
// create and position the handle for this splitter
this.p1pos = this.relative ? this.p1.position() : this.p1.offset();
this.p2pos = this.relative ? this.p2.position() : this.p2.offset();
this.handle = $('<div>')
.attr('id', this.id)
.attr('unselectable', 'on')
.attr('role', 'presentation')
.addClass('splitter ' + (this.horizontal ? 'splitter-h' : 'splitter-v'))
.appendTo(this.parent)
.bind('mousedown', onDragStart);
if (this.horizontal) {
var top = this.p1pos.top + this.p1.outerHeight();
this.handle.css({ left:'0px', top:top+'px' });
}
else {
var left = this.p1pos.left + this.p1.outerWidth();
this.handle.css({ left:left+'px', top:'0px' });
}
// listen to window resize on IE
if (bw.ie)
$(window).resize(onResize);
// read saved position from cookie
var cookie = this.get_cookie();
if (cookie && !isNaN(cookie)) {
this.pos = parseFloat(cookie);
this.resize();
}
else if (this.pos) {
this.resize();
this.set_cookie();
}
};
/**
* Set size and position of all DOM objects
* according to the saved splitter position
*/
this.resize = function()
{
if (this.horizontal) {
this.p1.css('height', Math.floor(this.pos - this.p1pos.top - Math.floor(this.halfsize)) + 'px');
this.p2.css('top', Math.ceil(this.pos + Math.ceil(this.halfsize) + 2) + 'px');
this.handle.css('top', Math.round(this.pos - this.halfsize + this.offset)+'px');
if (bw.ie) {
var new_height = parseInt(this.parent.outerHeight(), 10) - parseInt(this.p2.css('top'), 10) - (bw.ie8 ? 2 : 0);
this.p2.css('height', (new_height > 0 ? new_height : 0) + 'px');
}
}
else {
this.p1.css('width', Math.floor(this.pos - this.p1pos.left - Math.floor(this.halfsize)) + 'px');
this.p2.css('left', Math.ceil(this.pos + Math.ceil(this.halfsize)) + 'px');
this.handle.css('left', Math.round(this.pos - this.halfsize + this.offset + 3)+'px');
if (bw.ie) {
var new_width = parseInt(this.parent.outerWidth(), 10) - parseInt(this.p2.css('left'), 10) ;
this.p2.css('width', (new_width > 0 ? new_width : 0) + 'px');
}
}
this.p2.resize();
this.p1.resize();
// also resize iframe covers
if (this.drag_active) {
$('iframe').each(function(i, elem) {
var pos = $(this).offset();
$('#iframe-splitter-fix-'+i).css({ top: pos.top+'px', left: pos.left+'px', width:elem.offsetWidth+'px', height: elem.offsetHeight+'px' });
});
}
if (typeof this.render == 'function')
this.render(this);
};
/**
* Handler for mousedown events
*/
function onDragStart(e)
{
// disable text selection while dragging the splitter
if (bw.konq || bw.chrome || bw.safari)
document.body.style.webkitUserSelect = 'none';
me.p1pos = me.relative ? me.p1.position() : me.p1.offset();
me.p2pos = me.relative ? me.p2.position() : me.p2.offset();
me.drag_active = true;
// start listening to mousemove events
$(document).bind('mousemove.'+this.id, onDrag).bind('mouseup.'+this.id, onDragStop);
// enable dragging above iframes
$('iframe').each(function(i, elem) {
$('<div>')
.attr('id', 'iframe-splitter-fix-'+i)
.addClass('iframe-splitter-fix')
.css({ background: '#fff',
width: elem.offsetWidth+'px', height: elem.offsetHeight+'px',
position: 'absolute', opacity: '0.001', zIndex: 1000
})
.css($(this).offset())
.appendTo('body');
});
};
/**
* Handler for mousemove events
*/
function onDrag(e)
{
if (!me.drag_active)
return false;
// with timing events dragging action is more responsive
window.clearTimeout(me.ts);
me.ts = window.setTimeout(function() { onDragAction(e); }, 1);
return false;
};
/**
* Dragging action (see onDrag())
*/
function onDragAction(e)
{
var pos = rcube_event.get_mouse_pos(e);
if (me.relative) {
var parent = me.parent.offset();
pos.x -= parent.left;
pos.y -= parent.top;
}
if (me.horizontal) {
if (((pos.y - me.halfsize) > me.p1pos.top) && ((pos.y + me.halfsize) < (me.p2pos.top + me.p2.outerHeight()))) {
me.pos = Math.max(me.min, pos.y - Math.max(0, me.offset));
if (me.pos > me.min)
me.pos = Math.min(me.pos, me.parent.height() - me.min);
me.resize();
}
}
else {
if (((pos.x - me.halfsize) > me.p1pos.left) && ((pos.x + me.halfsize) < (me.p2pos.left + me.p2.outerWidth()))) {
me.pos = Math.max(me.min, pos.x - Math.max(0, me.offset));
if (me.pos > me.min)
me.pos = Math.min(me.pos, me.parent.width() - me.min);
me.resize();
}
}
me.p1pos = me.relative ? me.p1.position() : me.p1.offset();
me.p2pos = me.relative ? me.p2.position() : me.p2.offset();
};
/**
* Handler for mouseup events
*/
function onDragStop(e)
{
// resume the ability to highlight text
if (bw.konq || bw.chrome || bw.safari)
document.body.style.webkitUserSelect = 'auto';
// cancel the listening for drag events
$(document).unbind('.'+me.id);
me.drag_active = false;
// remove temp divs
$('div.iframe-splitter-fix').remove();
me.set_cookie();
if (typeof me.callback == 'function')
me.callback(me);
return bw.safari ? true : rcube_event.cancel(e);
};
/**
* Handler for window resize events
*/
function onResize(e)
{
if (me.horizontal) {
var new_height = parseInt(me.parent.outerHeight(), 10) - parseInt(me.p2[0].style.top, 10) - (bw.ie8 ? 2 : 0);
me.p2.css('height', (new_height > 0 ? new_height : 0) +'px');
}
else {
var new_width = parseInt(me.parent.outerWidth(), 10) - parseInt(me.p2[0].style.left, 10);
me.p2.css('width', (new_width > 0 ? new_width : 0) + 'px');
}
};
/**
* Get saved splitter position from cookie
*/
this.get_cookie = function()
{
return window.UI ? UI.get_pref(this.id) : null;
};
/**
* Saves splitter position in cookie
*/
this.set_cookie = function()
{
if (window.UI)
UI.save_pref(this.id, this.pos);
};
} // end class rcube_splitter
// static getter for splitter instances
rcube_splitter._instances = {};
rcube_splitter.get_instance = function(id)
{
return rcube_splitter._instances[id];
};
// @license-end
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Mon, Aug 17, 2:21 PM (17 h, 39 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1256926
Default Alt Text
(167 KB)
Attached To
Mode
R3 roundcubemail
Attached
Detach File
Event Timeline
Log In to Comment